简体   繁体   English

使用`git for-each-ref`和`git log`在源上的每个远程分支上显示最近的提交

[英]Show most recent commit on each remote branch on origin using `git for-each-ref` and `git log`

Having done git fetch --all --prune to fetch refs from the remote repositories I now want to see the most recent commit on each of the branches on origin 完成git fetch --all --prune从远程存储库中获取refs后,我现在想要查看每个origin上的最新提交

The command 命令

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

lists all sixteen branches on origin , and so I would expect the following command to show the most recent commit from each one 列出了所有16个分支的origin ,因此我希望以下命令显示每个分支的最新提交

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

(NB This is one line when I run it; I have split it over two for readability.) (注意,当我运行它时,这是一行;为了便于阅读,我将它拆分为两行。)

However the command does not work, it only lists one commit: it seems the one commit limit applies to the entire list and not to each branch in turn. 但是该命令不起作用,它只列出一个提交:似乎一个提交限制适用于整个列表而不是依次应用于每个分支。

What am I doing wrong? 我究竟做错了什么?

(Note that I have also tried to adapt the solution here (请注意,我也尝试在此处调整解决方案

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

but the --oneline flag is ignored and the result is too verbose.) 但是--oneline标志被忽略,结果太冗长了。)

A simpler solution is to use git ls-remote origin : 一个更简单的解决方案是使用git ls-remote origin

git ls-remote --heads origin

For example, in the git repo: 例如,在git repo中:

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

That will list the most recent commits... even without fetching first! 这将列出最近的提交......即使没有先获取!

That can be formatted and aliases easily: 这可以轻松格式化和别名:

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-"

Then a simple git rh would give: 然后一个简单的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>

That is: 那是:

git rh


This alias assume the remote is named 'origin' though. 这个别名假设遥控器被命名为“origin”。

To make it accept a parameter, it can be changed to a function : 要使其接受参数, 可以将其更改为函数

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"
                                                                        ^^

Then: 然后:

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

The problem is that git log only prints the log of one ref, that is why your xargs call is not working. 问题是git log只打印一个ref的日志,这就是你的xargs调用不起作用的原因。 If you eg call git log -n 1 origin/master origin/not_master (using xargs will result in a call like this) you'll get the log up to the most recent commit and that list is then limited to the first entry. 如果您例如调用git log -n 1 origin/master origin/not_master (使用xargs将导致这样的调用),您将获得最新提交的日志,然后该列表仅限于第一个条目。 I don't know what exactly will happen if the two branches have diverged, but still, you'll limit the complete log output to only one entry. 我不知道如果两个分支有分歧会究竟会发生什么,但是,你仍然会将完整的日志输出限制为只有一个条目。

Additionally to VonC's detailed answer, you can modify your command to achieve the desired result if you wrap the git log command in a loop instead of using 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

Use the --no-pager option to send the output directly to the console. 使用--no-pager选项将输出直接发送到控制台。

Combining Andrew C's comment on the original post, that the pattern matching can be included in the git command (instead of using grep), with andreas-hofmann's point (in his answer ) that xargs is conflating arguments, then another possible solution is this 结合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

This swaps the pattern matching to occur in the git command and tells xargs to provide at most one argument at a time. 这将交换模式匹配以在git命令中发生,并告诉xargs一次最多提供一个参数。

(NB The pattern matching in git's for-each-ref command goes from the start of the match so I have to use 'refs/remotes/origin/' instead of the pattern 'origin/' which I could use with grep. And I could replace --max-count=1 with -1 for brevity.) (注意:git的for-each-ref命令中的模式匹配从匹配的开始开始,所以我必须使用'refs / remotes / origin /'而不是我可以用grep使用的模式'origin /'。我为了简洁起见,可以用-1替换--max-count = 1。)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM