使用前缀的git log --branches

4
我希望记录特定一组分支的所有更改,以了解它们之间的关系。我发现:
git log --graph --oneline --topo-order --decorate --simplify-by-decoration `git branch --list -a origin/foo/*`

我希望它能够完全满足我的需求(即记录所有以foo / *为前缀的分支上的更改日志)。

但现在我对git log的--branches选项很好奇。它似乎应该以类似的方式工作,但如果我使用--branches=origin/foo/*--branches=remotes/origin/foo*甚至--branches=foo,输出会非常不同(只显示非常少且无关的提交)。

文档说:

--branches[=<pattern>]
Pretend as if all the refs in refs/heads are listed on the command line as
<commit>. If <pattern> is given, limit branches to ones matching given shell
glob. If pattern lacks ?, *, or [, /* at the end is implied.

有什么不同吗?我的问题已经解决了,因为我可以使用第一个版本 - 但我很好奇。 (如果避免使用反引号,则添加git别名会稍微简单一些。)

这个问题讨论了相关主题 - 但我没有看到任何关于我的具体问题的信息。


你有没有考虑在使用通配符时保护参数?就像这样 git log '--branches=origin/foo/*' - Pik'
@Pikrass 是的 - 那并没有帮助。 - Zitrax
1个回答

7

解释

这是一个典型的“你需要了解git内部机制才能理解文档”的案例。我们需要更少这样的情况。

--branches选项的文档说明它作用于“在refs/heads中的引用”。远程跟踪引用不在refs/heads中,而是在refs/remotes中。因此,当查找“origin/foo/*”时,找不到任何分支。因此,git log将恢复其默认行为,即从HEAD开始发现提交。

解决方案

您需要使用--remotes选项,该选项类似于--branches,但适用于refs/remotes中的引用。因此,变成:

git log --graph --oneline --topo-order --decorate --simplify-by-decoration --remotes='origin/foo/*'

另外,您还可以使用--glob,它适用于所有分支,但是您需要在前面加上heads/remotes/,或者使用通配符。例如:

git log --graph --oneline --topo-order --decorate --simplify-by-decoration --glob='refs/*/foo/*'

关于你的第一个命令

顺便提一下,你的第一个命令并不总是有效,因为你在反引号中使用了git branch这个外壳命令。外壳命令的输出可能会发生变化,所以它在将来可能会出现问题。实际上,在某些情况下,它已经无法工作,比如当你列举HEAD时。例如:

git log --graph --oneline --topo-order --decorate --simplify-by-decoration $(git branch --list -a 'origin/*')

这个命令给了我一个错误,说它无法将 -> 识别为参数。这是由于 git branch 的输出导致的:

remotes/origin/HEAD -> origin/master
remotes/origin/master

为了让您的命令在所有情况下都能正常工作并具有未来性,您可以使用git for-each-ref(这是一个管道命令),如下所示:
git log --graph --oneline --topo-order --decorate --simplify-by-decoration $(git for-each-ref --format='%(refname)' 'refs/remotes/origin/*')

好的,我明白了 - 尽管有点出乎意料,但这很有道理。谢谢。 - Zitrax

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接