0

I have a feature branch (in red) that a developer has been working on, and they periodically re-pulled from dev branch as other feature branches were started and completed in the intervening time, to minimize them from getting too far out of sync. (In iOS projects, certain Xcode-generated files are endless sources of hard-to-resolve merge conflicts, so it helps immensely to keep the branches from diverging too far.) It is not terribly relevant here, but dev branch (blue) has moved on even further.

enter image description here

I would like to rebase (and squash) this feature branch off of dev now that it is done. (Yes, I know that some teams prefer to just merge, but we have always rebased/squashed our feature branches.)

I've been doing this pattern for years, and it has worked fine. Everytime dev marches on, we rebase our various feature branches, and all is well.

But, with these merge commits, it seems that every git rebase -i xxxxxxx that I try is reporting a ton of previously resolved merge conflicts. Sure, I can imagine having merge conflicts for stuff that has taken place subsequent to this feature branch (above, off the top of the screen, in blue), but I would have thought that I should at least be able to rebase/squash back to some shared commit, e.g., e57aa49 (or a1fbff9 or 51b1aaa) with zero merge conflicts (as the dev has already resolved those conflicts when they did their interim merges). But the presence of these two merge commits (e61e820 and 60deb25) seem to be causing headaches. And when git rebase -i xxxxxxx, these two merge commits do not even appear in the list (so I can't explicitly pick, squash, or drop them). But I've tried all the logical permutations (picking just the red commits and dropping the blue ones, for example), and I always end up with merge conflicts in a code base that seems like it should have zero merge conflicts.

So, how do I rebase/squash this feature branch (currently at 2718a7a) to e57aa49, for example, without having to go through a ton of merge conflicts that the dev has already resolved?

Effectively, I'm looking to end up with something like the following (which I can then easily rebase to dev). But I just don't want to have to deal with merge conflicts that have already been resolved.

enter image description here

Rob
  • 415,655
  • 72
  • 787
  • 1,044
  • _"periodically re-pulled from dev branch"_... rebased or merged? – Phil Aug 17 '22 at 02:00
  • The fact that you don't see the merge commits is half the problem. You need to add `--preserve-merges` to your `rebase -i` command. The rebase will end up being a _lot_ more complicated, but it will be more complicated in a good cause. – matt Aug 17 '22 at 02:19
  • "But, with these merge commits, it seems that every git rebase -i xxxxxxx that I try is reporting a ton of previously resolved merge conflicts. " this is what [`git rerere`](https://git-scm.com/docs/git-rerere) is for, [you can light it retroactively](https://stackoverflow.com/questions/23857349/re-use-conflict-resolution-with-git). – jthill Aug 17 '22 at 02:19
  • 1
    @Phil “‘periodically re-pulled from dev branch’... rebased or merged?” ... they apparently merged rather than rebasing, as requested. – Rob Aug 17 '22 at 02:39
  • As [eftshift0 answered](https://stackoverflow.com/a/73385695/1256452), this particular Gordian Knot is best cut rather than carefully untied. If you wish to untie it anyway for some reason, the key will be to find some exclusionary commit hash ID (or name) that keeps away most of the unwanted commits, and using `--onto` to give you a different name. If you can't programmatically exclude all the commits, use `git rebase -i` and drop from the rebase all the to-be-excluded commits (this is painful). – torek Aug 17 '22 at 09:20

1 Answers1

1

If you mean to merge/squash, why do you bother rebasing?

git checkout my-branch
git merge my-upstream-branch
git reset --soft my-upstream-branch
# at this moment _all your changes_ are in index (no need to do conflict resolution)
git commit -m "My feature, in a single shot"
eftshift0
  • 26,375
  • 3
  • 36
  • 60