views:

53

answers:

1

Hi,

I want to be able to pass anything to a git command (maybe its a SHA, maybe it's just something like "origin/master" or "devel/epxerimental" etc.) and git tells me the ref path of the branch that the passed something lives in, e.g.

<git_command> 0dc27819b8e9 => output: refs/heads/master
<git_command> xyz/test => output: refs/remotes/xyz/master
...

I've been looking at git show or git log or git rev-parse and apart from --pretty=format:%d I couldn't find anything. (--pretty=format:%d output is quite strange with lotsa free space and empty lines and sometimes more than one ref paths are on one line bunched together).

There has to be a better way?

Thanks for reading.

Andre

+3  A: 

There is no fixed information which would record such a data, because SHA1 are not associated at all time with a ref path.
Branches can moves, be renamed or deleted, while the SHA1 will still be stored (except if it is not referenced by any ref pattern, it will eventually be pruned)

That being said:

git show-ref |grep yourSHA1|awk "{print $2}"
git show-ref --heads --tags -d |grep yourSHA1|awk "{print $2}"

comes pretty close to what yout want:

C:\Prog\Git\tests\rep\main5>git show-ref | grep f4a071 | awk "{print $2}"
refs/heads/master
refs/remotes/origin/HEAD
refs/remotes/origin/master

A lot of options are available for git show-ref and will allow you to:

  • display also dereferenced SHA1
  • display SHA1 only for a pattern of refs

The OP adds:

it will return nothing at all if a SHA passed does not reference a head or any other dereferencable commit?
Do you have an idea how we could do the intermediary step of figuring out the SHA of the most recent commit belonging to the same branch as the SHA passed?

One other plumbing command that can help would be git name-rev:

C:\Prog\Git\tests\rep\main5>git name-rev a7768453
a7768453 patches~1

C:\Prog\Git\tests\rep\main5>git name-rev a7768453|gawk "{gsub(/~.*/,\"\",$2);print $2}
patches

As Jefromi mentions in the comments, a porcelain command would be git branch --contain:

C:\Prog\Git\tests\rep\main5>git branch --contain 1e73e369
  master
* patches
  tmp

--contains <commit>

Only list branches which contain the specified commit.
It is used to find all branches which will need special attention if <commit> were to be rebased or amended, since those branches contain the specified <commit>.

VonC
Thanks a lot and you're right that does come close at least 9 times out of 10. Only problem left: it will return nothing at all if a SHA passed does not reference a head or any other dereferencable commit? Do you have an idea how we could do the intermediary step of figuring out the SHA of the most recent commit belonging to the same branch as the SHA passed (e.g. if we pass SHA for commit 32 we get the SHA back for commit 0 (aka HEAD))?
andreb
@andreb: good point. `show-ref` is only for SHA1 references directly by refs. `name-rev` can help catch the rest. See my updated answer.
VonC
@andreb: See also http://stackoverflow.com/questions/917102/in-git-is-there-a-way-to-get-the-friendly-name-for-an-arbitrary-commit for more
VonC
The other relevant command is `git branch --contains <commit>`, which tells you which branches contain the given commit.
Jefromi
@Jefromi: thank you for this porcelain command. Answer updated.
VonC
Wow guys you're great! That's awesome, exactly what I needed thanks a lot!
andreb