Git checkout refs / heads / master disables HEAD

I have a local branch "master" tracking the remote branch "origin / master".

When I check the master like this:

git checkout refs/heads/master

      

I end up with a separate head:

Note: checking "refs / heads / master".

You are in a detached HEAD state. You can look around, do experimental changes and commits, and you can discard any commits you make in this state without affecting any branches by doing another checkout.

Obviously, I could just check the "master", but that could be an ambiguous link. I just want to know what the "git way" is to disambiguate the branch name without separating the HEAD.

+3


source to share


1 answer


The documentation for git checkout

does not say how it behaves when master

ambiguous. After looking at the source code (I moved quickly so I might be wrong), it looks like it git checkout

assumes the name provided (for example master

) is the name of the branch until it finds what's in refs/heads/*

for the given name.

So the correct way to check out a branch when the revision is ambiguous is to leave the value refs/heads/

, for example git checkout master

.

From branching and revision

Note that there is a subtle but important difference between specifying a branch and specifying a revision (or other object). For commands and options that accept a revision (or shared object), the hint is the master

same as the job refs/heads/master

, unless master

it is ambiguous. It also matches the hint master^0

or SHA1 it points to master

, etc.

For commands and options that take a branch (for example, git branch

or --branches

for commands of type git log

), the specification is master

not the same as the assignment refs/heads/master

. In these cases, the full line is refs/heads/master

interpreted as the name of the branch, causing Git to create / checkout / update the ref with the name refs/heads/refs/heads/master

instead refs/heads/master

.



The command is git checkout

versatile, which is handy, but can be confusing in cases like master

vs. refs/heads/master

... When you point master

and a ref with a name refs/heads/master

exists, git checkout

assumes that you mean the branch master

and not the revision it points to master

. When you point refs/heads/master

and the ref with a name refs/heads/refs/heads/master

does not exist, it git checkout

assumes that you meant the revision you are pointing master

to and not the named branch refs/heads/master

(so you get detached HEAD

).

Checking non-interface when ambiguous

If you want to check out some other ref whose short name is also master

(like a tag with a name master

), you will need to specify the full name of the link (for example git checkout refs/tags/master

) or incantation of revision in a way that cannot be interpreted as a valid branch name (for example git checkout master^0

) ... The latter results in git checkout

following the ambiguity rules described in git help revisions

:

When ambiguous, a <refname>

is disambiguated by accepting the first match in the following rules:

  • If $GIT_DIR/<refname>

    there is, this is what you have in mind (usually only useful for HEAD

    , FETCH_HEAD

    , ORIG_HEAD

    , MERGE_HEAD

    and CHERRY_PICK_HEAD

    );
  • otherwise refs/<refname>

    , if it exists;
  • otherwise refs/tags/<refname>

    , if it exists;
  • otherwise refs/heads/<refname>

    , if it exists;
  • otherwise refs/remotes/<refname>

    , if it exists;
  • otherwise refs/remotes/<refname>/HEAD

    , if it exists.

Of course, the result will be a separate one HEAD

, but this always happens when you checkout a non-branch.

+1


source







All Articles