{"thread":{"id":"12515","subject":"error: refs/remotes/origin/HEAD points nowhere!","startedAt":"2008-03-05T11:38:44Z","lastAt":"2008-03-09T10:24:20Z","messageCount":10,"participants":["Teemu Likonen","Junio C Hamano","Johannes Schindelin"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"71067","messageId":"200803051338.44938.tlikonen@iki.fi","threadId":"12515","inReplyTo":null,"subject":"error: refs/remotes/origin/HEAD points nowhere!","fromName":"Teemu Likonen","fromEmail":"tlikonen@iki.fi","sentAt":"2008-03-05T11:38:44Z","receivedAt":"2008-03-05T11:38:44Z","isPatch":false,"sender":{"key":"tlikonen@iki.fi","avatar":null},"body":"Hi,\n\nVery annoying error \"error: refs/remotes/origin/HEAD points nowhere!\" \nkeeps popping up almost all the time after user has removed remote \nrepository \"origin\". Here's a kind of real-life example:\n\nI have cloned some remote repository:\n\n  git clone git://project/project.git\n\nAfter a while I start tracking some other remote repository. I do this:\n\n  git remote add ng git://project-ng/project.git\n\nThen I do \"git fetch ng\" and probably also \"git checkout --track -b \nmaster-ng ng/master\". Then I find the old \"origin\" useless to me so I \nremove it with \"git remote rm origin\".\n\nIt seems that refs/remotes/origin/HEAD is still left in my repository \nand hence I keep getting these annoying error messages all the time. \nWell, I know how to delete this file, but I believe that git should \nhave deleted it when I called \"git remote rm origin\". Am I right? What \nis the purpose of this refs/remotes/origin/HEAD in the first place?\n\nAnyway, thank you guys for this excellent tool and VCS/SCM system. \nGenerally git is really joy to use and very powerful. Thanks.\n"},{"id":"71125","messageId":"7v7iggn9ts.fsf@gitster.siamese.dyndns.org","threadId":"12515","inReplyTo":"200803051338.44938.tlikonen@iki.fi","subject":"Re: error: refs/remotes/origin/HEAD points nowhere!","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2008-03-05T21:24:15Z","receivedAt":"2008-03-05T21:24:15Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Teemu Likonen <tlikonen@iki.fi> writes:\n\n> After a while I start tracking some other remote repository. I do this:\n>\n>   git remote add ng git://project-ng/project.git\n>\n> Then I do \"git fetch ng\" and probably also \"git checkout --track -b \n> master-ng ng/master\". Then I find the old \"origin\" useless to me so I \n> remove it with \"git remote rm origin\".\n>\n> It seems that refs/remotes/origin/HEAD is still left in my repository \n> and hence I keep getting these annoying error messages all the time. \n\n> Well, I know how to delete this file, but I believe that git should have\n> deleted it when I called \"git remote rm origin\". Am I right?\n\nGood analysis.  I would say \"git remote rm\" should have removed\nit and it would be a bug if it didn't.\n\n> What is the purpose of this refs/remotes/origin/HEAD in the first place?\n\nTo let you say things like \"git diff remotes/origin\" as a short-hand for\n\"git diff remotes/origin/master\" (or whichever branch 'origin' repository\nconsidered the primary one, which is determined when you cloned from it).\n\n"},{"id":"71208","messageId":"200803060950.44873.tlikonen@iki.fi","threadId":"12515","inReplyTo":"7v7iggn9ts.fsf@gitster.siamese.dyndns.org","subject":"Re: error: refs/remotes/origin/HEAD points nowhere!","fromName":"Teemu Likonen","fromEmail":"tlikonen@iki.fi","sentAt":"2008-03-06T07:50:44Z","receivedAt":"2008-03-06T07:50:44Z","isPatch":false,"sender":{"key":"tlikonen@iki.fi","avatar":null},"body":"Junio C Hamano kirjoitti:\n\n> Teemu Likonen <tlikonen@iki.fi> writes:\n> > After a while I start tracking some other remote repository. I do\n> > this:\n> >\n> >   git remote add ng git://project-ng/project.git\n> >\n> > Then I do \"git fetch ng\" and probably also \"git checkout --track -b\n> > master-ng ng/master\". Then I find the old \"origin\" useless to me so\n> > I remove it with \"git remote rm origin\".\n> >\n> > It seems that refs/remotes/origin/HEAD is still left in my\n> > repository and hence I keep getting these annoying error messages\n> > all the time.\n> >\n> > Well, I know how to delete this file, but I believe that git should\n> > have deleted it when I called \"git remote rm origin\". Am I right?\n>\n> Good analysis.  I would say \"git remote rm\" should have removed\n> it and it would be a bug if it didn't.\n\nYes, \"git remote rm <remote>\" certainly doesn't remove the \nrefs/remotes/<remote>/HEAD file. I can reproduce this bug anytime with \ncurrent 'master' branch from git://git.kernel.org/pub/scm/git/git.git\n"},{"id":"71377","messageId":"1204923732-29141-1-git-send-email-tlikonen@iki.fi","threadId":"12515","inReplyTo":"200803051338.44938.tlikonen@iki.fi","subject":"[PATCH/RFC] Make \"git remote rm <remote>\" remove file refs/remotes/<remote>/HEAD","fromName":"Teemu Likonen","fromEmail":"tlikonen@iki.fi","sentAt":"2008-03-07T21:02:12Z","receivedAt":"2008-03-07T21:02:12Z","isPatch":true,"sender":{"key":"tlikonen@iki.fi","avatar":null},"body":"The command \"git remote rm <remote>\" used to leave the\nrefs/remotes/<remote>/HEAD file lying in the directory. This usually\nhappens when user has cloned a remote repository and later decided to\nremove the default \"origin\" with \"git remote rm origin\". The result is\nthat several git commans display the error message\n\n  error: refs/remotes/origin/HEAD points nowhere!\n\nThis patch makes \"git remote rm\" remove the HEAD file if it exists.\n\nSigned-off-by: Teemu Likonen <tlikonen@iki.fi>\n---\n\nI have never written or even read any perl code before this (I'm not really\na programmer) but I managed to come up with this. This seems to work well. If\nmore error checking or something is needed, I guess somebody else has to do it;\nmy skills aren't quite enough. :)\n\nAny comments?\n\n git-remote.perl |    6 ++++++\n 1 files changed, 6 insertions(+), 0 deletions(-)\n\ndiff --git a/git-remote.perl b/git-remote.perl\nindex b30ed73..f1f2a1a 100755\n--- a/git-remote.perl\n+++ b/git-remote.perl\n@@ -323,6 +323,7 @@ sub update_remote {\n \n sub rm_remote {\n \tmy ($name) = @_;\n+\tmy $git_dir = $ENV{GIT_DIR} || \".git\";\n \tif (!exists $remote->{$name}) {\n \t\tprint STDERR \"No such remote $name\\n\";\n \t\treturn 1;\n@@ -340,6 +341,11 @@ sub rm_remote {\n \t\t}\n \t};\n \n+\tmy $remotes_dir = \"$git_dir/refs/remotes/$name\";\n+\tif (-f \"$remotes_dir/HEAD\") {\n+\t\tunlink \"$remotes_dir/HEAD\";\n+\t}\n+\n \tmy @refs = $git->command('for-each-ref',\n \t\t'--format=%(refname) %(objectname)', \"refs/remotes/$name\");\n \tfor (@refs) {\n-- \n1.5.4.3.451.ga9908.dirty\n\n"},{"id":"71385","messageId":"200803080018.36349.tlikonen@iki.fi","threadId":"12515","inReplyTo":"1204923732-29141-1-git-send-email-tlikonen@iki.fi","subject":"Re: [PATCH/RFC] Make \"git remote rm <remote>\" remove file refs/remotes/<remote>/HEAD","fromName":"Teemu Likonen","fromEmail":"tlikonen@iki.fi","sentAt":"2008-03-07T22:18:36Z","receivedAt":"2008-03-07T22:18:36Z","isPatch":true,"sender":{"key":"tlikonen@iki.fi","avatar":null},"body":"Teemu Likonen kirjoitti:\n\n> If more error checking or something is needed,\n\nSuch as finding the .git directory even if $PWD is somewhere else in the \ntree.\n\n> I guess \n> somebody else has to do it; my skills aren't quite enough. :)\n\nI'm out.\n"},{"id":"71393","messageId":"7vskz2yomt.fsf@gitster.siamese.dyndns.org","threadId":"12515","inReplyTo":"1204923732-29141-1-git-send-email-tlikonen@iki.fi","subject":"Re: [PATCH/RFC] Make \"git remote rm <remote>\" remove file refs/remotes/<remote>/HEAD","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2008-03-08T01:45:46Z","receivedAt":"2008-03-08T01:45:46Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Teemu Likonen <tlikonen@iki.fi> writes:\n\n> The command \"git remote rm <remote>\" used to leave the\n> refs/remotes/<remote>/HEAD file lying in the directory. This usually\n> happens when user has cloned a remote repository and later decided to\n> remove the default \"origin\" with \"git remote rm origin\". The result is\n> that several git commans display the error message\n>\n>   error: refs/remotes/origin/HEAD points nowhere!\n>\n> This patch makes \"git remote rm\" remove the HEAD file if it exists.\n>\n> Signed-off-by: Teemu Likonen <tlikonen@iki.fi>\n> ---\n>\n> I have never written or even read any perl code before this (I'm not really\n> a programmer) but I managed to come up with this. This seems to work well. If\n> more error checking or something is needed, I guess somebody else has to do it;\n> my skills aren't quite enough. :)\n>\n> Any comments?\n\nHmm.  The loop grabs everything under refs/remotes/$that_remote/ and runs\n\"update-ref -d\" on them.\n\nI somehow had an impression that --no-deref option to update-ref was\ninvented to allow operating on the symbolic ref itself, instead of\noperating on the ref it points at, but it does not seem to work.\n\nI think \"update-ref -d\" should remove the ref without dereferencing\nanyway.  How about not doing your patch at all (you would need to manually\nremove the symref in \"prune\" codepath as well), and instead doing this?\n\nI do not know how this reacts when the tracked HEAD points at a ref that\nlexicographically sorts earlier, say branch \"A\".\n\n-- >8 --\ndelete_ref(): when symref is given, delete it, not the underlying ref.\n\nRemoving the underlying ref without touching the symref does not make any\nsense.  An alternative would be to remove the symref _and_ the underlying\nref, but this should do for now.\n\nSigned-off-by: Junio C Hamano <gitster@pobox.com>\n---\n refs.c |    2 +-\n 1 files changed, 1 insertions(+), 1 deletions(-)\n\ndiff --git a/refs.c b/refs.c\nindex c979fb1..e7c0c38 100644\n--- a/refs.c\n+++ b/refs.c\n@@ -887,7 +887,7 @@ int delete_ref(const char *refname, const unsigned char *sha1)\n \tstruct ref_lock *lock;\n \tint err, i, ret = 0, flag = 0;\n \n-\tlock = lock_ref_sha1_basic(refname, sha1, 0, &flag);\n+\tlock = lock_ref_sha1_basic(refname, sha1, REF_NODEREF, &flag);\n \tif (!lock)\n \t\treturn 1;\n \tif (!(flag & REF_ISPACKED)) {\n"},{"id":"71394","messageId":"7vlk4uyoln.fsf@gitster.siamese.dyndns.org","threadId":"12515","inReplyTo":"1204923732-29141-1-git-send-email-tlikonen@iki.fi","subject":"Re: [PATCH/RFC] Make \"git remote rm <remote>\" remove file refs/remotes/<remote>/HEAD","fromName":"Junio C Hamano","fromEmail":"junio@pobox.com","sentAt":"2008-03-08T01:46:28Z","receivedAt":"2008-03-08T01:46:28Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Junio C Hamano <gitster@pobox.com> writes:\n\n> I think \"update-ref -d\" should remove the ref without dereferencing\n> anyway.  How about not doing your patch at all (you would need to manually\n> remove the symref in \"prune\" codepath as well), and instead doing this?\n>\n> I do not know how this reacts when the tracked HEAD points at a ref that\n> lexicographically sorts earlier, say branch \"A\".\n\nAnd it turns out it does not react very well.  You would want to do\nsomething like this on top of that one.\n\n-- >8 --\n\"remote rm\": first remove symbolic and then real refs\n\nThis teaches a new %(reftype) to for-each-ref that returns \"symref\",\n\"packed\", or \"plain\" (we never pack symrefs, so this is the complete\nenumeration), and updates \"git remote rm\" to first remove the symrefs and\nthen the actual refs.\n\nSigned-off-by: Junio C Hamano <junio@pobox.com>\n---\n\n builtin-for-each-ref.c |   13 +++++++++++++\n git-remote.perl        |   14 ++++++++++++--\n 2 files changed, 25 insertions(+), 2 deletions(-)\n\ndiff --git a/builtin-for-each-ref.c b/builtin-for-each-ref.c\nindex 07d9c57..50e9eed 100644\n--- a/builtin-for-each-ref.c\n+++ b/builtin-for-each-ref.c\n@@ -31,6 +31,7 @@ struct ref_sort {\n \n struct refinfo {\n \tchar *refname;\n+\tint reftype;\n \tunsigned char objectname[20];\n \tstruct atom_value *value;\n };\n@@ -40,6 +41,7 @@ static struct {\n \tcmp_type cmp_type;\n } valid_atom[] = {\n \t{ \"refname\" },\n+\t{ \"reftype\" },\n \t{ \"objecttype\" },\n \t{ \"objectsize\", FIELD_ULONG },\n \t{ \"objectname\" },\n@@ -568,6 +570,16 @@ static void populate_value(struct refinfo *ref)\n \t\t\tchar *s = xmalloc(len + 4);\n \t\t\tsprintf(s, \"%s^{}\", ref->refname);\n \t\t\tv->s = s;\n+\t\t} else if (!strcmp(name, \"reftype\")) {\n+\t\t\tchar *s = xmalloc(20);\n+\t\t\t/* We do not pack symrefs */\n+\t\t\tif (ref->reftype & REF_ISSYMREF)\n+\t\t\t\tstrcpy(s, \"symref\");\n+\t\t\telse if (ref->reftype & REF_ISPACKED)\n+\t\t\t\tstrcpy(s, \"packed\");\n+\t\t\telse\n+\t\t\t\tstrcpy(s, \"plain\");\n+\t\t\tv->s = s;\n \t\t}\n \t}\n \n@@ -658,6 +670,7 @@ static int grab_single_ref(const char *refname, const unsigned char *sha1, int f\n \t */\n \tref = xcalloc(1, sizeof(*ref));\n \tref->refname = xstrdup(refname);\n+\tref->reftype = flag;\n \thashcpy(ref->objectname, sha1);\n \n \tcnt = cb->grab_cnt;\ndiff --git a/git-remote.perl b/git-remote.perl\nindex b30ed73..c57e29d 100755\n--- a/git-remote.perl\n+++ b/git-remote.perl\n@@ -341,9 +341,19 @@ sub rm_remote {\n \t};\n \n \tmy @refs = $git->command('for-each-ref',\n-\t\t'--format=%(refname) %(objectname)', \"refs/remotes/$name\");\n+\t\t\t\t '--format=%(refname) %(reftype) %(objectname)',\n+\t\t\t\t \"refs/remotes/$name\");\n+\tmy @nonsym = ();\n \tfor (@refs) {\n-\t\tmy ($ref, $object) = split;\n+\t\tmy ($ref, $type, $object) = split;\n+\t\tif ($type !~ /symref/) {\n+\t\t\tpush @nonsym, $_;\n+\t\t} else {\n+\t\t\t$git->command(qw(update-ref -d), $ref, $object);\n+\t\t}\n+\t}\n+\tfor (@nonsym) {\n+\t\tmy ($ref, $type, $object) = split;\n \t\t$git->command(qw(update-ref -d), $ref, $object);\n \t}\n \treturn 0;\n\n"},{"id":"71406","messageId":"200803080816.10811.tlikonen@iki.fi","threadId":"12515","inReplyTo":"7vlk4uyoln.fsf@gitster.siamese.dyndns.org","subject":"Re: [PATCH/RFC] Make \"git remote rm <remote>\" remove file refs/remotes/<remote>/HEAD","fromName":"Teemu Likonen","fromEmail":"tlikonen@iki.fi","sentAt":"2008-03-08T06:16:10Z","receivedAt":"2008-03-08T06:16:10Z","isPatch":true,"sender":{"key":"tlikonen@iki.fi","avatar":null},"body":"Junio C Hamano kirjoitti:\n\n> Junio C Hamano <gitster@pobox.com> writes:\n> > I think \"update-ref -d\" should remove the ref without dereferencing\n> > anyway.  How about not doing your patch at all (you would need to\n> > manually remove the symref in \"prune\" codepath as well), and\n> > instead doing this?\n> >\n> > I do not know how this reacts when the tracked HEAD points at a ref\n> > that lexicographically sorts earlier, say branch \"A\".\n>\n> And it turns out it does not react very well.  You would want to do\n> something like this on top of that one.\n\nThis turned out to be much more complicated than just deleting a file. \nThank you, these patches seem to work (at least from user's point of \nview).\n"},{"id":"71454","messageId":"alpine.LSU.1.00.0803082339060.3975@racer.site","threadId":"12515","inReplyTo":"7v7iggn9ts.fsf@gitster.siamese.dyndns.org","subject":"[PATCH] builtin remote rm: remove symbolic refs, too","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2008-03-08T22:40:42Z","receivedAt":"2008-03-08T22:40:42Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"\n\"git remote add\" can add a symbolic ref \"HEAD\", and \"rm\" should delete\nit, too.\n\nNoticed by Teemu Likonen.\n\nSigned-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n---\n builtin-remote.c  |    5 +++++\n t/t5505-remote.sh |    1 +\n 2 files changed, 6 insertions(+), 0 deletions(-)\n\ndiff --git a/builtin-remote.c b/builtin-remote.c\nindex aa90cc9..f7653b6 100644\n--- a/builtin-remote.c\n+++ b/builtin-remote.c\n@@ -267,6 +267,11 @@ static int add_branch_for_removal(const char *refname,\n \n \tif (!prefixcmp(refname, branches->prefix)) {\n \t\tstruct path_list_item *item;\n+\n+\t\t/* make sure that symrefs are deleted */\n+\t\tif (flags & REF_ISSYMREF)\n+\t\t\treturn unlink(git_path(refname));\n+\n \t\titem = path_list_append(refname, branches->branches);\n \t\titem->util = xmalloc(20);\n \t\thashcpy(item->util, sha1);\ndiff --git a/t/t5505-remote.sh b/t/t5505-remote.sh\nindex f45ea68..2822a65 100755\n--- a/t/t5505-remote.sh\n+++ b/t/t5505-remote.sh\n@@ -80,6 +80,7 @@ test_expect_success 'add another remote' '\n test_expect_success 'remove remote' '\n (\n \tcd test &&\n+\tgit symbolic-ref refs/remotes/second/HEAD refs/remotes/second/master &&\n \tgit remote rm second\n )\n '\n-- \n1.5.4.3.653.gbc310\n\n"},{"id":"71502","messageId":"7vlk4sp54b.fsf@gitster.siamese.dyndns.org","threadId":"12515","inReplyTo":"alpine.LSU.1.00.0803082339060.3975@racer.site","subject":"Re: [PATCH] builtin remote rm: remove symbolic refs, too","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2008-03-09T10:24:20Z","receivedAt":"2008-03-09T10:24:20Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:\n\n> \"git remote add\" can add a symbolic ref \"HEAD\", and \"rm\" should delete\n> it, too.\n>\n> Noticed by Teemu Likonen.\n>\n> Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n> ---\n>  builtin-remote.c  |    5 +++++\n>  t/t5505-remote.sh |    1 +\n>  2 files changed, 6 insertions(+), 0 deletions(-)\n>\n> diff --git a/builtin-remote.c b/builtin-remote.c\n> index aa90cc9..f7653b6 100644\n> --- a/builtin-remote.c\n> +++ b/builtin-remote.c\n> @@ -267,6 +267,11 @@ static int add_branch_for_removal(const char *refname,\n>  \n>  \tif (!prefixcmp(refname, branches->prefix)) {\n>  \t\tstruct path_list_item *item;\n> +\n> +\t\t/* make sure that symrefs are deleted */\n> +\t\tif (flags & REF_ISSYMREF)\n> +\t\t\treturn unlink(git_path(refname));\n> +\n\nHeh, doing this in C is much easier and simpler ;-)\n"}]}