remote: use remote_is_configured() for add and rename

Both remote add and remote rename use a slightly different hand-rolled check if the remote exits. The hand-rolled check may have some subtle cases in which it might fail to detect when a remote already exists. One such case was fixed in fb86e32 ("git remote: allow adding remotes agreeing with url.<...>.insteadOf"). Another case is when a remote is configured as follows: [remote "foo"] vcs = bar If we try to run `git remote add foo bar` with the above remote configuration, git segfaults. This change fixes it. In addition, git remote rename $existing foo with the configuration for foo as above silently succeeds, even though foo already exists, modifying its configuration. With this patch it fails with "remote foo already exists". Signed-off-by: Thomas Gummerer <t.gummerer@gmail.com> Reviewed-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Thomas Gummerer committed Feb 16, 2016 at 10:47 UTC a31eeae27f38246ba35000fa603d884cdd1a81ae
2 files changed +17 -5
builtin/remote.c
+2 -5
@@ -186,10 +186,7 @@ static int add(int argc, const char **argv)
186 url = argv[1];
187
188 remote = remote_get(name);
189 - if (remote && (remote->url_nr > 1 ||
190 - (strcmp(name, remote->url[0]) &&
191 - strcmp(url, remote->url[0])) ||
192 - remote->fetch_refspec_nr))
189 + if (remote_is_configured(remote))
190 die(_("remote %s already exists."), name);
191
192 strbuf_addf(&buf2, "refs/heads/test:refs/remotes/%s/test", name);
@@ -641,7 +638,7 @@ static int mv(int argc, const char **argv)
638 return migrate_file(oldremote);
639
640 newremote = remote_get(rename.new);
644 - if (newremote && (newremote->url_nr > 1 || newremote->fetch_refspec_nr))
641 + if (remote_is_configured(newremote))
642 die(_("remote %s already exists."), rename.new);
643
644 strbuf_addf(&buf, "refs/heads/test:refs/remotes/%s/test", rename.new);
t/t5505-remote.sh
+15
@@ -157,6 +157,21 @@ test_expect_success 'rename errors out early when deleting non-existent branch'
157 )
158 '
159
160 +test_expect_success 'add existing foreign_vcs remote' '
161 + test_config remote.foo.vcs bar &&
162 + echo "fatal: remote foo already exists." >expect &&
163 + test_must_fail git remote add foo bar 2>actual &&
164 + test_i18ncmp expect actual
165 +'
166 +
167 +test_expect_success 'add existing foreign_vcs remote' '
168 + test_config remote.foo.vcs bar &&
169 + test_config remote.bar.vcs bar &&
170 + echo "fatal: remote bar already exists." >expect &&
171 + test_must_fail git remote rename foo bar 2>actual &&
172 + test_i18ncmp expect actual
173 +'
174 +
175 cat >test/expect <<EOF
176 * remote origin
177 Fetch URL: $(pwd)/one