-1

as I work I create a branch (branch1) then I create a pr (pr1), then I keep working on the feature which is based on the code in that branch1. I create a branch (branch2) off of my branch (branch1). Then I create a pr(pr2) based on pr1. Maybe there's some feed back on pr1. So I create a new commit on branch1 and push it to pr1. Then I merge branch1 into branch2 and update pr2.

This seems like a totally natural way to work, and in fact I can't see any other reasonable way to work short of keeping everything in one branch and dumping a massive pr on my teammates to review.

The problem is that the remote is setup to squash merge your pr into main. So I merge pr1 into main. Then main has 1 new commit and branch2 has x number of basically orphaned commits. When I try to merge main into branch2, I spend the next hour resolving conflicts hoping I"m not undoing tons of work.

Given the intransigent fact that we are using squash merges, I can see only a couple "solutions".

  1. merge p4, into pr3 into pr2 into pr1, then squash merge pr1 into main. This stinks because you easily loose track of where new commits are merged to, and if they have been reviewed, it can be a real mess

  2. figure out exactly which commits are in branch2 but not in branch1 ( remember branch1 is still many commits, only main has the squash ). Then, I guess create a new branch. say branch2.1 off of main and rebase only those commits onto the new branch. This stinks for because a) I haven't even figured out how to do it and b) I would then loose all the context of pr2 on branch2 because it's now branch2.1 and c) because even if it's possible I suspect it will be a many step process that could easily be messed up.

I don't think it's reasonable to ask developers to wait for a PR to be completely reviewed and merged before doing more work. I also think that lots of folks, especially higher ups who make these kind of decisions like squash merges because it make it easy for them to see what's going on in the repository.

I've been search ( in between resolving conflicts ) for several days so far and have not found any system or even discussion about how to over come this situation. My first question is, is there a known way to do this. My second question is, if not, how could I go about crafting a series of commands that will reliably get me the correct commits and some how get them on top of the squash that comes from remote.

Thanks.

SO thinks this is a duplicate of What happens when branched branch gets merged however, it has very little to do with that question. My question is about resolving an issue where a branch contains commits which have been squashed in upstream branches

Raif
  • 8,641
  • 13
  • 45
  • 56

1 Answers1

1

It seems like you are the one who is merging these PRs. That means that you can emulate this “squashing” on your end and in that way keep up with the shenanigans that the remote is doing. (I’m assuming that it’s the remote that has to do the actual merge or else you wouldn’t be in this predicament.)

When you are about to merge x which is beneath y and z in the stack:

  1. git switch z (top of the stack)
  2. git rebase --interactive --update-refs <main branch>
    • --update-refs requires Git 2.38.0 or higher
  3. Interactively squash all the commits on x
  4. Force push x
  5. Do the merge
  6. Rebase z (with --update-refs) onto the updated main branch

(It might also work to rebase the bottom of the stack w.r.t. updating all the branches in the stack. I’m not sure.)

--update-refs will make sure that all the branches in your stack are updated. That’s why you can start the rebase on z, then force-push the updated x, and do a final rebase on z against the main branch.

Rebasing z on top of the updated main branch won’t be a problem most of the time since the “squashed” commit will contain the same as the squash you did manually. Or else someone else beat you to the punch and you might get a conflict, but that happens sometimes in any workflow.

Now your stack of branches should be properly updated.

Guildenstern
  • 2,179
  • 1
  • 17
  • 39
  • Thanks for the response. I'm checking it out. First issue I hit is that there doesn't seem to be a --update-refs flag for rebase. Is there something I'm missing? -- aha. I'm on v2.34.1 I'll update – Raif May 16 '23 at 23:01
  • 1
    @Raif You need at least Git 2.38.0 for that switch. – Guildenstern May 16 '23 at 23:05
  • Sorry, I deleted my comment, I was having trouble understanding rebase --update-refs. I'm getting a bit clearer now on it. thx – Raif May 16 '23 at 23:26