Subject: Re: [PATCH 1/2] builtin/symbolic-ref.c: add option to fall back to normal ref

From: Jan Krüger <[email-masked]>
Date: Mon, 27 Feb 2012 23:40:37 +0100

On 02/27/2012 11:21 PM, Junio C Hamano wrote:
> What is "the current value of HEAD"?

Well, essentially it contains a "type" and a "value". The type is either
"symbolic" or "not symbolic" and the value is a ref if HEAD is currently
symbolic or a SHA1 otherwise.

These definitions don't come from the glossary, obviously. It's just the
way I interpret HEAD. If you think the patch would be better off with a
different wording, I'd be happy for suggestions.

In any case, if you have the "value" without the "type", you can
actually derive the "type" from the "value": if it has the shape of a
SHA1, it was a direct ref; otherwise it was a symbolic ref (unless the
user has a ref that looks like a SHA1 but in that case some other tools
do funny things, too).

> The symbolic-ref command is there for people who _care_ about the
> distinction between a HEAD that points at a branch and a HEAD that points
> directly at a commit.  There is no room for the command to "fall back"
> anywhere, as that will only introduce an unnecessary ambiguity to the
> command whose sole purpose is to be able to tell them apart.

That's why it's an optional thing.

> If the caller does not need to know if the HEAD is detached or not, and
> wants to know what commit it points at, why is it insufficient to just use
> rev-parse, e.g. "git rev-parse --verify HEAD"?

The use case here is having one convenient command to remember what is
currently checked out, and being able to go back to that later. "git
checkout" will do the right thing if you just give it "master" or a
complete SHA1, so all we need to remember is that.

"git rev-parse --verify HEAD" will only give us the SHA1, even if HEAD
isn't actually detached.

Incidentally, the -s switch in the second patch makes this even easier:

    OLDHEAD=`git symbolic-ref -s -f HEAD`
    # do stuff here that involves switching branches or detaching or
    # whatever
    git checkout $OLDHEAD

Without these patches, the shortest way I can think of to do the same
thing would be:

    OLDHEAD=`git rev-parse --symbolic-full-name HEAD`
    [ "$OLDHEAD" = "HEAD" ] && OLDHEAD=`git rev-parse HEAD`
    # ...

-Jan