summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin von Zweigbergk <martin.von.zweigbergk@gmail.com>2011-09-01 20:50:33 -0400
committerJunio C Hamano <gitster@pobox.com>2011-09-11 21:39:55 -0700
commit28f555f6357ee0706847aff5b476b31b472b325c (patch)
tree43792d7b55a96f86e0a895a68f56c9527eb78025
parent509d59705ee07094bcc56b49a17ba0ae983da50f (diff)
downloadgit-28f555f6357ee0706847aff5b476b31b472b325c.tar.gz
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 <martin.von.zweigbergk@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
-rw-r--r--builtin/remote.c12
-rwxr-xr-xt/t5505-remote.sh20
2 files changed, 28 insertions, 4 deletions
diff --git a/builtin/remote.c b/builtin/remote.c
index 1fb441c964..af96849dc9 100644
--- a/builtin/remote.c
+++ b/builtin/remote.c
@@ -631,7 +631,8 @@ static int mv(int argc, const char **argv)
OPT_END()
};
struct remote *oldremote, *newremote;
- struct strbuf buf = STRBUF_INIT, buf2 = STRBUF_INIT, buf3 = STRBUF_INIT;
+ struct strbuf buf = STRBUF_INIT, buf2 = STRBUF_INIT, buf3 = STRBUF_INIT,
+ old_remote_context = STRBUF_INIT;
struct string_list remote_branches = STRING_LIST_INIT_NODUP;
struct rename_info rename;
int i;
@@ -669,15 +670,18 @@ static int mv(int argc, const char **argv)
strbuf_addf(&buf, "remote.%s.fetch", rename.new);
if (git_config_set_multivar(buf.buf, NULL, NULL, 1))
return error("Could not remove config section '%s'", buf.buf);
+ strbuf_addf(&old_remote_context, ":refs/remotes/%s/", rename.old);
for (i = 0; i < oldremote->fetch_refspec_nr; i++) {
char *ptr;
strbuf_reset(&buf2);
strbuf_addstr(&buf2, oldremote->fetch_refspec[i]);
- ptr = strstr(buf2.buf, rename.old);
+ ptr = strstr(buf2.buf, old_remote_context.buf);
if (ptr)
- strbuf_splice(&buf2, ptr-buf2.buf, strlen(rename.old),
- rename.new, strlen(rename.new));
+ strbuf_splice(&buf2,
+ ptr-buf2.buf + strlen(":refs/remotes/"),
+ strlen(rename.old), rename.new,
+ strlen(rename.new));
if (git_config_set_multivar(buf.buf, buf2.buf, "^$", 0))
return error("Could not append '%s'", buf.buf);
}
diff --git a/t/t5505-remote.sh b/t/t5505-remote.sh
index 0d0222ea2a..36c807c608 100755
--- a/t/t5505-remote.sh
+++ b/t/t5505-remote.sh
@@ -631,6 +631,26 @@ test_expect_success 'rename a remote' '
'
+test_expect_success 'rename does not update a non-default fetch refspec' '
+
+ git clone one four.one &&
+ (cd four.one &&
+ git config remote.origin.fetch +refs/heads/*:refs/heads/origin/* &&
+ git remote rename origin upstream &&
+ test "$(git config remote.upstream.fetch)" = "+refs/heads/*:refs/heads/origin/*")
+
+'
+
+test_expect_success 'rename a remote with name part of fetch spec' '
+
+ git clone one four.two &&
+ (cd four.two &&
+ git remote rename origin remote &&
+ git remote rename remote upstream &&
+ test "$(git config remote.upstream.fetch)" = "+refs/heads/*:refs/remotes/upstream/*")
+
+'
+
cat > remotes_origin << EOF
URL: $(pwd)/one
Push: refs/heads/master:refs/heads/upstream