Merging one commit at a time
Merging one commit at a time
Posted Jun 18, 2019 16:14 UTC (Tue) by epa (subscriber, #39769)Parent article: Rebasing and merging in kernel repositories
Is there a way to get the best of both worlds? Can I ask to merge a branch into mine a single commit at a time? That is, for each commit X on the other branch that's not already an ancestor of my branch, individually 'git merge X', resolving conflicts if necessary. Then go on to the next commit in the other branch, and so on to the end. The revision graph will become spaghetti, but you have individually reviewed each change rather than having to resolve conflicts as a big lump, and at the same time preserved the history of your branch. (If there were long sequences of commits that applied without conflicts, they could be replaced with a single merge commit merging in the last one of the sequence.)
Is there a git tool that will do this?
Posted Jun 18, 2019 17:21 UTC (Tue)
by mathstuf (subscriber, #69389)
[Link] (2 responses)
Posted Jun 18, 2019 18:27 UTC (Tue)
by epa (subscriber, #39769)
[Link] (1 responses)
Posted Jun 21, 2019 15:43 UTC (Fri)
by andrewsh (subscriber, #71043)
[Link]
Posted Jun 19, 2019 9:45 UTC (Wed)
by nilsmeyer (guest, #122604)
[Link]
Posted Jun 19, 2019 16:51 UTC (Wed)
by iabervon (subscriber, #722)
[Link] (1 responses)
There's nothing saying you can't do the error-prone merge, and, before pushing it, amend it to the error-free result you figured out some other way.
Posted Jun 19, 2019 17:14 UTC (Wed)
by epa (subscriber, #39769)
[Link]
Posted Jun 19, 2019 19:19 UTC (Wed)
by rweikusat2 (subscriber, #117920)
[Link] (8 responses)
Posted Jun 19, 2019 20:40 UTC (Wed)
by mbunkus (subscriber, #87248)
[Link] (3 responses)
Posted Jun 19, 2019 21:13 UTC (Wed)
by rweikusat2 (subscriber, #117920)
[Link] (2 responses)
Posted Jun 20, 2019 12:19 UTC (Thu)
by mbunkus (subscriber, #87248)
[Link] (1 responses)
git checkout -b $new work-with-old-to-new
The second command will
1. reset the current branch ("work-with-old-to-new") to the revision given with "--onto", meaning "work" and "work-with-old-to-new" will point to the same commit,
The result is that your new branch "work-with-old-to-new" will now contain all commits from the range $old..$new on top of what's already present in "work". And that sounds pretty much like what you described.
This procedure has nothing to do with "upstream" or with which branch "work" tracks.
Posted Jun 20, 2019 14:16 UTC (Thu)
by rweikusat2 (subscriber, #117920)
[Link]
Posted Jun 19, 2019 21:18 UTC (Wed)
by epa (subscriber, #39769)
[Link] (1 responses)
That’s why I asked about a tool which, instead of cherry-picking, does a merge at each step, leaving a revision that shows what happened and can in turn be merged automatically with others that might have done a similar thing.
Posted Jun 20, 2019 14:21 UTC (Thu)
by rweikusat2 (subscriber, #117920)
[Link]
Posted Jun 20, 2019 9:48 UTC (Thu)
by geert (subscriber, #98403)
[Link]
Posted Jun 23, 2019 17:21 UTC (Sun)
by nix (subscriber, #2304)
[Link]
(You can tell if the merge failed via the exitcode of the git cherry-pick: git cherry-pick --abort then gets you back to a consistent state.)
Merging one commit at a time
Merging one commit at a time
Merging one commit at a time
Merging one commit at a time
Merging one commit at a time
Merging one commit at a time
It's pretty simple, actually. Assuming you have two somehow identified commits, eg, tags, one representing and old version of something which is already incorporated in your code and one denoting a new version, the command
Merging one commit at a time
git rev-list --reverse "$old".."$new"
can be used to get a list of all commits between old and new in chronological order. These can then be applied one-by-one via
git cherry-pick "$commit"
I have a fairly simple (77 lines) script for this which aborts in case of a merge conflict after putting a tag with a magic name on the last 'clean' single commit merge. After resolving the conflict, the script can just be rerun. It'll find the last successful cherry-pick with the help of the tag, delete the tag and continue merging the remaining commits in the sequence.
Merging one commit at a time
Merging one commit at a time
Merging one commit at a time
git rebase --onto work ${old}~
2. take the commits in range $old..$new and cherry-pick each of them on top of the current branch (still "work-with-old-to-new")
3. If any of the cherry-pick attempts fails, git will pause rebasing, let you fix the situation (resolve conflichts, git add, git commit…) and then you run "git rebase --continue" and git will continue cherry-picking where it was interrupted.
Merging one commit at a time
Merging one commit at a time
Merging one commit at a time
Instead of rev-list, you can also use cherry:
Merging one commit at a time
git cherry -v $old $new
This will show all new commits, prefixed with a - or +, indicating if they are or are not yet present in the old branch.
Then you can cherry-pick the ones prefixes with +.
(yes, this is the same as what git rebase --onto does).
Merging one commit at a time