git 日志--带前缀的分支

git log --branches with prefix

我想记录一组特定分支上的所有更改以查看它们之间的关系,我发现:

git log --graph --oneline --topo-order --decorate --simplify-by-decoration `git branch --list -a origin/foo/*`

完全符合我的要求(即记录所有以 foo/* 为前缀的分支上的更改)。

不过现在很好奇git日志的--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 别名会稍微简单一些。)

This question 讨论了相关主题 - 但我看不到关于我的具体问题的任何信息。

说明

这就是 "you need to know git's internals to understand the documentation" 的完美案例。我们需要的更少。

--branches 的文档说明它适用于 "refs in refs/heads"。远程跟踪引用不在 refs/heads 中,它们在 refs/remotes 中。因此,当查找 "origin/foo/*" 时,将找不到分支。因此 git 日志将恢复为默认行为,即从 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,这是一个陶瓷命令。它可能会在未来崩溃,因为 porcelain 命令的输出可能会发生变化。事实上,它确实在某些情况下已经中断,例如当您列出 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/*')