11

I understand what's happening under the hood, when I run $ git checkout --detach.

While on master, when I $ git checkout --detach, my .git/HEAD is not pointing to ref: refs/heads/master but to a hash instead (same a as refs/heads/master).

What would be the use case, when I would actually want to do that?

jkulak
  • 768
  • 1
  • 6
  • 18
  • 2
    In fact, you never need the `--detach` *flag* because you can simply spell the revision specifier as, e.g., `refs/heads/master`. So the flag itself is just for convenience. Oliver Charlesworth's answer is the right one though—this is just an aside about the spelling of the way to request it. :-) – torek Nov 20 '16 at 20:43
  • Is useful when You want to remove a local branch and You are getting the error: Cannot delete the branch 'master' which you are currently on. – mario ruiz Apr 11 '18 at 15:39
  • It is useful to avoid bare repositories. https://stackoverflow.com/a/9283833/402322 – ceving Jun 26 '19 at 13:18

4 Answers4

8

According to the commit that introduced the flag:

For example, one might use this when making a temporary merge to test that two topics work well together.

I guess the idea is that deliberately detaching allows you to then make further commits that you know will be discarded once you're done (and once GC has run).

Note that this flag doesn't actually add any new functionality; you could achieve the same result previously with git checkout some-branch^0.

Oliver Charlesworth
  • 267,707
  • 33
  • 569
  • 680
  • 2
    So I detach at the tip of my current branch, try to merge something onto that detached HEAD to see how easy it will be, make some extra commits - for test purposes, then run build/tests (whatever) to see the results, and if everything looks OK, go for the "real" merge... right? – jkulak Nov 20 '16 at 21:09
  • 1
    @jkulak - Yes, I suppose that's what that comment is about. I've never had a need to do that myself, though ;) – Oliver Charlesworth Nov 20 '16 at 21:11
6

tl;dr: Checking out a branch which is already checked out in another worktree is illegal.
Enter git checkout --detach master


Now to more clearly explain how one gets to such situation, the following is a real world example of how I personally use git checkout --detach.


I am developing a program, called midimap, that I also have a stable long lived process of running in the background.

For that I utilize two worktrees, ~/vc/github.com/fossegrim/midimap, hereby referred to as DEV, for development and ~/vc/github.com/fossegrim/midimap-stable, hereby referred to as STABLE, for the long lived process.

When I start my computer I run the midimap program in STABLE and open GNU Emacs in DEV. As I work on my project in DEV I will eventually come to a point where I want to update the USAGE worktree to contain the changes of DEV.

Since checking out a branch which is already checked out in another worktree is illegal. I have to check it out another way: git checkout --detach master.

Qwerty
  • 29,062
  • 22
  • 108
  • 136
Olav Fosse
  • 128
  • 1
  • 5
  • 3
    Olav, you say you use two worktrees, DEV and STABLE, but mentioned a third, USAGE. Can you clarify the role of the third one? Might you be able to expand on your last paragraph? I'm afraid I don't understand it at all. – MCornejo Jul 14 '22 at 15:59
2

When you choose to checkout a commit hash, or a branch with --detach, any commits made will not belong to a specific branch.

So having a detached head, as this scenario is called, is useful when testing something.

References:

aleksander_si
  • 1,021
  • 10
  • 28
0

When you work in a multi-developer setup, you may come to a point when during a code review you want to try certain code changes in order to better understand what the other developer did, in order to provide better feedback.

Any commits that you add are hanging in the void and are not actually added to any branch.

The other developer then adjusts the code and pushes new commits.

After that you can just do a fetch and checkout--detached the original branch again without having to explicitly discard anything or solving merge conflicts.

You are also actually not fetching the branch physically locally, so that after you are done with the code review, you don't need to delete the branch (or the commits you added).

In short

The command git checkout origin/master --detach allows you to check out the commit that the branch points to without really fetching and tracking the branch itself. Any changes you then do and commits you create are going to be discarded automatically (including the "branch" itself) once you checkout another branch without you having to delete them manually.

Qwerty
  • 29,062
  • 22
  • 108
  • 136