logoalt Hacker News

xg15today at 11:37 AM2 repliesview on HN

I use interactive rebases frequently, but even then, I think conflicts happening during a rebase are often somewhat cryptic.

I think I know what happens in principle (each step of a rebase does a merge of the commit from the list with the last rebased commit) but it's still often hard to understand which side of the conflict represents what, and what would be the desired outcome for that step in the history. So I tend to abort the rebase when I get a conflict and see if I can plan it differently so I can get it through without conflicts.

What I found good to know is that only actions that modify the actual changes in the history - reordering, deleting or editing commits - can cause conflicts. The other actions - reword, fixup or squash - only modify how the changes are grouped into commits and cannot cause conflicts.

So I usually do an interactive rebase in several passes: First a rebase that only reorders commits (or rarely does deletes or edits) and where I deal with the resulting conflicts, then a second pass for fixup or squash operations that can then use the reordered history from the first pass.

Rewords are both harmless and don't require any particular ordering, so can be done in any pass.


Replies

OJFordtoday at 12:49 PM

> but it's still often hard to understand which side of the conflict represents what, and what would be the desired outcome for that step in the history.

Are you using diff3/zdiff3? I ask because you seem to be describing exactly the problem it solves, or at least the way I try to sell people on it.

Basically in addition to 'current' & 'incoming from the rebase' hunks you get 'parent commit of incoming from the rebase' – which allows you to see 'what was I trying to change', i.e. how does the intent of it apply to the different thing that's now on master (whatever I'm reading onto).

show 1 reply
wsc981today at 1:18 PM

In case of many commits with also many complex merge conflicts, I often find it easier to just:

1. Abort rebase.

2. Squash all my commits into a single commit.

3. Rebase on target branch again.