2

After an operation that moves HEAD (such as checkout, reset, etc.), you can always get the commit ID that HEAD pointed to before that operation by running, for instance,

git rev-parse @{1}

What I'm interested in, though, is getting the name of the reference (if any) that HEAD last pointed to. Here's an example that illustrates what I want. Let's say my repo looks as follows:

enter image description here

Then I check out the develop branch by running

git checkout develop

and end up with

enter image description here

How can I retrieve the information, from my repo's entrails, that HEAD was pointing at master, before that last checkout operation?

This answer suggests extracting the name from the reflog with awk as a possibility; for instance, with

git reflog -1 | awk '{ print $6; exit }'

(thanks to Ed and Etan for their suggestions).

As far as I can tell, that works well enough. It even prints the SHA of the previous commit, in case HEAD was detached before the last checkout.

However, the OP raises concerns about robustness and backward compatibility in his comment:

I am marking this answer as correct (which it is, technically), for want of a cleaner approach. However, I am not convinced that the string's format being hard-coded into Git's source code is a good thing, as it means it could break unexpectedly (i.e. in a later version of Git).

Are the OP's concerns legitimate? What is the most robust way to do that?

4

2 回答 2

2

在一些快速测试中,这似乎工作得相当好(尽管测试根本不彻底​​或强调奇怪的场景):

git rev-parse --symbolic-full-name @{-1}

我正在对@EmilDavtyan 的回答发表评论,说多参考问题是有问题的,因为我认为 git 不在乎(因此不跟踪)HEAD参考的最后位置,但后来我记得@{-1}以及如何如果它不能处理这种情况,那么它的用处就会少得多,所以在快速测试之后,它似乎以某种方式做了(据我所知,它很可能正在解析 reflog 中的消息)。

我还应该指出,链接的 OP 是正确的,手动解析 reflog 是不可靠的。事实上,当我在这里测试 awk 片段时,我没有得到正确的结果。原来那是因为我--decorate默认情况下使用额外的字段填充行并丢弃计数。

于 2014-09-02T14:58:41.503 回答
1

我只会使用:

git branch --contains HEAD@{1}

它将为您提供包含先前签出提交的分支。


使用@Etan 的答案做了一个小测试,我认为它没有为分支解析 git reflog 中的消息,它只是在查找它:

emil ~ git checkout -b temp2
Switched to a new branch 'temp2'
emil ~ git rev-parse --symbolic-full-name @{-1}
refs/heads/temp
emil ~ git branch -d temp
Deleted branch temp (was f3163f9).
emil ~ git rev-parse --symbolic-full-name @{-1}
@{-1}
fatal: ambiguous argument '@{-1}': unknown revision or path not in the working tree.
Use '--' to separate paths from revisions, like this:
'git <command> [<revision>...] -- [<file>...]'

因此,如果通过提交删除或更改分支,我认为该方法将失败。

于 2014-09-02T14:43:14.437 回答