Skip to content

Commit 28f555f

Browse files
Martin von Zweigbergkgitster
authored andcommitted
remote: write correct fetch spec when renaming remote 'remote'
When renaming a remote whose name is contained in a configured fetch refspec for that remote, we currently replace the first occurrence of the remote name in the refspec. This is correct in most cases, but breaks if the remote name occurs in the fetch refspec before the expected place. For example, we currently change [remote "remote"] url = git://git.kernel.org/pub/scm/git/git.git fetch = +refs/heads/*:refs/remotes/remote/* into [remote "origin"] url = git://git.kernel.org/pub/scm/git/git.git fetch = +refs/heads/*:refs/origins/remote/* Reduce the risk of changing incorrect sections of the refspec by matching the entire ":refs/remotes/<name>/" instead of just "<name>". Signed-off-by: Martin von Zweigbergk <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 509d597 commit 28f555f

File tree

2 files changed

+28
-4
lines changed

2 files changed

+28
-4
lines changed

builtin/remote.c

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -631,7 +631,8 @@ static int mv(int argc, const char **argv)
631631
OPT_END()
632632
};
633633
struct remote *oldremote, *newremote;
634-
struct strbuf buf = STRBUF_INIT, buf2 = STRBUF_INIT, buf3 = STRBUF_INIT;
634+
struct strbuf buf = STRBUF_INIT, buf2 = STRBUF_INIT, buf3 = STRBUF_INIT,
635+
old_remote_context = STRBUF_INIT;
635636
struct string_list remote_branches = STRING_LIST_INIT_NODUP;
636637
struct rename_info rename;
637638
int i;
@@ -669,15 +670,18 @@ static int mv(int argc, const char **argv)
669670
strbuf_addf(&buf, "remote.%s.fetch", rename.new);
670671
if (git_config_set_multivar(buf.buf, NULL, NULL, 1))
671672
return error("Could not remove config section '%s'", buf.buf);
673+
strbuf_addf(&old_remote_context, ":refs/remotes/%s/", rename.old);
672674
for (i = 0; i < oldremote->fetch_refspec_nr; i++) {
673675
char *ptr;
674676

675677
strbuf_reset(&buf2);
676678
strbuf_addstr(&buf2, oldremote->fetch_refspec[i]);
677-
ptr = strstr(buf2.buf, rename.old);
679+
ptr = strstr(buf2.buf, old_remote_context.buf);
678680
if (ptr)
679-
strbuf_splice(&buf2, ptr-buf2.buf, strlen(rename.old),
680-
rename.new, strlen(rename.new));
681+
strbuf_splice(&buf2,
682+
ptr-buf2.buf + strlen(":refs/remotes/"),
683+
strlen(rename.old), rename.new,
684+
strlen(rename.new));
681685
if (git_config_set_multivar(buf.buf, buf2.buf, "^$", 0))
682686
return error("Could not append '%s'", buf.buf);
683687
}

t/t5505-remote.sh

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -631,6 +631,26 @@ test_expect_success 'rename a remote' '
631631
632632
'
633633

634+
test_expect_success 'rename does not update a non-default fetch refspec' '
635+
636+
git clone one four.one &&
637+
(cd four.one &&
638+
git config remote.origin.fetch +refs/heads/*:refs/heads/origin/* &&
639+
git remote rename origin upstream &&
640+
test "$(git config remote.upstream.fetch)" = "+refs/heads/*:refs/heads/origin/*")
641+
642+
'
643+
644+
test_expect_success 'rename a remote with name part of fetch spec' '
645+
646+
git clone one four.two &&
647+
(cd four.two &&
648+
git remote rename origin remote &&
649+
git remote rename remote upstream &&
650+
test "$(git config remote.upstream.fetch)" = "+refs/heads/*:refs/remotes/upstream/*")
651+
652+
'
653+
634654
cat > remotes_origin << EOF
635655
URL: $(pwd)/one
636656
Push: refs/heads/master:refs/heads/upstream

0 commit comments

Comments
 (0)