Assume something like the following:
HEAD/master
|
A<--B<--C<--D<--E<--F<--G<--J
^
official
Where official
is a branch.
I wanted to cherry-pick 2 commits to official
branch e.g.E
and J
Both these commits were fixes affecting the same 3 files.
When I did git cherry-pick E
it went fine but when I did git cherry-pick J
I got some conflicts.
Looking at the diffs I realized that I needed to also cherry pick commit F which did a change in two of those 3 files which change was basically a method definition change and J
was done on top of that.
So it was easy to fix by just doing git cherry-pick F && git cherry-pick J
Question:
If I wasn't aware of the changes done in those files and commit F was a big commit changing many files: Is there another way to figure out on which commit a commit we are trying to cherry pick depends on without manually doing a git log on the file and going commit by commit?
Is there another way to figure out on which commit a commit we are trying to cherry pick depends on without manually doing a git log on the file and going commit by commit?
Yes there is - I wrote git-deps
to automate precisely that task. Since it currently accepts a range of commits to analyse, in the case of your example you would need to pass it a singleton range containing just commit J
, and also tell it to exclude any dependencies which are already in official
:
git deps --exclude-commits official J^!
Behind the scenes the tool will then look at the diff of J^
with J
, and then run git blame
on any lines which are removed or modified, plus a configurable number of lines of surrounding context. This would result in it discovering that one or more of the lines J
removes or modifies come from commit F
, therefore it would output the SHA1 of commit F
.
git-deps
can not only discover dependencies of a single commit or range of commits, but also recurse a whole dependency tree. Therefore the entire cherry-picking scenario you describe could be automated into a single command:
git deps --recurse --exclude-commits official J^! | \
tsort | \
tac | \
xargs -t git cherry-pick
Please note that this only guarantees that the cherry-picks will all cleanly apply, not that they are semantically correct. So the resulting branch head will still need to be carefully inspected and tested for correctness.
More convenient porting of commits between branches is the most obvious (but not the only) use case of git-deps
, and for this reason I have dedicated a section of the README specifically to this use case. It even includes a YouTube video showing you exactly how to use it.
If you would like more details, you may be interested in a couple of talks I have presented on this and other related tools:
I also spoke about the tool in episode #32 of the GitMinutes podcast.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With