I want to use git cherry
to show all commits that went to a specific branch but are missing from the master branch and log this using pretty format.
I tried this:
git cherry master branch_name | grep "^+" | sed 's/^+ //' | xargs -I {} git --no-pager log --pretty=format:'%h,%an,%d,%ae,%ad,%s' --date=short -1 {}
What this does is to:
git cherry master branch_name
- list in the terminal line by line all hashes of commits that have code in branch_name and not in master and the other way around with a + or a - sign before the hash.grep "^+"
- get only those that start with a + (the ones missing in master from branch_name actually)sed 's/^+ //'
- remove the+
from the line so we can get only the hash.xargs -I {} git --no-pager log --pretty=format:'%h,%an,%d,%ae,%ad,%s' --date=short -1 {}
- passes each hash as a parameter to git log to show the formatted log of each hash. Here--no-pager
mean to exit git log window and-1
to show only 1 commit.
The problem with this is that it starts concatenating each result for each hash returned from git cherry on the same line. It doesn't execute it line by line so I can copy paste them or so I can save them to a csv file using ... > tmp.csv
.
Not sure if there is anything else I can use apart for xargs
or if that is actually a problem with git log and this won't work.
What am I missing? and what am I doing wrong?
Thank you all and sorry for being a noob.
You used
--pretty=format:...
. Note that there is a--pretty=tformat:...
as well, and that it is a default:The
--pretty=tformat:...
form can therefore be abbreviated as--format=...
.Simplifying:
--no-walk
andsed
tricksAside from this, there's a somewhat better (more efficient) way to achieve the desired result. You can still use
git cherry
like this, and usesed
to strip off the markers, just as before. You can omit thegrep
sincesed
can do that as well: usesed -n
ands/pattern/replacement/p
. And, now that you have selected the right commits, you can then give them all as arguments to onegit log
command, and use--no-walk
to makegit log
look only at the supplied hashes, and not at any of their ancestors.That is, instead of:
you could do:
(you can now omit
--no-pager
too, as I did, since it's safe enough to let the pager run).But in fact, it's all built in
If
git log
were not essentially the same command asgit rev-list
, this would be the way to go—but in fact,git log
andgit rev-list
take all the same commit selection arguments. Furthermore,git cherry
is mostly just a front end forgit rev-list
,1 so there's an even more efficient way to do this:where
$format
is your desired format. (I think—getting the left/right only, cherry-pick/cherry-mark arguments correct is a bit tricky; this is based on a quick scan through the man page and somewhat hasty reading of your question.)1 When using
git cherry
with a<limit>
argument, I am not sure you can get the same fromgit rev-list
, though^<limit>
might work.