【问题标题】:What is the most robust way to get the name of the reference last pointed to by HEAD?获取 HEAD 最后指向的引用名称的最可靠方法是什么?
【发布时间】:2014-09-02 14:01:58
【问题描述】:

在移动HEAD(如checkoutreset等)的操作之后,您总是可以通过运行获得HEAD在该操作之前指向的提交ID,例如,

git rev-parse @{1}

不过,我感兴趣的是获取HEAD 最后指向的引用(如果有)的名称。这是一个说明我想要什么的例子。假设我的仓库如下所示:

然后我通过运行检查develop 分支

git checkout develop

最终得到

在最后一次结帐操作之前,我如何从我的 repo 的内脏中检索 HEAD 指向 master 的信息?

This answer 建议使用awk 从引用日志中提取名称;例如,与

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

(感谢EdEtan 的建议)。

据我所知,这已经足够好了。它甚至会打印上一次提交的 SHA,以防 HEAD 在上次结帐之前被分离。

但是,OP 在his comment 中提出了对健壮性和向后兼容性的担忧:

我将此答案标记为正确(从技术上讲是正确的),因为需要更清洁的方法。但是,我不相信将字符串的格式硬编码到 Git 的源代码中是一件好事,因为这意味着它可能会意外中断(即在更高版本的 Git 中)。

OP 的担忧是否合理?最可靠的方法是什么?

【问题讨论】:

  • 我不能说出你问题的主要观点,但永远不要这样做cmd | head -1 | awk '{ print $6 }',因为 awk 完全能够在没有额外中间头和管道的情况下仅在文件的第一行上运行: cmd | awk 'NR==1{ print $6; exit }'.
  • @EdMorton 谢谢 Ed。我对awk 还不是很熟悉。我将编辑我的问题。
  • 这里有一个额外的细节,git-reflog 完全能够将其自己的输出限制为单行。 git reflog -1.
  • @EtanReisner 你是对的。傻我。

标签: git awk branch reflog


【解决方案1】:

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

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

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

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

【讨论】:

  • 结帐后从何而来?还有什么版本的git?它适用于分支切换结帐。
  • 忘记我的最后评论。这似乎是答案。如果HEAD 在上次结帐之前被分离,您可能需要补充一点,您的命令不会输出任何内容。
  • @EtanReisner {-1} 指的是什么?我找不到有关它的文档。
  • @EmilDavtyan 结果是 git parsing the reflog message。我不知道在它到达那里之前会发生什么失败以阻止它在您的测试用例中工作,但这是一个不同的问题。这是从interpret_nth_prior_checkout 调用的。
【解决方案2】:

我只会使用:

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>...]'

所以如果通过commit删除或更改分支,我认为该方法会失败。

【讨论】:

  • 不幸的是,如果多个引用指向先前签出的提交,那么HEAD 指向的那些git branch --contains @{1} 没有给出。
  • 是的,但我认为git branch --contains HEAD@{1} 可以。
猜你喜欢
  • 2018-03-19
  • 2016-07-31
  • 1970-01-01
  • 1970-01-01
  • 2021-06-20
  • 2011-03-09
  • 1970-01-01
  • 2010-09-13
相关资源
最近更新 更多