{"thread":{"id":"21236","subject":"[PATCH] Proof-of-concept patch to remember what the detached HEAD was","startedAt":"2009-10-14T04:44:34Z","lastAt":"2009-10-27T17:58:21Z","messageCount":93,"participants":["Daniel Barkalow","Junio C Hamano","Jeff King","Johannes Schindelin","Jay Soffian","Nicolas Pitre","Eric Raible","James Pickens","Jakub Narebski","Björn Steinbrink","Michael J Gruber","Thomas Rast","Julian Phillips","Christoph Bartoschek","Sean Estabrooks","Nanako Shiraishi","Avery Pennarun"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"124925","messageId":"alpine.LNX.2.00.0910140037570.32515@iabervon.org","threadId":"21236","inReplyTo":null,"subject":"[PATCH] Proof-of-concept patch to remember what the detached HEAD was","fromName":"Daniel Barkalow","fromEmail":"barkalow@iabervon.org","sentAt":"2009-10-14T04:44:34Z","receivedAt":"2009-10-14T04:44:34Z","isPatch":true,"sender":{"key":"barkalow@iabervon.org","avatar":"https://avatars.githubusercontent.com/u/55364219?v=4"},"body":"When detaching HEAD (or \"browsing history\"), the user has specified\nthe commit with some \"extended SHA1\" which is not a local\nbranch. Exactly what that string was is likely to be useful to the\nuser later. Also, we can detect the user putting work into the history\nfor the first time (such that it is no longer going to be protected as\nuncommitted changes in the working tree) without a branch to hold it\nby seeing that there is such a description for the current state\nbefore the commit. (Afterwards, the description should be dropped; it\ndoesn't make sense to tell the user they checked out \"origin/master\"\nor \"d199fb7\" when they've now diverged from that remote branch with\nlocal changes or made a different commit.)\n\nThe upshot of the messages should be:\n\n $ git checkout origin/master\n Since you can't actually change \"origin/master\" yourself, you'll just\n be sightseeing unless you create a local branch to hold new local work.\n\n $ git branch\n * (not a local branch, but \"origin/master\")\n\n $ git commit\n You've been sightseeing \"origin/master\". The commit can't change that\n value, so your commit isn't held in any branch. If you want to create\n a branch to hold it, here's how.\n\n\"git checkout origin/master\" should be similar in complexity to\n\"svn checkout -r 8655\"; the difference is that svn won't let you\ncommit then and git will but you'll need to understand the\nimplications if you do so. If you don't commit (because you don't want\nto make any changes, because you don't think it would be possible, or\nbecause you don't want to worry about what would happen), there's no\nmeaningful difference, and you don't need to be told.\n\nThe messages have to be improved and made more useful.\n\nThe effects of \"git checkout HEAD\", \"git checkout origin/master; git \ncheckout HEAD^\", and \"git checkout origin/master; git reset --hard \norigin/next\" aren't handled quite right; none of them keep a description, \nbut there should always be some description of a detached HEAD unless the \nuser has made a commit (and therefore gotten the message about making a \nlocal branch to put it on).\n---\n branch.c                 |   13 +++++++++++++\n branch.h                 |    6 ++++++\n builtin-branch.c         |   13 ++++++++++++-\n builtin-checkout.c       |    8 +++++++-\n builtin-commit.c         |   10 +++++++++-\n t/t3203-branch-output.sh |    2 +-\n t/t7201-co.sh            |    6 ++----\n 7 files changed, 50 insertions(+), 8 deletions(-)\n\ndiff --git a/branch.c b/branch.c\nindex 05ef3f5..2c5b6d3 100644\n--- a/branch.c\n+++ b/branch.c\n@@ -194,6 +194,18 @@ void create_branch(const char *head,\n \tfree(real_ref);\n }\n \n+char *get_detached_head_string(void)\n+{\n+\tchar *filename = git_path(\"DETACH_NAME\");\n+\tstruct stat st;\n+\tif (stat(filename, &st) || !S_ISREG(st.st_mode))\n+\t\treturn NULL;\n+\tstruct strbuf buf = STRBUF_INIT;\n+\tstrbuf_read_file(&buf, filename, st.st_size);\n+\tstrbuf_trim(&buf);\n+\treturn strbuf_detach(&buf, 0);\n+}\n+\n void remove_branch_state(void)\n {\n \tunlink(git_path(\"MERGE_HEAD\"));\n@@ -201,4 +213,5 @@ void remove_branch_state(void)\n \tunlink(git_path(\"MERGE_MSG\"));\n \tunlink(git_path(\"MERGE_MODE\"));\n \tunlink(git_path(\"SQUASH_MSG\"));\n+\tunlink(git_path(\"DETACH_NAME\"));\n }\ndiff --git a/branch.h b/branch.h\nindex eed817a..0a30c3a 100644\n--- a/branch.h\n+++ b/branch.h\n@@ -22,6 +22,12 @@ void create_branch(const char *head, const char *name, const char *start_name,\n void remove_branch_state(void);\n \n /*\n+ * Returns the string used when detaching HEAD, or NULL if HEAD is not\n+ * detached.\n+ */\n+char *get_detached_head_string(void);\n+\n+/*\n  * Configure local branch \"local\" to merge remote branch \"remote\"\n  * taken from origin \"origin\".\n  */\ndiff --git a/builtin-branch.c b/builtin-branch.c\nindex 9f57992..9ce4127 100644\n--- a/builtin-branch.c\n+++ b/builtin-branch.c\n@@ -425,7 +425,18 @@ static void show_detached(struct ref_list *ref_list)\n \n \tif (head_commit && is_descendant_of(head_commit, ref_list->with_commit)) {\n \t\tstruct ref_item item;\n-\t\titem.name = xstrdup(\"(no branch)\");\n+\t\tchar *literal = get_detached_head_string();\n+\t\tstruct stat st;\n+\t\tif (literal) {\n+\t\t\tstruct strbuf buf = STRBUF_INIT;\n+\t\t\tstrbuf_addstr(&buf, \"(no branch, as \\\"\");\n+\t\t\tstrbuf_addstr(&buf, literal);\n+\t\t\tstrbuf_addstr(&buf, \"\\\")\");\n+\t\t\tfree(literal);\n+\t\t\titem.name = strbuf_detach(&buf, 0);\n+\t\t} else {\n+\t\t\titem.name = xstrdup(\"(no branch)\");\n+\t\t}\n \t\titem.len = strlen(item.name);\n \t\titem.kind = REF_LOCAL_BRANCH;\n \t\titem.dest = NULL;\ndiff --git a/builtin-checkout.c b/builtin-checkout.c\nindex d050c37..448397d 100644\n--- a/builtin-checkout.c\n+++ b/builtin-checkout.c\n@@ -510,11 +510,17 @@ static void update_refs_for_switch(struct checkout_opts *opts,\n \t\t\t   REF_NODEREF, DIE_ON_ERR);\n \t\tif (!opts->quiet) {\n \t\t\tif (old->path)\n-\t\t\t\tfprintf(stderr, \"Note: moving to '%s' which isn't a local branch\\nIf you want to create a new branch from this checkout, you may do so\\n(now or later) by using -b with the checkout command again. Example:\\n  git checkout -b <new_branch_name>\\n\", new->name);\n+\t\t\t\tfprintf(stderr, \"Note: moving to '%s' which isn't a local branch.\\nAny commits you may make will not affect the commit with this name.\\n\", new->name);\n \t\t\tdescribe_detached_head(\"HEAD is now at\", new->commit);\n \t\t}\n \t}\n \tremove_branch_state();\n+\tif (!new->path && strcmp(new->name, \"HEAD\")) {\n+\t\tFILE *detach_name;\n+\t\tdetach_name = fopen(git_path(\"DETACH_NAME\"), \"w\");\n+\t\tfprintf(detach_name, \"%s\\n\", new->name);\n+\t\tfclose(detach_name);\n+\t}\n \tstrbuf_release(&msg);\n \tif (!opts->quiet && (new->path || !strcmp(new->name, \"HEAD\")))\n \t\treport_tracking(new);\ndiff --git a/builtin-commit.c b/builtin-commit.c\nindex 200ffda..2ceb951 100644\n--- a/builtin-commit.c\n+++ b/builtin-commit.c\n@@ -24,6 +24,7 @@\n #include \"string-list.h\"\n #include \"rerere.h\"\n #include \"unpack-trees.h\"\n+#include \"branch.h\"\n \n static const char * const builtin_commit_usage[] = {\n \t\"git commit [options] [--] <filepattern>...\",\n@@ -968,6 +969,7 @@ int cmd_commit(int argc, const char **argv, const char *prefix)\n \tstruct ref_lock *ref_lock;\n \tstruct commit_list *parents = NULL, **pptr = &parents;\n \tstruct stat statbuf;\n+\tchar *detached_string;\n \tint allow_fast_forward = 1;\n \tstruct wt_status s;\n \n@@ -1089,10 +1091,13 @@ int cmd_commit(int argc, const char **argv, const char *prefix)\n \t\tdie(\"cannot update HEAD ref\");\n \t}\n \n+\tdetached_string = get_detached_head_string();\n+\n \tunlink(git_path(\"MERGE_HEAD\"));\n \tunlink(git_path(\"MERGE_MSG\"));\n \tunlink(git_path(\"MERGE_MODE\"));\n \tunlink(git_path(\"SQUASH_MSG\"));\n+\tunlink(git_path(\"DETACH_NAME\"));\n \n \tif (commit_index_files())\n \t\tdie (\"Repository has been updated, but unable to write\\n\"\n@@ -1101,8 +1106,11 @@ int cmd_commit(int argc, const char **argv, const char *prefix)\n \n \trerere();\n \trun_hook(get_index_file(), \"post-commit\", NULL);\n-\tif (!quiet)\n+\tif (!quiet) {\n+\t\tif (detached_string)\n+\t\t\tfprintf(stderr, \"\\nNote: you had checked out '%s' which isn't a local branch.\\nIf you want to create a new branch with this commit, you may do so\\n(now or later) by using -b with the checkout command. Example:\\n  git checkout -b <new_branch_name>\\n\\n\", detached_string);\n \t\tprint_summary(prefix, commit_sha1);\n+\t}\n \n \treturn 0;\n }\ndiff --git a/t/t3203-branch-output.sh b/t/t3203-branch-output.sh\nindex 809d1c4..08409cd 100755\n--- a/t/t3203-branch-output.sh\n+++ b/t/t3203-branch-output.sh\n@@ -67,7 +67,7 @@ test_expect_success 'git branch -v shows branch summaries' '\n '\n \n cat >expect <<'EOF'\n-* (no branch)\n+* (no branch, as \"HEAD^0\")\n   branch-one\n   branch-two\n   master\ndiff --git a/t/t7201-co.sh b/t/t7201-co.sh\nindex ebfd34d..0f40589 100755\n--- a/t/t7201-co.sh\n+++ b/t/t7201-co.sh\n@@ -171,10 +171,8 @@ test_expect_success 'checkout to detach HEAD' '\n \tgit checkout -f renamer && git clean -f &&\n \tgit checkout renamer^ 2>messages &&\n \t(cat >messages.expect <<EOF\n-Note: moving to '\\''renamer^'\\'' which isn'\\''t a local branch\n-If you want to create a new branch from this checkout, you may do so\n-(now or later) by using -b with the checkout command again. Example:\n-  git checkout -b <new_branch_name>\n+Note: moving to '\\''renamer^'\\'' which isn'\\''t a local branch.\n+Any commits you may make will not affect the commit with this name.\n HEAD is now at 7329388... Initial A one, A two\n EOF\n ) &&\n-- \n1.6.5.9.ge994f.dirty\n"},{"id":"124931","messageId":"7v4oq2mulf.fsf@alter.siamese.dyndns.org","threadId":"21236","inReplyTo":"alpine.LNX.2.00.0910140037570.32515@iabervon.org","subject":"Re: [PATCH] Proof-of-concept patch to remember what the detached HEAD was","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2009-10-14T05:07:40Z","receivedAt":"2009-10-14T05:07:40Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Daniel Barkalow <barkalow@iabervon.org> writes:\n\n> When detaching HEAD (or \"browsing history\"), the user has specified\n> the commit with some \"extended SHA1\" which is not a local\n> branch....\n\nI do not have enough mental bandwidth to think about (1) if this\ninformation is a good thing to have, shown in your transcript, or (2) if\nthe name of the branch _before_ getting into the detached state may be\nmore interesting information tonight.\n\nBut I have one question regarding the implementation.  Why do you need a\nnew file in $GIT_DIR for this?  Wouldn't what is in the logs/HEAD be\nenough, and if not why not?\n"},{"id":"124932","messageId":"20091014050851.GE31810@coredump.intra.peff.net","threadId":"21236","inReplyTo":"alpine.LNX.2.00.0910140037570.32515@iabervon.org","subject":"Re: [PATCH] Proof-of-concept patch to remember what the detached HEAD was","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2009-10-14T05:08:51Z","receivedAt":"2009-10-14T05:08:51Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Wed, Oct 14, 2009 at 12:44:34AM -0400, Daniel Barkalow wrote:\n\n> +char *get_detached_head_string(void)\n> +{\n> +\tchar *filename = git_path(\"DETACH_NAME\");\n> +\tstruct stat st;\n> +\tif (stat(filename, &st) || !S_ISREG(st.st_mode))\n> +\t\treturn NULL;\n> +\tstruct strbuf buf = STRBUF_INIT;\n> +\tstrbuf_read_file(&buf, filename, st.st_size);\n> +\tstrbuf_trim(&buf);\n> +\treturn strbuf_detach(&buf, 0);\n> +}\n\nWould it hurt to tuck this information into HEAD itself, as we already\nput arbitrary text into FETCH_HEAD?\n\n-Peff\n"},{"id":"124961","messageId":"alpine.DEB.1.00.0910141233060.4985@pacific.mpi-cbg.de","threadId":"21236","inReplyTo":"20091014050851.GE31810@coredump.intra.peff.net","subject":"Re: [PATCH] Proof-of-concept patch to remember what the detached HEAD was","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2009-10-14T10:33:22Z","receivedAt":"2009-10-14T10:33:22Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi,\n\nOn Wed, 14 Oct 2009, Jeff King wrote:\n\n> On Wed, Oct 14, 2009 at 12:44:34AM -0400, Daniel Barkalow wrote:\n> \n> > +char *get_detached_head_string(void)\n> > +{\n> > +\tchar *filename = git_path(\"DETACH_NAME\");\n> > +\tstruct stat st;\n> > +\tif (stat(filename, &st) || !S_ISREG(st.st_mode))\n> > +\t\treturn NULL;\n> > +\tstruct strbuf buf = STRBUF_INIT;\n> > +\tstrbuf_read_file(&buf, filename, st.st_size);\n> > +\tstrbuf_trim(&buf);\n> > +\treturn strbuf_detach(&buf, 0);\n> > +}\n> \n> Would it hurt to tuck this information into HEAD itself, as we already\n> put arbitrary text into FETCH_HEAD?\n\nAFAIR we still remember HEAD to be a symlink.\n\nCiao,\nDscho\n"},{"id":"124981","messageId":"20091014153934.GA3680@coredump.intra.peff.net","threadId":"21236","inReplyTo":"alpine.DEB.1.00.0910141233060.4985@pacific.mpi-cbg.de","subject":"Re: [PATCH] Proof-of-concept patch to remember what the detached HEAD was","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2009-10-14T15:39:34Z","receivedAt":"2009-10-14T15:39:34Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Wed, Oct 14, 2009 at 12:33:22PM +0200, Johannes Schindelin wrote:\n\n> > > +char *get_detached_head_string(void)\n> > > +{\n> > > +\tchar *filename = git_path(\"DETACH_NAME\");\n> > > +\tstruct stat st;\n> > > +\tif (stat(filename, &st) || !S_ISREG(st.st_mode))\n> > > +\t\treturn NULL;\n> > > +\tstruct strbuf buf = STRBUF_INIT;\n> > > +\tstrbuf_read_file(&buf, filename, st.st_size);\n> > > +\tstrbuf_trim(&buf);\n> > > +\treturn strbuf_detach(&buf, 0);\n> > > +}\n> > \n> > Would it hurt to tuck this information into HEAD itself, as we already\n> > put arbitrary text into FETCH_HEAD?\n> \n> AFAIR we still remember HEAD to be a symlink.\n\nI think that has been abandoned for detached HEAD (that is, if you\nsupport only symlinked HEAD, then you cannot detach at all). But I might\nbe wrong. It has been a while since I looked at that code.\n\n-Peff\n"},{"id":"124984","messageId":"alpine.LNX.2.00.0910141143520.32515@iabervon.org","threadId":"21236","inReplyTo":"20091014050851.GE31810@coredump.intra.peff.net","subject":"Re: [PATCH] Proof-of-concept patch to remember what the detached HEAD was","fromName":"Daniel Barkalow","fromEmail":"barkalow@iabervon.org","sentAt":"2009-10-14T15:56:20Z","receivedAt":"2009-10-14T15:56:20Z","isPatch":true,"sender":{"key":"barkalow@iabervon.org","avatar":"https://avatars.githubusercontent.com/u/55364219?v=4"},"body":"On Wed, 14 Oct 2009, Jeff King wrote:\n\n> On Wed, Oct 14, 2009 at 12:44:34AM -0400, Daniel Barkalow wrote:\n> \n> > +char *get_detached_head_string(void)\n> > +{\n> > +\tchar *filename = git_path(\"DETACH_NAME\");\n> > +\tstruct stat st;\n> > +\tif (stat(filename, &st) || !S_ISREG(st.st_mode))\n> > +\t\treturn NULL;\n> > +\tstruct strbuf buf = STRBUF_INIT;\n> > +\tstrbuf_read_file(&buf, filename, st.st_size);\n> > +\tstrbuf_trim(&buf);\n> > +\treturn strbuf_detach(&buf, 0);\n> > +}\n> \n> Would it hurt to tuck this information into HEAD itself, as we already\n> put arbitrary text into FETCH_HEAD?\n\nI don't know; I'll have to try that and see if the tools that handle HEAD \nare happy with extra text there. If it works, it's a good solution.\n\nI think I tried it at some point and things failed all over the place, but \nthat may have been before symrefs, when you could get the actual sha1 \nhash out of HEAD with \"$(cat .git/HEAD)\".\n\n\t-Daniel\n*This .sig left intentionally blank*\n"},{"id":"125001","messageId":"7vljjdese3.fsf@alter.siamese.dyndns.org","threadId":"21236","inReplyTo":"20091014153934.GA3680@coredump.intra.peff.net","subject":"Re: [PATCH] Proof-of-concept patch to remember what the detached HEAD was","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2009-10-14T18:34:44Z","receivedAt":"2009-10-14T18:34:44Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Jeff King <peff@peff.net> writes:\n\n> On Wed, Oct 14, 2009 at 12:33:22PM +0200, Johannes Schindelin wrote:\n>\n>> > > +char *get_detached_head_string(void)\n>> > > +{\n>> > > +\tchar *filename = git_path(\"DETACH_NAME\");\n>> > > +\tstruct stat st;\n>> > > +\tif (stat(filename, &st) || !S_ISREG(st.st_mode))\n>> > > +\t\treturn NULL;\n>> > > +\tstruct strbuf buf = STRBUF_INIT;\n>> > > +\tstrbuf_read_file(&buf, filename, st.st_size);\n>> > > +\tstrbuf_trim(&buf);\n>> > > +\treturn strbuf_detach(&buf, 0);\n>> > > +}\n>> > \n>> > Would it hurt to tuck this information into HEAD itself, as we already\n>> > put arbitrary text into FETCH_HEAD?\n>> \n>> AFAIR we still remember HEAD to be a symlink.\n>\n> I think that has been abandoned for detached HEAD (that is, if you\n> support only symlinked HEAD, then you cannot detach at all). But I might\n> be wrong. It has been a while since I looked at that code.\n\nIf I understand what Daniel is doing correctly, the idea is to keep this\nextra information only while the HEAD is detached, no?  \"HEAD itself\ncould be a symlink\" is an irrelevant issue, isn't it?\n"},{"id":"125003","messageId":"20091014184018.GB15522@coredump.intra.peff.net","threadId":"21236","inReplyTo":"7vljjdese3.fsf@alter.siamese.dyndns.org","subject":"Re: [PATCH] Proof-of-concept patch to remember what the detached HEAD was","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2009-10-14T18:40:18Z","receivedAt":"2009-10-14T18:40:18Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Wed, Oct 14, 2009 at 11:34:44AM -0700, Junio C Hamano wrote:\n\n> >> AFAIR we still remember HEAD to be a symlink.\n> >\n> > I think that has been abandoned for detached HEAD (that is, if you\n> > support only symlinked HEAD, then you cannot detach at all). But I might\n> > be wrong. It has been a while since I looked at that code.\n> \n> If I understand what Daniel is doing correctly, the idea is to keep this\n> extra information only while the HEAD is detached, no?  \"HEAD itself\n> could be a symlink\" is an irrelevant issue, isn't it?\n\nRight. That is what I was trying to say, but somehow it didn't come out\nvery clearly.\n\n-Peff\n"},{"id":"125006","messageId":"76718490910141156g440ee455t2e1db72ad72b7049@mail.gmail.com","threadId":"21236","inReplyTo":"alpine.LNX.2.00.0910140037570.32515@iabervon.org","subject":"Re: [PATCH] Proof-of-concept patch to remember what the detached HEAD was","fromName":"Jay Soffian","fromEmail":"jaysoffian@gmail.com","sentAt":"2009-10-14T18:56:11Z","receivedAt":"2009-10-14T18:56:11Z","isPatch":true,"sender":{"key":"jaysoffian@gmail.com","avatar":"https://avatars.githubusercontent.com/u/155970?v=4"},"body":"On Wed, Oct 14, 2009 at 12:44 AM, Daniel Barkalow <barkalow@iabervon.org> wrote:\n>  $ git commit\n>  You've been sightseeing \"origin/master\". The commit can't change that\n>  value, so your commit isn't held in any branch. If you want to create\n>  a branch to hold it, here's how.\n>\n> \"git checkout origin/master\" should be similar in complexity to\n> \"svn checkout -r 8655\"; the difference is that svn won't let you\n> commit then and git will but you'll need to understand the\n> implications if you do so. If you don't commit (because you don't want\n> to make any changes, because you don't think it would be possible, or\n> because you don't want to worry about what would happen), there's no\n> meaningful difference, and you don't need to be told.\n\nHuh, I hadn't seen this message before I wrote in a reply to\n\"builtin-checkout: suggest creating local branch\" that we do the\nfollowing at commit, which I think is what you're suggesting:\n\n$ git commit -m \"blah\"\nCannot commit while not on any branch. Please use git commit -b <branch> to\nspecify the name of a new branch to commit to, or use git commit -f to\nforce a detached commit.\n\nI'm not sure that requires the complexity of remembering how the user\ngot detached though?\n\nj.\n"},{"id":"125009","messageId":"alpine.LNX.2.00.0910141509200.32515@iabervon.org","threadId":"21236","inReplyTo":"76718490910141156g440ee455t2e1db72ad72b7049@mail.gmail.com","subject":"Re: [PATCH] Proof-of-concept patch to remember what the detached HEAD was","fromName":"Daniel Barkalow","fromEmail":"barkalow@iabervon.org","sentAt":"2009-10-14T19:15:26Z","receivedAt":"2009-10-14T19:15:26Z","isPatch":true,"sender":{"key":"barkalow@iabervon.org","avatar":"https://avatars.githubusercontent.com/u/55364219?v=4"},"body":"On Wed, 14 Oct 2009, Jay Soffian wrote:\n\n> On Wed, Oct 14, 2009 at 12:44 AM, Daniel Barkalow <barkalow@iabervon.org> wrote:\n> >  $ git commit\n> >  You've been sightseeing \"origin/master\". The commit can't change that\n> >  value, so your commit isn't held in any branch. If you want to create\n> >  a branch to hold it, here's how.\n> >\n> > \"git checkout origin/master\" should be similar in complexity to\n> > \"svn checkout -r 8655\"; the difference is that svn won't let you\n> > commit then and git will but you'll need to understand the\n> > implications if you do so. If you don't commit (because you don't want\n> > to make any changes, because you don't think it would be possible, or\n> > because you don't want to worry about what would happen), there's no\n> > meaningful difference, and you don't need to be told.\n> \n> Huh, I hadn't seen this message before I wrote in a reply to\n> \"builtin-checkout: suggest creating local branch\" that we do the\n> following at commit, which I think is what you're suggesting:\n> \n> $ git commit -m \"blah\"\n> Cannot commit while not on any branch. Please use git commit -b <branch> to\n> specify the name of a new branch to commit to, or use git commit -f to\n> force a detached commit.\n\nThe difference is that some experienced users depend on being able to \ncommit while not on a branch, and want to not get a warning for every \ncommit while not on a branch.\n\n> I'm not sure that requires the complexity of remembering how the user\n> got detached though?\n\nWhat matters there is actually whether we got to the present state by \ncommitting or not. It's also relevant to telling the user what they've got \nchecked out that isn't a branch.\n\n\t-Daniel\n*This .sif left intentionally blank*"},{"id":"125017","messageId":"alpine.LFD.2.00.0910141616530.20122@xanadu.home","threadId":"21236","inReplyTo":"alpine.LNX.2.00.0910141509200.32515@iabervon.org","subject":"Re: [PATCH] Proof-of-concept patch to remember what the detached HEAD was","fromName":"Nicolas Pitre","fromEmail":"nico@fluxnic.net","sentAt":"2009-10-14T20:18:03Z","receivedAt":"2009-10-14T20:18:03Z","isPatch":true,"sender":{"key":"nico@fluxnic.net","avatar":"https://avatars.githubusercontent.com/u/702790?v=4"},"body":"On Wed, 14 Oct 2009, Daniel Barkalow wrote:\n\n> On Wed, 14 Oct 2009, Jay Soffian wrote:\n> \n> > $ git commit -m \"blah\"\n> > Cannot commit while not on any branch. Please use git commit -b <branch> to\n> > specify the name of a new branch to commit to, or use git commit -f to\n> > force a detached commit.\n> \n> The difference is that some experienced users depend on being able to \n> commit while not on a branch, and want to not get a warning for every \n> commit while not on a branch.\n\nI assume that the -f would silence any warning?\n\n\nNicolas\n"},{"id":"125018","messageId":"alpine.LNX.2.00.0910141625170.32515@iabervon.org","threadId":"21236","inReplyTo":"alpine.LFD.2.00.0910141616530.20122@xanadu.home","subject":"Re: [PATCH] Proof-of-concept patch to remember what the detached HEAD was","fromName":"Daniel Barkalow","fromEmail":"barkalow@iabervon.org","sentAt":"2009-10-14T20:37:07Z","receivedAt":"2009-10-14T20:37:07Z","isPatch":true,"sender":{"key":"barkalow@iabervon.org","avatar":"https://avatars.githubusercontent.com/u/55364219?v=4"},"body":"On Wed, 14 Oct 2009, Nicolas Pitre wrote:\n\n> On Wed, 14 Oct 2009, Daniel Barkalow wrote:\n> \n> > On Wed, 14 Oct 2009, Jay Soffian wrote:\n> > \n> > > $ git commit -m \"blah\"\n> > > Cannot commit while not on any branch. Please use git commit -b <branch> to\n> > > specify the name of a new branch to commit to, or use git commit -f to\n> > > force a detached commit.\n> > \n> > The difference is that some experienced users depend on being able to \n> > commit while not on a branch, and want to not get a warning for every \n> > commit while not on a branch.\n> \n> I assume that the -f would silence any warning?\n\nI suppose; I don't know if that would be acceptable to the relevant users. \nIt would certainly require script changes, but that's not an issue for \n1.7.0, presumably.\n\nI personally normally use the order:\n\n$ git checkout origin/master\n(change stuff, test)\n$ git checkout -b my-topic\n$ git commit\n\nSo I only care about detaching, not committing while detached, and I'm not \nthe right person to ask.\n\n\t-Daniel\n*This .sig left intentionally blank*\n"},{"id":"125021","messageId":"7v7huxbtbk.fsf@alter.siamese.dyndns.org","threadId":"21236","inReplyTo":"alpine.LFD.2.00.0910141616530.20122@xanadu.home","subject":"Re: [PATCH] Proof-of-concept patch to remember what the detached HEAD was","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2009-10-14T20:42:55Z","receivedAt":"2009-10-14T20:42:55Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Nicolas Pitre <nico@fluxnic.net> writes:\n\n> On Wed, 14 Oct 2009, Daniel Barkalow wrote:\n>\n>> On Wed, 14 Oct 2009, Jay Soffian wrote:\n>> \n>> > $ git commit -m \"blah\"\n>> > Cannot commit while not on any branch. Please use git commit -b <branch> to\n>> > specify the name of a new branch to commit to, or use git commit -f to\n>> > force a detached commit.\n>> \n>> The difference is that some experienced users depend on being able to \n>> commit while not on a branch, and want to not get a warning for every \n>> commit while not on a branch.\n>\n> I assume that the -f would silence any warning?\n\nIt won't help to alleviate my irritation if I need to give -f to each and\nevery invocation of \"git commit\" while detached, though.\n"},{"id":"125022","messageId":"alpine.LFD.2.00.0910141647390.20122@xanadu.home","threadId":"21236","inReplyTo":"7v7huxbtbk.fsf@alter.siamese.dyndns.org","subject":"Re: [PATCH] Proof-of-concept patch to remember what the detached HEAD was","fromName":"Nicolas Pitre","fromEmail":"nico@fluxnic.net","sentAt":"2009-10-14T20:48:29Z","receivedAt":"2009-10-14T20:48:29Z","isPatch":true,"sender":{"key":"nico@fluxnic.net","avatar":"https://avatars.githubusercontent.com/u/702790?v=4"},"body":"On Wed, 14 Oct 2009, Junio C Hamano wrote:\n\n> Nicolas Pitre <nico@fluxnic.net> writes:\n> \n> > On Wed, 14 Oct 2009, Daniel Barkalow wrote:\n> >\n> >> On Wed, 14 Oct 2009, Jay Soffian wrote:\n> >> \n> >> > $ git commit -m \"blah\"\n> >> > Cannot commit while not on any branch. Please use git commit -b <branch> to\n> >> > specify the name of a new branch to commit to, or use git commit -f to\n> >> > force a detached commit.\n> >> \n> >> The difference is that some experienced users depend on being able to \n> >> commit while not on a branch, and want to not get a warning for every \n> >> commit while not on a branch.\n> >\n> > I assume that the -f would silence any warning?\n> \n> It won't help to alleviate my irritation if I need to give -f to each and\n> every invocation of \"git commit\" while detached, though.\n\nAgreed.  Presumably some expert mode config would imply -f \nautomatically.\n\n\nNicolas\n"},{"id":"125027","messageId":"7vws2xa9lu.fsf@alter.siamese.dyndns.org","threadId":"21236","inReplyTo":"alpine.LFD.2.00.0910141647390.20122@xanadu.home","subject":"Re: [PATCH] Proof-of-concept patch to remember what the detached HEAD was","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2009-10-14T22:34:05Z","receivedAt":"2009-10-14T22:34:05Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Nicolas Pitre <nico@fluxnic.net> writes:\n\n> On Wed, 14 Oct 2009, Junio C Hamano wrote:\n>\n>> Nicolas Pitre <nico@fluxnic.net> writes:\n>> \n>> > On Wed, 14 Oct 2009, Daniel Barkalow wrote:\n>> >\n>> >> On Wed, 14 Oct 2009, Jay Soffian wrote:\n>> >> \n>> >> > $ git commit -m \"blah\"\n>> >> > Cannot commit while not on any branch. Please use git commit -b <branch> to\n>> >> > specify the name of a new branch to commit to, or use git commit -f to\n>> >> > force a detached commit.\n>> >> \n>> >> The difference is that some experienced users depend on being able to \n>> >> commit while not on a branch, and want to not get a warning for every \n>> >> commit while not on a branch.\n>> >\n>> > I assume that the -f would silence any warning?\n>> \n>> It won't help to alleviate my irritation if I need to give -f to each and\n>> every invocation of \"git commit\" while detached, though.\n>\n> Agreed.  Presumably some expert mode config would imply -f \n> automatically.\n\nNo, I do not want an expert mode.  I can probably live with \"per session\"\nsetting, that makes me decide to set or not set it when I detach, though.\n"},{"id":"125032","messageId":"20091014230934.GC29664@coredump.intra.peff.net","threadId":"21236","inReplyTo":"7vws2xa9lu.fsf@alter.siamese.dyndns.org","subject":"Re: [PATCH] Proof-of-concept patch to remember what the detached HEAD was","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2009-10-14T23:09:34Z","receivedAt":"2009-10-14T23:09:34Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Wed, Oct 14, 2009 at 03:34:05PM -0700, Junio C Hamano wrote:\n\n> > Agreed.  Presumably some expert mode config would imply -f \n> > automatically.\n> \n> No, I do not want an expert mode.  I can probably live with \"per session\"\n> setting, that makes me decide to set or not set it when I detach, though.\n\nThat makes the most sense to me. If \"git checkout\" could write metadata\ninto HEAD (or into DETACH_HEAD, as in Daniel's patch), then checkout\ncould record an \"ok to commit\" bit. And could also be used to change it\nafter the fact. E.g.:\n\n  $ git checkout --detach=commit origin/master\n  $ git commit ;# should be ok\n\n  $ git checkout --detach=examine origin/master\n  $ git commit ;# complain\n  $ git checkout --detach=commit HEAD\n  $ git commit ;# ok\n\nI guess something like \"rebase\" should detach with \"ok to commit\", since\nit is planning on attaching the commits later. I'm not sure about \"git\nbisect\". I guess probably it should be \"not ok to commit\" to be on the\nsafe side, and then somebody can \"git checkout --detach=commit\" if they\nwant to.\n\n-Peff\n"},{"id":"125034","messageId":"alpine.LFD.2.00.0910141926170.20122@xanadu.home","threadId":"21236","inReplyTo":"20091014230934.GC29664@coredump.intra.peff.net","subject":"Re: [PATCH] Proof-of-concept patch to remember what the detached HEAD was","fromName":"Nicolas Pitre","fromEmail":"nico@fluxnic.net","sentAt":"2009-10-14T23:34:46Z","receivedAt":"2009-10-14T23:34:46Z","isPatch":true,"sender":{"key":"nico@fluxnic.net","avatar":"https://avatars.githubusercontent.com/u/702790?v=4"},"body":"On Wed, 14 Oct 2009, Jeff King wrote:\n\n> On Wed, Oct 14, 2009 at 03:34:05PM -0700, Junio C Hamano wrote:\n> \n> > > Agreed.  Presumably some expert mode config would imply -f \n> > > automatically.\n> > \n> > No, I do not want an expert mode.  I can probably live with \"per session\"\n> > setting, that makes me decide to set or not set it when I detach, though.\n> \n> That makes the most sense to me. If \"git checkout\" could write metadata\n> into HEAD (or into DETACH_HEAD, as in Daniel's patch), then checkout\n> could record an \"ok to commit\" bit. And could also be used to change it\n> after the fact. E.g.:\n> \n>   $ git checkout --detach=commit origin/master\n>   $ git commit ;# should be ok\n> \n>   $ git checkout --detach=examine origin/master\n>   $ git commit ;# complain\n>   $ git checkout --detach=commit HEAD\n>   $ git commit ;# ok\n> \n> I guess something like \"rebase\" should detach with \"ok to commit\", since\n> it is planning on attaching the commits later. I'm not sure about \"git\n> bisect\". I guess probably it should be \"not ok to commit\" to be on the\n> safe side, and then somebody can \"git checkout --detach=commit\" if they\n> want to.\n\nWhatever is done about this... I'm afraid Git will end up less useful as \noperations that were possible before won't be anymore for \"security's \nsake\" unless some obnoxious override mode is involved.\n\nIsn't the reflog already dealing with the security issue by making sure \nthat nothing is \"lost\"?\n\nCan't the user confusion be dealt with through some means other than \nmaking the tool less flexible?  I don't mind extra help message to be \ndisplayed after a headless commit is made for example.  But trying to \nmake the tool more friendly should perhaps come from better education \nrather than added restrictions.\n\nMy thoughts only.\n\n\nNicolas\n"},{"id":"125035","messageId":"loom.20091015T013728-831@post.gmane.org","threadId":"21236","inReplyTo":"7v7huxbtbk.fsf@alter.siamese.dyndns.org","subject":"Re: [PATCH] Proof-of-concept patch to remember what the detached HEAD was","fromName":"Eric Raible","fromEmail":"raible@gmail.com","sentAt":"2009-10-14T23:52:25Z","receivedAt":"2009-10-14T23:52:25Z","isPatch":true,"sender":{"key":"raible@gmail.com","avatar":null},"body":"Junio C Hamano <gitster <at> pobox.com> writes:\n\n> It won't help to alleviate my irritation if I need to give -f to each and\n> every invocation of \"git commit\" while detached, though.\n\nI'm missing something fundamental here, I think.\nI simply don't see the advantage of branching after committing\nover branching before committing.\n\nAt worst, a temporary is cheap, eh?  So what is the value\nof even allowing committing while HEAD is detached\n(aside from the historical argument)?\n"},{"id":"125036","messageId":"7viqeha2zv.fsf@alter.siamese.dyndns.org","threadId":"21236","inReplyTo":"alpine.LFD.2.00.0910141926170.20122@xanadu.home","subject":"Re: [PATCH] Proof-of-concept patch to remember what the detached HEAD was","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2009-10-15T00:56:52Z","receivedAt":"2009-10-15T00:56:52Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Nicolas Pitre <nico@fluxnic.net> writes:\n\n> Can't the user confusion be dealt with through some means other than \n> making the tool less flexible?  I don't mind extra help message to be \n> displayed after a headless commit is made for example.  But trying to \n> make the tool more friendly should perhaps come from better education \n> rather than added restrictions.\n>\n> My thoughts only.\n\nI actually share that but there apparently are people who have given up on\nthe education route.\n"},{"id":"125037","messageId":"20091015014737.GA9923@coredump.intra.peff.net","threadId":"21236","inReplyTo":"7viqeha2zv.fsf@alter.siamese.dyndns.org","subject":"Re: [PATCH] Proof-of-concept patch to remember what the detached HEAD was","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2009-10-15T01:47:37Z","receivedAt":"2009-10-15T01:47:37Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Wed, Oct 14, 2009 at 05:56:52PM -0700, Junio C Hamano wrote:\n\n> Nicolas Pitre <nico@fluxnic.net> writes:\n> \n> > Can't the user confusion be dealt with through some means other than \n> > making the tool less flexible?  I don't mind extra help message to be \n> > displayed after a headless commit is made for example.  But trying to \n> > make the tool more friendly should perhaps come from better education \n> > rather than added restrictions.\n> >\n> > My thoughts only.\n> \n> I actually share that but there apparently are people who have given up on\n> the education route.\n\nI am personally undecided on this issue (my \"this is the best option\"\nwas the best of \"a -f switch to commit, an 'expert' config option', or a\nsession-based option to commit\").\n\nBut we really seem to have reached an impasse with how to proceed with\ngit ui.\n\nPeople like Dscho are fed up with user complaints about parts of git\nthat can be unfriendly to new users. And I can understand that.  There\n_is_ a perception that git is hard for beginners to use, and I don't\nthink that perception is entirely without merit. We expect the user to\nunderstand the basic concepts of git, like history graphs, named refs\nversus detached heads, tracking refs, the index, etc.\n\nAt the same time, I think that is what many of us _like_ about git. It\nis based around simple and powerful concepts, and it doesn't get in your\nway when you want to use those concepts in a powerful and flexible\nmanner. And I can understand resistance to making those features hard or\ninconvenient to access; detached HEADs were invented for a reason, and\nwe want to use them.\n\nSo what is the right way to mediate between those desires? We have tried\nor suggested several options, including:\n\n  1. Educate users. Keep exposing them to the concepts, but make\n     messages more clear. Improve documentation. This is largely the\n     route taken with the index. Has it worked? I think there is still a\n     perception among new users that the index is confusing.\n\n  2. Use configuration options to differentiate behavior. This comes in\n     the form of the sometimes-requested \"expert/beginner mode\" option.\n     But it can also mean a config option for a specific behavior. The\n     argument against it I have seen is that it can make git\n     unpredictable for new versus old users. An old-timer helping a new\n     person is more out-of-touch with what the new person's setup will\n     do (which hurts when sitting at their terminal or when giving them\n     advice online).\n\n  3. Make a new porcelain interface that wraps the git plumbing. We have\n     seen some examples of this. Obviously cogito was the first, and it\n     has fallen by the wayside as people moved towards core git. That\n     may be an artifact of its timing, though, as core git was a rapidly\n     moving target, and power users wanted to use the new features. More\n     recently we've had 'eg'. I don't know how many people are using it,\n     but it is certainly not discussed on this list much. There are also\n     GUIs wrapping git. I think these are subject to the same argument\n     as (2), but even more so. An entirely new interface like 'eg' is\n     really splitting the user base. As a git old-timer, I can keep up\n     with what newbie options might impact git's behavior. But I haven't\n     a clue how to do anything in 'eg'.\n\n  4. Hide potentially dangerous behavior behind \"-f\" or similar options,\n     or make it even more inaccessible. We have done this with some\n     obviously dangerous cases, like \"push -f\" or \"checkout -f\", which\n     can throw away data. But I think in cases where the behavior is\n     simply confusing and not dangerous, we tend not to do this (at\n     least I couldn't think of any examples off the top of my head). The\n     obvious argument against it is that it inconveniences more\n     experienced users. Dscho advocated \"the good of the many\" versus\n     \"the good of the few\". And I can see some logic in that. At the\n     same time, open source is about scratching itches. Is anyone really\n     interested in doing something that makes our own itch worse?\n     Everytime you use it, won't you be thinking about scratching?\n\nSo I don't know what the solution is. And maybe this is just useless\npontificating. But I feel like we have this discussion over and over,\nevery few months, about a different feature. I wish there were some way\nto fix that.\n\nOut of ideas,\n-Peff\n"},{"id":"125038","messageId":"alpine.LFD.2.00.0910142237010.20122@xanadu.home","threadId":"21236","inReplyTo":"20091015014737.GA9923@coredump.intra.peff.net","subject":"Re: [PATCH] Proof-of-concept patch to remember what the detached HEAD was","fromName":"Nicolas Pitre","fromEmail":"nico@fluxnic.net","sentAt":"2009-10-15T03:08:59Z","receivedAt":"2009-10-15T03:08:59Z","isPatch":true,"sender":{"key":"nico@fluxnic.net","avatar":"https://avatars.githubusercontent.com/u/702790?v=4"},"body":"On Wed, 14 Oct 2009, Jeff King wrote:\n\n> On Wed, Oct 14, 2009 at 05:56:52PM -0700, Junio C Hamano wrote:\n> \n> > Nicolas Pitre <nico@fluxnic.net> writes:\n> > \n> > > Can't the user confusion be dealt with through some means other than \n> > > making the tool less flexible?  I don't mind extra help message to be \n> > > displayed after a headless commit is made for example.  But trying to \n> > > make the tool more friendly should perhaps come from better education \n> > > rather than added restrictions.\n> > >\n> > > My thoughts only.\n> > \n> > I actually share that but there apparently are people who have given up on\n> > the education route.\n> \n> I am personally undecided on this issue (my \"this is the best option\"\n> was the best of \"a -f switch to commit, an 'expert' config option', or a\n> session-based option to commit\").\n> \n> But we really seem to have reached an impasse with how to proceed with\n> git ui.\n> \n> People like Dscho are fed up with user complaints about parts of git\n> that can be unfriendly to new users. And I can understand that.\n\nPeople like Dscho have to grow a thicker skin then.  There will _always_ \nbe user complaints regardless of how balanced you try to make a UI.\n\n> There _is_ a perception that git is hard for beginners to use, and I \n> don't think that perception is entirely without merit. We expect the \n> user to understand the basic concepts of git, like history graphs, \n> named refs versus detached heads, tracking refs, the index, etc.\n\nSure.  That's part of it, and beginners must get over with that \nperception.  Git is a professional tool and not a toy project anymore.  \nLike any professional grade tool, there is a greater effort needed from \nbeginners before being comfortable with the tool.\n\n> At the same time, I think that is what many of us _like_ about git. It\n> is based around simple and powerful concepts, and it doesn't get in your\n> way when you want to use those concepts in a powerful and flexible\n> manner. And I can understand resistance to making those features hard or\n> inconvenient to access; detached HEADs were invented for a reason, and\n> we want to use them.\n\nRight.  Removing features That _are_ being used sounds a bit backward. \nJust because they happen to be confusing to beginners is not a good \njustification to remove/cripple them IMHO.\n\n> So what is the right way to mediate between those desires? We have tried\n> or suggested several options, including:\n> \n>   1. Educate users. Keep exposing them to the concepts, but make\n>      messages more clear. Improve documentation. This is largely the\n>      route taken with the index. Has it worked? I think there is still a\n>      perception among new users that the index is confusing.\n\nWell, New users won't be new forever.  And Git is different from most \nother SCMs.  Eventually that difference is well understood by most \nnot-so-new-anymore Git users.  Right now I have to deal with Perforce at \n$work and I find it _terribly_ confusing and obnoxious to use.  So it's \nonly a question of getting used to something different.\n\nIMHO this patch proposed by Daniel about the detached head is probably a \ngood compromise.  It makes \"confusing\" operations more verbose to give \nnew users a better feeling while keeping the flexibility intact.  And \nincreased verbosity is less annoying than decreased flexibility.\n\n\nNicolas\n"},{"id":"125059","messageId":"20091015042159.GA21701@coredump.intra.peff.net","threadId":"21236","inReplyTo":"alpine.LFD.2.00.0910142237010.20122@xanadu.home","subject":"Re: [PATCH] Proof-of-concept patch to remember what the detached HEAD was","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2009-10-15T04:21:59Z","receivedAt":"2009-10-15T04:21:59Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Wed, Oct 14, 2009 at 11:08:59PM -0400, Nicolas Pitre wrote:\n\n> IMHO this patch proposed by Daniel about the detached head is probably a \n> good compromise.  It makes \"confusing\" operations more verbose to give \n> new users a better feeling while keeping the flexibility intact.  And \n> increased verbosity is less annoying than decreased flexibility.\n\nAnd I don't think there is as much opposition to a config option to\nsilence verbosity, because it isn't really a change in behavior. We\nalready have advice.*, and if the new message is too annoying, we can\nget advice.commitDetachedHead.\n\n-Peff\n"},{"id":"125061","messageId":"885649360910150036o72c3bd97ofad85d5316dc5b35@mail.gmail.com","threadId":"21236","inReplyTo":"20091014230934.GC29664@coredump.intra.peff.net","subject":"Re: [PATCH] Proof-of-concept patch to remember what the detached HEAD was","fromName":"James Pickens","fromEmail":"jepicken@gmail.com","sentAt":"2009-10-15T07:36:33Z","receivedAt":"2009-10-15T07:36:33Z","isPatch":true,"sender":{"key":"jepicken@gmail.com","avatar":null},"body":"On Wed, Oct 14, 2009 at 4:09 PM, Jeff King <peff@peff.net> wrote:\n> That makes the most sense to me. If \"git checkout\" could write metadata\n> into HEAD (or into DETACH_HEAD, as in Daniel's patch), then checkout\n> could record an \"ok to commit\" bit. And could also be used to change it\n> after the fact. E.g.:\n>\n>  $ git checkout --detach=commit origin/master\n>  $ git commit ;# should be ok\n>\n>  $ git checkout --detach=examine origin/master\n>  $ git commit ;# complain\n>  $ git checkout --detach=commit HEAD\n>  $ git commit ;# ok\n>\n> I guess something like \"rebase\" should detach with \"ok to commit\", since\n> it is planning on attaching the commits later. I'm not sure about \"git\n> bisect\". I guess probably it should be \"not ok to commit\" to be on the\n> safe side, and then somebody can \"git checkout --detach=commit\" if they\n> want to.\n\nHow about not detaching the head at all if the user checks out any ref, and\nreject commits if he checked out a tag or remote branch.  For example:\n\n$ git checkout origin/master\n$ git status\n# On branch origin/master\n$ git commit ;# complain\n\n$ git checkout v1.0.1\n$ git status\n# On tag v1.0.1\n$ git commit ;# complain\n\n$ git checkout v1.0.1^0 ;# detach\n$ git commit ;# ok\n\nI think this would help the newbies and wouldn't cost the experts too much.\nChecking out anything other than a plain ref would still detach the head, and\ncommits on a detached head would still be allowed.  Perhaps as an additional\nsafety feature, Git could refuse to switch away from a detached head if the head\nisn't reachable from any ref, and require -f to override:\n\n$ git checkout $sha1\n$ git commit\n$ git checkout master ;# complain\n$ git checkout -f master ;# ok\n\nMaybe I'm missing something and this all can't be done, but it seems simpler\nthan the other options I've seen in this thread.\n\nJames\n"},{"id":"125073","messageId":"m3bpk8g6nj.fsf@localhost.localdomain","threadId":"21236","inReplyTo":"885649360910150036o72c3bd97ofad85d5316dc5b35@mail.gmail.com","subject":"Re: [PATCH] Proof-of-concept patch to remember what the detached HEAD was","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2009-10-15T12:54:52Z","receivedAt":"2009-10-15T12:54:52Z","isPatch":true,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"James Pickens <jepicken@gmail.com> writes:\n\n> How about not detaching the head at all if the user checks out any ref, and\n> reject commits if he checked out a tag or remote branch.  For example:\n> \n> $ git checkout origin/master\n> $ git status\n> # On branch origin/master\n> $ git commit ;# complain\n> \n> $ git checkout v1.0.1\n> $ git status\n> # On tag v1.0.1\n> $ git commit ;# complain\n> \n> $ git checkout v1.0.1^0 ;# detach\n> $ git commit ;# ok\n> \n> I think this would help the newbies and wouldn't cost the experts too much.\n> Checking out anything other than a plain ref would still detach the head, and\n> commits on a detached head would still be allowed.\n\nI think it is a very good idea.\n\nThis makes it easy to checkout remote-tracking branch or a tag for\nviewing, something that was (I think) one of problems (use cases) that\nlead to invention of detached HEAD... and then it turned out that\ndetached HEAD (unnamed branch) is scary for newbie git users.  (So the\ndifficulty of having to create new branch or rewind some branch to\nview non-committable ref was replaced by scary detached HEAD concept.)\n\nWith this idea there are no problems with git commands that use\ndetached HEAD such as git-bisect (which uses it in viewing mode, but\nthen skips through history, so detached HEAD is a good solution here)\nor git-rebase (which does committing on detached HEAD for easier\naborting and cleanup).\n\n\nLet me propose additional feature: \"smart\" (context sensitive)\nwarnings, namely that in the following sequence\n\n  $ git checkout origin/master\n  $ git status\n  # On remote-tracking branch origin/master of remote origin\n  # ...\n\n  $ git commit\n\n'git commit' would refuse committing on non-heads ref, and propose,\nbeside _always_ proposing detaching HEAD and committing on such\ndetached HEAD (unnamed branch) via \"git checkout HEAD^0\", or\n\"git checkout --detach [HEAD]\":\n\n1. If there is no local branch which follows 'origin/master'\n   (which has 'origin/master' as upstream, which tracks 'origin/master')\n   propose creating it before comitting:\n\n    $ git checkout -t origin/master\n\n2. If there is single local branch that follows 'origin/master',\n   and it fast-forwards to 'origin/master' propose... \n   errr, something that would mean fast-forwarding this branch\n   and making a commit on local branch that has 'origin/master'\n   as upstream.\n   \n3. If there is single local branch that follows 'origin/master', but\n   it has changes / diverges from 'origin/master' we are viewing,\n   propose... hmmm, what then?\n\n4. If there are more than one local branch that has 'origin/master'\n   as upstream, list all those branches in message.\n\n> Perhaps as an additional safety feature, Git could refuse to switch\n> away from a detached head if the head isn't reachable from any ref,\n> and require -f to override:\n> \n> $ git checkout $sha1\n> $ git commit\n> $ git checkout master ;# complain\n> $ git checkout -f master ;# ok\n> \n> Maybe I'm missing something and this all can't be done, but it seems simpler\n> than the other options I've seen in this thread.\n\nI'm not sure about overloading '-f' option, unless we would require\ndoubled '-f' for overriding both safety checks: checkout from detached\nHEAD, and current meaning of forcing a switch even if index or the\nworking are differs from HEAD.  So you would need\n\n  $ git checkout -f -f master\n\nif you are on detached HEAD and have uncommitted changes (dirty tree \nor dirty index).\n\n-- \nJakub Narebski\nPoland\nShadeHawk on #git\n"},{"id":"125075","messageId":"20091015141151.GA7867@atjola.homenet","threadId":"21236","inReplyTo":"m3bpk8g6nj.fsf@localhost.localdomain","subject":"Re: [PATCH] Proof-of-concept patch to remember what the detached HEAD was","fromName":"Björn Steinbrink","fromEmail":"b.steinbrink@gmx.de","sentAt":"2009-10-15T14:11:51Z","receivedAt":"2009-10-15T14:11:51Z","isPatch":true,"sender":{"key":"b.steinbrink@gmx.de","avatar":"https://avatars.githubusercontent.com/u/230962?v=4"},"body":"On 2009.10.15 05:54:52 -0700, Jakub Narebski wrote:\n> James Pickens <jepicken@gmail.com> writes:\n> > Perhaps as an additional safety feature, Git could refuse to switch\n> > away from a detached head if the head isn't reachable from any ref,\n> > and require -f to override:\n> > \n> > $ git checkout $sha1\n> > $ git commit\n> > $ git checkout master ;# complain\n> > $ git checkout -f master ;# ok\n> > \n> > Maybe I'm missing something and this all can't be done, but it seems simpler\n> > than the other options I've seen in this thread.\n> \n> I'm not sure about overloading '-f' option, unless we would require\n> doubled '-f' for overriding both safety checks: checkout from detached\n> HEAD, and current meaning of forcing a switch even if index or the\n> working are differs from HEAD.  So you would need\n> \n>   $ git checkout -f -f master\n> \n> if you are on detached HEAD and have uncommitted changes (dirty tree \n> or dirty index).\n\nA dirty index/worktree doesn't necessarily stop you from checking out a\ndifferent branch head/commit. Only if you have uncommitted changes to a\nfile that also has changes between HEAD and <other_branch>, git refuses\nto switch. And if you want to keep your uncommitted changes, you want to\nuse -m (3-way merge), not -f (drop changes).\n\ngit checkout -f foo ~= git reset --hard && git checkout foo\n\nSo -f is most likely _not_ the flag one wants to overload.\n\nBjörn\n"},{"id":"125078","messageId":"alpine.LNX.2.00.0910151054190.32515@iabervon.org","threadId":"21236","inReplyTo":"885649360910150036o72c3bd97ofad85d5316dc5b35@mail.gmail.com","subject":"Re: [PATCH] Proof-of-concept patch to remember what the detached HEAD was","fromName":"Daniel Barkalow","fromEmail":"barkalow@iabervon.org","sentAt":"2009-10-15T15:36:51Z","receivedAt":"2009-10-15T15:36:51Z","isPatch":true,"sender":{"key":"barkalow@iabervon.org","avatar":"https://avatars.githubusercontent.com/u/55364219?v=4"},"body":"On Thu, 15 Oct 2009, James Pickens wrote:\n\n> On Wed, Oct 14, 2009 at 4:09 PM, Jeff King <peff@peff.net> wrote:\n> > That makes the most sense to me. If \"git checkout\" could write metadata\n> > into HEAD (or into DETACH_HEAD, as in Daniel's patch), then checkout\n> > could record an \"ok to commit\" bit. And could also be used to change it\n> > after the fact. E.g.:\n> >\n> >  $ git checkout --detach=commit origin/master\n> >  $ git commit ;# should be ok\n> >\n> >  $ git checkout --detach=examine origin/master\n> >  $ git commit ;# complain\n> >  $ git checkout --detach=commit HEAD\n> >  $ git commit ;# ok\n> >\n> > I guess something like \"rebase\" should detach with \"ok to commit\", since\n> > it is planning on attaching the commits later. I'm not sure about \"git\n> > bisect\". I guess probably it should be \"not ok to commit\" to be on the\n> > safe side, and then somebody can \"git checkout --detach=commit\" if they\n> > want to.\n> \n> How about not detaching the head at all if the user checks out any ref, and\n> reject commits if he checked out a tag or remote branch.  For example:\n> \n> $ git checkout origin/master\n> $ git status\n> # On branch origin/master\n> $ git commit ;# complain\n>\n> $ git checkout v1.0.1\n> $ git status\n> # On tag v1.0.1\n> $ git commit ;# complain\n> \n> $ git checkout v1.0.1^0 ;# detach\n> $ git commit ;# ok\n> \n> I think this would help the newbies and wouldn't cost the experts too much.\n> Checking out anything other than a plain ref would still detach the head, and\n> commits on a detached head would still be allowed.\n\nI think reducing users' exposure to the \"detached HEAD\" state would just \nmake it take longer for them to find that state familiar.\n\nIt's not like the concept is actually very difficult or unusual. CVS has \nit as \"cvs checkout -r <something>\" or \"cvs checkout -D <something>\"; SVN \nhas it as \"svn checkout -r <something>\". It was weird and scary in CVS if \nyou did it (it was \"sticky tags\", and you had to find a different option \nto get back to normal), but SVN is easier (\"svn checkout -r HEAD\").\n\nI think the description used in CVS and SVN (and, I think, others) is that \nyou're not at the HEAD revision. I think they both account for the state \nwhere you've checked out the revision by number that's the latest \nrevision, but you still can't grow the branch because you can't \nsimultaneously stay on r1000 (as requested explicitly) and add a new \ncommit.\n\nSo maybe the right explanation is:\n\n$ git checkout master; git branch\n* master\n$ git checkout origin/master; git branch\n* origin/master (not at head)\n$ git checkout 123cafe^5; git branch\n* 123cafe^5 (not at head)\n$ git checkout HEAD^2; git branch\n* 123cafe^5^2\n$ git commit; git branch\n* (temporary branch)\n\nThen we can say that one way that git is different from SVN is that all \nbranches of other repositories are read-only, and you can't be at the \nhead when you're on them (because the head of those branches are in \ndifferent repositories); instead you grow the history locally, and you \ntell the remote branch to adopt your history.\n\n> Perhaps as an additional safety feature, Git could refuse to switch away \n> from a detached head if the head isn't reachable from any ref\n\nAs far as I know, people don't actually seem to lose stuff this way. In \npart, that's because they get scared before they get there; in part, \nthat's because they just don't think to go there; and in part, we tell \nthem how to recover stuff at that point (using the ref log or the sha1).\n\n\t-Daniel\n*This .sig left intentionally blank*\n"},{"id":"125082","messageId":"4AD74DE6.9010800@drmicha.warpmail.net","threadId":"21236","inReplyTo":"alpine.LNX.2.00.0910151054190.32515@iabervon.org","subject":"Re: [PATCH] Proof-of-concept patch to remember what the detached HEAD was","fromName":"Michael J Gruber","fromEmail":"git@drmicha.warpmail.net","sentAt":"2009-10-15T16:29:26Z","receivedAt":"2009-10-15T16:29:26Z","isPatch":true,"sender":{"key":"git@grubix.eu","avatar":"https://avatars.githubusercontent.com/u/233215?v=4"},"body":"Daniel Barkalow venit, vidit, dixit 15.10.2009 17:36:\n> On Thu, 15 Oct 2009, James Pickens wrote:\n> \n>> On Wed, Oct 14, 2009 at 4:09 PM, Jeff King <peff@peff.net> wrote:\n>>> That makes the most sense to me. If \"git checkout\" could write metadata\n>>> into HEAD (or into DETACH_HEAD, as in Daniel's patch), then checkout\n>>> could record an \"ok to commit\" bit. And could also be used to change it\n>>> after the fact. E.g.:\n>>>\n>>>  $ git checkout --detach=commit origin/master\n>>>  $ git commit ;# should be ok\n>>>\n>>>  $ git checkout --detach=examine origin/master\n>>>  $ git commit ;# complain\n>>>  $ git checkout --detach=commit HEAD\n>>>  $ git commit ;# ok\n>>>\n>>> I guess something like \"rebase\" should detach with \"ok to commit\", since\n>>> it is planning on attaching the commits later. I'm not sure about \"git\n>>> bisect\". I guess probably it should be \"not ok to commit\" to be on the\n>>> safe side, and then somebody can \"git checkout --detach=commit\" if they\n>>> want to.\n>>\n>> How about not detaching the head at all if the user checks out any ref, and\n>> reject commits if he checked out a tag or remote branch.  For example:\n>>\n>> $ git checkout origin/master\n>> $ git status\n>> # On branch origin/master\n>> $ git commit ;# complain\n>>\n>> $ git checkout v1.0.1\n>> $ git status\n>> # On tag v1.0.1\n>> $ git commit ;# complain\n>>\n>> $ git checkout v1.0.1^0 ;# detach\n>> $ git commit ;# ok\n>>\n>> I think this would help the newbies and wouldn't cost the experts too much.\n>> Checking out anything other than a plain ref would still detach the head, and\n>> commits on a detached head would still be allowed.\n> \n> I think reducing users' exposure to the \"detached HEAD\" state would just \n> make it take longer for them to find that state familiar.\n\nYep. Which is why I keep suggesting that git clone does not create any\nlocal branches at all ;)\n\n> It's not like the concept is actually very difficult or unusual. CVS has \n> it as \"cvs checkout -r <something>\" or \"cvs checkout -D <something>\"; SVN \n> has it as \"svn checkout -r <something>\". It was weird and scary in CVS if \n> you did it (it was \"sticky tags\", and you had to find a different option \n> to get back to normal), but SVN is easier (\"svn checkout -r HEAD\").\n\nsvn up -r HEAD\n\n> I think the description used in CVS and SVN (and, I think, others) is that \n> you're not at the HEAD revision. I think they both account for the state \n> where you've checked out the revision by number that's the latest \n> revision, but you still can't grow the branch because you can't \n> simultaneously stay on r1000 (as requested explicitly) and add a new \n> commit.\n\nI'd say the fundamental difference is that in CVS and SVN, there is\nalways only one \"tip\", which they call HEAD. This is also why revision\nnumbers make sense.\n\nIn git and hg there can be many tips (branch heads) from which to grow\nthe DAG. Heck, you can grow a new one from any commit ;)\n\n> So maybe the right explanation is:\n> \n> $ git checkout master; git branch\n> * master\n> $ git checkout origin/master; git branch\n> * origin/master (not at head)\n\nOuch, please don't. HEAD has a completely different meaning in git. I\nknow you know, of course.\n\n> $ git checkout 123cafe^5; git branch\n> * 123cafe^5 (not at head)\n> $ git checkout HEAD^2; git branch\n> * 123cafe^5^2\n> $ git commit; git branch\n> * (temporary branch)\n> \n> Then we can say that one way that git is different from SVN is that all \n> branches of other repositories are read-only, and you can't be at the \n> head when you're on them (because the head of those branches are in \n> different repositories); instead you grow the history locally, and you \n> tell the remote branch to adopt your history.\n\nYou can change your refs/remotes/origin/master, of course, it's just by\nconvention (for a good reason) that git treats them as read-only, and\nporc. respects that.\n\ngit's branches are simply completely different, they're movable tags,\nand I think that's one point new users *have* to grok. Once they're over\nthis then even detached heads are a natural thing.\n\n>> Perhaps as an additional safety feature, Git could refuse to switch away \n>> from a detached head if the head isn't reachable from any ref\n> \n> As far as I know, people don't actually seem to lose stuff this way. In \n> part, that's because they get scared before they get there; in part, \n> that's because they just don't think to go there; and in part, we tell \n> them how to recover stuff at that point (using the ref log or the sha1).\n\nMaybe we just don't scare them enough yet :)\n\nMichael\n"},{"id":"125094","messageId":"alpine.LFD.2.00.0910151436180.20122@xanadu.home","threadId":"21236","inReplyTo":"885649360910150036o72c3bd97ofad85d5316dc5b35@mail.gmail.com","subject":"Re: [PATCH] Proof-of-concept patch to remember what the detached HEAD was","fromName":"Nicolas Pitre","fromEmail":"nico@fluxnic.net","sentAt":"2009-10-15T18:51:00Z","receivedAt":"2009-10-15T18:51:00Z","isPatch":true,"sender":{"key":"nico@fluxnic.net","avatar":"https://avatars.githubusercontent.com/u/702790?v=4"},"body":"On Thu, 15 Oct 2009, James Pickens wrote:\n\n> On Wed, Oct 14, 2009 at 4:09 PM, Jeff King <peff@peff.net> wrote:\n> > That makes the most sense to me. If \"git checkout\" could write metadata\n> > into HEAD (or into DETACH_HEAD, as in Daniel's patch), then checkout\n> > could record an \"ok to commit\" bit. And could also be used to change it\n> > after the fact. E.g.:\n> >\n> >  $ git checkout --detach=commit origin/master\n> >  $ git commit ;# should be ok\n> >\n> >  $ git checkout --detach=examine origin/master\n> >  $ git commit ;# complain\n> >  $ git checkout --detach=commit HEAD\n> >  $ git commit ;# ok\n> >\n> > I guess something like \"rebase\" should detach with \"ok to commit\", since\n> > it is planning on attaching the commits later. I'm not sure about \"git\n> > bisect\". I guess probably it should be \"not ok to commit\" to be on the\n> > safe side, and then somebody can \"git checkout --detach=commit\" if they\n> > want to.\n> \n> How about not detaching the head at all if the user checks out any ref, and\n> reject commits if he checked out a tag or remote branch.  For example:\n> \n> $ git checkout origin/master\n> $ git status\n> # On branch origin/master\n> $ git commit ;# complain\n> \n> $ git checkout v1.0.1\n> $ git status\n> # On tag v1.0.1\n> $ git commit ;# complain\n> \n> $ git checkout v1.0.1^0 ;# detach\n> $ git commit ;# ok\n> \n> I think this would help the newbies and wouldn't cost the experts too much.\n\nI agree.\n\n> Checking out anything other than a plain ref would still detach the \n> head, and commits on a detached head would still be allowed.  Perhaps \n> as an additional safety feature, Git could refuse to switch away from \n> a detached head if the head isn't reachable from any ref, and require \n> -f to override:\n> \n> $ git checkout $sha1\n> $ git commit\n> $ git checkout master ;# complain\n> $ git checkout -f master ;# ok\n\nNah.  This is obnoxious.  The usual \"this is not a local branch\" warning \ncould be displayed at that point, and if one really ignores the warning \nthen any commit made that way is always reachable through the reflog.  \nYou would have had to work a bit harder to detach HEAD already anyway, \nso at that point you're not supposed to be such a newbie anymore.\n\n> Maybe I'm missing something and this all can't be done, but it seems simpler\n> than the other options I've seen in this thread.\n\nIt is indeed simpler.  It makes the checkout command less verbose as \nwell.  Only the commit command would need to warn the user and only if a \nforbidden operation is attempted (like committing on a non \nrefs/heads/*). I think I like this.\n\n\nNicolas\n"},{"id":"125095","messageId":"alpine.LFD.2.00.0910151451120.20122@xanadu.home","threadId":"21236","inReplyTo":"m3bpk8g6nj.fsf@localhost.localdomain","subject":"Re: [PATCH] Proof-of-concept patch to remember what the detached HEAD was","fromName":"Nicolas Pitre","fromEmail":"nico@fluxnic.net","sentAt":"2009-10-15T19:03:44Z","receivedAt":"2009-10-15T19:03:44Z","isPatch":true,"sender":{"key":"nico@fluxnic.net","avatar":"https://avatars.githubusercontent.com/u/702790?v=4"},"body":"On Thu, 15 Oct 2009, Jakub Narebski wrote:\n\n> James Pickens <jepicken@gmail.com> writes:\n> \n> > I think this would help the newbies and wouldn't cost the experts too much.\n> > Checking out anything other than a plain ref would still detach the head, and\n> > commits on a detached head would still be allowed.\n> \n> I think it is a very good idea.\n> \n> This makes it easy to checkout remote-tracking branch or a tag for\n> viewing, something that was (I think) one of problems (use cases) that\n> lead to invention of detached HEAD... and then it turned out that\n> detached HEAD (unnamed branch) is scary for newbie git users.  (So the\n> difficulty of having to create new branch or rewind some branch to\n> view non-committable ref was replaced by scary detached HEAD concept.)\n\nI don't think detached head is scary at all (unless viewed in another \ncontext other than git) but if that encounter can be kept away from most \nusers without denying its use then all for the better.\n\n> With this idea there are no problems with git commands that use\n> detached HEAD such as git-bisect (which uses it in viewing mode, but\n> then skips through history, so detached HEAD is a good solution here)\n> or git-rebase (which does committing on detached HEAD for easier\n> aborting and cleanup).\n\nI do like and actively use manual committing on a detached HEAD as well, \nso please let's not forget about that use case.\n\n> Let me propose additional feature: \"smart\" (context sensitive)\n> warnings, namely that in the following sequence\n> \n>   $ git checkout origin/master\n>   $ git status\n>   # On remote-tracking branch origin/master of remote origin\n>   # ...\n\nSure.\n\n>   $ git commit\n> \n> 'git commit' would refuse committing on non-heads ref, and propose,\n> beside _always_ proposing detaching HEAD and committing on such\n> detached HEAD (unnamed branch) via \"git checkout HEAD^0\", or\n> \"git checkout --detach [HEAD]\":\n\n... or the current \"this is not a local branch -- use checkout -b to \ncreate one\" warning, just like what we have today when checking out a \ntag or remote branch, except that the warning is deferred to the commit \noperation which in fact might even not take place.\n\n> 1. If there is no local branch which follows 'origin/master'\n>    (which has 'origin/master' as upstream, which tracks 'origin/master')\n>    propose creating it before comitting:\n> \n>     $ git checkout -t origin/master\n> \n> 2. If there is single local branch that follows 'origin/master',\n>    and it fast-forwards to 'origin/master' propose... \n>    errr, something that would mean fast-forwarding this branch\n>    and making a commit on local branch that has 'origin/master'\n>    as upstream.\n>    \n> 3. If there is single local branch that follows 'origin/master', but\n>    it has changes / diverges from 'origin/master' we are viewing,\n>    propose... hmmm, what then?\n> \n> 4. If there are more than one local branch that has 'origin/master'\n>    as upstream, list all those branches in message.\n\nI wouldn't go too far in that direction though.  Too many suggestions \nwould simply bring back confusion to the new user who at that point \nmight not even understand yet what all the different concepts are.\n\n\nNicolas\n"},{"id":"125096","messageId":"alpine.LFD.2.00.0910151504510.20122@xanadu.home","threadId":"21236","inReplyTo":"alpine.LNX.2.00.0910151054190.32515@iabervon.org","subject":"Re: [PATCH] Proof-of-concept patch to remember what the detached HEAD was","fromName":"Nicolas Pitre","fromEmail":"nico@fluxnic.net","sentAt":"2009-10-15T19:07:19Z","receivedAt":"2009-10-15T19:07:19Z","isPatch":true,"sender":{"key":"nico@fluxnic.net","avatar":"https://avatars.githubusercontent.com/u/702790?v=4"},"body":"On Thu, 15 Oct 2009, Daniel Barkalow wrote:\n\n> I think the description used in CVS and SVN (and, I think, others) is that \n> you're not at the HEAD revision. I think they both account for the state \n> where you've checked out the revision by number that's the latest \n> revision, but you still can't grow the branch because you can't \n> simultaneously stay on r1000 (as requested explicitly) and add a new \n> commit.\n> \n> So maybe the right explanation is:\n> \n> $ git checkout master; git branch\n> * master\n> $ git checkout origin/master; git branch\n> * origin/master (not at head)\n> $ git checkout 123cafe^5; git branch\n> * 123cafe^5 (not at head)\n\nI think this is wrong.  Git has multiple heads, and insisting on \"not at \nhead\" would be extremely confusing.\n\n\nNicolas\n"},{"id":"125097","messageId":"alpine.LNX.2.00.0910151517070.32515@iabervon.org","threadId":"21236","inReplyTo":"alpine.LFD.2.00.0910151504510.20122@xanadu.home","subject":"Re: [PATCH] Proof-of-concept patch to remember what the detached HEAD was","fromName":"Daniel Barkalow","fromEmail":"barkalow@iabervon.org","sentAt":"2009-10-15T19:22:37Z","receivedAt":"2009-10-15T19:22:37Z","isPatch":true,"sender":{"key":"barkalow@iabervon.org","avatar":"https://avatars.githubusercontent.com/u/55364219?v=4"},"body":"On Thu, 15 Oct 2009, Nicolas Pitre wrote:\n\n> On Thu, 15 Oct 2009, Daniel Barkalow wrote:\n> \n> > I think the description used in CVS and SVN (and, I think, others) is that \n> > you're not at the HEAD revision. I think they both account for the state \n> > where you've checked out the revision by number that's the latest \n> > revision, but you still can't grow the branch because you can't \n> > simultaneously stay on r1000 (as requested explicitly) and add a new \n> > commit.\n> > \n> > So maybe the right explanation is:\n> > \n> > $ git checkout master; git branch\n> > * master\n> > $ git checkout origin/master; git branch\n> > * origin/master (not at head)\n> > $ git checkout 123cafe^5; git branch\n> > * 123cafe^5 (not at head)\n> \n> I think this is wrong.  Git has multiple heads, and insisting on \"not at \n> head\" would be extremely confusing.\n\nMaybe \"(not at a head)\"? Git does have multiple heads, but what's checked \nout isn't one of them, and that's actually the point.\n\n\t-Daniel\n*This .sig left intentionally blank*\n"},{"id":"125098","messageId":"alpine.LNX.2.00.0910151523020.32515@iabervon.org","threadId":"21236","inReplyTo":"885649360910150036o72c3bd97ofad85d5316dc5b35@mail.gmail.com","subject":"Re: [PATCH] Proof-of-concept patch to remember what the detached HEAD was","fromName":"Daniel Barkalow","fromEmail":"barkalow@iabervon.org","sentAt":"2009-10-15T19:31:13Z","receivedAt":"2009-10-15T19:31:13Z","isPatch":true,"sender":{"key":"barkalow@iabervon.org","avatar":"https://avatars.githubusercontent.com/u/55364219?v=4"},"body":"On Thu, 15 Oct 2009, James Pickens wrote:\n\n> On Wed, Oct 14, 2009 at 4:09 PM, Jeff King <peff@peff.net> wrote:\n> > That makes the most sense to me. If \"git checkout\" could write metadata\n> > into HEAD (or into DETACH_HEAD, as in Daniel's patch), then checkout\n> > could record an \"ok to commit\" bit. And could also be used to change it\n> > after the fact. E.g.:\n> >\n> >  $ git checkout --detach=commit origin/master\n> >  $ git commit ;# should be ok\n> >\n> >  $ git checkout --detach=examine origin/master\n> >  $ git commit ;# complain\n> >  $ git checkout --detach=commit HEAD\n> >  $ git commit ;# ok\n> >\n> > I guess something like \"rebase\" should detach with \"ok to commit\", since\n> > it is planning on attaching the commits later. I'm not sure about \"git\n> > bisect\". I guess probably it should be \"not ok to commit\" to be on the\n> > safe side, and then somebody can \"git checkout --detach=commit\" if they\n> > want to.\n> \n> How about not detaching the head at all if the user checks out any ref, and\n> reject commits if he checked out a tag or remote branch.  For example:\n> \n> $ git checkout origin/master\n> $ git status\n> # On branch origin/master\n> $ git commit ;# complain\n\n $ git checkout origin/master\n $ git fetch\n $ git checkout origin/next\n Uncommited file '...' would be overwritten.\n\nIf HEAD is a symref to refs/remotes/origin/master, and you update \nrefs/remotes/origin/master, git will subsequently see that your index \ndoesn't match HEAD, and when you switch branches, it will try to apply a \nrevert to the branch you're switching to. It's the same issue as pushing \ninto a non-bare repository.\n\n\t-Daniel\n*This .sig left intentionally blank*\n"},{"id":"125099","messageId":"7v1vl45t9k.fsf@alter.siamese.dyndns.org","threadId":"21236","inReplyTo":"alpine.LFD.2.00.0910151436180.20122@xanadu.home","subject":"Re: [PATCH] Proof-of-concept patch to remember what the detached HEAD was","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2009-10-15T19:52:55Z","receivedAt":"2009-10-15T19:52:55Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Nicolas Pitre <nico@fluxnic.net> writes:\n\n> It is indeed simpler.  It makes the checkout command less verbose as \n> well.  Only the commit command would need to warn the user and only if a \n> forbidden operation is attempted (like committing on a non \n> refs/heads/*). I think I like this.\n\nI like James's suggestion to allow us to store refs other than refs/heads/\nin HEAD to denote this state, and keep commit and reset from updating such\na ref through updating HEAD.\n\nWe have code to prevent HEAD from pointing at anywhere outside refs/heads/\nand that may even be an isolated single codepath we need to tweak.  But I\nam reasonably sure that the layers above these core-level routines have\ntheir own checks to make sure HEAD is either detached or points at\nrefs/heads/ somewhere; we would need to identify and change them as well.\nAlso things like \"git branch\" need to be told that HEAD may point outside\nof refs/heads/ now to adjust their output style accordingly.  They may\nprobably strip refs/heads/ (or 11 bytes) assuming that attached HEAD will\nnever point outside the local branch hierarchy.\n\nSo I expect there will be tons of tiny fallouts from a change like that,\nbut still it is conceptually simpler, and it would reduce the scope of\ndetached HEAD to a temporary state that is not even worth being named with\na branch name, which is exactly what it is.\n"},{"id":"125103","messageId":"7v3a5k4cri.fsf@alter.siamese.dyndns.org","threadId":"21236","inReplyTo":"alpine.LNX.2.00.0910151523020.32515@iabervon.org","subject":"Re: [PATCH] Proof-of-concept patch to remember what the detached HEAD was","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2009-10-15T20:34:41Z","receivedAt":"2009-10-15T20:34:41Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Daniel Barkalow <barkalow@iabervon.org> writes:\n\n>  $ git checkout origin/master\n>  $ git fetch\n>  $ git checkout origin/next\n>  Uncommited file '...' would be overwritten.\n>\n> If HEAD is a symref to refs/remotes/origin/master, and you update \n> refs/remotes/origin/master, git will subsequently see that your index \n> doesn't match HEAD, and when you switch branches, it will try to apply a \n> revert to the branch you're switching to. It's the same issue as pushing \n> into a non-bare repository.\n\nI think the idea here is to allow HEAD to point at outside refs/heads/,\ne.g. refs/remotes/origin/master, but forbid commit and other commands from\nupdating HEAD and its underlying ref via update_ref() unless HEAD is\ndetached or points at a local branch.\n"},{"id":"125106","messageId":"20091015212632.GA13180@coredump.intra.peff.net","threadId":"21236","inReplyTo":"7v1vl45t9k.fsf@alter.siamese.dyndns.org","subject":"Re: [PATCH] Proof-of-concept patch to remember what the detached HEAD was","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2009-10-15T21:26:32Z","receivedAt":"2009-10-15T21:26:32Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Thu, Oct 15, 2009 at 12:52:55PM -0700, Junio C Hamano wrote:\n\n> I like James's suggestion to allow us to store refs other than refs/heads/\n> in HEAD to denote this state, and keep commit and reset from updating such\n> a ref through updating HEAD.\n\nDidn't we already consider and reject this the first time around? For\nexample, this thread has a ton of stuff about how we shouldn't prevent\npeople from making commits on the wandering state:\n\n  http://thread.gmane.org/gmane.comp.version-control.git/35777/focus=35835\n\nAnd here's me even advocating this exact strategy (and I'm sure I didn't\nthink of it; it's probably discussed elsewhere, too):\n\n  http://thread.gmane.org/gmane.comp.version-control.git/35777/focus=35858\n\nNot that I am not necessarily complaining, but I just hope this decision\nis \"with new-found knowledge we are revisiting this decision\" and not\n\"we totally forgot about what came before\".\n\n-Peff\n"},{"id":"125108","messageId":"alpine.LNX.2.00.0910151653480.32515@iabervon.org","threadId":"21236","inReplyTo":"7v3a5k4cri.fsf@alter.siamese.dyndns.org","subject":"Re: [PATCH] Proof-of-concept patch to remember what the detached HEAD was","fromName":"Daniel Barkalow","fromEmail":"barkalow@iabervon.org","sentAt":"2009-10-15T21:35:10Z","receivedAt":"2009-10-15T21:35:10Z","isPatch":true,"sender":{"key":"barkalow@iabervon.org","avatar":"https://avatars.githubusercontent.com/u/55364219?v=4"},"body":"On Thu, 15 Oct 2009, Junio C Hamano wrote:\n\n> Daniel Barkalow <barkalow@iabervon.org> writes:\n> \n> >  $ git checkout origin/master\n> >  $ git fetch\n> >  $ git checkout origin/next\n> >  Uncommited file '...' would be overwritten.\n> >\n> > If HEAD is a symref to refs/remotes/origin/master, and you update \n> > refs/remotes/origin/master, git will subsequently see that your index \n> > doesn't match HEAD, and when you switch branches, it will try to apply a \n> > revert to the branch you're switching to. It's the same issue as pushing \n> > into a non-bare repository.\n> \n> I think the idea here is to allow HEAD to point at outside refs/heads/,\n> e.g. refs/remotes/origin/master, but forbid commit and other commands from\n> updating HEAD and its underlying ref via update_ref() unless HEAD is\n> detached or points at a local branch.\n\n $ git checkout origin/master\n $ git fetch\n (Some error)\n\nI think it would be much more confusing for many users if you couldn't \ndo:\n\n $ git checkout origin/master\n (look at origin/master)\n (wait a day)\n $ git fetch\n $ git checkout origin/next\n (look at origin/next)\n\nPart of the original point of detached HEAD was to support this pattern \nwithout creating an undesired local branch (which falls out of date),\nhaving problems with updating the tracking branches, or having problems \nwith direct changes to the ref that HEAD points to.\n\nCurrently, HEAD is never a symref to anything that will ever be updated \nnormally except though the symref. That's a really handy property that \navoids making us deal with lots of special cases in weird places. And \nthose special cases would not only be annoying to have to handle again, \nbut they'd be complexity that users would have to be exposed to.\n\n\t-Daniel\n*This .sig left intentionally blank*\n"},{"id":"125109","messageId":"alpine.LFD.2.00.0910151743230.20122@xanadu.home","threadId":"21236","inReplyTo":"alpine.LNX.2.00.0910151653480.32515@iabervon.org","subject":"Re: [PATCH] Proof-of-concept patch to remember what the detached HEAD was","fromName":"Nicolas Pitre","fromEmail":"nico@fluxnic.net","sentAt":"2009-10-15T21:48:04Z","receivedAt":"2009-10-15T21:48:04Z","isPatch":true,"sender":{"key":"nico@fluxnic.net","avatar":"https://avatars.githubusercontent.com/u/702790?v=4"},"body":"On Thu, 15 Oct 2009, Daniel Barkalow wrote:\n\n> On Thu, 15 Oct 2009, Junio C Hamano wrote:\n> \n> > Daniel Barkalow <barkalow@iabervon.org> writes:\n> > \n> > >  $ git checkout origin/master\n> > >  $ git fetch\n> > >  $ git checkout origin/next\n> > >  Uncommited file '...' would be overwritten.\n> > >\n> > > If HEAD is a symref to refs/remotes/origin/master, and you update \n> > > refs/remotes/origin/master, git will subsequently see that your index \n> > > doesn't match HEAD, and when you switch branches, it will try to apply a \n> > > revert to the branch you're switching to. It's the same issue as pushing \n> > > into a non-bare repository.\n> > \n> > I think the idea here is to allow HEAD to point at outside refs/heads/,\n> > e.g. refs/remotes/origin/master, but forbid commit and other commands from\n> > updating HEAD and its underlying ref via update_ref() unless HEAD is\n> > detached or points at a local branch.\n> \n>  $ git checkout origin/master\n>  $ git fetch\n>  (Some error)\n\nRight.\n\nSo we're back to your initial proposal I guess (storing some info/state \nin .git/HEAD when detached).\n\n\nNicolas\n"},{"id":"125110","messageId":"7v1vl42uid.fsf@alter.siamese.dyndns.org","threadId":"21236","inReplyTo":"20091015212632.GA13180@coredump.intra.peff.net","subject":"Re: [PATCH] Proof-of-concept patch to remember what the detached HEAD was","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2009-10-15T21:54:18Z","receivedAt":"2009-10-15T21:54:18Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Jeff King <peff@peff.net> writes:\n\n> On Thu, Oct 15, 2009 at 12:52:55PM -0700, Junio C Hamano wrote:\n>\n>> I like James's suggestion to allow us to store refs other than refs/heads/\n>> in HEAD to denote this state, and keep commit and reset from updating such\n>> a ref through updating HEAD.\n>\n> Didn't we already consider and reject this the first time around? For\n> example, this thread has a ton of stuff about how we shouldn't prevent\n> people from making commits on the wandering state:\n>\n>   http://thread.gmane.org/gmane.comp.version-control.git/35777/focus=35835\n>\n> And here's me even advocating this exact strategy (and I'm sure I didn't\n> think of it; it's probably discussed elsewhere, too):\n>\n>   http://thread.gmane.org/gmane.comp.version-control.git/35777/focus=35858\n>\n> Not that I am not necessarily complaining, but I just hope this decision\n> is \"with new-found knowledge we are revisiting this decision\" and not\n> \"we totally forgot about what came before\".\n\nMaybe we are reading different messages in the same message.\n\nMy understanding of James's suggestion is:\n\n (1) \"git checkout $token\" makes HEAD point at the refname dwim_ref()\n     expands $token to, iff dwim_ref() is happy, and otherwise detaches\n     HEAD;\n\n (2) \"git commit\" (and other things like \"git reset HEAD^\" that updates\n     underlying ref thru updates to HEAD when HEAD is a symref) rejects\n     when HEAD points at a ref outside refs/heads/, but works when HEAD\n     points at a local branch, or when HEAD is detached.\n\nAs a consequence:\n\n    $ git checkout v1.6.5      ;# does not detach, cannot update\n    $ git symbolic-ref HEAD\n    refs/tags/v1.6.5\n    $ git checkout origin/next ;# ditto\n    $ git symbolic-ref HEAD\n    refs/remotes/origin/next\n\nThese are often done by sightseers, and we can add instructions to fork\nand record upon an attempt to \"git commit\".\n\nAs a bonus, we get Daniel's extra information for detached HEAD for free,\nas we can just read HEAD and learn what it points at.  We need to design\nwhat \"git branch\" should say in this case.\n\nThis is backward incompatible, and makes what experts are used to do\nslightly cumbersome to spell, i.e.\n\n    $ git checkout v1.6.5^0      ;# detaches and can commit\n    $ git checkout origin/next^0 ;# ditto\n    $ git checkout $(git merge-base master sp/smart-http) ;# ditto\n\nThese detach, and I can apply the updates series to the same base as the\nprevious round on an unnamed branch.\n\nSo in other words, the semantics for detached HEAD case does not change at\nall.  We never forbid committing or resetting while on detached HEAD, as\nit is meant to be an easy way to get an unnamed throw-away state that is\nnot even worth coming up with a unique temporary branch name, and I do not\nthink the above contradicts with what was said in 35835.\n\nWe used to have only two states on HEAD: either on a local branch or\ndetached.  James is introducing another state: on a ref that is not a\nlocal branch.\n\nAs that is useful for common sightseer tasks, we can afford to forbid\ncommitting or updating for safety and we do not have to worry about\nhurting the established usefulness of how detached HEAD works.\n\nOne drawback is that you cannot be in this sightseeing state without\nhaving a ref.  You can have \"look-but-not-touch\" checkout on origin/next\nor origin/master, but you cannot sightsee the parent of origin/next the\nsame way (it would detach).  I do not know if it is a big deal, though.\n\nIf it is very important to support:\n\n    $ git checkout --look-but-not-touch origin/next^\n\nthen James's approach would not be very useful, as we do have to detach\nHEAD and implement the \"do not touch\" logic for detached HEAD state\nanyway, so we might just use the same logic we would use for origin/next^\nwhen checking out origin/next itself.\n"},{"id":"125111","messageId":"7vfx9k1faa.fsf@alter.siamese.dyndns.org","threadId":"21236","inReplyTo":"7v1vl42uid.fsf@alter.siamese.dyndns.org","subject":"Re: [PATCH] Proof-of-concept patch to remember what the detached HEAD was","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2009-10-15T22:08:29Z","receivedAt":"2009-10-15T22:08:29Z","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>     $ git checkout origin/next ;# ditto\n>     $ git symbolic-ref HEAD\n>     refs/remotes/origin/next\n\nOk, after reading Daniel's message to remind us that \"git fetch\" after\nthis will get us into trouble, I agree that detaching HEAD is inevitable.\n"},{"id":"125113","messageId":"20091015221657.GC13180@coredump.intra.peff.net","threadId":"21236","inReplyTo":"7v1vl42uid.fsf@alter.siamese.dyndns.org","subject":"Re: [PATCH] Proof-of-concept patch to remember what the detached HEAD was","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2009-10-15T22:16:57Z","receivedAt":"2009-10-15T22:16:57Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Thu, Oct 15, 2009 at 02:54:18PM -0700, Junio C Hamano wrote:\n\n> Maybe we are reading different messages in the same message.\n> \n> My understanding of James's suggestion is:\n> \n>  (1) \"git checkout $token\" makes HEAD point at the refname dwim_ref()\n>      expands $token to, iff dwim_ref() is happy, and otherwise detaches\n>      HEAD;\n> \n>  (2) \"git commit\" (and other things like \"git reset HEAD^\" that updates\n>      underlying ref thru updates to HEAD when HEAD is a symref) rejects\n>      when HEAD points at a ref outside refs/heads/, but works when HEAD\n>      points at a local branch, or when HEAD is detached.\n\nRight. I thought the idea of \"don't complain at checkout time, but\ncomplain at commit\" had been considered and rejected. But I guess you\ncould argue that the difference between this and the original discussion\nis that we are going to have _both_ the detached HEAD state and the\n\"refs/tags/* in HEAD\" state, and treat them differently.\n\nI feel like the latter idea was discussed in more detail (I made\nreference to it in the latter email I linked to, but I don't think that\nwas the origin of it), but I can't seem to find any discussion.\n\nSo I will buy that this is somewhat of a new idea. I am still confused\nabout what happens with this, though:\n\n  $ git checkout origin/next\n  $ git fetch ;# updates origin/next\n\nDo we refuse the fetch? Does the user now have a working tree and index\nthat doesn't match their HEAD?\n\n> This is backward incompatible, and makes what experts are used to do\n> slightly cumbersome to spell, i.e.\n> \n>     $ git checkout v1.6.5^0      ;# detaches and can commit\n>     $ git checkout origin/next^0 ;# ditto\n>     $ git checkout $(git merge-base master sp/smart-http) ;# ditto\n\nI think it is less cumbersome if we add \"git checkout -d v1.6.5\" (well,\nsame number of characters, but a lot less ugly). Assuming that the rest\nof it is a good idea.\n\n-Peff\n"},{"id":"125112","messageId":"20091015221735.GA26775@coredump.intra.peff.net","threadId":"21236","inReplyTo":"20091015221657.GC13180@coredump.intra.peff.net","subject":"Re: [PATCH] Proof-of-concept patch to remember what the detached HEAD was","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2009-10-15T22:17:35Z","receivedAt":"2009-10-15T22:17:35Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Thu, Oct 15, 2009 at 06:16:57PM -0400, Jeff King wrote:\n\n> So I will buy that this is somewhat of a new idea. I am still confused\n> about what happens with this, though:\n> \n>   $ git checkout origin/next\n>   $ git fetch ;# updates origin/next\n> \n> Do we refuse the fetch? Does the user now have a working tree and index\n> that doesn't match their HEAD?\n\nOK, nevermind about this, we just crossed emails.\n\n-Peff\n"},{"id":"125120","messageId":"200910160056.33217.trast@student.ethz.ch","threadId":"21236","inReplyTo":"alpine.LNX.2.00.0910151517070.32515@iabervon.org","subject":"Re: [PATCH] Proof-of-concept patch to remember what the detached HEAD was","fromName":"Thomas Rast","fromEmail":"trast@student.ethz.ch","sentAt":"2009-10-15T22:56:31Z","receivedAt":"2009-10-15T22:56:31Z","isPatch":true,"sender":{"key":"tr@thomasrast.ch","avatar":"https://avatars.githubusercontent.com/u/153510?v=4"},"body":"Daniel Barkalow wrote:\n> On Thu, 15 Oct 2009, Nicolas Pitre wrote:\n> \n> > On Thu, 15 Oct 2009, Daniel Barkalow wrote:\n> > \n> > > I think the description used in CVS and SVN (and, I think, others) is that \n> > > you're not at the HEAD revision.\n[...]\n> > > * origin/master (not at head)\n> > > $ git checkout 123cafe^5; git branch\n> > > * 123cafe^5 (not at head)\n> > \n> > I think this is wrong.  Git has multiple heads, and insisting on \"not at \n> > head\" would be extremely confusing.\n> \n> Maybe \"(not at a head)\"? Git does have multiple heads, but what's checked \n> out isn't one of them, and that's actually the point.\n\nPlease don't reuse 'head' (even lowercase) in this context/meaning.  I\nsee enough people coming to IRC who are confused about the fact that\nthey checked out some old commit, hence HEAD is just that, but they\nrefer to the *newest* commit on whatever branch they like most as HEAD\nbecause that's what it means in SVN.\n\nNow imagine having to explain to them that their (SVN) 'HEAD' is not\nthe same as git's 'HEAD', but can rightly be considered the equivalent\nof master's 'head'; and that furthermore, you are always at 'HEAD' but\nnot always at 'head'.\n\nI think in this case '(detached)' would be more consistent with\ncurrent terminology, though we may of course try to change it.\n\n(I've tried to consistently use 'tip' in the branch tip meaning,\nadmittedly without knowing exactly how this intersects with\nmercurial's definition of the term.)\n\n-- \nThomas Rast\ntrast@{inf,student}.ethz.ch\n"},{"id":"125121","messageId":"alpine.LFD.2.00.0910151912470.20122@xanadu.home","threadId":"21236","inReplyTo":"7vfx9k1faa.fsf@alter.siamese.dyndns.org","subject":"Re: [PATCH] Proof-of-concept patch to remember what the detached HEAD was","fromName":"Nicolas Pitre","fromEmail":"nico@fluxnic.net","sentAt":"2009-10-15T23:16:13Z","receivedAt":"2009-10-15T23:16:13Z","isPatch":true,"sender":{"key":"nico@fluxnic.net","avatar":"https://avatars.githubusercontent.com/u/702790?v=4"},"body":"On Thu, 15 Oct 2009, Junio C Hamano wrote:\n\n> Junio C Hamano <gitster@pobox.com> writes:\n> \n> >     $ git checkout origin/next ;# ditto\n> >     $ git symbolic-ref HEAD\n> >     refs/remotes/origin/next\n> \n> Ok, after reading Daniel's message to remind us that \"git fetch\" after\n> this will get us into trouble, I agree that detaching HEAD is inevitable.\n\nEither the fetch should be refused just like a commit would, or HEAD \ngets detached automatically in that case.  Probably the former would be \nless confusing, otherwise the user might expect to see the updated \nremote branch after the fetch and not understand that a detached HEAD \nremained on the previous remote branch state.\n\n\nNicolas\n"},{"id":"125122","messageId":"885649360910151647v27a15334x63fe3b6f5035dbd2@mail.gmail.com","threadId":"21236","inReplyTo":"7vfx9k1faa.fsf@alter.siamese.dyndns.org","subject":"Re: [PATCH] Proof-of-concept patch to remember what the detached HEAD was","fromName":"James Pickens","fromEmail":"jepicken@gmail.com","sentAt":"2009-10-15T23:47:57Z","receivedAt":"2009-10-15T23:47:57Z","isPatch":true,"sender":{"key":"jepicken@gmail.com","avatar":null},"body":"On Thu, Oct 15, 2009 at 3:08 PM, Junio C Hamano <gitster@pobox.com> wrote:\n> Junio C Hamano <gitster@pobox.com> writes:\n>\n>>     $ git checkout origin/next ;# ditto\n>>     $ git symbolic-ref HEAD\n>>     refs/remotes/origin/next\n>\n> Ok, after reading Daniel's message to remind us that \"git fetch\" after\n> this will get us into trouble, I agree that detaching HEAD is inevitable.\n\nSome people liked the idea, so let's not give up just yet.  Here are a few\nthings Git could do when a fetch wants to update the currently checked out\nbranch:\n\n1. Refuse the fetch.\n2. Update the ref, leaving the user with a work tree and index that don't\n   match their HEAD.\n3. Detach the HEAD, then update the ref.\n4. Update the ref, then check it out.\n\nOption 1 is ok, as long as the \"next step\" is not too complicated.  It's no\ngood if the user has to checkout a different branch, then fetch, then\ncheckout the original branch again.\n\nOption 2 is crap.\n\nOption 3 seems reasonable, but it might be just as scary/confusing to\nnewbies as the current behavior, so I don't think it should be the default.\n\nOption 4 also seems reasonable, but you run into problems if the user had\nchanged the index or work tree.  In that case Git could do 'checkout\n--merge' automatically.  This option is also less \"pure\" since it lets 'git\nfetch' modify the index and work tree.\n\nSo how about this:\n* 'git fetch' refuses the fetch by default.\n* 'git fetch --detach' detaches HEAD, then updates the ref\n* 'git pull' detaches HEAD, updates the ref, then checks out the new ref\n  with --merge.\n\nBTW I'm not convinced this is any better than the current UI... just\nthinking out loud.  And I find it more than a little depressing that most\nof these ideas have already been discussed almost 3 years ago (thanks Jeff\nfor the pointer).\n\nJames\n"},{"id":"125125","messageId":"alpine.LFD.2.00.0910152032050.20122@xanadu.home","threadId":"21236","inReplyTo":"885649360910151647v27a15334x63fe3b6f5035dbd2@mail.gmail.com","subject":"Re: [PATCH] Proof-of-concept patch to remember what the detached HEAD was","fromName":"Nicolas Pitre","fromEmail":"nico@fluxnic.net","sentAt":"2009-10-16T00:34:37Z","receivedAt":"2009-10-16T00:34:37Z","isPatch":true,"sender":{"key":"nico@fluxnic.net","avatar":"https://avatars.githubusercontent.com/u/702790?v=4"},"body":"On Thu, 15 Oct 2009, James Pickens wrote:\n\n> BTW I'm not convinced this is any better than the current UI... just\n> thinking out loud.\n\nI concur with that.\n\n> And I find it more than a little depressing that most\n> of these ideas have already been discussed almost 3 years ago (thanks Jeff\n> for the pointer).\n\nRehashing them from time to time is not necessarily a bad idea.  Maybe \nsomething better might (or not) turn up this time.\n\n\nNicolas\n"},{"id":"125126","messageId":"alpine.DEB.1.00.0910160240440.4985@pacific.mpi-cbg.de","threadId":"21236","inReplyTo":"885649360910151647v27a15334x63fe3b6f5035dbd2@mail.gmail.com","subject":"Re: [PATCH] Proof-of-concept patch to remember what the detached HEAD was","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2009-10-16T00:43:17Z","receivedAt":"2009-10-16T00:43:17Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi,\n\nOn Thu, 15 Oct 2009, James Pickens wrote:\n\n> On Thu, Oct 15, 2009 at 3:08 PM, Junio C Hamano <gitster@pobox.com> wrote:\n> > Junio C Hamano <gitster@pobox.com> writes:\n> >\n> >>     $ git checkout origin/next ;# ditto\n> >>     $ git symbolic-ref HEAD\n> >>     refs/remotes/origin/next\n> >\n> > Ok, after reading Daniel's message to remind us that \"git fetch\" after\n> > this will get us into trouble, I agree that detaching HEAD is inevitable.\n> \n> Some people liked the idea, so let's not give up just yet.  Here are a few\n> things Git could do when a fetch wants to update the currently checked out\n> branch:\n> \n> 1. Refuse the fetch.\n> 2. Update the ref, leaving the user with a work tree and index that don't\n>    match their HEAD.\n> 3. Detach the HEAD, then update the ref.\n> 4. Update the ref, then check it out.\n\nEverything but 1 and 4 would blatantly violate the law of the Least \nSurprise.\n\nAnd that very much includes what our beloved maintainer proposes.\n\nBTW I appreciate that finally a few users join discussion.  It felt \nawfully lonely for a while.\n\nCiao,\nDscho\n"},{"id":"125127","messageId":"alpine.DEB.1.00.0910160245310.4985@pacific.mpi-cbg.de","threadId":"21236","inReplyTo":"7viqeha2zv.fsf@alter.siamese.dyndns.org","subject":"Re: [PATCH] Proof-of-concept patch to remember what the detached HEAD was","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2009-10-16T00:53:45Z","receivedAt":"2009-10-16T00:53:45Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi,\n\nOn Wed, 14 Oct 2009, Junio C Hamano wrote:\n\n> Nicolas Pitre <nico@fluxnic.net> writes:\n> \n> > Can't the user confusion be dealt with through some means other than \n> > making the tool less flexible?  I don't mind extra help message to be \n> > displayed after a headless commit is made for example.  But trying to \n> > make the tool more friendly should perhaps come from better education \n> > rather than added restrictions.\n> >\n> > My thoughts only.\n> \n> I actually share that but there apparently are people who have given up on\n> the education route.\n\nAt some point, when you try to teach something that people (i.e. more than \none person) do not get easily, you cannot do anything but admit that what \nyou try to teach is crap.  Obviously you did not have that experience.  \nMaybe you are just more picky than me when it comes to who you try to \nteach.  But of course, that does not make what you try to teach less crap.\n\nIn this particular case, I cannot help but notice that commits performed \non a detached HEAD will get lost _unless_ they are somehow put onto a \nnamed branch eventually.  So the only question is whether you restrict \nflexibility by requiring to name the branch first before committing, \ninstead of committing and then naming the branch.\n\nSo you are talking about \"retaining flexibility\" in favor of making the \ntool less user-friendly, when all it would take from the few power-users \nis to name the branch before committing to it, instead of the other way \nround.\n\nYou must be kidding me.\n\nCiao,\nDscho\n"},{"id":"125128","messageId":"alpine.DEB.1.00.0910160256180.4985@pacific.mpi-cbg.de","threadId":"21236","inReplyTo":"alpine.LFD.2.00.0910142237010.20122@xanadu.home","subject":"Re: [PATCH] Proof-of-concept patch to remember what the detached HEAD was","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2009-10-16T01:04:11Z","receivedAt":"2009-10-16T01:04:11Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi,\n\nOn Wed, 14 Oct 2009, Nicolas Pitre wrote:\n\n> On Wed, 14 Oct 2009, Jeff King wrote:\n> \n> > On Wed, Oct 14, 2009 at 05:56:52PM -0700, Junio C Hamano wrote:\n> > \n> > > Nicolas Pitre <nico@fluxnic.net> writes:\n> > > \n> > > > Can't the user confusion be dealt with through some means other than \n> > > > making the tool less flexible?  I don't mind extra help message to be \n> > > > displayed after a headless commit is made for example.  But trying to \n> > > > make the tool more friendly should perhaps come from better education \n> > > > rather than added restrictions.\n> > > >\n> > > > My thoughts only.\n> > > \n> > > I actually share that but there apparently are people who have given up on\n> > > the education route.\n> > \n> > I am personally undecided on this issue (my \"this is the best option\"\n> > was the best of \"a -f switch to commit, an 'expert' config option', or a\n> > session-based option to commit\").\n> > \n> > But we really seem to have reached an impasse with how to proceed with\n> > git ui.\n> > \n> > People like Dscho are fed up with user complaints about parts of git\n> > that can be unfriendly to new users. And I can understand that.\n> \n> People like Dscho have to grow a thicker skin then.  There will _always_ \n> be user complaints regardless of how balanced you try to make a UI.\n\nYou are seriously misreading my intentions, then.  Or my intelligence.\n\nIt is not about growing a thicker skin towards unmerited complaints.\n\nIt is about shedding the thick skin when there are merited complaints, and \nsome people are just too used to the old ways to understand that some of \nthe complaints have _a lot_ of merit.\n\nIt is just like with the olden days when only a precious few could drive \ncars, and maintained that it _is_ hard to drive a car, and _not_ everybody \ncan do it _because_ you will have a breakdown with the car and you _have_ \nto be able to fix it yourself.\n\nFast-forward a hundred years.\n\nNone of this is true any longer.\n\nNone.\n\nGuess what?  In these days, we do not need a hundred years.  Four is \nplenty enough.  We have a lot of Git users who do not understand the inner \nworkings of Git.  And why should they need to?\n\nWho are you to say they should?\n\nWe, the old Gits need to change.  Not the many other people.\n\nRemember: you do not know how exactly the clutch interacts with the 2nd \ncylinder of the engine.  And you do not _need_ to.\n\nNeither should Git users need to.\n\nCiao,\nDscho\n"},{"id":"125129","messageId":"alpine.LFD.2.00.0910152118360.20122@xanadu.home","threadId":"21236","inReplyTo":"alpine.DEB.1.00.0910160256180.4985@pacific.mpi-cbg.de","subject":"Re: [PATCH] Proof-of-concept patch to remember what the detached HEAD was","fromName":"Nicolas Pitre","fromEmail":"nico@fluxnic.net","sentAt":"2009-10-16T01:36:44Z","receivedAt":"2009-10-16T01:36:44Z","isPatch":true,"sender":{"key":"nico@fluxnic.net","avatar":"https://avatars.githubusercontent.com/u/702790?v=4"},"body":"On Fri, 16 Oct 2009, Johannes Schindelin wrote:\n\n> We, the old Gits need to change.  Not the many other people.\n> \n> Remember: you do not know how exactly the clutch interacts with the 2nd \n> cylinder of the engine.  And you do not _need_ to.\n\nReally, the detached HEAD concept can't be _that_ hard.  It is not like \nif we were asking our users to fully grok the blob/tree/commit hierarchy \nand delta compression heuristics to be able to work with Git.\n\n> Neither should Git users need to.\n\nWhat you're asking for, though, is more comparable to asking old Gits to \ngive up on their clutch and manual gearbox because most American Git \nusers are expecting automatic transmissions.  Maybe that's not the case \nin Germany, but over here automatic transmissions are by far the norm \nand a manual gearbox can be obtained only in limited cases if at all.\n\n\nNicolas\n"},{"id":"125130","messageId":"alpine.DEB.1.00.0910160357370.4985@pacific.mpi-cbg.de","threadId":"21236","inReplyTo":"alpine.LFD.2.00.0910152118360.20122@xanadu.home","subject":"Re: [PATCH] Proof-of-concept patch to remember what the detached HEAD was","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2009-10-16T02:07:23Z","receivedAt":"2009-10-16T02:07:23Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi,\n\nOn Thu, 15 Oct 2009, Nicolas Pitre wrote:\n\n> On Fri, 16 Oct 2009, Johannes Schindelin wrote:\n> \n> > We, the old Gits need to change.  Not the many other people.\n> > \n> > Remember: you do not know how exactly the clutch interacts with the 2nd \n> > cylinder of the engine.  And you do not _need_ to.\n> \n> Really, the detached HEAD concept can't be _that_ hard.\n\nYou are trying to educate the users to use the double-clutch.  Rather than \nmaking the double-clutch obsolete.\n\nThat's what I call \"BlameTheWrongThing\".\n\n> > Neither should Git users need to.\n> \n> What you're asking for, though, is more comparable to asking old Gits to \n> give up on their clutch and manual gearbox because most American Git \n> users are expecting automatic transmissions.  Maybe that's not the case \n> in Germany, but over here automatic transmissions are by far the norm \n> and a manual gearbox can be obtained only in limited cases if at all.\n\nYour point being?  You really think Git is already at the stage where it \nhas automatic transmission and all you have to do is hit the gas or the \nbrake?  No, Nico, you are too intelligent to believe that.\n\nBesides, Git is not even at the stage of a manual gearbox.\n\nJust recently, I had a user request (a very valid one, mind you) where the \nuser does not want to provide a commit message, and wants to just commit \nall the current changes.  In that particular case, it is very sensible to \nask for these things.  It is something utterly simple to ask for. Yet, it \nis utterly hard with Git, especially if I have to explain it.\n\nMaybe the core Git developers should spend a month explaining the core \nprinciples of Git to some random software developers, just so all of us \nget an idea just how wrong we are on the account of how intuitive Git is.\n\nCiao,\nDscho\n"},{"id":"125132","messageId":"alpine.LFD.2.00.0910152211590.20122@xanadu.home","threadId":"21236","inReplyTo":"alpine.DEB.1.00.0910160357370.4985@pacific.mpi-cbg.de","subject":"Re: [PATCH] Proof-of-concept patch to remember what the detached HEAD was","fromName":"Nicolas Pitre","fromEmail":"nico@fluxnic.net","sentAt":"2009-10-16T02:45:39Z","receivedAt":"2009-10-16T02:45:39Z","isPatch":true,"sender":{"key":"nico@fluxnic.net","avatar":"https://avatars.githubusercontent.com/u/702790?v=4"},"body":"On Fri, 16 Oct 2009, Johannes Schindelin wrote:\n\n> Hi,\n> \n> On Thu, 15 Oct 2009, Nicolas Pitre wrote:\n> \n> > On Fri, 16 Oct 2009, Johannes Schindelin wrote:\n> > \n> > > We, the old Gits need to change.  Not the many other people.\n> > > \n> > > Remember: you do not know how exactly the clutch interacts with the 2nd \n> > > cylinder of the engine.  And you do not _need_ to.\n> > \n> > Really, the detached HEAD concept can't be _that_ hard.\n> \n> You are trying to educate the users to use the double-clutch.  Rather than \n> making the double-clutch obsolete.\n> That's what I call \"BlameTheWrongThing\".\n\nI just can't convince myself to share that point of view.  Doesn't mean \nthat I'm right though, but that's how I see it given the alternative.\n\n> > > Neither should Git users need to.\n> > \n> > What you're asking for, though, is more comparable to asking old Gits to \n> > give up on their clutch and manual gearbox because most American Git \n> > users are expecting automatic transmissions.  Maybe that's not the case \n> > in Germany, but over here automatic transmissions are by far the norm \n> > and a manual gearbox can be obtained only in limited cases if at all.\n> \n> Your point being?  You really think Git is already at the stage where it \n> has automatic transmission and all you have to do is hit the gas or the \n> brake?  No, Nico, you are too intelligent to believe that.\n\nNo, Git is not at the automatic transmission level, and I _don't_ want \nit to, ever.  That would not be _my_ choice.\n\n> Besides, Git is not even at the stage of a manual gearbox.\n\nHere I disagree.\n\n> Just recently, I had a user request (a very valid one, mind you) where the \n> user does not want to provide a commit message, and wants to just commit \n> all the current changes.  In that particular case, it is very sensible to \n> ask for these things.  It is something utterly simple to ask for. Yet, it \n> is utterly hard with Git, especially if I have to explain it.\n\nI hope this is a bad example.  I just can't imagine how \"very sensible\" \nyou may consider messageless commits.  I've dealt with them too many \ntimes in my life.\n\nBut still, if someone just can't be bothered at all then the \n\"workaround\" is easy: just use '-m.' or any other meaningless character \nof your choice.  At least _I_ will be able to identify those commits as \nbeing purposely messageless and make a better informed opinion on that \ncommitter instead of blaming it on ignorance.\n\n> Maybe the core Git developers should spend a month explaining the core \n> principles of Git to some random software developers, just so all of us \n> get an idea just how wrong we are on the account of how intuitive Git is.\n\nSorry but I don't share that feeling of hopelessness that seems to \naffect those random software developers you might have tried to teach \nGit to.  Well, actually I do have to deal with hopeless software \ndevelopers once in a while which are simply total idiots, and they \ncertainly shine at depicting Git, or any other tool at their disposal \nfor that matter, as utter crap.  But fortunately for me, the few people \nto whom I've explained Git so far simply got it in very little time.  \nIn my opinion, the most important concept to explain first is Git \nbranching.  Everything else is kinda secondary.  Worked for me pretty \nwell so far.\n\n\nNicolas\n"},{"id":"125133","messageId":"7vvdigxczv.fsf@alter.siamese.dyndns.org","threadId":"21236","inReplyTo":"alpine.DEB.1.00.0910160357370.4985@pacific.mpi-cbg.de","subject":"Re: [PATCH] Proof-of-concept patch to remember what the detached HEAD was","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2009-10-16T02:56:52Z","receivedAt":"2009-10-16T02:56:52Z","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> You are trying to educate the users to use the double-clutch.  Rather than \n> making the double-clutch obsolete.\n\nI do not quite get your double-clutch rhetoric, in the sense that I do not\nthink it has anything analogous in the topic of detached HEAD we have been\ndiscussing.\n\nDidn't we discuss possible solutions to make sure that you do not have to\ndetach HEAD and lose commits by coming back without saving them?  I would\nconsider that corresponds to inventing automatic (iow, making sure that\nsightseeing can be done without having to worry about accidentally\ncommitting on that state and later losing them).  Obviously, you would\nneed to cover cases other than we have discussed (e.g. if \"rebase -i\"\ndetaches, it needs to allow \"commit\", \"commit --amend\", and \"reset --soft\nHEAD^\", but you probably would not want to allow \"checkout\" to switch to\nanother branch).  Thinking things through so that we can fill in all these\ndetails is a tedious and hard work, but I would say it would be worth it.\nIn the ideal world, if you do not have to (nor want to) use the detached\nHEAD feature, you do not have to.\n\nBut that is entirely different from saying \"I do not need to use detached\nHEAD, I cannot explain it to my users. Let's make it unusable, iow, I give\nup\".  Unfortunately that is the impression I am getting from your whining.\n\nIf you have been advocating for something else, and you share the goal of\nhelping users by e.g. making it unnecessary to worry about accidentally\ncommitting on that state and later losing them, you would need to do a\nbetter job explaining yourself.\n\n> Just recently, I had a user request (a very valid one, mind you) where the \n> user does not want to provide a commit message, and wants to just commit \n> all the current changes.  In that particular case, it is very sensible to \n> ask for these things.  It is something utterly simple to ask for. Yet, it \n> is utterly hard with Git, especially if I have to explain it.\n\nI suspect the above is another example of your needing to do a better job\nexplaining yourself here, but from \"just commit all the changes without\nsaying message\", my knee-jerk reaction is \"git commit -a -m 'no message'\".\n\nYou would need to justify why -m 'no message' does not fit the bill better\nthan just saying \"is very sensible to ask for these things\", as I highly\nsuspect that I misunderstood what \"these things\" are in your five lines to\ncome up with that \"solution\" that you are now going to explain why that is\nnot what the end user wanted.  And in this case, I do not think it is that\nme being disconnected from the real world, but that your explanation is\ninsufficient.\n"},{"id":"125131","messageId":"7voco8xcua.fsf@alter.siamese.dyndns.org","threadId":"21236","inReplyTo":"alpine.DEB.1.00.0910160245310.4985@pacific.mpi-cbg.de","subject":"Re: [PATCH] Proof-of-concept patch to remember what the detached HEAD was","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2009-10-16T03:00:13Z","receivedAt":"2009-10-16T03:00:13Z","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> In this particular case, I cannot help but notice that commits performed \n> on a detached HEAD will get lost _unless_ they are somehow put onto a \n> named branch eventually.  So the only question is whether you restrict \n> flexibility by requiring to name the branch first before committing, \n> instead of committing and then naming the branch.\n\nYou are forgetting another important case.  You may not even want to keep\nwhat you will be committing to the throw-away temporary state.\n\nThat is why I liked the proposal by James to introduce a third state\n(i.e. not on local branch, but cannot commit) at the conceptual level,\neven though as Daniel pointed out and Nico and I concurred later, the\nimplementation may need to be based on the detached HEAD to avoid \"git\nfetch\" surprises.\n\nYou can of course fix it in different ways.  The third state could be\nimplemented by pointing at a non local branch ref with HEAD, and then by\nmaking fetch refuse to update, just like we refuse a push from side to\nmake the working tree state inconsistent.\n\nEither way, confusion arising from accidental (or unintended) detaching\nwould be removed for new users, and that won't have to harm people who\nneed to (because they _are_ used to) be able to work on detached HEAD, no?\n"},{"id":"125136","messageId":"20091016042955.GA9233@atjola.homenet","threadId":"21236","inReplyTo":"7v1vl42uid.fsf@alter.siamese.dyndns.org","subject":"Re: [PATCH] Proof-of-concept patch to remember what the detached HEAD was","fromName":"Björn Steinbrink","fromEmail":"b.steinbrink@gmx.de","sentAt":"2009-10-16T04:29:55Z","receivedAt":"2009-10-16T04:29:55Z","isPatch":true,"sender":{"key":"b.steinbrink@gmx.de","avatar":"https://avatars.githubusercontent.com/u/230962?v=4"},"body":"On 2009.10.15 14:54:18 -0700, Junio C Hamano wrote:\n> If it is very important to support:\n> \n>     $ git checkout --look-but-not-touch origin/next^\n> \n> then James's approach would not be very useful, as we do have to detach\n> HEAD and implement the \"do not touch\" logic for detached HEAD state\n> anyway, so we might just use the same logic we would use for origin/next^\n> when checking out origin/next itself.\n\nI don't have any numbers backing this up, but my gut feeling says that\nmost cases of \"Where have my commits gone?\" that I have seen on #git\nwere due to \"git checkout HEAD~2\"-like actions. Either because the user\nassumed SVN-like behaviour (you can't commit until you do \"svn up\", like\n\"git reset --merge HEAD@{1}\") or thought that \"git checkout\n<committish>\" would act like \"git reset --hard <committish>\".\n\nFor the latter I fail to envision any solution except for\neducation (and I have no idea why the user expected checkout to work\nlike reset).\n\nThe former can be solved by the proposed extra information in HEAD,\nforbidding changes to HEAD that make it reference a commit that's not\nreachable through the head stored in the extra information[*1*] and providing\nsome command that acts like \"svn up\".\n\nThis seems quite different from the plain \"forbid committing\" or \"detach\nand know how you get there\", but more like \"detach and know where you're\ncoming from\".\n\n[*1*] If certain updates to HEAD aren't forbidden, a \"checkout deadbeef\"\n(or a reset or update-ref) would possibly invalidate the extra\ninformation in HEAD, which would require implicit detaching, making the\nconcept useless. For example:\n\nA---B---C---D---E (master)\n         \\     /\n          F---G---H---I (foo)\n\ngit checkout master\ngit checkout master~2 # Put refs/heads/master into the extra info\ngit reset --hard HEAD^ # Allow?\ngit reset --hard foo~2 # Allow? Change extra info? It's also in master\n\n\ngit checkout master\ngit checkout foo~2\n\nIs that checkout allowed? \"foo~2\" is also reachable through master. Does\n\"checkout\" do some smart parsing and puts refs/heads/foo into the extra\ninfo? Or should refs/heads/master end up there?\n\n\ngit checkout master\ngit checkout foo~1\n\nBasically, same deal as above, but foo~1 is not reachable through\nmaster.\n\n\nAnd finally the pure commit id cases:\ngit checkout master\ngit checkout $(git rev-parse master^)\n\nIs that to be allowed? We can't derive the extra info from the argument\ngiven to checkout, but could check that it's reachable from master\n(currently referenced HEAD at the time of the command being run)\n\nAnd:\ngit checkout master\ngit checkout $(git rev-parse foo^)\n\nNeither can we guess what the extra info should be from the argument\ngiven to checkout, nor is the given commit reachable through master. So\nthis should be forbidden and should require ^0?\n\n\nThis whole thing is indeed a whole lot less complex with a SVN-like\nmodel, where you basically work with the linearly growing reflog only.\n\nBjörn\n"},{"id":"125137","messageId":"20091016050312.GB9233@atjola.homenet","threadId":"21236","inReplyTo":"885649360910151647v27a15334x63fe3b6f5035dbd2@mail.gmail.com","subject":"Re: [PATCH] Proof-of-concept patch to remember what the detached HEAD was","fromName":"Björn Steinbrink","fromEmail":"b.steinbrink@gmx.de","sentAt":"2009-10-16T05:03:12Z","receivedAt":"2009-10-16T05:03:12Z","isPatch":true,"sender":{"key":"b.steinbrink@gmx.de","avatar":"https://avatars.githubusercontent.com/u/230962?v=4"},"body":"On 2009.10.15 16:47:57 -0700, James Pickens wrote:\n> On Thu, Oct 15, 2009 at 3:08 PM, Junio C Hamano <gitster@pobox.com> wrote:\n> > Junio C Hamano <gitster@pobox.com> writes:\n> >\n> >>     $ git checkout origin/next ;# ditto\n> >>     $ git symbolic-ref HEAD\n> >>     refs/remotes/origin/next\n> >\n> > Ok, after reading Daniel's message to remind us that \"git fetch\" after\n> > this will get us into trouble, I agree that detaching HEAD is inevitable.\n> \n> Some people liked the idea, so let's not give up just yet.  Here are a few\n> things Git could do when a fetch wants to update the currently checked out\n> branch:\n> \n> 1. Refuse the fetch.\n> 2. Update the ref, leaving the user with a work tree and index that don't\n>    match their HEAD.\n> 3. Detach the HEAD, then update the ref.\n> 4. Update the ref, then check it out.\n> \n> Option 1 is ok, as long as the \"next step\" is not too complicated.  It's no\n> good if the user has to checkout a different branch, then fetch, then\n> checkout the original branch again.\n\nNot good. It makes \"git fetch; git log ..origin/foo\" impossible. And\nthat's IMHO a very useful thing for people that just want to follow\nthings and look at what happens.\n\n> Option 2 is crap.\n\nAgreed.\n\n> Option 3 seems reasonable, but it might be just as scary/confusing to\n> newbies as the current behavior, so I don't think it should be the default.\n\nDoesn't seem very good to me. The idea was to stop people from\naccidently getting on a detached HEAD, if common operations like \"fetch\"\nnow suddenly detach HEAD, that's _worse_ than before. And for a\nsingle-branch remote, even \"git pull\" may detach HEAD then:\n\ngit init;\ngit remote add -f -t master origin git://...\ngit checkout origin/master\n*wait*\ngit pull # Will work, as the fetch refspec is not a glob\n\nBut that \"pull\" does:\ngit fetch origin refs/heads/master:refs/remotes/origin/master\n\nWhich detaches HEAD before merging/fast-forwarding.\n\nBad.\n\nAnd seeing that the requests for \"clone just a single branch\" seem to\nincrease in #git, I guess that such non-globbing refspecs for\nremote.origin.fetch might become more common in the future.\n\n> Option 4 also seems reasonable, but you run into problems if the user had\n> changed the index or work tree.  In that case Git could do 'checkout\n> --merge' automatically.  This option is also less \"pure\" since it lets 'git\n> fetch' modify the index and work tree.\n\nSame as for option 1, it kills \"git fetch; git log ..origin/foo\". And\nthat would basically turn \"fetch\" into a hypothetical \"pull --reset\".\nThat's IMHO better done in a separate command.\n\n> So how about this:\n> * 'git fetch' refuses the fetch by default.\n> * 'git fetch --detach' detaches HEAD, then updates the ref\n> * 'git pull' detaches HEAD, updates the ref, then checks out the new ref\n>   with --merge.\n\n\"fetch --detach\" doesn't feel right to me. Wrong class of commands to\nhave such an option. And I'm not sure about adding a third mode to\n\"pull\" (besides \"merge\" and \"rebase\") that only triggers for special\ncases. Again, I'd prefer a separate command.\n\nIf we store \"where did I come from\" instead of just \"where am I\" in HEAD\nwhen detached, those problems don't seem to show up (but just storing\nthat information correctly seems hard enough, see the other mail I wrote\na few minutes ago).\n\n\"git fetch\" just updates the remote tracking branch, you stay at where\nyou are, \"git log ..origin/foo\" keeps working. It could give a special\nhint that you might want to use \"git checkout origin/foo\" or \"git\nnew-command\" to update your working tree to the newest version, when\nyour working tree is based upon an old version of that remote tracking\nbranch.\n\nAnd \"git pull\" might perform a fast-forward automatically (figuring out\nthe right remote from the extra info in HEAD), but refuse to do merges\n(if upstream has been rewritten), pointing the user to \"git checkout\" or\n\"git new-command\". (Interestingly, \"pull --rebase\" wouldn't suffer from\nsuch history rewriting, as it looks at the reflog for the remote\ntracking branch, but I guess a working \"git pull --rebase\" while \"git\npull\" fails is bound to cause major user confusion).\n\n\"git new-command\" could act like \"svn up\", doing a fetch and a\n\"checkout --merge <remote_tracking_branch>\" to just get the user\nup-to-date keeping local uncommitted modifications. I can't tell why,\nbut my feeling is that this should be a new command, and not part of\npull, as said above.\n\nBjörn\n"},{"id":"125141","messageId":"alpine.LNX.2.00.0910160128400.32515@iabervon.org","threadId":"21236","inReplyTo":"20091016042955.GA9233@atjola.homenet","subject":"Re: [PATCH] Proof-of-concept patch to remember what the detached HEAD was","fromName":"Daniel Barkalow","fromEmail":"barkalow@iabervon.org","sentAt":"2009-10-16T06:02:09Z","receivedAt":"2009-10-16T06:02:09Z","isPatch":true,"sender":{"key":"barkalow@iabervon.org","avatar":"https://avatars.githubusercontent.com/u/55364219?v=4"},"body":"On Fri, 16 Oct 2009, Björn Steinbrink wrote:\n\n> On 2009.10.15 14:54:18 -0700, Junio C Hamano wrote:\n> > If it is very important to support:\n> > \n> >     $ git checkout --look-but-not-touch origin/next^\n> > \n> > then James's approach would not be very useful, as we do have to detach\n> > HEAD and implement the \"do not touch\" logic for detached HEAD state\n> > anyway, so we might just use the same logic we would use for origin/next^\n> > when checking out origin/next itself.\n> \n> I don't have any numbers backing this up, but my gut feeling says that\n> most cases of \"Where have my commits gone?\" that I have seen on #git\n> were due to \"git checkout HEAD~2\"-like actions. Either because the user\n> assumed SVN-like behaviour (you can't commit until you do \"svn up\", like\n> \"git reset --merge HEAD@{1}\") or thought that \"git checkout\n> <committish>\" would act like \"git reset --hard <committish>\".\n> \n> For the latter I fail to envision any solution except for\n> education (and I have no idea why the user expected checkout to work\n> like reset).\n> \n> The former can be solved by the proposed extra information in HEAD,\n> forbidding changes to HEAD that make it reference a commit that's not\n> reachable through the head stored in the extra information[*1*] and providing\n> some command that acts like \"svn up\".\n> \n> This seems quite different from the plain \"forbid committing\" or \"detach\n> and know how you get there\", but more like \"detach and know where you're\n> coming from\".\n\nWhat's the state before the \"git checkout HEAD~2\"?\n\nIf it's:\n\n$ git checkout origin/some-obscure-branch\n(get curious about the commit a bit back)\n$ git checkout HEAD~2\n\nAnd then the user doesn't know how to get back to where they were, then it \nshould work if git had stored \"origin/some-obscure-branch~2\" at this point \n(having substituted \"origin/some-obscure-branch\" (the previous extra info) \nfor HEAD). Then we could have a \"git up\" that would discard modifiers from \nthe extra info and check that out. Or users might find \"git checkout \norigin/some-obscure-branch\" obvious enough if git is reporting something \nrelated.\n\nI know I often find my git.git repos on \"* (no branch)\", and I don't \nremember if I checked that out as origin/master or origin/next. And that's \nan important clue as to when I'd been doing there previously, and what I \nmight want to do next. Perhaps these users are having a similar problem, \nwhere they're relying on git to remember what they were doing?\n\n\t-Daniel\n*This .sig left intentionally blank*"},{"id":"125148","messageId":"20091016082755.GA19395@atjola.homenet","threadId":"21236","inReplyTo":"alpine.LNX.2.00.0910160128400.32515@iabervon.org","subject":"Re: [PATCH] Proof-of-concept patch to remember what the detached HEAD was","fromName":"Björn Steinbrink","fromEmail":"b.steinbrink@gmx.de","sentAt":"2009-10-16T08:27:55Z","receivedAt":"2009-10-16T08:27:55Z","isPatch":true,"sender":{"key":"b.steinbrink@gmx.de","avatar":"https://avatars.githubusercontent.com/u/230962?v=4"},"body":"On 2009.10.16 02:02:09 -0400, Daniel Barkalow wrote:\n> On Fri, 16 Oct 2009, Björn Steinbrink wrote:\n> \n> > On 2009.10.15 14:54:18 -0700, Junio C Hamano wrote:\n> > > If it is very important to support:\n> > > \n> > >     $ git checkout --look-but-not-touch origin/next^\n> > > \n> > > then James's approach would not be very useful, as we do have to detach\n> > > HEAD and implement the \"do not touch\" logic for detached HEAD state\n> > > anyway, so we might just use the same logic we would use for origin/next^\n> > > when checking out origin/next itself.\n> > \n> > I don't have any numbers backing this up, but my gut feeling says that\n> > most cases of \"Where have my commits gone?\" that I have seen on #git\n> > were due to \"git checkout HEAD~2\"-like actions. Either because the user\n> > assumed SVN-like behaviour (you can't commit until you do \"svn up\", like\n> > \"git reset --merge HEAD@{1}\") or thought that \"git checkout\n> > <committish>\" would act like \"git reset --hard <committish>\".\n> > \n> > For the latter I fail to envision any solution except for\n> > education (and I have no idea why the user expected checkout to work\n> > like reset).\n> > \n> > The former can be solved by the proposed extra information in HEAD,\n> > forbidding changes to HEAD that make it reference a commit that's not\n> > reachable through the head stored in the extra information[*1*] and providing\n> > some command that acts like \"svn up\".\n> > \n> > This seems quite different from the plain \"forbid committing\" or \"detach\n> > and know how you get there\", but more like \"detach and know where you're\n> > coming from\".\n> \n> What's the state before the \"git checkout HEAD~2\"?\n> \n> If it's:\n> \n> $ git checkout origin/some-obscure-branch\n> (get curious about the commit a bit back)\n> $ git checkout HEAD~2\n\nIIRC, most of the time it was:\ngit checkout master # not detaching\ngit checkout HEAD~2\n\nAnother version I recall (but that's what I use myself regularly, so I\nmight be biased and think that it's more common that it actually was)\nis:\n\ngit checkout master\ngit log # Find commit, copy hash\ngit checkout <hash> # Pasting the copied hash\n\n> And then the user doesn't know how to get back to where they were, then it \n> should work if git had stored \"origin/some-obscure-branch~2\" at this point \n> (having substituted \"origin/some-obscure-branch\" (the previous extra info) \n> for HEAD). Then we could have a \"git up\" that would discard modifiers from \n> the extra info and check that out. Or users might find \"git checkout \n> origin/some-obscure-branch\" obvious enough if git is reporting something \n> related.\n\nI'd not put \"origin/some-obscure-branch~2\" in there, but just\n\"origin/some-obscure-branch\". Rationale: The ~2 modifier may become\ninvalid when you do \"git fetch\". And I don't see any value in having\nthat modifier, and even if there are some corner-cases, those could use\n\"git describe\" or so, to get the modifiers on the fly.\n\n> I know I often find my git.git repos on \"* (no branch)\", and I don't \n> remember if I checked that out as origin/master or origin/next. And that's \n> an important clue as to when I'd been doing there previously, and what I \n> might want to do next. Perhaps these users are having a similar problem, \n> where they're relying on git to remember what they were doing?\n\nHm, maybe. I'm more inclined to think that they assumed that \"git\ncheckout <branch_head>\" 'binds' them to that branch head. But git allows\nthem to jump around freely, the 'binding' is very weak.\n\nSVN has:\n\"svn up\": Get an older/newer version of the branch I'm on\n\"svn switch\": Switch to a different branch\n\nYou cannot jump around without binding yourself to any branch.\n\ngit has:\n\"git checkout\": Go anywhere, bind to that till the next checkout.\n\nWith \"git checkout <non-branch-head>\" working like a temporary unnamed\nbranch head.\n\nIn my view, there's the huge conceptual difference that svn has named\nbranches, while git only has named branch heads, that have a history\n(reflog) that isn't necessarily even remotely similar to that of the\nbranch it currently points at.\n\n          G---H---I (bar)\n         /       /\nA---B---C---D---E (master)\n     \\\n      F (foo)\n\nIn SVN, you'd have a history that describes how \"bar\" came into its\ncurrent state, consisting of: G, H, I (Not following the copy at\nG).\n\nIn git, you have a history that describes how commit I came into\nexistence (not branch head \"bar\"!), that is: A, B, C, D, E, G, H, I.\n\nAnd the actual history for \"bar\" in git (the reflog) might be as weird\nas: E, F, H, I, B, I. Jumping wildly across the commit DAG.\n\n\nMy view is that with git you're never \"on a branch\", but you have an\nactive branch head (possibly unnamed [detached HEAD]) that marks a tip,\nwhere the DAG grows. A branch, to me, has an extent. In the above graph,\nG, H, I is a branch, and F is a branch, but \"bar\" is not. \"bar\" has no\nextent, it's just where the \"G, H, I\" branch might possibly grow.\n\nWhen you do \"git checkout bar~2\", you're not on \"no branch\". Your active\nbranch head is just unnamed. The branch is yet to be born (unless you\nconsider e.g. \"A, B, C, G\" to be your branch), but at least after doing\na \"git commit\", you'll have:\n\n            J (HEAD)\n           /\n          G---H---I (bar)\n         /       /\nA---B---C---D---E (master)\n     \\\n      F (foo)\n\nAnd then you clearly do have a branch \"J\" there. At least if you stop saying\nthat a branch is just its head. And \"git branch\" saying that you're on\n\"no branch\" makes no sense at all then.\n\nGit simply doesn't expose branches in a sense of \"a series of commit\".\nTo get that, you need things like \"git log master..bar\" to get the \"G, H,\nI\" branch.\n\nSVN has this clear \"this branch has this name\" concept, git does not. I\nprefer gits way. But maybe it should simply not use the term \"branch\"\nwhen it means \"branch head\".\n\nAnd the glossary even somewhat agrees with me, although it disagrees\nwith itself:\n\n  branch\n    A \"branch\" is an active line of development. The most recent commit\n    on a branch is referred to as the tip of that branch. The tip of\n    the branch is referenced by a branch head, which moves forward as\n    additional development is done on the branch. A single git\n    repository can track an arbitrary number of branches, but your\n    working tree is associated with just one of them (the \"current\" or\n    \"checked out\" branch), and HEAD points to that branch.\n\nSo a branch is an active line of development. If I do \"git checkout\nfoo~2\" and \"git commit\", I clearly do have an active line of\ndevelopment. So it's not \"no branch\".\n\nAnd a \"branch head\" references the tip (point of growth) of a branch.\nIt's not identical to a branch.\n\nBut then there comes HEAD, which is said to point to a branch, while it\nof course points to a branch head. I guess the glossary is outdated WRT\ndetached HEAD, but if you ignore the implementation details, it could\nstill be said that in case of a detached HEAD, HEAD points to an unnamed\nbranch head.\n\n\nThe user manual also makes this distinction, but says that \"when no\nconfusion will result, we often just use the term 'branch' both for\nbranches and for branch heads\".\n\nAnd the command man pages follow that \"just use 'branch'\" way:\n\n\"git checkout\" is said to checkout (and possibly create) a branch, not a\nbranch head.\n\n\"git branch\":\n - List, create or delete branches\n - --contains/--merged/--no-merged => show branches that...\n\nBut the clear winner is (from git-branch(1)):\n\"If the <commit> argument is missing it defaults to HEAD (i.e. the tip\nof the current branch).\"\n\nCombine that with a detached HEAD and the according \"git branch\" output.\nThe <commit> argument will default to the tip of no branch! Epic.\n\n\nDon't get me wrong though. I like git's model, and think that its\nanonymous branches with named branch heads offer a lot more than e.g.\nSVN's named branches (and namespace pollution is just a minor factor).\nBut I'm more and more convinced that suggesting the unknowing user who\ndidn't read the \"we term A for A and B\" notice in the manual, that git\ndoes have named branches (branches being a series of commits) is a bad\nthing that leads to confusion (in contrast to what the manual assumes).\n\nExamples:\n\nUser asking about deleting a \"branch\" without deleting its commits:\nhttp://colabti.de/irclogger/irclogger_log/git?date=2009-10-14#l2113\n\nUser asking whether deleting master will mess up other \"branches\":\nhttp://colabti.de/irclogger/irclogger_log/git?date=2009-10-13#l2407\n\n(I thought that there were two more in the last week, but I couldn't\nfind them, so maybe I was wrong, or they used some other word than\n\"delete\", which I used to search the logs).\n\nIn both cases, the user wanted to delete the branch head, but was afraid\nthat that would kill the commits, as they were told that they will\ndelete the \"branch\" and assumed the \"branch\" to be all commits reachable\nthrough the branch head.\n\nAnd I kind of doubt that this just applies to SVN refugees that are used\nto SVN's meaning of branches, but also to people that are new to any\nkind of VCS and \"naively\" apply the branch-analogy to real-world trees,\nwhere branches are more than just their tips.\n\nAnd I believe that this is closely related to the detached HEAD thing.\nSee above for the \"no branch\" stuff that now doesn't even make any sense\nto me anymore (even less after reading the git-branch(1) man page ;-)).\nBut also the fact that checkout is hardly about branches, but about\n(possibly unnamed) branch heads. One might have certain branch heads\nthat are never rewound and thus might be more or less equal to a branch,\nbut that seems like it's almost(?) a special case if you consider what\n\"checkout\" can actually do.\n\nI'm not sure how this can be alleviated. Just saying \"branch head\"\ninstead of \"branch\" is more correct, but probably still doesn't really\nexpress those differences that make git what it is. Making \"git branch\"\nsay \"* (unnamed branch head)\" instead of \"* (no branch)\" seems like a\ngood start, but the user manual would need a very close look to catch\nall the text that stops to make sense when you suddenly start to make a\nstronger difference between a branch and a branch head. I'll look into\nthat over the weekend, but won't promise anything.\n\nBjörn, hoping that he didn't run too far off the track\n"},{"id":"125165","messageId":"alpine.LNX.2.00.0910161311460.28491@reaper.quantumfyre.co.uk","threadId":"21236","inReplyTo":"alpine.LNX.2.00.0910151523020.32515@iabervon.org","subject":"Re: [PATCH] Proof-of-concept patch to remember what the detached HEAD was","fromName":"Julian Phillips","fromEmail":"julian@quantumfyre.co.uk","sentAt":"2009-10-16T12:15:35Z","receivedAt":"2009-10-16T12:15:35Z","isPatch":true,"sender":{"key":"julian@quantumfyre.co.uk","avatar":"https://avatars.githubusercontent.com/u/948888?v=4"},"body":"On Thu, 15 Oct 2009, Daniel Barkalow wrote:\n\n> On Thu, 15 Oct 2009, James Pickens wrote:\n>\n>> How about not detaching the head at all if the user checks out any ref, and\n>> reject commits if he checked out a tag or remote branch.  For example:\n>>\n>> $ git checkout origin/master\n>> $ git status\n>> # On branch origin/master\n>> $ git commit ;# complain\n>\n> $ git checkout origin/master\n> $ git fetch\n> $ git checkout origin/next\n> Uncommited file '...' would be overwritten.\n\nHow about:\n\n$ git checkout origin/master\n$ git fetch\nRefusing to fetch, as it would update a checkedout branch\n\"git fetch -f\" will force the update, but you will need to run \"git \nreset --hard HEAD\" to update your checkout to match.\n\n?\n\n-- \nJulian\n\n  ---\n    If you care, you just get disappointed all the time. If you don't care\nnothing matters so you are never upset.\t  -- Calvin\n"},{"id":"125181","messageId":"20091016143041.GA11821@atjola.homenet","threadId":"21236","inReplyTo":"alpine.LNX.2.00.0910161311460.28491@reaper.quantumfyre.co.uk","subject":"Re: [PATCH] Proof-of-concept patch to remember what the detached HEAD was","fromName":"Björn Steinbrink","fromEmail":"b.steinbrink@gmx.de","sentAt":"2009-10-16T14:30:41Z","receivedAt":"2009-10-16T14:30:41Z","isPatch":true,"sender":{"key":"b.steinbrink@gmx.de","avatar":"https://avatars.githubusercontent.com/u/230962?v=4"},"body":"On 2009.10.16 13:15:35 +0100, Julian Phillips wrote:\n> On Thu, 15 Oct 2009, Daniel Barkalow wrote:\n> \n> >On Thu, 15 Oct 2009, James Pickens wrote:\n> >\n> >>How about not detaching the head at all if the user checks out any ref, and\n> >>reject commits if he checked out a tag or remote branch.  For example:\n> >>\n> >>$ git checkout origin/master\n> >>$ git status\n> >># On branch origin/master\n> >>$ git commit ;# complain\n> >\n> >$ git checkout origin/master\n> >$ git fetch\n> >$ git checkout origin/next\n> >Uncommited file '...' would be overwritten.\n> \n> How about:\n> \n> $ git checkout origin/master\n> $ git fetch\n> Refusing to fetch, as it would update a checkedout branch\n> \"git fetch -f\" will force the update, but you will need to run \"git\n> reset --hard HEAD\" to update your checkout to match.\n\nThat would redefine -f (currently means \"allow non-fast-forward\nupdates\"), the flag that allows the checked out branch head to be\nupdated is -u, --update-head-ok, and is for internal use only.\n\nAnd suggesting \"reset --hard\" seems wrong, that just kills any\nuncommitted changes.\n\nAnd such uncommitted changes would be lost in the big \"undo the fetch\nupdate\" diff. So you'd have to do:\ngit reset --soft HEAD@{1}\ngit checkout --merge HEAD@{1}\n\nto keep them, while updating to the new state of the remote tracking\nbranch. Not quite intuitive, is it?\n\nBjörn\n"},{"id":"125187","messageId":"alpine.LFD.2.00.0910161137540.20122@xanadu.home","threadId":"21236","inReplyTo":"alpine.LNX.2.00.0910160128400.32515@iabervon.org","subject":"Re: [PATCH] Proof-of-concept patch to remember what the detached HEAD was","fromName":"Nicolas Pitre","fromEmail":"nico@fluxnic.net","sentAt":"2009-10-16T15:44:10Z","receivedAt":"2009-10-16T15:44:10Z","isPatch":true,"sender":{"key":"nico@fluxnic.net","avatar":"https://avatars.githubusercontent.com/u/702790?v=4"},"body":"On Fri, 16 Oct 2009, Daniel Barkalow wrote:\n\n> What's the state before the \"git checkout HEAD~2\"?\n\nIt is HEAD@{1}.\n\n> I know I often find my git.git repos on \"* (no branch)\", and I don't \n> remember if I checked that out as origin/master or origin/next.\n\nJust have a look at the output of \"git reflog\".  Pretty unambiguous IMHO.\n\n\nNicolas\n"},{"id":"125196","messageId":"alpine.LNX.2.00.0910161821230.30589@reaper.quantumfyre.co.uk","threadId":"21236","inReplyTo":"20091016143041.GA11821@atjola.homenet","subject":"Re: [PATCH] Proof-of-concept patch to remember what the detached HEAD was","fromName":"Julian Phillips","fromEmail":"julian@quantumfyre.co.uk","sentAt":"2009-10-16T17:31:23Z","receivedAt":"2009-10-16T17:31:23Z","isPatch":true,"sender":{"key":"julian@quantumfyre.co.uk","avatar":"https://avatars.githubusercontent.com/u/948888?v=4"},"body":"On Fri, 16 Oct 2009, Bj?rn Steinbrink wrote:\n\n> On 2009.10.16 13:15:35 +0100, Julian Phillips wrote:\n>> On Thu, 15 Oct 2009, Daniel Barkalow wrote:\n>>\n>>> On Thu, 15 Oct 2009, James Pickens wrote:\n>>>\n>>>> How about not detaching the head at all if the user checks out any ref, and\n>>>> reject commits if he checked out a tag or remote branch.  For example:\n>>>>\n>>>> $ git checkout origin/master\n>>>> $ git status\n>>>> # On branch origin/master\n>>>> $ git commit ;# complain\n>>>\n>>> $ git checkout origin/master\n>>> $ git fetch\n>>> $ git checkout origin/next\n>>> Uncommited file '...' would be overwritten.\n>>\n>> How about:\n>>\n>> $ git checkout origin/master\n>> $ git fetch\n>> Refusing to fetch, as it would update a checkedout branch\n>> \"git fetch -f\" will force the update, but you will need to run \"git\n>> reset --hard HEAD\" to update your checkout to match.\n>\n> That would redefine -f (currently means \"allow non-fast-forward\n> updates\"), the flag that allows the checked out branch head to be\n> updated is -u, --update-head-ok, and is for internal use only.\n>\n> And suggesting \"reset --hard\" seems wrong, that just kills any\n> uncommitted changes.\n\nOk, so the commands were wrong.  Not important.\n\nIt was the approach that I was trying to suggest rather than the actual \ncommands.  The point I was trying to make was how, as a user, I would be \nhappy to git behave.\n\nSo, I try to run fetch, git says \"ooh, now that would be dangerous - you \ncan force it happen by running \"git foo\", but you will then be in \nsituation X, which you can then recover from by running \"git bar\", though \nyou may need to run \"git stash\" to save any edits you have made\" or \nsomething similar.\n\nNow as a user I know that I have tried to do something a bit unusual, but \nI don't have to run to the mailing list or #git saying \"I just did X Y Z \nand everything is now FUBARed\".  I can even proceed to do the unusal \nthing, as git itself has given me the information I need to sort things \nout afterwards.\n\n> And such uncommitted changes would be lost in the big \"undo the fetch\n> update\" diff. So you'd have to do:\n> git reset --soft HEAD@{1}\n> git checkout --merge HEAD@{1}\n>\n> to keep them, while updating to the new state of the remote tracking\n> branch. Not quite intuitive, is it?\n\nI don't care what git has to do, I'm talking about the user experience - \nif we have to write some new code to support it, that really isn't a \nterribly hard thing to do.  UIs should be driven down from the user \ninteraction not up from the implementation.\n\n-- \nJulian\n\n  ---\nCaptain: \"Catalyzer's a nothing part, captain.\"\n\nMal: \"It's nothing until you don't got one. Then it appears to be everything.\"\n \t\t\t\t--Episode #8, \"Out of Gas\"\n"},{"id":"125200","messageId":"alpine.LNX.2.00.0910161340140.32515@iabervon.org","threadId":"21236","inReplyTo":"alpine.LNX.2.00.0910161821230.30589@reaper.quantumfyre.co.uk","subject":"Re: [PATCH] Proof-of-concept patch to remember what the detached HEAD was","fromName":"Daniel Barkalow","fromEmail":"barkalow@iabervon.org","sentAt":"2009-10-16T18:29:15Z","receivedAt":"2009-10-16T18:29:15Z","isPatch":true,"sender":{"key":"barkalow@iabervon.org","avatar":"https://avatars.githubusercontent.com/u/55364219?v=4"},"body":"On Fri, 16 Oct 2009, Julian Phillips wrote:\n\n> It was the approach that I was trying to suggest rather than the actual\n> commands.  The point I was trying to make was how, as a user, I would be happy\n> to git behave.\n> \n> So, I try to run fetch, git says \"ooh, now that would be dangerous - you can\n> force it happen by running \"git foo\", but you will then be in situation X,\n> which you can then recover from by running \"git bar\", though you may need to\n> run \"git stash\" to save any edits you have made\" or something similar.\n> \n> Now as a user I know that I have tried to do something a bit unusual, but I\n> don't have to run to the mailing list or #git saying \"I just did X Y Z and\n> everything is now FUBARed\".  I can even proceed to do the unusal thing, as git\n> itself has given me the information I need to sort things out afterwards.\n\nThe thing is that that sequence shouldn't be unusual or dangerous or \nrequire sorting things out afterwards. In the current version of git, it's \na completely normal thing to do that behaves nicely and does what the user \nalmost certainly wants. We *could* horribly break it, and then add \nmessages to tell the user they're doing something that's now horribly \nbroken, and tell the user how to cope with the fact that what they want to \ndo involves something that's horribly broken, and roll our eyes when users \nwho have only used working systems like SVN or git 1.6.X ignore the \nmessage and can't figure out what's going on. Or we could just not break \nit in the first place.\n\nSVN doesn't think that your working directory is supposed to change when \nsomeone else makes a commit. Git shouldn't think your working directory \nshould change when you find out that someone made a commit. If you want to \nsee now commits, you do \"svn up\" or \"git checkout\".\n\n\t-Daniel\n*This .sig left intentionally blank*\n"},{"id":"125204","messageId":"7vvdiftb0d.fsf@alter.siamese.dyndns.org","threadId":"21236","inReplyTo":"alpine.LNX.2.00.0910161821230.30589@reaper.quantumfyre.co.uk","subject":"Re: [PATCH] Proof-of-concept patch to remember what the detached HEAD was","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2009-10-16T19:05:38Z","receivedAt":"2009-10-16T19:05:38Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Julian Phillips <julian@quantumfyre.co.uk> writes:\n\n>> And such uncommitted changes would be lost in the big \"undo the fetch\n>> update\" diff. So you'd have to do:\n>> git reset --soft HEAD@{1}\n>> git checkout --merge HEAD@{1}\n>>\n>> to keep them, while updating to the new state of the remote tracking\n>> branch. Not quite intuitive, is it?\n>\n> I don't care what git has to do, I'm talking about the user experience\n\nBut Björn is showing two commands the _user_ has to type, iow, the comment\nis about the user experience.\n"},{"id":"125205","messageId":"alpine.LNX.2.00.0910162029460.31673@reaper.quantumfyre.co.uk","threadId":"21236","inReplyTo":"7vvdiftb0d.fsf@alter.siamese.dyndns.org","subject":"Re: [PATCH] Proof-of-concept patch to remember what the detached HEAD was","fromName":"Julian Phillips","fromEmail":"julian@quantumfyre.co.uk","sentAt":"2009-10-16T19:48:20Z","receivedAt":"2009-10-16T19:48:20Z","isPatch":true,"sender":{"key":"julian@quantumfyre.co.uk","avatar":"https://avatars.githubusercontent.com/u/948888?v=4"},"body":"On Fri, 16 Oct 2009, Junio C Hamano wrote:\n\n> Julian Phillips <julian@quantumfyre.co.uk> writes:\n>\n>>> And such uncommitted changes would be lost in the big \"undo the fetch\n>>> update\" diff. So you'd have to do:\n>>> git reset --soft HEAD@{1}\n>>> git checkout --merge HEAD@{1}\n>>>\n>>> to keep them, while updating to the new state of the remote tracking\n>>> branch. Not quite intuitive, is it?\n>>\n>> I don't care what git has to do, I'm talking about the user experience\n>\n> But Bj?rn is showing two commands the _user_ has to type, iow, the comment\n> is about the user experience.\n\nOnly Currently.  My point was that _if_ we wanted to support this sort of \nthing, then we can make is simpler to do by providing a simple command for \nthe user.\n\nThe point I wanted to make was that the decision on what to do should be \ndriven by the user's experience - not by the fact that it is easier to \nimplement something else.\n\nMy interest in this thread is solely that it might provide a mechanism to \nfind out which tag was checked out.  So, I'm just chucking in my $0.02 as \na user.  My suggestions are probably complete rubbish, as I haven't really \nhad time to think them through... Sorry.\n\n-- \nJulian\n\n  ---\n\nLook, just gimme some inner peace, or I'll mop the floor with ya!\n\n \t\t-- Homer Simpson\n \t\t   El Viaje Misterioso de Nuestro Homer\n"},{"id":"125209","messageId":"alpine.LFD.2.00.0910161557500.20122@xanadu.home","threadId":"21236","inReplyTo":"alpine.LNX.2.00.0910162029460.31673@reaper.quantumfyre.co.uk","subject":"Re: [PATCH] Proof-of-concept patch to remember what the detached HEAD was","fromName":"Nicolas Pitre","fromEmail":"nico@fluxnic.net","sentAt":"2009-10-16T20:19:26Z","receivedAt":"2009-10-16T20:19:26Z","isPatch":true,"sender":{"key":"nico@fluxnic.net","avatar":"https://avatars.githubusercontent.com/u/702790?v=4"},"body":"On Fri, 16 Oct 2009, Julian Phillips wrote:\n\n> My interest in this thread is solely that it might provide a mechanism to find\n> out which tag was checked out.  So, I'm just chucking in my $0.02 as a user.\n\nTry this:\n\n$ git checkout v1.5.5\nNote: moving to 'v1.5.5' which isn't a local branch\nIf you want to create a new branch from this checkout, you may do so\n(now or later) by using -b with the checkout command again. Example:\n  git checkout -b <new_branch_name>\nHEAD is now at 1d2375d... GIT 1.5.5\n\n[look around, and then ...]\n\n$ git checkout HEAD~2\nPrevious HEAD position was 1d2375d... GIT 1.5.5\nHEAD is now at f61cc48... git-svn: fix following renamed paths when tracking a single path\n\n[go out for lunch ... and forget what this was about.]\n\n$ git reflog -3\nf61cc48 HEAD@{0}: checkout: moving from 1d2375d... to HEAD~2\n1d2375d HEAD@{1}: checkout: moving from master to v1.5.5\nc274db7 HEAD@{2}: pull : Fast forward\n\nHere I have all the information to see what I did, and from what state.  \nI even know that I did a pull on the master branch before moving away \nfrom it.  The -3 limits the log to 3 entries.  With no limit you get it \nall in your default pager.\n\nSo there is no need for another mechanism to find out what tag was \nactually checked out -- you have it all already.\n\n\nNicolas\n"},{"id":"125207","messageId":"7vk4yvt7kp.fsf@alter.siamese.dyndns.org","threadId":"21236","inReplyTo":"alpine.LNX.2.00.0910162029460.31673@reaper.quantumfyre.co.uk","subject":"Re: [PATCH] Proof-of-concept patch to remember what the detached HEAD was","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2009-10-16T20:19:50Z","receivedAt":"2009-10-16T20:19:50Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Julian Phillips <julian@quantumfyre.co.uk> writes:\n\n> On Fri, 16 Oct 2009, Junio C Hamano wrote:\n>\n>> Julian Phillips <julian@quantumfyre.co.uk> writes:\n>> ...\n>>> I don't care what git has to do, I'm talking about the user experience\n>>\n>> But Bj?rn is showing two commands the _user_ has to type, iow, the comment\n>> is about the user experience.\n>\n> Only Currently.  My point was that _if_ we wanted to support this sort\n> of thing, then we can make is simpler to do by providing a simple\n> command for the user.\n>\n> The point I wanted to make was that the decision on what to do should\n> be driven by the user's experience - not by the fact that it is easier\n> to implement something else.\n\nSorry, but I do not see in what way what you said in the thread connects\nto the above three lines.  Are you talking about this one from you a few\nmessages back?\n\n    How about:\n\n    $ git checkout origin/master\n    $ git fetch\n    Refusing to fetch, as it would update a checkedout branch\n    \"git fetch -f\" will force the update, but you will need to run \"git\n    reset --hard HEAD\" to update your checkout to match.\n\nI am not seeing \"not the implementation ease but the user experience\"\ndrive in this suggestion.  If you are driving from the user experience\npoint of view, I would have instead suggested:\n\n    How about:\n\n    $ git checkout origin/master\n    $ git fetch\n\n    and fetch happily updates the tracked branch, without affecting the\n    HEAD state (nor index nor the work tree, of course).\n\nUser experience here is:\n\n    * Let's checkout what the upstream has on the master.  I am at least\n      aware that git is distributed and does not go to the network unless\n      I tell it to, and am aware that origin/master is the state of the\n      upsream _when I told git to look at it the last time_.  So I'll get\n      the state I talked with the upstream the last time, and that is what\n      I want to look at.\n\n    * Hmm, there may be even more updates since I talked with the upstream\n      the last time.  Let's tell git to fetch.  I already know that this\n      updates origin/master to a more recent state.\n\nIsn't it much cleaner and less confusing?  And with these kind of\nawareness, the user can choose to do various things from here, e.g.:\n\n    * Oh, fetch did fetched something.  I want the updated state.  Let's\n      check it out with \"git checkout origin/master\"; or\n\n    * Ok, what changed since I last talked with the upstream?  I have one\n      end of the state already checked out, and I updated origin/master\n      with their latest, so I can say \"git diff HEAD origin/master\".\n\nNotice in the latter the user can be a neophyte who hasn't learned reflogs\nyet.\n\n> My interest in this thread is solely that it might provide a mechanism\n> to find out which tag was checked out.\n\nHmm, what is lacking in \"git describe HEAD\" for that?  I am not\ncomplaining that you might be asking for something that exists, but I _do_\nwant to know if something that exists is not a satisfactory solution and\nif so how it can be improved.\n"},{"id":"125227","messageId":"m49nq6-uk5.ln1@burns.bruehl.pontohonk.de","threadId":"21236","inReplyTo":"alpine.LNX.2.00.0910140037570.32515@iabervon.org","subject":"Re: [PATCH] Proof-of-concept patch to remember what the detached HEAD was","fromName":"Christoph Bartoschek","fromEmail":"bartoschek@gmx.de","sentAt":"2009-10-16T22:36:37Z","receivedAt":"2009-10-16T22:36:37Z","isPatch":true,"sender":{"key":"bartoschek@gmx.de","avatar":null},"body":"Daniel Barkalow wrote:\n\n> The upshot of the messages should be:\n> \n>  $ git checkout origin/master\n>  Since you can't actually change \"origin/master\" yourself, you'll just\n>  be sightseeing unless you create a local branch to hold new local work.\n> \n>  $ git branch\n>  * (not a local branch, but \"origin/master\")\n> \n>  $ git commit\n>  You've been sightseeing \"origin/master\". The commit can't change that\n>  value, so your commit isn't held in any branch. If you want to create\n>  a branch to hold it, here's how.\n\n\nI appreciate such a message for git branch as a user. Today I had the \nfollowing problem:\n\nI wanted to compile Qt Creator 1.3 from their repository. I cloned it with \ngit clone and then issued git checkout origin/1.3.0-beta. First there came a \nthe warning and I was not sure whether the checkout succeeded at all. I had \nto ask in the IRC channel whether the checkout was ok.\n\nBut then I was not able to verify that the checkout indeed matched the \n1.3.0-beta.  \"git status\" and \"git branch\" did not help here. \n\nHaving an improved \"git branch\" would help a lot, especially if one returns \nsome weeks later to the directory and wants to know what the checkout is.\n\nChristoph\n"},{"id":"125228","messageId":"BLU0-SMTP840FB343954FC20ACA699CAEC30@phx.gbl","threadId":"21236","inReplyTo":"alpine.DEB.1.00.0910160357370.4985@pacific.mpi-cbg.de","subject":"Re: [PATCH] Proof-of-concept patch to remember what the detached HEAD was","fromName":"Sean Estabrooks","fromEmail":"seanlkml@sympatico.ca","sentAt":"2009-10-17T07:24:17Z","receivedAt":"2009-10-17T07:24:17Z","isPatch":true,"sender":{"key":"seanlkml@sympatico.ca","avatar":"https://gravatar.com/avatar/f92923f54fc08c401fc59b71829d4b89e9b8087fbba45ff87c82e6a83aee02ae?d=mp&s=160"},"body":"On Fri, 16 Oct 2009 04:07:23 +0200 (CEST)\nJohannes Schindelin <Johannes.Schindelin@gmx.de> wrote:\n\n> Just recently, I had a user request (a very valid one, mind you) where the \n> user does not want to provide a commit message, and wants to just commit \n> all the current changes.  In that particular case, it is very sensible to \n> ask for these things.  It is something utterly simple to ask for. Yet, it \n> is utterly hard with Git, especially if I have to explain it.\n\nHey Johannes,\n\nIt's actually easy, but maybe hard to find:\n\n\t$ git commit --cleanup=verbatim -m \"\"\n\nCheers,\nSean\n"},{"id":"125229","messageId":"7vr5t2h3do.fsf@alter.siamese.dyndns.org","threadId":"21236","inReplyTo":"m49nq6-uk5.ln1@burns.bruehl.pontohonk.de","subject":"Re: [PATCH] Proof-of-concept patch to remember what the detached HEAD was","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2009-10-17T07:43:31Z","receivedAt":"2009-10-17T07:43:31Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Christoph Bartoschek <bartoschek@gmx.de> writes:\n\n[jc: added Daniel back to cc list; please do not cull the cc list without\ngood reason]\n\n> Daniel Barkalow wrote:\n>\n>> The upshot of the messages should be:\n>> \n>>  $ git checkout origin/master\n>>  Since you can't actually change \"origin/master\" yourself, you'll just\n>>  be sightseeing unless you create a local branch to hold new local work.\n>> \n>>  $ git branch\n>>  * (not a local branch, but \"origin/master\")\n>> \n>>  $ git commit\n>>  You've been sightseeing \"origin/master\". The commit can't change that\n>>  value, so your commit isn't held in any branch. If you want to create\n>>  a branch to hold it, here's how.\n> ...\n> But then I was not able to verify that the checkout indeed matched the \n> 1.3.0-beta.  \"git status\" and \"git branch\" did not help here. \n\nThis is not going to help you, but \"git reflog\" would have helped here.\n\nThe reason my suggesting \"git reflog\" now won't help you is because the\nword \"reflog\" does not connect the question \"how did I get here\" unless\nand until you know git already; in other words, it is not your fault that\nyou got lost, but it is showing a wart in the UI.\n\nIf the question you were asking was \"does the files I have in my work tree\nafter issuing that scary checkout actually match origin/1.3.0-beta?\", you\ncould have asked that question in a more direct way, and the command to do\nso is \"git diff origin/1.3.0-beta\".  I do not think this would be asking\nthe user to be doing something unreasonably unintuitive.\n\nIf the question you were asking was (and it was not, from the description\nof your experience, but you could be in that situation when you \"return\nsome weeks later\") \"how does the checked out history relate to 1.3.0-beta?\",\nthen there is a way to ask the question in a very direct way, and the\ncommand to do so is \"git show-branch HEAD origin/1.3.0-beta\" (or give the\nsame argument to \"gitk\").\n\nAlthough it is not _so_ unreasonable to expect \"git status\" to show the\ninformation, I suspect it would not be practical.  After all, whenever\nsomebody is lost, everything is \"status\".  For a person who is lost and\ndoes not know where in the history he is, it might be reasonable to expect\n\"status\" to give the relationship between your HEAD and some branch/tag,\nwhile for another person who was hit by \"git gui\" complaining that he has\ntoo many loose objects, it might be reasonable for him to expect \"status\"\nto give the number of loose objects in the repository.  IOW, \"status\" is\ntoo broad a word and following the path to cram everything into \"status\"\nso that any new person who gets lost can get necessary infor from the\ncommand will unfortunately lead to insanity.\n\nThe second item in the Daniel's transcript above may be an improvement but\nI think it is a wrong economy to record and show 'but \"origin/master\"'\n(which cannot be correct forever and has to be invalidated once the user\nstarts committing or resetting) in the message.  I am wondering if a\nsimilar effect to help new users can be had by rewording the message to:\n\n    $ git branch\n    * (not a local branch; see \"git reflog\" to learn how you got here)\n\nThe user can see how he got there even after doing something else after\nthe checkout (see Nico's write-up in $gmane/130527).  The difference is\nbetween giving fish and teaching how to catch one himself.\n"},{"id":"125231","messageId":"20091017075551.GA5474@atjola.homenet","threadId":"21236","inReplyTo":"alpine.LNX.2.00.0910161821230.30589@reaper.quantumfyre.co.uk","subject":"Re: [PATCH] Proof-of-concept patch to remember what the detached HEAD was","fromName":"Björn Steinbrink","fromEmail":"b.steinbrink@gmx.de","sentAt":"2009-10-17T07:55:51Z","receivedAt":"2009-10-17T07:55:51Z","isPatch":true,"sender":{"key":"b.steinbrink@gmx.de","avatar":"https://avatars.githubusercontent.com/u/230962?v=4"},"body":"On 2009.10.16 18:31:23 +0100, Julian Phillips wrote:\n> On Fri, 16 Oct 2009, Bj?rn Steinbrink wrote:\n> >On 2009.10.16 13:15:35 +0100, Julian Phillips wrote:\n> >>How about:\n> >>\n> >>$ git checkout origin/master\n> >>$ git fetch\n> >>Refusing to fetch, as it would update a checkedout branch\n> >>\"git fetch -f\" will force the update, but you will need to run \"git\n> >>reset --hard HEAD\" to update your checkout to match.\n> >\n> >That would redefine -f (currently means \"allow non-fast-forward\n> >updates\"), the flag that allows the checked out branch head to be\n> >updated is -u, --update-head-ok, and is for internal use only.\n> >\n> >And suggesting \"reset --hard\" seems wrong, that just kills any\n> >uncommitted changes.\n> \n> Ok, so the commands were wrong.  Not important.\n> \n> It was the approach that I was trying to suggest rather than the\n> actual commands.  The point I was trying to make was how, as a user,\n> I would be happy to git behave.\n\nYour approach explicitly included \"mess up the index/worktree state\",\notherwise, \"git fetch\" would not have to tell the user that he has to do\na \"git reset --hard HEAD\". I honestly can't believe that you would be\nhappy with git messing up your work.\n\n> So, I try to run fetch, git says \"ooh, now that would be dangerous -\n> you can force it happen by running \"git foo\", but you will then be\n> in situation X, which you can then recover from by running \"git\n> bar\", though you may need to run \"git stash\" to save any edits you\n> have made\" or something similar.\n\nBut why make \"git fetch\" with non-\"obscure\" refspecs dangerous to begin\nwith? If we detach but keep some extra information, there's no need to\nmake \"git fetch\" dangerous, _and_ we can still provide a command that\njust fetches the most recent version of the \"checked out\" remote\ntracking branch and checks that out. May it be another mode of operation\nfor \"git pull\" or some \"git up\" command or whatever.\n\n> >And such uncommitted changes would be lost in the big \"undo the fetch\n> >update\" diff. So you'd have to do:\n> >git reset --soft HEAD@{1}\n> >git checkout --merge HEAD@{1}\n> >\n> >to keep them, while updating to the new state of the remote tracking\n> >branch. Not quite intuitive, is it?\n> \n> I don't care what git has to do, I'm talking about the user\n> experience - if we have to write some new code to support it, that\n> really isn't a terribly hard thing to do.  UIs should be driven down\n> from the user interaction not up from the implementation.\n\nThose commands are those that git would have to show to you, instead of\n\"git reset --hard HEAD\", i.e. they're what you, as the user, have to do.\nAnd while \"git reset --hard HEAD\" might be remotely understandable to\nthe user, that command sequence is very unlikely to be understood by\nmost. And providing a command that does just this sequence is insane,\nit's just a bandaid for git doing crap to your worktree/index state. So\nlet's better not start with git doing that crap at all.\n\nMy current \"idea\" (I don't think I'll have time to implement that any\ntime soon) is:\n\nKeep some extra information in HEAD (or somewhere else) when HEAD is\ndetached about the ref that HEAD is \"weakly\" bound to. For example, \"git\ncheckout origin/master\" might create a weak binding to\nrefs/remotes/origin/master (for other [corner] cases, see the other\nmail I wrote, in which I outlined some cases I considered interesting).\n\n\"git update\" can use the branch.<name>.{remote,merge} setup, or\nalternatively the \"weak binding\" information, to fetch from the right\nremote, and checks whether a fast-forward of HEAD to the according\nupstream branch head is possible. If so, it does a \"git checkout --merge\n<upstream>\" (possibly leaving conflicts for the uncommitted changes,\njust like \"svn update\"). If a fast-forward is not possible, it\ncomplains, telling the user that he needs to use \"git merge/rebase/pull\"\ninstead, and might want to create a branch head, in case of a detached\nHEAD.\n\nIf there's also going to be a rule that forbids commits on some kind of\ndetached HEAD, than the command could also tell the user (when a\nfast-forward is not possible) that upstream possibly rewrote history,\nand that the user might want to use \"git checkout --merge <upstream>\"\n(or maybe \"git update -f\"?) to just go to the new upstream version (not\nsure if that hint should be shown in addition to or instead of the \"git\nmerge/rebase/pull\" hint).\n\nBjörn\n"},{"id":"125232","messageId":"7vws2ue8yc.fsf@alter.siamese.dyndns.org","threadId":"21236","inReplyTo":"20091017075551.GA5474@atjola.homenet","subject":"Re: [PATCH] Proof-of-concept patch to remember what the detached HEAD was","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2009-10-17T08:11:23Z","receivedAt":"2009-10-17T08:11:23Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Björn Steinbrink <B.Steinbrink@gmx.de> writes:\n\n> ... If so, it does a \"git checkout --merge\n> <upstream>\" (possibly leaving conflicts for the uncommitted changes,\n> just like \"svn update\").\n\nUp to this point I was reading with quite a lot of interest.  But here I\nstrongly disagree to the point of getting actually disgusted.\n\n\"svn up\" is one of the areas Subversion folks failed to make their system\na better CVS.  It has the same \"local changes are lost in the merge\nconflict mess in an irreversible way\" failure mode, and we shouldn't be\nmaking it easy to new people.  It is not something we should emulate.\n\nYou can and should instead refuse the update, and suggest committing first\nso that the user has a safe record of what he has done and the merge with\nupstream can be retried if necessary.  As you need to have that \"refuse\nbut guide the lost soul by telling what to do\" mode anyway when...\n\n> ... If a fast-forward is not possible, it\n> complains, telling the user that he needs to use \"git merge/rebase/pull\"\n> instead, and might want to create a branch head, in case of a detached\n> HEAD.\n"},{"id":"125233","messageId":"20091017081901.GB5474@atjola.homenet","threadId":"21236","inReplyTo":"7vr5t2h3do.fsf@alter.siamese.dyndns.org","subject":"Re: [PATCH] Proof-of-concept patch to remember what the detached HEAD was","fromName":"Björn Steinbrink","fromEmail":"b.steinbrink@gmx.de","sentAt":"2009-10-17T08:19:01Z","receivedAt":"2009-10-17T08:19:01Z","isPatch":true,"sender":{"key":"b.steinbrink@gmx.de","avatar":"https://avatars.githubusercontent.com/u/230962?v=4"},"body":"On 2009.10.17 00:43:31 -0700, Junio C Hamano wrote:\n> Christoph Bartoschek <bartoschek@gmx.de> writes:\n> > Daniel Barkalow wrote:\n> >\n> >> The upshot of the messages should be:\n> >> \n> >>  $ git checkout origin/master\n> >>  Since you can't actually change \"origin/master\" yourself, you'll just\n> >>  be sightseeing unless you create a local branch to hold new local work.\n> >> \n> >>  $ git branch\n> >>  * (not a local branch, but \"origin/master\")\n> >> \n> >>  $ git commit\n> >>  You've been sightseeing \"origin/master\". The commit can't change that\n> >>  value, so your commit isn't held in any branch. If you want to create\n> >>  a branch to hold it, here's how.\n\n[...]\n\n> The second item in the Daniel's transcript above may be an improvement but\n> I think it is a wrong economy to record and show 'but \"origin/master\"'\n> (which cannot be correct forever and has to be invalidated once the user\n> starts committing or resetting) in the message.\n\nI don't think it's entirely wrong to record that information, git just\nhas to know when to invalidate it, possibly requiring the user to really\ndetach HEAD.\n\ngit checkout origin/master\ngit checkout origin/master~3\ngit checkout HEAD^2~5\ngit reset --hard HEAD~2\n\nThose commands are all about walking the ancestry of origin/master in\nsome way. So it seems reasonable to assume that HEAD is still weakly\nbound to origin/master. And based upon that, there could be something\nlike \"git update\", and things like \"git status\" could show that you're\nbrowsing through the ancestry of origin/master, and that \"git commit\"\nmessage could maybe say \"You've been sightseeing 'origin/master'\n[currently at 'origin/master~3^2~7'] ...\".\n\n> I am wondering if a similar effect to help new users can be had by\n> rewording the message to:\n> \n>     $ git branch\n>     * (not a local branch; see \"git reflog\" to learn how you got here)\n> \n> The user can see how he got there even after doing something else after\n> the checkout (see Nico's write-up in $gmane/130527).  The difference is\n> between giving fish and teaching how to catch one himself.\n\nThat could be used when the user actively detached HEAD, invalidating\nthe \"weak binding\". Maybe implicitly by \"git commit\" or \n\"git reset <something_we_can't_keep_track_of>\", or maybe explicitly,\nif committing on a \"semi-detached HEAD\" becomes forbidden.\n\nOr maybe it could always be shown, in addition to \"You are here\", you\nalso get told \"Do this to find out how you got there\". Does seem like a\ngood idea.\n\nBjörn\n"},{"id":"125234","messageId":"20091017084025.GC5474@atjola.homenet","threadId":"21236","inReplyTo":"7vws2ue8yc.fsf@alter.siamese.dyndns.org","subject":"Re: [PATCH] Proof-of-concept patch to remember what the detached HEAD was","fromName":"Björn Steinbrink","fromEmail":"b.steinbrink@gmx.de","sentAt":"2009-10-17T08:40:25Z","receivedAt":"2009-10-17T08:40:25Z","isPatch":true,"sender":{"key":"b.steinbrink@gmx.de","avatar":"https://avatars.githubusercontent.com/u/230962?v=4"},"body":"On 2009.10.17 01:11:23 -0700, Junio C Hamano wrote:\n> Björn Steinbrink <B.Steinbrink@gmx.de> writes:\n> \n> > ... If so, it does a \"git checkout --merge\n> > <upstream>\" (possibly leaving conflicts for the uncommitted changes,\n> > just like \"svn update\").\n> \n> Up to this point I was reading with quite a lot of interest.  But here I\n> strongly disagree to the point of getting actually disgusted.\n> \n> \"svn up\" is one of the areas Subversion folks failed to make their system\n> a better CVS.  It has the same \"local changes are lost in the merge\n> conflict mess in an irreversible way\" failure mode, and we shouldn't be\n> making it easy to new people.  It is not something we should emulate.\n> \n> You can and should instead refuse the update, and suggest committing first\n> so that the user has a safe record of what he has done and the merge with\n> upstream can be retried if necessary.  As you need to have that \"refuse\n> but guide the lost soul by telling what to do\" mode anyway when...\n\nHm, probably I (mentally) focussed to much on \"people that just want to\nlook\" and didn't really think that they'd have much to lose. Not sure.\nOver the time, I got so used to do \"git checkout --merge <something>\"\nwith some I-don't-care-much debugging or whatever change, that I lost\ntrack of how bad that was with svn. If I have just I care about, I\ncommit, and then \"git update\" would no longer be an option anyway. But\nyeah, not a good option to give to the uninitiated user...\n\nInterestingly, I irregularly give advice to use \"git stash; git\ncheckout; git stash apply\" instead of \"git checkout -m\" on #git, as that\nallows you to try again if you messed up the conflict resolution, and\neven allows you to completely go back to the initial state. Maybe that\nwould be an option? But I fail to come up with a convenient and at the\nsame time error safe way for such a \"stash wrap\". The only thing that\ncomes to mind would be to have \"git update\" completely wrapping the\nthing:\n\ngit update\n - Stashes uncommitted changes\n - fetches\n - checks out\n - \"stash apply --index\", if that fails, just \"stash apply\"\n\nIf there are conflicts, show options (similar to what rebase does):\n\ngit update --retry # Start over\n - reset --hard\n - \"stash apply --index\", if that fails, just \"stash apply\"\n\ngit update --abort\n - git reset --hard HEAD@{1}\n - \"stash apply --index\"\n - \"stash drop stash@{0}\"\n\ngit update --done\n - Check whether there are still unmerged files, if so: complain\n - otherwise: \"stash drop stash@{0}\"\n\n\nOTOH, it might be easier to just tell the user to do the stash thing\nhimself. But I wonder how many users would really know how to get back\nto the initial state then.\n\nBjörn\n"},{"id":"125235","messageId":"7vaazqcry5.fsf@alter.siamese.dyndns.org","threadId":"21236","inReplyTo":"20091017084025.GC5474@atjola.homenet","subject":"Re: [PATCH] Proof-of-concept patch to remember what the detached HEAD was","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2009-10-17T09:04:02Z","receivedAt":"2009-10-17T09:04:02Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Björn Steinbrink <B.Steinbrink@gmx.de> writes:\n\n> Interestingly, I irregularly give advice to use \"git stash; git\n> checkout; git stash apply\" instead of \"git checkout -m\" on #git, as that\n> allows you to try again if you messed up the conflict resolution, and\n> even allows you to completely go back to the initial state. Maybe that\n> would be an option?\n\nAs I already said many times (here and elsewhere), \"up\" is an inferior and\nmore dangerous model we would be better off not following if we can.\n\nIt is not even entirely CVS/SVN's fault that their \"scm up\" is an error\nprone operation.  They use a centralized model, in which there is _no_ way\nto record your local modification and run a retryable merge, so they have\nan excuse to force users to do things in \"work, then update without\nrecording wip anywhere\" order.\n\nYou can afford to (and it is even more natural to) do things in \"work,\nsave and then merge\" order with git.  I simply cannot believe people who\nadvocate for helping uninitiated would even think of modelling any \"user\nfriendliness\" features around \"up\" model.\n\nThe \"save\" part of the work-save-then-merge sequence should be made very\nvisible to help people get used to the \"not up, but work-save-then-merge\"\nmental model.  I do not think it would help people in the long run to make\nthe \"save\" step less visible by wrapping the sequence into an unreliable\n\"up\" script, especially because the script would sometimes work but other\ntimes *has to* force users to know that what is happening behind the scene\nis work-save-then-merge in order to resolve and recover from conflicts\nanyway.\n\n> OTOH, it might be easier to just tell the user to do the stash thing\n> himself. But I wonder how many users would really know how to get back\n> to the initial state then.\n\nI agree with the first sentence, but I do not understand what \"the initial\nstate\" you talk about here in the second sentence, sorry.\n"},{"id":"125239","messageId":"alpine.LNX.2.00.0910171557290.6644@reaper.quantumfyre.co.uk","threadId":"21236","inReplyTo":"20091017075551.GA5474@atjola.homenet","subject":"Re: [PATCH] Proof-of-concept patch to remember what the detached HEAD was","fromName":"Julian Phillips","fromEmail":"julian@quantumfyre.co.uk","sentAt":"2009-10-17T15:02:26Z","receivedAt":"2009-10-17T15:02:26Z","isPatch":true,"sender":{"key":"julian@quantumfyre.co.uk","avatar":"https://avatars.githubusercontent.com/u/948888?v=4"},"body":"On Sat, 17 Oct 2009, Bj?rn Steinbrink wrote:\n\n> On 2009.10.16 18:31:23 +0100, Julian Phillips wrote:\n>> On Fri, 16 Oct 2009, Bj?rn Steinbrink wrote:\n>>> On 2009.10.16 13:15:35 +0100, Julian Phillips wrote:\n>>>> How about:\n>>>>\n>>>> $ git checkout origin/master\n>>>> $ git fetch\n>>>> Refusing to fetch, as it would update a checkedout branch\n>>>> \"git fetch -f\" will force the update, but you will need to run \"git\n>>>> reset --hard HEAD\" to update your checkout to match.\n>>>\n>>> That would redefine -f (currently means \"allow non-fast-forward\n>>> updates\"), the flag that allows the checked out branch head to be\n>>> updated is -u, --update-head-ok, and is for internal use only.\n>>>\n>>> And suggesting \"reset --hard\" seems wrong, that just kills any\n>>> uncommitted changes.\n>>\n>> Ok, so the commands were wrong.  Not important.\n>>\n>> It was the approach that I was trying to suggest rather than the\n>> actual commands.  The point I was trying to make was how, as a user,\n>> I would be happy to git behave.\n>\n> Your approach explicitly included \"mess up the index/worktree state\",\n> otherwise, \"git fetch\" would not have to tell the user that he has to do\n> a \"git reset --hard HEAD\". I honestly can't believe that you would be\n> happy with git messing up your work.\n>\n>> So, I try to run fetch, git says \"ooh, now that would be dangerous -\n>> you can force it happen by running \"git foo\", but you will then be\n>> in situation X, which you can then recover from by running \"git\n>> bar\", though you may need to run \"git stash\" to save any edits you\n>> have made\" or something similar.\n>\n> But why make \"git fetch\" with non-\"obscure\" refspecs dangerous to begin\n> with? If we detach but keep some extra information, there's no need to\n> make \"git fetch\" dangerous, _and_ we can still provide a command that\n> just fetches the most recent version of the \"checked out\" remote\n> tracking branch and checks that out. May it be another mode of operation\n> for \"git pull\" or some \"git up\" command or whatever.\n\nMy entire argument was in the context of the mail that I orginally replied \nto, i.e. assuming that the decision to not detach had been taken.  If that \nis not the case, then everything I had said is irrelevant.\n\nI wasn't arguing against detaching, but rather trying to say that _if_ we \nare not going to detach then I think it would better like this than that. \nI don't personally have any input on the detach or not, as I have been \nusing git for too long to know if detaching is a problem for others.  I \ncan tell from my bash prompt if I'm detached or on a branch - and that's \nfine for me.\n\n-- \nJulian\n\n  ---\nWedding is destiny, and hanging likewise.\n \t\t-- John Heywood\n"},{"id":"125241","messageId":"alpine.LNX.2.00.0910171606180.6644@reaper.quantumfyre.co.uk","threadId":"21236","inReplyTo":"alpine.LFD.2.00.0910161557500.20122@xanadu.home","subject":"Re: [PATCH] Proof-of-concept patch to remember what the detached HEAD was","fromName":"Julian Phillips","fromEmail":"julian@quantumfyre.co.uk","sentAt":"2009-10-17T15:15:13Z","receivedAt":"2009-10-17T15:15:13Z","isPatch":true,"sender":{"key":"julian@quantumfyre.co.uk","avatar":"https://avatars.githubusercontent.com/u/948888?v=4"},"body":"On Fri, 16 Oct 2009, Nicolas Pitre wrote:\n\n> On Fri, 16 Oct 2009, Julian Phillips wrote:\n>\n>> My interest in this thread is solely that it might provide a mechanism to find\n>> out which tag was checked out.  So, I'm just chucking in my $0.02 as a user.\n>\n> Try this:\n>\n> $ git checkout v1.5.5\n> Note: moving to 'v1.5.5' which isn't a local branch\n> If you want to create a new branch from this checkout, you may do so\n> (now or later) by using -b with the checkout command again. Example:\n>  git checkout -b <new_branch_name>\n> HEAD is now at 1d2375d... GIT 1.5.5\n>\n> [look around, and then ...]\n>\n> $ git checkout HEAD~2\n> Previous HEAD position was 1d2375d... GIT 1.5.5\n> HEAD is now at f61cc48... git-svn: fix following renamed paths when tracking a single path\n>\n> [go out for lunch ... and forget what this was about.]\n>\n> $ git reflog -3\n> f61cc48 HEAD@{0}: checkout: moving from 1d2375d... to HEAD~2\n> 1d2375d HEAD@{1}: checkout: moving from master to v1.5.5\n> c274db7 HEAD@{2}: pull : Fast forward\n>\n> Here I have all the information to see what I did, and from what state.\n> I even know that I did a pull on the master branch before moving away\n> from it.  The -3 limits the log to 3 entries.  With no limit you get it\n> all in your default pager.\n>\n> So there is no need for another mechanism to find out what tag was\n> actually checked out -- you have it all already.\n\nWhat I want is a way for my build process to reliably know what branch or \ntag is currently being built.  \"git symbolic-ref HEAD\" will give me the \nbranch name, but doesn't work for tags.  \"git describe\" will find _a_ tag, \nbut I can't tell if it's actually the one checked out.\n\nUsing the reflog isn't something that had occured to me, but it seems a \nbit ... uncontrolled ... for a script.  I'd rather have a plumbing level \ncommand that just told me what I had actually checked out.  Though I may \nwell look into using the reflog until such a command is available (or I \nfind out there already is one).\n\n-- \nJulian\n\n  ---\nI doubt, therefore I might be.\n"},{"id":"125242","messageId":"alpine.LNX.2.00.0910171617580.6644@reaper.quantumfyre.co.uk","threadId":"21236","inReplyTo":"7vk4yvt7kp.fsf@alter.siamese.dyndns.org","subject":"Re: [PATCH] Proof-of-concept patch to remember what the detached HEAD was","fromName":"Julian Phillips","fromEmail":"julian@quantumfyre.co.uk","sentAt":"2009-10-17T15:32:14Z","receivedAt":"2009-10-17T15:32:14Z","isPatch":true,"sender":{"key":"julian@quantumfyre.co.uk","avatar":"https://avatars.githubusercontent.com/u/948888?v=4"},"body":"On Fri, 16 Oct 2009, Junio C Hamano wrote:\n\n> Julian Phillips <julian@quantumfyre.co.uk> writes:\n>\n>> On Fri, 16 Oct 2009, Junio C Hamano wrote:\n>>\n>>> Julian Phillips <julian@quantumfyre.co.uk> writes:\n>>> ...\n>>>> I don't care what git has to do, I'm talking about the user experience\n>>>\n>>> But Bj?rn is showing two commands the _user_ has to type, iow, the comment\n>>> is about the user experience.\n>>\n>> Only Currently.  My point was that _if_ we wanted to support this sort\n>> of thing, then we can make is simpler to do by providing a simple\n>> command for the user.\n>>\n>> The point I wanted to make was that the decision on what to do should\n>> be driven by the user's experience - not by the fact that it is easier\n>> to implement something else.\n>\n> Sorry, but I do not see in what way what you said in the thread connects\n> to the above three lines.  Are you talking about this one from you a few\n> messages back?\n>\n>    How about:\n>\n>    $ git checkout origin/master\n>    $ git fetch\n>    Refusing to fetch, as it would update a checkedout branch\n>    \"git fetch -f\" will force the update, but you will need to run \"git\n>    reset --hard HEAD\" to update your checkout to match.\n>\n> I am not seeing \"not the implementation ease but the user experience\"\n> drive in this suggestion.  If you are driving from the user experience\n> point of view, I would have instead suggested:\n>\n>    How about:\n>\n>    $ git checkout origin/master\n>    $ git fetch\n>\n>    and fetch happily updates the tracked branch, without affecting the\n>    HEAD state (nor index nor the work tree, of course).\n\nTrue.  I was saying that having git stop and explain things is better than \nmaking a mess for the user to clear up.  Having it just work would of \ncourse be even better.  Hoist by my own petard indead ...\n\n>> My interest in this thread is solely that it might provide a mechanism\n>> to find out which tag was checked out.\n>\n> Hmm, what is lacking in \"git describe HEAD\" for that?  I am not\n> complaining that you might be asking for something that exists, but I _do_\n> want to know if something that exists is not a satisfactory solution and\n> if so how it can be improved.\n\nWhat is lacking is the \"checked out\" part.  \"git describe HEAD\" will tell \nme _a_ tag that matches the currently checked out state.  However, it \nmakes no guarantee that it was the one I checked out.  If I tag the code \nwith \"v1.0.0\", and a colleague later tags it with \"this_version_sucks\", \nthen when I check out and build the code for the customer the version it \nreports could well be \"this_version_sucks\" instead of \"v1.0.0\" ...\n\nNicolas Pitre suggested using the reflog, which does seem to include the \ninformation that I want, but I feel a little uneasy about accessing it via \na script - how certain is it that the format of the message won't change? \nIs accessing the reflog the sort of thing people expect as part of the \nscripting interface?\n\n-- \nJulian\n\n  ---\nThose who would repeat the past must control the teaching of history.\n\n   -- Bene Gesserit Coda\n"},{"id":"125246","messageId":"20091017170421.GA10490@atjola.homenet","threadId":"21236","inReplyTo":"alpine.LNX.2.00.0910171606180.6644@reaper.quantumfyre.co.uk","subject":"Re: [PATCH] Proof-of-concept patch to remember what the detached HEAD was","fromName":"Björn Steinbrink","fromEmail":"b.steinbrink@gmx.de","sentAt":"2009-10-17T17:04:21Z","receivedAt":"2009-10-17T17:04:21Z","isPatch":true,"sender":{"key":"b.steinbrink@gmx.de","avatar":"https://avatars.githubusercontent.com/u/230962?v=4"},"body":"On 2009.10.17 16:15:13 +0100, Julian Phillips wrote:\n> On Fri, 16 Oct 2009, Nicolas Pitre wrote:\n> \n> >On Fri, 16 Oct 2009, Julian Phillips wrote:\n> >\n> >>My interest in this thread is solely that it might provide a mechanism to find\n> >>out which tag was checked out.  So, I'm just chucking in my $0.02 as a user.\n> >\n> >Try this:\n> >\n> >$ git checkout v1.5.5\n> >Note: moving to 'v1.5.5' which isn't a local branch\n> >If you want to create a new branch from this checkout, you may do so\n> >(now or later) by using -b with the checkout command again. Example:\n> > git checkout -b <new_branch_name>\n> >HEAD is now at 1d2375d... GIT 1.5.5\n> >\n> >[look around, and then ...]\n> >\n> >$ git checkout HEAD~2\n> >Previous HEAD position was 1d2375d... GIT 1.5.5\n> >HEAD is now at f61cc48... git-svn: fix following renamed paths when tracking a single path\n> >\n> >[go out for lunch ... and forget what this was about.]\n> >\n> >$ git reflog -3\n> >f61cc48 HEAD@{0}: checkout: moving from 1d2375d... to HEAD~2\n> >1d2375d HEAD@{1}: checkout: moving from master to v1.5.5\n> >c274db7 HEAD@{2}: pull : Fast forward\n> >\n> >Here I have all the information to see what I did, and from what state.\n> >I even know that I did a pull on the master branch before moving away\n> >from it.  The -3 limits the log to 3 entries.  With no limit you get it\n> >all in your default pager.\n> >\n> >So there is no need for another mechanism to find out what tag was\n> >actually checked out -- you have it all already.\n> \n> What I want is a way for my build process to reliably know what\n> branch or tag is currently being built.  \"git symbolic-ref HEAD\"\n> will give me the branch name, but doesn't work for tags.  \"git\n> describe\" will find _a_ tag, but I can't tell if it's actually the\n> one checked out.\n\nDo you have multiple (annotated) tags for the same commit? Otherwise, I\ndon't see why \"git describe HEAD\" should print the wrong one. If there's\na tag that can be resolved to the same commit that HEAD can be resolved,\nthen \"git describe HEAD\" must output that one. Otherwise, that'd be a\nclear bug to me.\n\nBjörn\n"},{"id":"125248","messageId":"885649360910171007p1115b4afq11d1755a2a46be4a@mail.gmail.com","threadId":"21236","inReplyTo":"7vaazqcry5.fsf@alter.siamese.dyndns.org","subject":"Re: [PATCH] Proof-of-concept patch to remember what the detached HEAD was","fromName":"James Pickens","fromEmail":"jepicken@gmail.com","sentAt":"2009-10-17T17:07:58Z","receivedAt":"2009-10-17T17:07:58Z","isPatch":true,"sender":{"key":"jepicken@gmail.com","avatar":null},"body":"On Sat, Oct 17, 2009, Junio C Hamano <gitster@pobox.com> wrote:\n> As I already said many times (here and elsewhere), \"up\" is an inferior and\n> more dangerous model we would be better off not following if we can.\n\nI agree that the \"up\" model is inferior, but I have to say, \"up\" is one of the\nmost common things my users ask about.  It is very common for users to have some\nwork in progress that they aren't ready to commit, and they want to get up to\ndate with the latest code from the central repository.  Most of the time, they\nhaven't modified any files that have also been modified upstream, so all they\nneed is \"git pull\".  But once in a while, they will have modified the same file,\nand the pull will be rejected, and they don't know what to do.\n\nThese are not sophisticated users, so telling them to commit first, then pull,\nand rebase later on to clean up the history (since the work they committed\nwasn't finished) is no good.  They don't care to preserve their exact state and\njust want to get up to date with the central repo.\n\nIf they ask me what to do, I tell them that if they're ready to commit, do so,\notherwise use 'git stash; git pull; git stash pop'.  To a typical user, this\nlooks like Git is inferior since it requires 3 commands to do what only takes 1\ncommand in CVS/SVN.  One of my users didn't ask, and I later found out that he\nhad been doing this:\n\n$ git pull ;# rejected due to modifications in file1\n$ mv file1 file1.bak\n$ git checkout HEAD file1\n$ git pull ;# rejected due to modifications in file2\n$ mv file2 file2.bak\n$ git checkout HEAD file2\n$ git pull ;# ok\n<manually merge file1.bak with file1>\n<manually merge file2.bak with file2>\n\nSo I think an \"scm up\" like command is not an unreasonable thing to want.  There\nis a valid, and fairly common, use case.  There are ways to get the same result\nin Git, but they're cumbersome compared to just typing \"scm up\".  It shouldn't\nbe the default, but I think a lot of users would appreciate having it.\n\nJames\n"},{"id":"125251","messageId":"alpine.LNX.2.00.0910171829430.7906@reaper.quantumfyre.co.uk","threadId":"21236","inReplyTo":"20091017170421.GA10490@atjola.homenet","subject":"Re: [PATCH] Proof-of-concept patch to remember what the detached HEAD was","fromName":"Julian Phillips","fromEmail":"julian@quantumfyre.co.uk","sentAt":"2009-10-17T17:35:38Z","receivedAt":"2009-10-17T17:35:38Z","isPatch":true,"sender":{"key":"julian@quantumfyre.co.uk","avatar":"https://avatars.githubusercontent.com/u/948888?v=4"},"body":"On Sat, 17 Oct 2009, Bj?rn Steinbrink wrote:\n\n> On 2009.10.17 16:15:13 +0100, Julian Phillips wrote:\n>> On Fri, 16 Oct 2009, Nicolas Pitre wrote:\n>>\n>>> On Fri, 16 Oct 2009, Julian Phillips wrote:\n>>>\n>>>> My interest in this thread is solely that it might provide a mechanism to find\n>>>> out which tag was checked out.  So, I'm just chucking in my $0.02 as a user.\n>>>\n>>> Try this:\n>>>\n>>> $ git checkout v1.5.5\n>>> Note: moving to 'v1.5.5' which isn't a local branch\n>>> If you want to create a new branch from this checkout, you may do so\n>>> (now or later) by using -b with the checkout command again. Example:\n>>> git checkout -b <new_branch_name>\n>>> HEAD is now at 1d2375d... GIT 1.5.5\n>>>\n>>> [look around, and then ...]\n>>>\n>>> $ git checkout HEAD~2\n>>> Previous HEAD position was 1d2375d... GIT 1.5.5\n>>> HEAD is now at f61cc48... git-svn: fix following renamed paths when tracking a single path\n>>>\n>>> [go out for lunch ... and forget what this was about.]\n>>>\n>>> $ git reflog -3\n>>> f61cc48 HEAD@{0}: checkout: moving from 1d2375d... to HEAD~2\n>>> 1d2375d HEAD@{1}: checkout: moving from master to v1.5.5\n>>> c274db7 HEAD@{2}: pull : Fast forward\n>>>\n>>> Here I have all the information to see what I did, and from what state.\n>>> I even know that I did a pull on the master branch before moving away\n>>> from it.  The -3 limits the log to 3 entries.  With no limit you get it\n>>> all in your default pager.\n>>>\n>>> So there is no need for another mechanism to find out what tag was\n>>> actually checked out -- you have it all already.\n>>\n>> What I want is a way for my build process to reliably know what\n>> branch or tag is currently being built.  \"git symbolic-ref HEAD\"\n>> will give me the branch name, but doesn't work for tags.  \"git\n>> describe\" will find _a_ tag, but I can't tell if it's actually the\n>> one checked out.\n>\n> Do you have multiple (annotated) tags for the same commit?\n\nPotentially, yes.  Releasing isn't the only thing that requires keeping \ntrack of things.  It's even possible that the person creating the newer \ntag doesn't yet know that a release tag has been applied if the person \nwho applied it hasn't yet pushed it back.\n\n> Otherwise, I don't see why \"git describe HEAD\" should print the wrong \n> one. If there's a tag that can be resolved to the same commit that HEAD \n> can be resolved, then \"git describe HEAD\" must output that one. \n> Otherwise, that'd be a clear bug to me.\n\nOh, definately no bug.  git describe works exactly as expected, the \nproblem is that the tag checked out isn't always the latest tag applied to \nthat commit.\n\n-- \nJulian\n\n  ---\nJayne: Shee-nio high tech Alliance crap!\"\n \t\t\t\t--Episode #9, \"Ariel\"\n"},{"id":"125252","messageId":"7vr5t17w82.fsf@alter.siamese.dyndns.org","threadId":"21236","inReplyTo":"20091017081901.GB5474@atjola.homenet","subject":"Re: [PATCH] Proof-of-concept patch to remember what the detached HEAD was","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2009-10-17T17:42:53Z","receivedAt":"2009-10-17T17:42:53Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Björn Steinbrink <B.Steinbrink@gmx.de> writes:\n\n> On 2009.10.17 00:43:31 -0700, Junio C Hamano wrote:\n>> Christoph Bartoschek <bartoschek@gmx.de> writes:\n>> > Daniel Barkalow wrote:\n>> >\n>> >> The upshot of the messages should be:\n>> >> \n>> >>  $ git checkout origin/master\n>> >>  Since you can't actually change \"origin/master\" yourself, you'll just\n>> >>  be sightseeing unless you create a local branch to hold new local work.\n>> >> \n>> >>  $ git branch\n>> >>  * (not a local branch, but \"origin/master\")\n>> >> \n>> >>  $ git commit\n>> >>  You've been sightseeing \"origin/master\". The commit can't change that\n>> >>  value, so your commit isn't held in any branch. If you want to create\n>> >>  a branch to hold it, here's how.\n>\n> [...]\n>\n>> The second item in the Daniel's transcript above may be an improvement but\n>> I think it is a wrong economy to record and show 'but \"origin/master\"'\n>> (which cannot be correct forever and has to be invalidated once the user\n>> starts committing or resetting) in the message.\n>\n> I don't think it's entirely wrong to record that information, git just\n> has to know when to invalidate it, possibly requiring the user to really\n> detach HEAD.\n\nIsn't it redundant information to begin with?  See $gmane/130527\n\n> git checkout origin/master\n> git checkout origin/master~3\n> git checkout HEAD^2~5\n> git reset --hard HEAD~2\n>\n> Those commands are all about walking the ancestry of origin/master in\n> some way. So it seems reasonable to assume that HEAD is still weakly\n> bound to origin/master.\n\nBut as \"walking\" gets longer, the information will become less and less\nrelevant and at some point it becomes misleading.  I cannot explain why\n\"let's take pains to maintain and carefully invalidate an extra piece of\nredundant information so that we can show information the end user\nshouldn't be trained to trust to begin with because it is unreliable\" is a\ngood idea.\n"},{"id":"125253","messageId":"7vljj97w7u.fsf@alter.siamese.dyndns.org","threadId":"21236","inReplyTo":"alpine.LNX.2.00.0910171617580.6644@reaper.quantumfyre.co.uk","subject":"Re: [PATCH] Proof-of-concept patch to remember what the detached HEAD was","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2009-10-17T17:43:01Z","receivedAt":"2009-10-17T17:43:01Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Julian Phillips <julian@quantumfyre.co.uk> writes:\n\n>>> My interest in this thread is solely that it might provide a mechanism\n>>> to find out which tag was checked out.\n>>\n>> Hmm, what is lacking in \"git describe HEAD\" for that?  I am not\n>> complaining that you might be asking for something that exists, but I _do_\n>> want to know if something that exists is not a satisfactory solution and\n>> if so how it can be improved.\n>\n> What is lacking is the \"checked out\" part.  \"git describe HEAD\" will\n> tell me _a_ tag that matches the currently checked out state.\n> However, it makes no guarantee that it was the one I checked out.  If\n> I tag the code with \"v1.0.0\", and a colleague later tags it with\n> \"this_version_sucks\", then when I check out and build the code for the\n> customer the version it reports could well be \"this_version_sucks\"\n> instead of \"v1.0.0\" ...\n\nI think I understand why you think showing what you gave to your last \"git\ncheckout\" (e.g. \"checkout origin/master\" or \"checkout v1.0.0\") and using\nthat as a build identification token is a good idea.  But \"origin/master\"\nis a moving target---it depends on when you checked it out.  describe uses\ntags and does not use branch heads for a good reason.\n\n\"v1.0.0\" also is to a lessor degree, as you may have tagged v1.0.0 locally\nand somebody else also has used the tag for a different version, but a tag\nis far less likely to move due to social convention.  \"describe --long\"\nwould make sure this won't be an issue anyway, though.\n"},{"id":"125254","messageId":"20091017174843.GA16251@atjola.homenet","threadId":"21236","inReplyTo":"alpine.LNX.2.00.0910171829430.7906@reaper.quantumfyre.co.uk","subject":"Re: [PATCH] Proof-of-concept patch to remember what the detached HEAD was","fromName":"Björn Steinbrink","fromEmail":"b.steinbrink@gmx.de","sentAt":"2009-10-17T17:48:43Z","receivedAt":"2009-10-17T17:48:43Z","isPatch":true,"sender":{"key":"b.steinbrink@gmx.de","avatar":"https://avatars.githubusercontent.com/u/230962?v=4"},"body":"On 2009.10.17 18:35:38 +0100, Julian Phillips wrote:\n> On Sat, 17 Oct 2009, Bj?rn Steinbrink wrote:\n> >Do you have multiple (annotated) tags for the same commit?\n> \n> Potentially, yes.  Releasing isn't the only thing that requires\n> keeping track of things.  It's even possible that the person\n> creating the newer tag doesn't yet know that a release tag has been\n> applied if the person who applied it hasn't yet pushed it back.\n\nOK, I'd consider that namespace pollution, as things like\n\"this-version-sucks\" doesn't seem like it show go into public repos, but\nanyway. If your release tags fix into a certain \"unique\" format, you\ncould use describe with --match, like:\ngit describe --match 'v[0-9]*'\n\n> >Otherwise, I don't see why \"git describe HEAD\" should print the\n> >wrong one. If there's a tag that can be resolved to the same\n> >commit that HEAD can be resolved, then \"git describe HEAD\" must\n> >output that one. Otherwise, that'd be a clear bug to me.\n> \n> Oh, definately no bug.  git describe works exactly as expected, the\n> problem is that the tag checked out isn't always the latest tag\n> applied to that commit.\n\nI misworded that one. Should be \"If there's only tag that can be ...\".\nIOW it was meant for \"only one tag per commit\", which is what I assumed\nto be the case.\n\nBjörn\n"},{"id":"125256","messageId":"20091017194153.GA30003@atjola.homenet","threadId":"21236","inReplyTo":"7vaazqcry5.fsf@alter.siamese.dyndns.org","subject":"Re: [PATCH] Proof-of-concept patch to remember what the detached HEAD was","fromName":"Björn Steinbrink","fromEmail":"b.steinbrink@gmx.de","sentAt":"2009-10-17T19:41:53Z","receivedAt":"2009-10-17T19:41:53Z","isPatch":true,"sender":{"key":"b.steinbrink@gmx.de","avatar":"https://avatars.githubusercontent.com/u/230962?v=4"},"body":"On 2009.10.17 02:04:02 -0700, Junio C Hamano wrote:\n> The \"save\" part of the work-save-then-merge sequence should be made very\n> visible to help people get used to the \"not up, but work-save-then-merge\"\n> mental model.  I do not think it would help people in the long run to make\n> the \"save\" step less visible by wrapping the sequence into an unreliable\n> \"up\" script, especially because the script would sometimes work but other\n> times *has to* force users to know that what is happening behind the scene\n> is work-save-then-merge in order to resolve and recover from conflicts\n> anyway.\n\nHm, which cases would that be? I basically see three cases:\n\n 1) No uncommitted changes => No problem\n 2) Uncommitted changes merge cleanly => No problem\n 3) Uncommitted changes causes conflicts =>\n   - User can resolve\n   - User can start over (git update --retry)\n   - User can give up (git update --abort)\n\nOf course the user can clearly see that some state was saved (otherwise\nyou couldn't retry or abort), but I don't see how the user is \"forced\"\nin any way, he just gets those two commands to work with (which\ninternally just wrap reset + stash apply, making things more\nconvenient).\n\nI do see problems with a \"stash around merge\" thing (\"stash\" around\nrebase seems easier, as that could just create a commit and reset later,\nbut I'm not exactly sure that such smartness is a good idea). As soon as\nthe merge has conflicts, you need to know that you have to unstash after\ncommitting the merge, but what I have in mind is fast-forward only (or\npossibly reset, when upstream was rewritten).  Primarily for users that\ndon't commit at all, but just look at things [*1*]. And also for the\nsemi-detached HEAD case, in which you may not commit and in which doing\na merge/rebase is therefore not an option, but git still knows what to\nfetch/checkout by using the discussed extra info in HEAD, or by\nexamining the reflog.\n\n> > OTOH, it might be easier to just tell the user to do the stash thing\n> > himself. But I wonder how many users would really know how to get back\n> > to the initial state then.\n> \n> I agree with the first sentence, but I do not understand what \"the initial\n> state\" you talk about here in the second sentence, sorry.\n\nThe state they were in before they did the \"git stash\" part.\n\n*work on stuff not ready to be committed*\ngit pull # refused\ngit stash\ngit pull\ngit stash apply # Conflicts, user decides that he wants go back\n\nAt that point, you need the reflog (also handle fast-forwards), and do:\n\ngit reset --hard HEAD@{1}\ngit stash apply --index\n\n\nOf course, a more correct way might be to use commit and rebase instead:\n\n*work on stuff not ready to be committed*\ngit pull # refused\ngit add -A # Or whatever\ngit commit\ngit pull --rebase # conflicts, decide to abort\ngit rebase --abort\ngit reset HEAD^\n\nBut that still needs the extra \"reset HEAD^\" step to really get back to\nthe state with your uncommitted changes.\n\nThe problem with \"svn up\" is that there's no other way, and no way back.\nGit has other ways, but no convenient one for non-committers and no\n\"obvious\" way to go back, should you decide that you actually prefer not\nto update after seeing the conflicts.\n\nAnyway, this isn't _my_ itch and to some (large) degree I'm trying to\nguess what someone else would expect. If at all, I'm more interested in\na command that figures out which remote tracking branch I checked out,\nand that updates it, and updates my work tree/index as well. Uncommitted\nchanges aren't important to me there. So I'll simply give up on that\npart.\n\nBjörn\n\n\n[*1*] One could also say: Users that don't give a damn about git, but\njust need it to get the code and maybe have some minor, uncommitted\nmodifications on top. I'm _not_ thinking about users that actually\ncommit and do stuff. Those should use merge/rebase/pull, and get a\ncomplaint from \"git update\" if the update is not a fast-forward one,\ntelling them what to use instead.\n"},{"id":"125257","messageId":"alpine.LNX.2.00.0910171528390.32515@iabervon.org","threadId":"21236","inReplyTo":"7vr5t2h3do.fsf@alter.siamese.dyndns.org","subject":"Re: [PATCH] Proof-of-concept patch to remember what the detached HEAD was","fromName":"Daniel Barkalow","fromEmail":"barkalow@iabervon.org","sentAt":"2009-10-17T20:35:44Z","receivedAt":"2009-10-17T20:35:44Z","isPatch":true,"sender":{"key":"barkalow@iabervon.org","avatar":"https://avatars.githubusercontent.com/u/55364219?v=4"},"body":"On Sat, 17 Oct 2009, Junio C Hamano wrote:\n\n> Christoph Bartoschek <bartoschek@gmx.de> writes:\n> \n> [jc: added Daniel back to cc list; please do not cull the cc list without\n> good reason]\n> \n> > Daniel Barkalow wrote:\n> >\n> >> The upshot of the messages should be:\n> >> \n> >>  $ git checkout origin/master\n> >>  Since you can't actually change \"origin/master\" yourself, you'll just\n> >>  be sightseeing unless you create a local branch to hold new local work.\n> >> \n> >>  $ git branch\n> >>  * (not a local branch, but \"origin/master\")\n> >> \n> >>  $ git commit\n> >>  You've been sightseeing \"origin/master\". The commit can't change that\n> >>  value, so your commit isn't held in any branch. If you want to create\n> >>  a branch to hold it, here's how.\n> > ...\n> > But then I was not able to verify that the checkout indeed matched the \n> > 1.3.0-beta.  \"git status\" and \"git branch\" did not help here. \n> \n> This is not going to help you, but \"git reflog\" would have helped here.\n> \n> The reason my suggesting \"git reflog\" now won't help you is because the\n> word \"reflog\" does not connect the question \"how did I get here\" unless\n> and until you know git already; in other words, it is not your fault that\n> you got lost, but it is showing a wart in the UI.\n> \n> If the question you were asking was \"does the files I have in my work tree\n> after issuing that scary checkout actually match origin/1.3.0-beta?\", you\n> could have asked that question in a more direct way, and the command to do\n> so is \"git diff origin/1.3.0-beta\".  I do not think this would be asking\n> the user to be doing something unreasonably unintuitive.\n> \n> If the question you were asking was (and it was not, from the description\n> of your experience, but you could be in that situation when you \"return\n> some weeks later\") \"how does the checked out history relate to 1.3.0-beta?\",\n> then there is a way to ask the question in a very direct way, and the\n> command to do so is \"git show-branch HEAD origin/1.3.0-beta\" (or give the\n> same argument to \"gitk\").\n> \n> Although it is not _so_ unreasonable to expect \"git status\" to show the\n> information, I suspect it would not be practical.  After all, whenever\n> somebody is lost, everything is \"status\".  For a person who is lost and\n> does not know where in the history he is, it might be reasonable to expect\n> \"status\" to give the relationship between your HEAD and some branch/tag,\n> while for another person who was hit by \"git gui\" complaining that he has\n> too many loose objects, it might be reasonable for him to expect \"status\"\n> to give the number of loose objects in the repository.  IOW, \"status\" is\n> too broad a word and following the path to cram everything into \"status\"\n> so that any new person who gets lost can get necessary infor from the\n> command will unfortunately lead to insanity.\n> \n> The second item in the Daniel's transcript above may be an improvement but\n> I think it is a wrong economy to record and show 'but \"origin/master\"'\n> (which cannot be correct forever and has to be invalidated once the user\n> starts committing or resetting) in the message.\n\nIt's easy to invalidate it for reasons of the user going elsewhere: you \ninvalidate it when you invalidate MERGE_HEAD (which, incidentally, \nlocates a bug in my original patch: there's a third \n\"unlink(git_path(\"MERGE_HEAD\"));\" I didn't think of, in builtin-merge.c).\n\nI think the case of it going stale, mainly due to updating a ref it uses, \nis a matter of having whatever wants to describe HEAD check if the \nextended sha1 still expands to the same sha1.\n\nI also think that it fits with the git world model to distinguish \n\"lvalues\" from \"non-lvalues\". An \"lvalue\" is something where you can make \na commit and change the value while the expression stays the same; you can \nassign to it. If your current position is not an \"lvalue\" and you commit, \nyour current position must become a new temporary \"lvalue\", diverging from \nthe thing you can't change. But if you don't assign to it, there's no \nproblem with having a non-lvalue be your current position.\n\n> I am wondering if a similar effect to help new users can be had by \n> rewording the message to:\n> \n>     $ git branch\n>     * (not a local branch; see \"git reflog\" to learn how you got here)\n> \n> The user can see how he got there even after doing something else after\n> the checkout (see Nico's write-up in $gmane/130527).  The difference is\n> between giving fish and teaching how to catch one himself.\n\nThe reflog hint is a good one in general; on the other hand, I think it \nwould be generally helpful to have the information in a more \nmachine-readable fashion, for a \"git checkout (whatever I gave to reset or \ncheckout before)\".\n\nPerhaps the right implementation is actually to have machine-readable \ndescriptions in the HEAD reflog? That would actually lead to the \ninteresting:\n\n$ git checkout topic\n$ git checkout origin/master\n$ git checkout HEAD@{1}\n$ git branch\n* topic\n\nActually, we turn out to have a flaw in our reflog explanation: when \nrebase finishes, it doesn't log that it's back to a particular branch.\n\n\t-Daniel\n*This .sig left intentionally blank*\n"},{"id":"125260","messageId":"alpine.LNX.2.00.0910172257270.9794@reaper.quantumfyre.co.uk","threadId":"21236","inReplyTo":"7vljj97w7u.fsf@alter.siamese.dyndns.org","subject":"Re: [PATCH] Proof-of-concept patch to remember what the detached HEAD was","fromName":"Julian Phillips","fromEmail":"julian@quantumfyre.co.uk","sentAt":"2009-10-17T22:19:46Z","receivedAt":"2009-10-17T22:19:46Z","isPatch":true,"sender":{"key":"julian@quantumfyre.co.uk","avatar":"https://avatars.githubusercontent.com/u/948888?v=4"},"body":"On Sat, 17 Oct 2009, Junio C Hamano wrote:\n\n> Julian Phillips <julian@quantumfyre.co.uk> writes:\n>\n>>>> My interest in this thread is solely that it might provide a mechanism\n>>>> to find out which tag was checked out.\n>>>\n>>> Hmm, what is lacking in \"git describe HEAD\" for that?  I am not\n>>> complaining that you might be asking for something that exists, but I _do_\n>>> want to know if something that exists is not a satisfactory solution and\n>>> if so how it can be improved.\n>>\n>> What is lacking is the \"checked out\" part.  \"git describe HEAD\" will\n>> tell me _a_ tag that matches the currently checked out state.\n>> However, it makes no guarantee that it was the one I checked out.  If\n>> I tag the code with \"v1.0.0\", and a colleague later tags it with\n>> \"this_version_sucks\", then when I check out and build the code for the\n>> customer the version it reports could well be \"this_version_sucks\"\n>> instead of \"v1.0.0\" ...\n>\n> I think I understand why you think showing what you gave to your last \"git\n> checkout\" (e.g. \"checkout origin/master\" or \"checkout v1.0.0\") and using\n> that as a build identification token is a good idea.  But \"origin/master\"\n> is a moving target---it depends on when you checked it out.  describe uses\n> tags and does not use branch heads for a good reason.\n\nFor my purposes the branch that I built from is much more useful than the \noutput from describe.  Releases are always made from tags, but for builds \nused in the lab it is generally much more useful to know which branch was \nbuilt directly rather than being able to find the exact commit that was \nbuilt.\n\n> \"v1.0.0\" also is to a lessor degree, as you may have tagged v1.0.0 locally\n> and somebody else also has used the tag for a different version, but a tag\n> is far less likely to move due to social convention.  \"describe --long\"\n> would make sure this won't be an issue anyway, though.\n\nFor any particular release only one person is given the job of making the \nrelease tag, so we don't have the problem of multiple instances of the \nsame tag - but we do need to make sure that the version output is the \ncorrect tag.\n\n-- \nJulian\n\n  ---\nWater, taken in moderation cannot hurt anybody.\n \t\t-- Mark Twain\n"},{"id":"125262","messageId":"alpine.LNX.2.00.0910172320060.9794@reaper.quantumfyre.co.uk","threadId":"21236","inReplyTo":"20091017174843.GA16251@atjola.homenet","subject":"Re: [PATCH] Proof-of-concept patch to remember what the detached HEAD was","fromName":"Julian Phillips","fromEmail":"julian@quantumfyre.co.uk","sentAt":"2009-10-17T22:28:45Z","receivedAt":"2009-10-17T22:28:45Z","isPatch":true,"sender":{"key":"julian@quantumfyre.co.uk","avatar":"https://avatars.githubusercontent.com/u/948888?v=4"},"body":"On Sat, 17 Oct 2009, Bj?rn Steinbrink wrote:\n\n> On 2009.10.17 18:35:38 +0100, Julian Phillips wrote:\n>> On Sat, 17 Oct 2009, Bj?rn Steinbrink wrote:\n>>> Do you have multiple (annotated) tags for the same commit?\n>>\n>> Potentially, yes.  Releasing isn't the only thing that requires\n>> keeping track of things.  It's even possible that the person\n>> creating the newer tag doesn't yet know that a release tag has been\n>> applied if the person who applied it hasn't yet pushed it back.\n>\n> OK, I'd consider that namespace pollution, as things like\n> \"this-version-sucks\" doesn't seem like it show go into public repos, but\n> anyway. If your release tags fix into a certain \"unique\" format, you\n> could use describe with --match, like:\n> git describe --match 'v[0-9]*'\n\nWell - that only helps if we only ever build the release tags.  Which \nisn't the case.  The other tags are there for similar purposes and also \nshould go into the version string - but only when they were the tag \nchecked out.\n\nIs it really that unreasonable to want to know exactly what it was that \nwas checked out?  It's one of the few things that I miss from Subversion.\n\n-- \nJulian\n\n  ---\nprintk(KERN_INFO MYNAM \": English readable SCSI-3 strings enabled :-)\\n\");\n         linux-2.6.6/drivers/message/fusion/mptbase.c\n"},{"id":"125297","messageId":"7vws2snwum.fsf@alter.siamese.dyndns.org","threadId":"21236","inReplyTo":"20091017194153.GA30003@atjola.homenet","subject":"Re: [PATCH] Proof-of-concept patch to remember what the detached HEAD was","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2009-10-18T22:47:13Z","receivedAt":"2009-10-18T22:47:13Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Björn Steinbrink <B.Steinbrink@gmx.de> writes:\n\n> On 2009.10.17 02:04:02 -0700, Junio C Hamano wrote:\n>> The \"save\" part of the work-save-then-merge sequence should be made very\n>> visible to help people get used to the \"not up, but work-save-then-merge\"\n>> mental model.  I do not think it would help people in the long run to make\n>> the \"save\" step less visible by wrapping the sequence into an unreliable\n>> \"up\" script, especially because the script would sometimes work but other\n>> times *has to* force users to know that what is happening behind the scene\n>> is work-save-then-merge in order to resolve and recover from conflicts\n>> anyway.\n>\n> Hm, which cases would that be? I basically see three cases:\n>\n>  1) No uncommitted changes => No problem\n>  2) Uncommitted changes merge cleanly => No problem\n>  3) Uncommitted changes causes conflicts =>\n>    - User can resolve\n>    - User can start over (git update --retry)\n>    - User can give up (git update --abort)\n\nBy \"--abort\", if you meant to discard the local change, that is only\nsuitable for people who would say \"what I was doing was minor anyway, and\nI'll redo them based on the updated upstream\", and may not be so useful, I\nthink.  The user may want to pretend that he did not even start \"update\"\n(i.e. not pulled while he was still working on something) at this point,\nand if you meant by \"give up\" (aka --abort) to \"reset --hard @{1} &&\nunstash\", I think it makes quite a lot of sense.  Then the user has an\noption to fork a topic at that point:\n\n    git update --abort\n    git checkout -b topic\n    work on more with committing\n    git checkout master\n    git update\n\nBut then this starts to look more like an enhanced failure recovery mode\nfor \"git pull\" command.\n\nIn addition, I think that you would internally implement the \"save\" step\nwith \"stash\" (which would be a sane thing to do), but then you would need\nto worry about the case where the user was in the middle of a merge (or\n\"revert\", \"cherry-pick\", \"checkout -m\") that did not complete.  \"git pull\"\nfails upfront, says why and tells users what to do.  \"git update\" should\ndo the same.\n\n> I do see problems with a \"stash around merge\" thing (\"stash\" around\n> rebase seems easier, as that could just create a commit and reset later,\n> but I'm not exactly sure that such smartness is a good idea). As soon as\n> the merge has conflicts, you need to know that you have to unstash after\n> committing the merge, but what I have in mind is fast-forward only (or\n> possibly reset, when upstream was rewritten).  Primarily for users that\n> don't commit at all, but just look at things [*1*].\n\nOk.  If you have a clean way to guarantee that \"update\" users won't\ncommit, I think the above would sort of make sense and my earlier worries\nabout (1) a user who wish he did not fetch and (2) a user who was doing\nsomething more complex and had conflicts already would go away.\n\nIf the sole target audience is \"minor changes only, never committing\"\npeople, then I would even rescind my earlier suggestion on --abort; it\nshould mean \"remove the minor changes and get pristine copy of the\nupstream---the user will redo the minor changes to adjust to the updated\nupstream from scratch\", to keep the end user experience simpler and\nclearer.\n\nI am undecided if it is a good thing to divide the userbase into two\nclasses, \"update\" people and \"work-commit-fetch-merge-resolve\" people.\n\n> [*1*] One could also say: Users that don't give a damn about git, but\n> just need it to get the code and maybe have some minor, uncommitted\n> modifications on top. I'm _not_ thinking about users that actually\n> commit and do stuff. Those should use merge/rebase/pull, and get a\n> complaint from \"git update\" if the update is not a fast-forward one,\n> telling them what to use instead.\n"},{"id":"125360","messageId":"20091019084407.GA2796@atjola.homenet","threadId":"21236","inReplyTo":"7vws2snwum.fsf@alter.siamese.dyndns.org","subject":"Re: [PATCH] Proof-of-concept patch to remember what the detached HEAD was","fromName":"Björn Steinbrink","fromEmail":"b.steinbrink@gmx.de","sentAt":"2009-10-19T08:44:07Z","receivedAt":"2009-10-19T08:44:07Z","isPatch":true,"sender":{"key":"b.steinbrink@gmx.de","avatar":"https://avatars.githubusercontent.com/u/230962?v=4"},"body":"On 2009.10.18 15:47:13 -0700, Junio C Hamano wrote:\n> Björn Steinbrink <B.Steinbrink@gmx.de> writes:\n> > On 2009.10.17 02:04:02 -0700, Junio C Hamano wrote:\n> >  1) No uncommitted changes => No problem\n> >  2) Uncommitted changes merge cleanly => No problem\n> >  3) Uncommitted changes causes conflicts =>\n> >    - User can resolve\n> >    - User can start over (git update --retry)\n> >    - User can give up (git update --abort)\n> \n> By \"--abort\", if you meant to discard the local change, that is only\n> suitable for people who would say \"what I was doing was minor anyway, and\n> I'll redo them based on the updated upstream\", and may not be so useful, I\n> think.  The user may want to pretend that he did not even start \"update\"\n> (i.e. not pulled while he was still working on something) at this point,\n> and if you meant by \"give up\" (aka --abort) to \"reset --hard @{1} &&\n> unstash\", I think it makes quite a lot of sense.  Then the user has an\n> option to fork a topic at that point:\n> \n>     git update --abort\n>     git checkout -b topic\n>     work on more with committing\n>     git checkout master\n>     git update\n\nYes, I meant the latter. The former would just be \"git reset --hard\" and\nis pointless to be rewrapped in \"git update --abort\". Maybe \"abort\" is\nthe wrong word there? I'm not a native speaker and basically took that\nfrom \"git rebase\", which returns you to your (unchanged) branch head,\ni.e. the state you were in before you started the rebase.\n\n> But then this starts to look more like an enhanced failure recovery mode\n> for \"git pull\" command.\n\nYeah, I notice that, also while working on my \"proof-of-concept\"\nimplementation. Currently, I simply suggest \"git pull\" to the user when\nthe update is not a fast-forward one.\n\nI'm probably influenced by a latent hatred for \"git pull\"... Explaining\nthat it is fetch+merge/rebase and uses defaults from the config which\nare automagically setup is probably something my fingers can do on\ntheir own by now. Confusion about \"git pull\" probably beats\nmisunderstandings about HEAD.\n\nIf it wasn't so inconvenient for people that actually commit, I'd even\ndare to suggest:\n\ngit update\n - FF update only, using branch.<name>.{remote,merge}\n - suggests \"git update --merge\" or \"git update --rebase\" if non-ff\n\ngit update --merge\n - Does a merge\n\ngit update --rebase\n - Does a rebase\n\nAnd \"git pull\" would stop using branch.<name>.{remote,merge} and require\ncommand line arguments.\n\nThat would at least raise awareness that \"git update --merge\" is doing a\nmerge, unlike \"git pull\", which many new users simply treat as magic,\nnot realizing what actually happens (and thus they create butt-ugly\ncriss-cross merge histories). Of course, I can't tell whether being\naware that a merge happens actually makes the user realize that they\nshouldn't update/pull/merge 50 times a day.\n\nBut passing --merge all the time seems just too inconvenient. And having\na config option to make --merge or --rebase the default would probably\nend up with --merge as the \"default default\", ultimately turning \"git\nupdate\" into \"git pull\".\n\nAnyway, I'm probably getting quite far off the track here.\n\n> In addition, I think that you would internally implement the \"save\" step\n> with \"stash\" (which would be a sane thing to do), but then you would need\n> to worry about the case where the user was in the middle of a merge (or\n> \"revert\", \"cherry-pick\", \"checkout -m\") that did not complete.  \"git pull\"\n> fails upfront, says why and tells users what to do.  \"git update\" should\n> do the same.\n\nYup, got the same check in my PoC\n\n> > I do see problems with a \"stash around merge\" thing (\"stash\" around\n> > rebase seems easier, as that could just create a commit and reset later,\n> > but I'm not exactly sure that such smartness is a good idea). As soon as\n> > the merge has conflicts, you need to know that you have to unstash after\n> > committing the merge, but what I have in mind is fast-forward only (or\n> > possibly reset, when upstream was rewritten).  Primarily for users that\n> > don't commit at all, but just look at things [*1*].\n> \n> Ok.  If you have a clean way to guarantee that \"update\" users won't\n> commit, I think the above would sort of make sense and my earlier worries\n> about (1) a user who wish he did not fetch and (2) a user who was doing\n> something more complex and had conflicts already would go away.\n\nCurrently it's just:\ntest -z \"$(git rev-list -1 $upstream..)\"\n\nAs a \"is a fast-forward\" check, suggesting the user to use \"git pull\"\ninstead of \"git update\", if it is not. Maybe I should use \"git\nmerge-base\" there instead? Is that better? Not sure whether history\nsimplication might break the rev-list based test...\n\n> If the sole target audience is \"minor changes only, never committing\"\n> people, then I would even rescind my earlier suggestion on --abort; it\n> should mean \"remove the minor changes and get pristine copy of the\n> upstream---the user will redo the minor changes to adjust to the updated\n> upstream from scratch\", to keep the end user experience simpler and\n> clearer.\n\nHmhm... If the user can't resolve the conflict, but still keep those\nchanges, he might want to ask someone else for help. And then he might\nwant to present his changes to that other person, so I think allowing\nthe user to go back to the old commit with his changes on top is better.\nMaybe \"git update --drop\" could do the \"drop the user's changes\", if the\nuser wants to do so. No support for going back is what's bad about \"svn\nupdate\" (and, I guess, \"git checkout --merge\").\n\n> I am undecided if it is a good thing to divide the userbase into two\n> classes, \"update\" people and \"work-commit-fetch-merge-resolve\" people.\n\nI expect that there are already two userbases. Developers in one\nuserbase and users that just want the latest code in the other. And\nthese users might have some uncommitted stuff (either self-made or\npossibly found somewhere, or maybe a bit of both).\n\nI just wonder what's easier/better: to cater to each one or trying to\nunify them by trying to educate the one that actually doesn't care.\n\nBjörn\n"},{"id":"125956","messageId":"alpine.DEB.1.00.0910262317430.4985@pacific.mpi-cbg.de","threadId":"21236","inReplyTo":"BLU0-SMTP840FB343954FC20ACA699CAEC30@phx.gbl","subject":"Re: [PATCH] Proof-of-concept patch to remember what the detached HEAD was","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2009-10-26T22:22:13Z","receivedAt":"2009-10-26T22:22:13Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi,\n\nOn Sat, 17 Oct 2009, Sean Estabrooks wrote:\n\n> On Fri, 16 Oct 2009 04:07:23 +0200 (CEST)\n> Johannes Schindelin <Johannes.Schindelin@gmx.de> wrote:\n> \n> > Just recently, I had a user request (a very valid one, mind you) where \n> > the user does not want to provide a commit message, and wants to just \n> > commit all the current changes.  In that particular case, it is very \n> > sensible to ask for these things.  It is something utterly simple to \n> > ask for. Yet, it is utterly hard with Git, especially if I have to \n> > explain it.\n> \n> Hey Johannes,\n> \n> It's actually easy, but maybe hard to find:\n> \n> \t$ git commit --cleanup=verbatim -m \"\"\n\nOf course that leaves out the main part.  But it is simple once you \nknow it (I did not): git add -A (we even went out of our way _not_ to name \nthe long option --addremove, but --all -- it does not seem to be an \nexpressive-enough option name to me, but what does my impression \nmatter...)\n\nSo I retract my claim that it is utterly hard to do with Git (but not the \nrest).\n\nCiao,\nDscho\n"},{"id":"125986","messageId":"20091027124156.6117@nanako3.lavabit.com","threadId":"21236","inReplyTo":"alpine.DEB.1.00.0910262317430.4985@pacific.mpi-cbg.de","subject":"Re: [PATCH] Proof-of-concept patch to remember what the detached HEAD was","fromName":"Nanako Shiraishi","fromEmail":"nanako3@lavabit.com","sentAt":"2009-10-27T03:41:56Z","receivedAt":"2009-10-27T03:41:56Z","isPatch":true,"sender":{"key":"nanako3@lavabit.com","avatar":"https://gravatar.com/avatar/3777b9e201c5883a62b1a6fdf7c53f2d712d1d80989146063ea861e33aad72a8?d=mp&s=160"},"body":"Quoting Johannes Schindelin <Johannes.Schindelin@gmx.de>\n\n> On Sat, 17 Oct 2009, Sean Estabrooks wrote:\n>\n>> On Fri, 16 Oct 2009 04:07:23 +0200 (CEST)\n>> Johannes Schindelin <Johannes.Schindelin@gmx.de> wrote:\n>> \n>> > Just recently, I had a user request (a very valid one, mind you) where \n>> > the user does not want to provide a commit message, and wants to just \n>> > commit all the current changes.  In that particular case, it is very \n>> > sensible to ask for these things.  It is something utterly simple to \n>> > ask for. Yet, it is utterly hard with Git, especially if I have to \n>> > explain it.\n>> \n>> Hey Johannes,\n>> \n>> It's actually easy, but maybe hard to find:\n>> \n>> \t$ git commit --cleanup=verbatim -m \"\"\n>\n> Of course that leaves out the main part.  But it is simple once you \n> know it (I did not): git add -A (we even went out of our way _not_ to name \n> the long option --addremove, but --all -- it does not seem to be an \n> expressive-enough option name to me, but what does my impression \n> matter...)\n>\n> So I retract my claim that it is utterly hard to do with Git (but not the \n> rest).\n\nLast week, Junio gave this comment to your message.\n\n> I suspect the above is another example of your needing to do \n> a better job explaining yourself here, but from \"just commit \n> all the changes without saying message\", my knee-jerk \n> reaction is \"git commit -a -m 'no message'\".\n\n> You would need to justify why -m 'no message' does not fit \n> the bill better than just saying \"is very sensible to ask for \n> these things\", as I highly suspect that I misunderstood what \n> \"these things\" are in your five lines to come up with that \n> \"solution\" that you are now going to explain why that is not \n> what the end user wanted.  And in this case, I do not think \n> it is that me being disconnected from the real world, but \n> that your explanation is insufficient.\n\nI'm also curious about the situation when a commit with no message \nis useful, but unfortunately I don't think I saw you explained \nclearly enough what this user request wanted to achieve or what \n\"these things\" in your message were for us to understand why it is \na sensible and valid thing to ask. Did I miss some messages in the \nthread?\n\n-- \nNanako Shiraishi\nhttp://ivory.ap.teacup.com/nanako3/\n"},{"id":"126003","messageId":"alpine.DEB.1.00.0910271118470.4985@pacific.mpi-cbg.de","threadId":"21236","inReplyTo":"20091027124156.6117@nanako3.lavabit.com","subject":"Making Git easy to use -- without RTFM, was Re: [PATCH] Proof-of-concept patch to remember what the detached HEAD was","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2009-10-27T10:33:49Z","receivedAt":"2009-10-27T10:33:49Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi,\n\n[culling the Cc: list, as this subthread is probably irrelevant most of \nthe previous members]\n\nOn Tue, 27 Oct 2009, Nanako Shiraishi wrote:\n\n> Quoting Johannes Schindelin <Johannes.Schindelin@gmx.de>\n> \n> [actually not, Nanako quoted Junio here, I guess]\n>\n> > I suspect the above is another example of your needing to do a better \n> > job explaining yourself here, but from \"just commit all the changes \n> > without saying message\", my knee-jerk reaction is \"git commit -a -m \n> > 'no message'\".\n> \n> > You would need to justify why -m 'no message' does not fit the bill \n> > better than just saying \"is very sensible to ask for these things\", as \n> > I highly suspect that I misunderstood what \"these things\" are in your \n> > five lines to come up with that \"solution\" that you are now going to \n> > explain why that is not what the end user wanted.  And in this case, I \n> > do not think it is that me being disconnected from the real world, but \n> > that your explanation is insufficient.\n> \n> I'm also curious about the situation when a commit with no message is \n> useful, but unfortunately I don't think I saw you explained clearly \n> enough what this user request wanted to achieve or what \"these things\" \n> in your message were for us to understand why it is a sensible and valid \n> thing to ask.\n\nI am sure that your creative mind does not need my concrete example to \ncome up with a situation where an empty commit message is useful.\n\nAnyhow, here it is: one of my users refused to touch SCMs _at all_, for \ndecades.  There was only one choice: have a Git branch with a purely \nlinear history that contains the copy of the working tree at the end of \nthe day, with whatever changes accumulated over the day, or no history at \nall.\n\nSure, some people will now argue that it should be easy to educate that \nuser to use Git properly.  But that is as naive as it would be to try to \neducate those people so they know how unrealistic educating users is.  \nNot because users are not intelligent -- they are -- but because they want \nto spend their time in a more efficient manner than to learn how to \noperate a version control system.\n\nYou know, when there is a hurdle half of the people you see cannot get \nover, there are some who make the hurdle half as high, and there are \nothers who put more hurdles there and call it a sport.\n\nIn this case, I would have preferred to make the hurdle half as high, but \nI think I just have to wait a couple of years; reality will take care of \nthings.\n\nCiao,\nDscho\n"},{"id":"126042","messageId":"32541b130910271058u514c3356j84f98182b6b3ede9@mail.gmail.com","threadId":"21236","inReplyTo":"alpine.DEB.1.00.0910271118470.4985@pacific.mpi-cbg.de","subject":"Re: Making Git easy to use -- without RTFM, was Re: [PATCH] Proof-of-concept patch to remember what the detached HEAD was","fromName":"Avery Pennarun","fromEmail":"apenwarr@gmail.com","sentAt":"2009-10-27T17:58:21Z","receivedAt":"2009-10-27T17:58:21Z","isPatch":true,"sender":{"key":"apenwarr@gmail.com","avatar":"https://avatars.githubusercontent.com/u/20592?v=4"},"body":"On Tue, Oct 27, 2009 at 6:33 AM, Johannes Schindelin\n<Johannes.Schindelin@gmx.de> wrote:\n> Anyhow, here it is: one of my users refused to touch SCMs _at all_, for\n> decades.  There was only one choice: have a Git branch with a purely\n> linear history that contains the copy of the working tree at the end of\n> the day, with whatever changes accumulated over the day, or no history at\n> all.\n[...]\n> You know, when there is a hurdle half of the people you see cannot get\n> over, there are some who make the hurdle half as high, and there are\n> others who put more hurdles there and call it a sport.\n>\n> In this case, I would have preferred to make the hurdle half as high, but\n> I think I just have to wait a couple of years; reality will take care of\n> things.\n\nIn this case, what would you have preferred to change in order to make\nthe hurdle half as high?\n\nThanks,\n\nAvery\n"}]}