Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

git

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

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

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

(N.B. 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.)

like image 615
dumbledad Avatar asked Jan 10 '16 09:01

dumbledad


2 Answers

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

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.

(N.B. 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.)

like image 154
dumbledad Avatar answered Sep 29 '22 10:09

dumbledad


The problem is that git log only prints the log of one ref, that is why your xargs call is not working. If you e.g. 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. 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:

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.

like image 22
andreas-hofmann Avatar answered Sep 29 '22 09:09

andreas-hofmann