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/*')
我想记录一组特定分支上的所有更改以查看它们之间的关系,我发现:
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/*')