Re: [PATCH] Detached HEAD (experimental)
From: Edgar Toernig <hidden>
Date: 2016-06-15 22:42:47
[Note: casual git-user speaking] Junio C Hamano wrote:
This allows "git checkout -d v1.4.3" to detach the HEAD from any branch but point directly at the named commit. After this, "git branch" starts reporting that you are not on any branch.
Nice. But why -d? Create more confusion? [1]
You can go back the normal state by switching to an existing branch, say, "git checkout master" for example.
This is fine. Often you want to test a couple of tags, one after another, so "git checkout v1", "git checkout v2", ... should work.
Another way to get out of this is "git checkout -b newbranch".
Wth should this do? I already noticed this line in your posting
from 29.Dec: [slightly edited]
$ git checkout v1.5.0
Checking out a tag -- you are not on any branch now...
$ <modify>
$ git commit -m 'fix' -a
You cannot commit without a current branch.
$ git checkout -b maint-1.5.0
$ git commit -m 'fix' -a
I assume it will create a new branch and modify HEAD so that
the current working dir/index gets committed into that branch.
(Basically "git branch main-1.5.0 &&
echo 'ref: refs/head/main-1.5.0' >.git/HEAD")
If that's the case, I was looking for that incantation for
a long time and couldn't find it. I'm using the git-branch
and echo as shown above to get that. The man-page isn't
very helpful for that special case of git-checkout.
Anyway, if I want to commit and git tells me that I can't
because I'm not on a branch, the _most unintuitive_ thing
would be calling 'git-checkout'. I want to checkin! No
way that I call checkout and risk losing all my changes.
What's wrong with a -b option to commit, similar to -b on
checkout?
$ git checkout v1.5.0
Checking out a tag -- you are not on any branch now...
$ <modify>
$ git commit -m 'fix' -a
You cannot commit without a current branch.
Give '-b <newbranch>' to commit into a new branch.
$ git commit -b maint-1.5.0 -m 'fix' -a
Another variant (the one I prefer): commit just updates HEAD and
git-branch can be used to give it a name (and switch to it!).
So these workflows would be possible:
Name after commit:
$ git checkout v1.5.0
Checking out a tag -- you are not on any branch now...
$ git branch
master
* (unnamed) c8ff51290518949225c832bae1e22b1bba6ab2cd
$ <modify>
$ git commit -m 'fix' -a
Warning: data committed into unnamed branch.
Give it a name now with "git branch <newname>"
$ git branch
master
* (unnamed) 13482f25863e5380cdd41065338e1709d469a605
$ git branch maint-1.5.0
$ git branch
master
* main-1.5.0
or name before commit:
$ git checkout v1.5.0
Checking out a tag -- you are not on any branch now...
$ <modify>
$ git branch
master
* (unnamed) c8ff51290518949225c832bae1e22b1bba6ab2cd
$ git branch maint-1.5.0
$ git branch
master
* maint-1.5.0
$ git commit -m 'fix' -a
Yes, 'git branch <newname>' would get a new semantic:
if no start-point is given the newname will become the
new current branch.
[Btw, I would even do that when we are on some branch. How
often did I do a checkout of a regular branch and only later
noticed, that I want to commit changes into a temp-branch:
$ git checkout master
$ <play around, fix compile issues, add debug stuff>
$ git branch debug
$ git branch
master
* debug
$ git commit -a -m "Add foo debugging code"
]
But that special case is IMHO (M = my, a casual user's) much
better than some weird checkout-incantations.
Ciao, ET.
[1] My pet-peeve:
$ git checkout foo
fatal: Entry 'bar' not uptodate. Cannot merge.
What the heck? Nobody asked for a merge!?!?! What
is it trying to do? Does it actually mean:
fatal: Working dir is dirty. Either give '-f'
to force the checkout and lose your changes, or
give '-m' to merge 'foo' and your changes.
? But then, why does an 'rm bar' fixes that? Now 'bar'
definitely isn't "uptodate".