* RFC - rebase--
@ 2025-06-06 21:00 Edmundo Carmona Antoranz
2025-06-12 0:06 ` Nico Williams
0 siblings, 1 reply; 2+ messages in thread
From: Edmundo Carmona Antoranz @ 2025-06-06 21:00 UTC (permalink / raw)
To: Git List
Hi, everybody! It's been a while. I hope you are all doing great.
You remember that I had spent some time trying to come around ways to
get rebase to take advantage of the original commits that were being
rebased to tackle conflict resolution... I don't think that anything
was implemented back then from my patches but there were interesting
conversations about the topic. It had been a while since I stopped
thinking about the subject but in the last few days I felt like giving
it another bite and see how far I could take it.
So, I sat down and wrote rebase--, a pygit2-based script (yeah, I
know, I am a shameless cheater :-)) that _attempts_ to run rebases and
take advantage of previous merge commits to try and avoid asking the
user to redo conflicts **if they are easy to deal with**. It is _not_
meant to be a replacement of rebase, given that rebase has a lot of
very powerful (not to mention useful!!!) options that I do not want to
replicate (hence -- instead of ++). I just want to be able to run a
straight-forward non-interactive rebase that might include merges.
At the time, it is able to give me the expected results in some
scenarios where git gives up... here's a quick example using a linux
repo:
$ git rebase --rebase-merges v2.6.39~100 v2.6.39~80 --onto v2.6.39~110
This one breaks on bab0dcc717e2.
with rebase--:
$ rebase-- v2.6.39~100 v2.6.39~80 --onto v2.6.39~110
Rebasing 189/189
Resulting commit: dc3441f19784813f65979f279133bff1c2c6642d
(it ran in less that 0.4 sec... working tree does not move, no
references are changed, it's all done "in-memory" and writing objects
in the repo db)
Now,I should expect to see the same differences between v2.6.39~110
and v2.6.39~100 to be present between dc3441f197848 and v2.6.39~80.
$ git diff v2.6.39~110 v2.6.39~100 | md5sum -
aee0292465ed6ba76fd1d283a820568c -
$ git diff dc3441f197848 v2.6.39~80 | md5sum -
aee0292465ed6ba76fd1d283a820568c -
So, at least it is working with this example where rebase-- could
solve the conflicts by taking the appropriate existing object
(tree/blob) in full that made sense for each scenario.... if it can't
solve it, it just reports where it gave up:
$ rebase-- v2.6.39~20 v2.6.39 --onto v2.6.39~100
Rebasing 49/80
Could not rebase commit b5e6ab589d570ac79cc939517fab05c87a23c262: We
could not merge path mm/page_alloc.c
Or with --verbose:
$ rebase-- v2.6.39~20 v2.6.39 --onto v2.6.39~100 --verbose
Rebasing 49/80
Failed to merge commit b5e6ab589d570ac79cc939517fab05c87a23c262
Current path: mm/page_alloc.c
original object: 3f8bce264df66f712e9a44092f871d9f90eafe22
original parent objects: [570d944daeb5d9cd0593c68b57698b2019acfdc9]
rebased parent objects: [9f8a97b9a350d17ec070d5e741c04f8d9998e7a8]
Could not rebase commit b5e6ab589d570ac79cc939517fab05c87a23c262: We
could not merge path mm/page_alloc.c
So, if you feel like it, please, give it a test and let me know how it
goes of if you have comments or questions.
My next steps for it:
- At the moment, it does not try to _merge_ blobs. It deals with them
_in full_ and takes a full blob if the scenario allows it. If not, a
merge would be required to see if any of the conflicts that is popping
up was already solved in the original commit being rebased...... I
will try to turn that paragraph into code.
- allow moving the working tree and adjust checked out reference
- fix bugs
Thanks for reading.
Here's the gh repo:
https://github.com/eantoranz/rebase--
BR!
^ permalink raw reply [flat|nested] 2+ messages in thread
* Re: RFC - rebase--
2025-06-06 21:00 RFC - rebase-- Edmundo Carmona Antoranz
@ 2025-06-12 0:06 ` Nico Williams
0 siblings, 0 replies; 2+ messages in thread
From: Nico Williams @ 2025-06-12 0:06 UTC (permalink / raw)
To: Edmundo Carmona Antoranz; +Cc: Git List
On Fri, Jun 06, 2025 at 11:00:10PM +0200, Edmundo Carmona Antoranz wrote:
> So, I sat down and wrote rebase--, a pygit2-based script (yeah, I
> know, I am a shameless cheater :-)) that _attempts_ to run rebases and
> take advantage of previous merge commits to try and avoid asking the
> user to redo conflicts **if they are easy to deal with**. [...]
That's cool, but I hope not to ever benefit from it because I prefer
rebase-only workflows -- look ma'! no merges! :)
I use a different approach which is to use something like a bisection to
find the first upstream commit where a conflict arises -if any- so I can
resolve the conflict there where the information about what changed
upstream is most relevant. This is the script I use:
https://gist.github.com/nicowilliams/ea2fa2b445c2db50d2ee6509c3526297
In the comments you'll find links to several similar tools:
https://gist.github.com/nicowilliams/ea2fa2b445c2db50d2ee6509c3526297?permalink_comment_id=4659501#gistcomment-4659501
git-imerge in particular is real pithy about what it does for you:
| Reduce the pain of resolving merge conflicts to its unavoidable
| minimum, by finding and presenting the smallest possible conflicts:
| those between the changes introduced by one commit from each branch.
But yeah, if you have a codebase that merged from upstream and now you
want to rebase it, then using the conflict resolutions from the merges
makes sense. It's just I hope dearly to avoid merges, and IMO more
people should do that too.
I get that this message risks starting a flame war :( but it's not my
intent to start a flame war. And I get that there are cases where you
have to merge features from multiple upstreams and cherry-picking gets
tricky enough that merging becomes the only viable option. But if you
have to track multiple upstreams and you can help it you'll be much
better off cherry-picking than merging, and in all other cases just
follow a rebase workflow.
This sort of problem (rebasing or merging across massively many commits
upstream) is the sort where rebase workflows shine precisely because
your commits are "always on top", therefore they are always easily
identified as the commits you want to "move" to be based on a new
upstream HEAD. With merge workflows you simply can't get the
information you need to resolve conflicts, and the best you can do is
"see how I did it before", but with rebase workflows and conflict
bisection you get to have the most pristine conflicts -- the ones where
you have the most local and upstream information available to help you
resolve the conflict.
Nico
--
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2025-06-12 0:24 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-06-06 21:00 RFC - rebase-- Edmundo Carmona Antoranz
2025-06-12 0:06 ` Nico Williams
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox