{"thread":{"id":"28283","subject":"[PATCHv2 1/2] remote: write correct fetch spec when renaming remote 'remote'","startedAt":"2011-09-02T00:50:33Z","lastAt":"2011-09-10T19:39:23Z","messageCount":10,"participants":["Martin von Zweigbergk","Jeff King","Junio C Hamano"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"174724","messageId":"1314924634-12235-1-git-send-email-martin.von.zweigbergk@gmail.com","threadId":"28283","inReplyTo":null,"subject":"[PATCHv2 1/2] remote: write correct fetch spec when renaming remote 'remote'","fromName":"Martin von Zweigbergk","fromEmail":"martin.von.zweigbergk@gmail.com","sentAt":"2011-09-02T00:50:33Z","receivedAt":"2011-09-02T00:50:33Z","isPatch":false,"sender":{"key":"martinvonz@gmail.com","avatar":"https://avatars.githubusercontent.com/u/891642?v=4"},"body":"When renaming a remote whose name is contained in a configured fetch\nrefspec for that remote, we currently replace the first occurrence of\nthe remote name in the refspec. This is correct in most cases, but\nbreaks if the remote name occurs in the fetch refspec before the\nexpected place. For example, we currently change\n\n[remote \"remote\"]\n\turl = git://git.kernel.org/pub/scm/git/git.git\n\tfetch = +refs/heads/*:refs/remotes/remote/*\n\ninto\n\n[remote \"origin\"]\n\turl = git://git.kernel.org/pub/scm/git/git.git\n\tfetch = +refs/heads/*:refs/origins/remote/*\n\nReduce the risk of changing incorrect sections of the refspec by\nmatching the entire \":refs/remotes/<name>/\" instead of just \"<name>\".\n\nSigned-off-by: Martin von Zweigbergk <martin.von.zweigbergk@gmail.com>\n---\nNow matches more strictly, namely on \":/refs/remotes/$OLD/\".\n\n builtin/remote.c  |   12 ++++++++----\n t/t5505-remote.sh |   20 ++++++++++++++++++++\n 2 files changed, 28 insertions(+), 4 deletions(-)\n\ndiff --git a/builtin/remote.c b/builtin/remote.c\nindex f2a9c26..6d08738 100644\n--- a/builtin/remote.c\n+++ b/builtin/remote.c\n@@ -621,7 +621,8 @@ static int mv(int argc, const char **argv)\n \t\tOPT_END()\n \t};\n \tstruct remote *oldremote, *newremote;\n-\tstruct strbuf buf = STRBUF_INIT, buf2 = STRBUF_INIT, buf3 = STRBUF_INIT;\n+\tstruct strbuf buf = STRBUF_INIT, buf2 = STRBUF_INIT, buf3 = STRBUF_INIT,\n+\t\told_remote_context = STRBUF_INIT;\n \tstruct string_list remote_branches = STRING_LIST_INIT_NODUP;\n \tstruct rename_info rename;\n \tint i;\n@@ -659,15 +660,18 @@ static int mv(int argc, const char **argv)\n \tstrbuf_addf(&buf, \"remote.%s.fetch\", rename.new);\n \tif (git_config_set_multivar(buf.buf, NULL, NULL, 1))\n \t\treturn error(\"Could not remove config section '%s'\", buf.buf);\n+\tstrbuf_addf(&old_remote_context, \":refs/remotes/%s/\", rename.old);\n \tfor (i = 0; i < oldremote->fetch_refspec_nr; i++) {\n \t\tchar *ptr;\n \n \t\tstrbuf_reset(&buf2);\n \t\tstrbuf_addstr(&buf2, oldremote->fetch_refspec[i]);\n-\t\tptr = strstr(buf2.buf, rename.old);\n+\t\tptr = strstr(buf2.buf, old_remote_context.buf);\n \t\tif (ptr)\n-\t\t\tstrbuf_splice(&buf2, ptr-buf2.buf, strlen(rename.old),\n-\t\t\t\t\trename.new, strlen(rename.new));\n+\t\t\tstrbuf_splice(&buf2,\n+\t\t\t\t      ptr-buf2.buf + strlen(\":refs/remotes/\"),\n+\t\t\t\t      strlen(rename.old), rename.new,\n+\t\t\t\t      strlen(rename.new));\n \t\tif (git_config_set_multivar(buf.buf, buf2.buf, \"^$\", 0))\n \t\t\treturn error(\"Could not append '%s'\", buf.buf);\n \t}\ndiff --git a/t/t5505-remote.sh b/t/t5505-remote.sh\nindex 0d0222e..36c807c 100755\n--- a/t/t5505-remote.sh\n+++ b/t/t5505-remote.sh\n@@ -631,6 +631,26 @@ test_expect_success 'rename a remote' '\n \n '\n \n+test_expect_success 'rename does not update a non-default fetch refspec' '\n+\n+\tgit clone one four.one &&\n+\t(cd four.one &&\n+\t git config remote.origin.fetch +refs/heads/*:refs/heads/origin/* &&\n+\t git remote rename origin upstream &&\n+\t test \"$(git config remote.upstream.fetch)\" = \"+refs/heads/*:refs/heads/origin/*\")\n+\n+'\n+\n+test_expect_success 'rename a remote with name part of fetch spec' '\n+\n+\tgit clone one four.two &&\n+\t(cd four.two &&\n+\t git remote rename origin remote &&\n+\t git remote rename remote upstream &&\n+\t test \"$(git config remote.upstream.fetch)\" = \"+refs/heads/*:refs/remotes/upstream/*\")\n+\n+'\n+\n cat > remotes_origin << EOF\n URL: $(pwd)/one\n Push: refs/heads/master:refs/heads/upstream\n-- \n1.7.6.51.g07e0e\n"},{"id":"174725","messageId":"1314924634-12235-2-git-send-email-martin.von.zweigbergk@gmail.com","threadId":"28283","inReplyTo":"1314924634-12235-1-git-send-email-martin.von.zweigbergk@gmail.com","subject":"[PATCHv2 2/2] remote: \"rename o foo\" should not rename ref \"origin/bar\"","fromName":"Martin von Zweigbergk","fromEmail":"martin.von.zweigbergk@gmail.com","sentAt":"2011-09-02T00:50:34Z","receivedAt":"2011-09-02T00:50:34Z","isPatch":false,"sender":{"key":"martinvonz@gmail.com","avatar":"https://avatars.githubusercontent.com/u/891642?v=4"},"body":"When renaming a remote called 'o' using 'git remote rename o foo', git\nshould also rename any remote-tracking branches for the remote. This\ndoes happen, but any remote-tracking branches starting with\n'refs/remotes/o', such as 'refs/remotes/origin/bar', will also be\nrenamed (to 'refs/remotes/foorigin/bar' in this case).\n\nFix it by simply matching one more character, up to the slash\nfollowing the remote name.\n\nSigned-off-by: Martin von Zweigbergk <martin.von.zweigbergk@gmail.com>\n---\nNo changes since v1.\n\n builtin/remote.c  |    2 +-\n t/t5505-remote.sh |   10 ++++++++++\n 2 files changed, 11 insertions(+), 1 deletions(-)\n\ndiff --git a/builtin/remote.c b/builtin/remote.c\nindex 6d08738..0df6ab0 100644\n--- a/builtin/remote.c\n+++ b/builtin/remote.c\n@@ -570,7 +570,7 @@ static int read_remote_branches(const char *refname,\n \tunsigned char orig_sha1[20];\n \tconst char *symref;\n \n-\tstrbuf_addf(&buf, \"refs/remotes/%s\", rename->old);\n+\tstrbuf_addf(&buf, \"refs/remotes/%s/\", rename->old);\n \tif (!prefixcmp(refname, buf.buf)) {\n \t\titem = string_list_append(rename->remote_branches, xstrdup(refname));\n \t\tsymref = resolve_ref(refname, orig_sha1, 1, &flag);\ndiff --git a/t/t5505-remote.sh b/t/t5505-remote.sh\nindex 36c807c..15186c8 100755\n--- a/t/t5505-remote.sh\n+++ b/t/t5505-remote.sh\n@@ -651,6 +651,16 @@ test_expect_success 'rename a remote with name part of fetch spec' '\n \n '\n \n+test_expect_success 'rename a remote with name prefix of other remote' '\n+\n+\tgit clone one four.three &&\n+\t(cd four.three &&\n+\t git remote add o git://example.com/repo.git &&\n+\t git remote rename o upstream &&\n+\t test \"$(git rev-parse origin/master)\" = \"$(git rev-parse master)\")\n+\n+'\n+\n cat > remotes_origin << EOF\n URL: $(pwd)/one\n Push: refs/heads/master:refs/heads/upstream\n-- \n1.7.6.51.g07e0e\n"},{"id":"174752","messageId":"20110902160333.GB19690@sigill.intra.peff.net","threadId":"28283","inReplyTo":"1314924634-12235-1-git-send-email-martin.von.zweigbergk@gmail.com","subject":"Re: [PATCHv2 1/2] remote: write correct fetch spec when renaming remote 'remote'","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2011-09-02T16:03:33Z","receivedAt":"2011-09-02T16:03:33Z","isPatch":false,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Thu, Sep 01, 2011 at 08:50:33PM -0400, Martin von Zweigbergk wrote:\n\n> +\tstrbuf_addf(&old_remote_context, \":refs/remotes/%s/\", rename.old);\n>  \tfor (i = 0; i < oldremote->fetch_refspec_nr; i++) {\n>  \t\tchar *ptr;\n>  \n>  \t\tstrbuf_reset(&buf2);\n>  \t\tstrbuf_addstr(&buf2, oldremote->fetch_refspec[i]);\n> -\t\tptr = strstr(buf2.buf, rename.old);\n> +\t\tptr = strstr(buf2.buf, old_remote_context.buf);\n>  \t\tif (ptr)\n> -\t\t\tstrbuf_splice(&buf2, ptr-buf2.buf, strlen(rename.old),\n> -\t\t\t\t\trename.new, strlen(rename.new));\n> +\t\t\tstrbuf_splice(&buf2,\n> +\t\t\t\t      ptr-buf2.buf + strlen(\":refs/remotes/\"),\n> +\t\t\t\t      strlen(rename.old), rename.new,\n> +\t\t\t\t      strlen(rename.new));\n>  \t\tif (git_config_set_multivar(buf.buf, buf2.buf, \"^$\", 0))\n>  \t\t\treturn error(\"Could not append '%s'\", buf.buf);\n\nIf we find a refspec that does not match this pattern, what should we\ndo? This code silently ignores it.\n\nAt the very least, I'd like to see a warning indicating that one or more\nfetch refspecs were not rewritten, and that the user should update the\nconfig manually.\n\nWhat should happen if there are multiple refspecs, and one doesn't\nmatch? Should we rewrite the ones we can, or should we abort and not\nrewrite anything at all? I think the latter is probably less confusing.\n\nThese are corner cases, obviously, and most people will just have the\nstock refspecs or something that follows their pattern.\n\n-Peff\n"},{"id":"174788","messageId":"1315063619-6072-1-git-send-email-martin.von.zweigbergk@gmail.com","threadId":"28283","inReplyTo":"20110902160333.GB19690@sigill.intra.peff.net","subject":"[PATCHv2 3/2] remote rename: warn when refspec was not updated","fromName":"Martin von Zweigbergk","fromEmail":"martin.von.zweigbergk@gmail.com","sentAt":"2011-09-03T15:26:59Z","receivedAt":"2011-09-03T15:26:59Z","isPatch":false,"sender":{"key":"martinvonz@gmail.com","avatar":"https://avatars.githubusercontent.com/u/891642?v=4"},"body":"When renaming a remote, we also try to update the fetch refspec\naccordingly, but only if it has the default format. For others, such\nas refs/heads/master:refs/heads/origin, we are conservative and leave\nit untouched. Let's give the user a warning about refspecs that are\nnot updated, so he can manually update the config if necessary.\n\nSuggested-by: Jeff King <peff@peff.net>\nSigned-off-by: Martin von Zweigbergk <martin.von.zweigbergk@gmail.com>\n---\n\nThis addresses the first part of your email. I'm not sure what should\nhappen when only some refspecs can be updated. I can't think of any\nsensible examples with mixed default and non-default refspecs, so for\nme it's hard to see whether we would make things better or worse by\nmaking it all-or-nothing. I have more or less always used the default\nones myself. Do you have any good examples?\n\n builtin/remote.c |    6 ++++++\n 1 files changed, 6 insertions(+), 0 deletions(-)\n\ndiff --git a/builtin/remote.c b/builtin/remote.c\nindex 0df6ab0..61326cb 100644\n--- a/builtin/remote.c\n+++ b/builtin/remote.c\n@@ -672,6 +672,12 @@ static int mv(int argc, const char **argv)\n \t\t\t\t      ptr-buf2.buf + strlen(\":refs/remotes/\"),\n \t\t\t\t      strlen(rename.old), rename.new,\n \t\t\t\t      strlen(rename.new));\n+\t\telse\n+\t\t\twarning(\"Not updating non-default fetch respec\\n\"\n+\t\t\t\t\"\\t%s\\n\"\n+\t\t\t\t\"\\tPlease update the configuration manually if necessary.\",\n+\t\t\t\tbuf2.buf);\n+\n \t\tif (git_config_set_multivar(buf.buf, buf2.buf, \"^$\", 0))\n \t\t\treturn error(\"Could not append '%s'\", buf.buf);\n \t}\n-- \n1.7.6.51.g07e0e\n"},{"id":"174970","messageId":"7vaaah6zx0.fsf@alter.siamese.dyndns.org","threadId":"28283","inReplyTo":"1314924634-12235-1-git-send-email-martin.von.zweigbergk@gmail.com","subject":"Re: [PATCHv2 1/2] remote: write correct fetch spec when renaming remote 'remote'","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2011-09-06T22:58:51Z","receivedAt":"2011-09-06T22:58:51Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Martin von Zweigbergk <martin.von.zweigbergk@gmail.com> writes:\n\n> @@ -659,15 +660,18 @@ static int mv(int argc, const char **argv)\n>  \tstrbuf_addf(&buf, \"remote.%s.fetch\", rename.new);\n>  \tif (git_config_set_multivar(buf.buf, NULL, NULL, 1))\n>  \t\treturn error(\"Could not remove config section '%s'\", buf.buf);\n> +\tstrbuf_addf(&old_remote_context, \":refs/remotes/%s/\", rename.old);\n>  \tfor (i = 0; i < oldremote->fetch_refspec_nr; i++) {\n>  \t\tchar *ptr;\n>  \n>  \t\tstrbuf_reset(&buf2);\n>  \t\tstrbuf_addstr(&buf2, oldremote->fetch_refspec[i]);\n> -\t\tptr = strstr(buf2.buf, rename.old);\n> +\t\tptr = strstr(buf2.buf, old_remote_context.buf);\n>  \t\tif (ptr)\n> -\t\t\tstrbuf_splice(&buf2, ptr-buf2.buf, strlen(rename.old),\n> -\t\t\t\t\trename.new, strlen(rename.new));\n> +\t\t\tstrbuf_splice(&buf2,\n> +\t\t\t\t      ptr-buf2.buf + strlen(\":refs/remotes/\"),\n> +\t\t\t\t      strlen(rename.old), rename.new,\n> +\t\t\t\t      strlen(rename.new));\n>  \t\tif (git_config_set_multivar(buf.buf, buf2.buf, \"^$\", 0))\n>  \t\t\treturn error(\"Could not append '%s'\", buf.buf);\n>  \t}\n\nIt is somewhat bothering that we do not say \"we didn't do any magic\" here\nwhen we did not move the tracking branch specifications, but that is not a\nnew problem, so I am OK with this change.\n\nI however suspect that you would want to keep the record of what you\nchanged here, so that the renaming of actual refs done in [PATCH 2/2] is\nlimited to those that you updated the specifications for, no?\n"},{"id":"175057","messageId":"alpine.DEB.2.00.1109062136350.12564@debian","threadId":"28283","inReplyTo":"7vaaah6zx0.fsf@alter.siamese.dyndns.org","subject":"Re: [PATCHv2 1/2] remote: write correct fetch spec when renaming remote 'remote'","fromName":"Martin von Zweigbergk","fromEmail":"martin.von.zweigbergk@gmail.com","sentAt":"2011-09-08T01:40:57Z","receivedAt":"2011-09-08T01:40:57Z","isPatch":false,"sender":{"key":"martinvonz@gmail.com","avatar":"https://avatars.githubusercontent.com/u/891642?v=4"},"body":"On Tue, 6 Sep 2011, Junio C Hamano wrote:\n\n> It is somewhat bothering that we do not say \"we didn't do any magic\" here\n> when we did not move the tracking branch specifications, but that is not a\n> new problem, so I am OK with this change.\n\nIf I understand you correctly, this is the same concern that Jeff had\nand that I tried to address in patch 3/2.\n\n> I however suspect that you would want to keep the record of what you\n> changed here, so that the renaming of actual refs done in [PATCH 2/2] is\n> limited to those that you updated the specifications for, no?\n\nSorry, I don't think I really understand. Are you worried that we\nmight rename too many refs, i.e. unrelated ones? We match exactly the\nsame pattern both when updating refspecs and when renaming refs. Of\ncourse, we can never be certain that a ref \"refs/remotes/origin/foo\"\nis really related to the remote called \"origin\". The user could have\nsimply created the ref manually. Is that what you are getting at?\n\n\nMartin\n"},{"id":"175061","messageId":"7vzkifzol6.fsf@alter.siamese.dyndns.org","threadId":"28283","inReplyTo":"alpine.DEB.2.00.1109062136350.12564@debian","subject":"Re: [PATCHv2 1/2] remote: write correct fetch spec when renaming remote 'remote'","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2011-09-08T03:43:01Z","receivedAt":"2011-09-08T03:43:01Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Martin von Zweigbergk <martin.von.zweigbergk@gmail.com> writes:\n\n> same pattern both when updating refspecs and when renaming refs. Of\n> course, we can never be certain that a ref \"refs/remotes/origin/foo\"\n> is really related to the remote called \"origin\". The user could have\n> simply created the ref manually. Is that what you are getting at?\n\nYou have two separate and independent code that are not linked together\nbut should logically be.\n\nOne updates fetch refspec whose RHS is \"refs/remotes/$OLD/<anything>\" to\n\"refs/remotes/$NEW/<the same thing>\". If you do not find any such fetch\nrefspec, then you do not update these configuration variables, which is\ngood.\n\nLater in the same mv() function, the other one renames refs/remotes/$OLD/\nto refs/remotes/$NEW/, even when you did not find any fetch refspec that\nstores under \"refs/remotes/$OLD/<anything>\" in the earlier logic.\n\nNow, these actual refs may have been placed manually by the user. They may\nhave been placed by an old config that the user may have edited. You\nsimply do not know.\n\nBut you know one thing. You _do_ know is that these refs did _not_ come\nfrom any \"[remote \"$OLD\"] fetch = ...\" configuration, and by inference, it\nwill not come from any \"[remote \"$NEW\"] fetch = ...\", in other words, they\ndo not have any relation with the \"$NEW\" remote. So I do not see a good\nreason to move them from refs/remotes/$OLD/ to refs/remotes/$NEW/. That\nwas what I was pointing out.\n"},{"id":"175077","messageId":"alpine.DEB.2.00.1109080458500.12564@debian","threadId":"28283","inReplyTo":"7vzkifzol6.fsf@alter.siamese.dyndns.org","subject":"Re: [PATCHv2 1/2] remote: write correct fetch spec when renaming remote 'remote'","fromName":"Martin von Zweigbergk","fromEmail":"martin.von.zweigbergk@gmail.com","sentAt":"2011-09-08T09:08:16Z","receivedAt":"2011-09-08T09:08:16Z","isPatch":false,"sender":{"key":"martinvonz@gmail.com","avatar":"https://avatars.githubusercontent.com/u/891642?v=4"},"body":"On Wed, 7 Sep 2011, Junio C Hamano wrote:\n\n> Later in the same mv() function, the other one renames refs/remotes/$OLD/\n> to refs/remotes/$NEW/, even when you did not find any fetch refspec that\n> stores under \"refs/remotes/$OLD/<anything>\" in the earlier logic.\n\nAh, of course. Sorry for being slow and thanks for the explanation. So\nif there are two configured refspecs with RHSs \"refs/remotes/$OLD/foo\"\nand \"refs/remotes/$OLD/bar/*\", we should remember that we updated\nthose and only update refs that match the same patterns. I will see\nwhat I can do and will hopefully soon get back with a \"patch 4/2\".\n\n\nMartin\n"},{"id":"175114","messageId":"7vr53rx9r6.fsf@alter.siamese.dyndns.org","threadId":"28283","inReplyTo":"alpine.DEB.2.00.1109080458500.12564@debian","subject":"Re: [PATCHv2 1/2] remote: write correct fetch spec when renaming remote 'remote'","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2011-09-08T16:46:21Z","receivedAt":"2011-09-08T16:46:21Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Martin von Zweigbergk <martin.von.zweigbergk@gmail.com> writes:\n\n> On Wed, 7 Sep 2011, Junio C Hamano wrote:\n>\n>> Later in the same mv() function, the other one renames refs/remotes/$OLD/\n>> to refs/remotes/$NEW/, even when you did not find any fetch refspec that\n>> stores under \"refs/remotes/$OLD/<anything>\" in the earlier logic.\n>\n> Ah, of course. Sorry for being slow and thanks for the explanation. So\n> if there are two configured refspecs with RHSs \"refs/remotes/$OLD/foo\"\n> and \"refs/remotes/$OLD/bar/*\", we should remember that we updated\n> those and only update refs that match the same patterns. I will see\n> what I can do and will hopefully soon get back with a \"patch 4/2\".\n\nWhat I had in mind was nothing that elaborate--it would be sufficiently\nsafe to just remember if you replaced any in the config, and if you\ndidn't, not to move anything.\n"},{"id":"175280","messageId":"1315683563-11416-1-git-send-email-martin.von.zweigbergk@gmail.com","threadId":"28283","inReplyTo":"7vr53rx9r6.fsf@alter.siamese.dyndns.org","subject":"[PATCH 4/2] remote: only update remote-tracking branch if updating refspec","fromName":"Martin von Zweigbergk","fromEmail":"martin.von.zweigbergk@gmail.com","sentAt":"2011-09-10T19:39:23Z","receivedAt":"2011-09-10T19:39:23Z","isPatch":true,"sender":{"key":"martinvonz@gmail.com","avatar":"https://avatars.githubusercontent.com/u/891642?v=4"},"body":"'git remote rename' will only update the remote's fetch refspec if it\nlooks like a default one. If the remote has no default fetch refspec,\nas in\n\n[remote \"origin\"]\n    url = git://git.kernel.org/pub/scm/git/git.git\n    fetch = +refs/heads/*:refs/remotes/upstream/*\n\nwe would not update the fetch refspec and even if there is a ref\ncalled \"refs/remotes/origin/master\", we should not rename it, since it\nwas not created by fetching from the remote.\n\nSuggested-by: Junio C Hamano <gitster@pobox.com>\nSigned-off-by: Martin von Zweigbergk <martin.von.zweigbergk@gmail.com>\n---\n\nSome questions on style:\n\n1. Should I wrap the statement in \"else\" block in braces when \"then\"\n   block has braces? I couldn't find anything conclusive by looking at\n   existing code.\n\n2. Is it ok (as I did) to return from the function prematurely even\n   though it is not an error case? This will of course make the\n   function more brittle when it comes to adding code at the end of\n   it. Would you prefer to invert the condition and put the remainder\n   of the function inside the \"then\" block? Or even to extract the\n   code into a new function?\n\n builtin/remote.c  |   10 +++++++---\n t/t5505-remote.sh |    3 ++-\n 2 files changed, 9 insertions(+), 4 deletions(-)\n\ndiff --git a/builtin/remote.c b/builtin/remote.c\nindex 61326cb..b25dfb4 100644\n--- a/builtin/remote.c\n+++ b/builtin/remote.c\n@@ -625,7 +625,7 @@ static int mv(int argc, const char **argv)\n \t\told_remote_context = STRBUF_INIT;\n \tstruct string_list remote_branches = STRING_LIST_INIT_NODUP;\n \tstruct rename_info rename;\n-\tint i;\n+\tint i, refspec_updated = 0;\n \n \tif (argc != 3)\n \t\tusage_with_options(builtin_remote_rename_usage, options);\n@@ -667,12 +667,13 @@ static int mv(int argc, const char **argv)\n \t\tstrbuf_reset(&buf2);\n \t\tstrbuf_addstr(&buf2, oldremote->fetch_refspec[i]);\n \t\tptr = strstr(buf2.buf, old_remote_context.buf);\n-\t\tif (ptr)\n+\t\tif (ptr) {\n+\t\t\trefspec_updated = 1;\n \t\t\tstrbuf_splice(&buf2,\n \t\t\t\t      ptr-buf2.buf + strlen(\":refs/remotes/\"),\n \t\t\t\t      strlen(rename.old), rename.new,\n \t\t\t\t      strlen(rename.new));\n-\t\telse\n+\t\t} else\n \t\t\twarning(\"Not updating non-default fetch respec\\n\"\n \t\t\t\t\"\\t%s\\n\"\n \t\t\t\t\"\\tPlease update the configuration manually if necessary.\",\n@@ -695,6 +696,9 @@ static int mv(int argc, const char **argv)\n \t\t}\n \t}\n \n+\tif (!refspec_updated)\n+\t\treturn 0;\n+\n \t/*\n \t * First remove symrefs, then rename the rest, finally create\n \t * the new symrefs.\ndiff --git a/t/t5505-remote.sh b/t/t5505-remote.sh\nindex 15186c8..e8af615 100755\n--- a/t/t5505-remote.sh\n+++ b/t/t5505-remote.sh\n@@ -637,7 +637,8 @@ test_expect_success 'rename does not update a non-default fetch refspec' '\n \t(cd four.one &&\n \t git config remote.origin.fetch +refs/heads/*:refs/heads/origin/* &&\n \t git remote rename origin upstream &&\n-\t test \"$(git config remote.upstream.fetch)\" = \"+refs/heads/*:refs/heads/origin/*\")\n+\t test \"$(git config remote.upstream.fetch)\" = \"+refs/heads/*:refs/heads/origin/*\" &&\n+\t git rev-parse -q origin/master)\n \n '\n \n-- \n1.7.7.rc0.317.gd0afe\n"}]}