使用`git for-each-ref`和`git log`显示origin上每个远程分支的最新提交记录

15

我已经执行了git fetch --all --prune命令以从远程仓库获取引用,现在我想看到origin上每个分支的最新提交。

该命令为:

git for-each-ref --format='%(refname:short)' | grep 'origin/'

列出origin上的所有十六个分支,因此我期望以下命令能够显示每个分支最近的提交记录

git for-each-ref --format='%(refname:short)' | grep 'origin/' | 
xargs git log --source -n 1 

请注意:当我运行此命令时,它只显示了一行,但为了方便阅读,我将其拆分成两行。

但是这个命令不起作用,它只列出了一个提交记录:看来整个列表应用于每个分支,而不是逐个分支应用一个提交记录的限制。

我做错了什么?

(请注意,我还尝试了在这里适应该解决方案)

git for-each-ref --format='%(refname:short)' | grep 'origin/' | 
xargs git show --oneline 

但是 --oneline 标志被忽略了,结果过于冗长。


1
请注意 - 您可以在 for-each-ref 中限制分支,因此无需调用 grep。 - Andrew C
3个回答

12

更简单的解决方案是使用 git ls-remote origin 命令:

git ls-remote --heads origin

例如,在git仓库中:
C:\Users\vonc\prog\git\git>git ls-remote --heads origin|
117eea7eaaeb5ecb77d9b7cebdb40b4e85f37374        refs/heads/maint
f5b6079871904ba5b0a8548f91545f126caf898b        refs/heads/master
edb03e5a9b9b63d0864557f99f339b2b5f3a9e4e        refs/heads/next
014438bc5bdf9deef0d3888e58c9f76addc1106c        refs/heads/pu
56f24e80f0af4dd3591c8f143183b59cf9a34620        refs/heads/tmp
33f854ca9eb8251f5b7fa1c670d4abcdd76764ce        refs/heads/todo

这将列出最近的提交记录……甚至在没有先获取的情况下!

这可以轻松地进行格式化和别名设置:

C:\Users\vonc\prog\git\git>
git config alias.rh "!git ls-remote -h origin | while read b; do PAGER='' git log -n1 --color --pretty=format:'%ct%C(yellow)%d%Creset - %Cred%h%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset%n' --abbrev-commit $( echo $b | cut -d' ' -f1 ) --; done | sort -rn -k1,10 | cut -c11-"

然后简单的 git rh 就会给出:
C:\Users\vonc\prog\git\git>git rh
 (origin/master, origin/HEAD) - f5b6079 Second batch for 2.7 (3 months ago) <Junio C Hamano>
 (origin/next, next) - edb03e5 Sync with 2.1-rc2 (1 year, 5 months ago) <Junio C Hamano>
 (origin/tmp, tmp) - 56f24e8 completion: handle '!f() { ... }; f' and "!sh -c '...' -" aliases (1 year, 7 months ago) <Steffen Prohaska>
 (origin/pu) - 014438b Merge branch 'nd/multiple-work-trees' into pu (1 year, 10 months ago) <Junio C Hamano>
 (origin/todo) - 33f854c What's cooking (2013/07 #09) (2 years, 5 months ago) <Junio C Hamano>
 (tag: v1.8.3.4, origin/maint) - 117eea7 Git 1.8.3.4 (2 years, 6 months ago) <Junio C Hamano>

那就是:

git rh


这个别名假设远程仓库的名称为“origin”。
要使其接受参数,它可以被更改为一个函数
C:\Users\vonc\prog\git\git>git config alias.rh "!f() { git ls-remote -h $1 | while read b; do PAGER='' git log -n1 --pretty=format:'%h%n' --abbrev-commit $( echo $b | cut -d' ' -f1 ) --; done; }; f"
                                                                        ^^

然后:

C:\Users\vonc\prog\git\git>git rh upstream
833e482
7548842
ef7b32d
f67e31e
e2281f4

太棒了 - 可以在未获取前工作,并且可以使用巧妙的格式选项!谢谢。我暂时不会将其标记为答案;虽然我可能会转换到这种技术,但我想知道我的 xargs 方法哪里出错了。 - dumbledad
1
@dumbledad 我已经编辑了答案,使其接受一个参数。这样,您可以查询任何您想要的远程仓库(origin或其他命名的仓库)。 - VonC
尽管 git ls-remote 指令可以在未先获取内容的情况下使用,但是 git log 指令需要先获取内容才能保持最新吗? - dumbledad
@dumbledad 是的,它确实有用。不过,OP 开始时是这样说的:“已经执行了 git fetch --all --prune 以从远程仓库获取引用”,所以先进行了获取操作。 - VonC

8

结合 Andrew C 在原帖中的评论,指出可以将模式匹配包含在 git 命令中(而不是使用 grep),并且结合 andreas-hofmann 在 他的回答 中指出 xargs 正在混淆参数,那么另一个可能的解决方案如下:

git for-each-ref --format='%(refname:short)' refs/remotes/origin/ | xargs -n1 git log --max-count=1 --source

这将交换模式匹配以在git命令中发生,并告诉xargs一次最多提供一个参数。
(注意:git的for-each-ref命令中的模式匹配从匹配的开始处开始,因此我必须使用'refs/remotes/origin/'而不是可以使用grep的模式'origin/'。为了简洁起见,我可以用-1替换--max-count=1。)

我同意这似乎是模式更好的使用方式。+1 - VonC
有没有办法只显示特定的分支(例如主分支和开发分支)?或者只显示标签? - bubbles
你不需要使用 xargs,因为你可以在 --format 中获取几乎所有内容。 - shabunc

6
问题在于git log仅打印一个引用的日志,因此您的xargs调用无法正常工作。例如,如果您调用git log -n 1 origin/master origin/not_master(使用xargs将导致这样的调用),则会获得最新提交的日志,并且该列表仅限于第一个条目。我不知道如果两个分支分叉会发生什么情况,但是您将限制完整的日志输出为仅有一个条目。

除了VonC详细的答案外,您还可以修改命令以实现所需的结果,如果您将git log命令包装在循环中而不是使用xargs:

for ref in $(git for-each-ref --format='%(refname:short)' | grep 'origin/')
do
    git --no-pager log $ref -n 1 --oneline
done

使用--no-pager选项将输出直接发送到控制台。

1
太棒了,谢谢。对于在Bash控制台键入,我选择了 for ref in $(git for-each-ref --format='%(refname:short)' | grep 'origin/'); do git --no-pager log $ref -n 1 --source ; done - dumbledad
1
xargs做得很好,加1。 - VonC

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