Home > Mobile >  Doing both a rebase and a reverse merge to a branch at the same time
Doing both a rebase and a reverse merge to a branch at the same time

Time:09-16

When you have a feature branch that is long-lived, there are two standard ways to keep it somewhat in sync with your primary release branch without actually putting your code into the primary release branch.

Periodically, either you rebase your feature branch against the primary release branch, or you reverse-merge the changes in your primary release branch to your feature branch.

The rebase converts this:

A - - - PRIMARY BRANCH
 \
  \-1-2-3-FEATURE BRANCH

into this:

A - - - PRIMARY BRANCH
         \
          \-1'-2'-3'-FEATURE BRANCH

where the 1' 2' 3' are rebased versions of the original 1 2 3.

The merge converts it into

A - - - PRIMARY BRANCH
 \          \
  \ -1-2-3-  X - FEATURE BRANCH

Where X is a merge commit that has parents in both PRIMARY and in the original FEATURE branch.

A downside to the rebase solution is that someone with a copy of the feature branch now has a seemingly unrelated set of changes, as their 1 2 and 3 are not the same CLs as the ones after the rebase.

The changes in the rebase case reflect the changes "as if you did it at the moment of rebase" on the primary branch. This has some nice properties, as if you can roll back these changes one at a time and see how they behave in the current primary branch.

The Question

Is there an easy way using standard git tools to do both at once, keeping both the connection to the original feature branch, and a set of CLs that represent doing it against the current primary?

A - - - PRIMARY BRANCH
 \        \ 1'-2'-3' -
  \                   \
   \ -1-2-3----------- X - FEATURE BRANCH

in this case, the X would have the same content as the X in the reverse-merge scenario, except it also states that the original feature branch is a parent CL.

From this, we'd get the rebase workflow, but other people with access to the original feature branch aren't abandoned -- if they remerge against upstream FEATURE, git fully understands what is going on.

A - - - PRIMARY BRANCH
 \        \ 1'-2'-3' -
  \                   \
   \ -1-2-3----------- X - FEATURE BRANCH
           \- 3rd party

The 3rd party CL has a clear merge path to move to the tip of FEATURE BRANCH, instead of the mess it has to work through in the case of

A - - - PRIMARY BRANCH
 \        \ 1'-2'-3' - FEATURE BRANCH
  \                  
   \ -1-2-3-- OLD FEATURE BRANCH
           \- 3rd party

the traditional rebase.

CodePudding user response:

Is there an easy way using standard git tools to do both at once... ?

Yes, you can easily create the graph exactly as you proposed:

git fetch
git checkout feature
git branch feature-old-copy # create a copy of feature
git rebase origin/primary
git merge --strategy=ours feature-old-copy

Note that the final merge should have no effect; i.e. it's a pointless merge except to keep the old set of commit IDs in the branch...

However, IMHO I think you've misidentified the primary reason to choose rebase in the first place. Your statement:

The changes in the rebase case reflect the changes "as if you did it at the moment of rebase" on the primary branch. This has some nice properties, as if you can roll back these changes one at a time and see how they behave in the current primary branch.

is also true of a merge. (You can revert a commit regardless of whether it was rewritten with a rebase or merged in, though there is indeed a slight benefit to rebase.*) The primary benefit of rebase is a cleaner history without multiple merge commits that are (typically) unnecessary. As an example, when I use a rebase workflow I typically rebase onto the future target branch multiple times per day. If my branch lasts 2-3 days I have saved maybe 10 unnecessary merge commits on my branch. With your suggested workflow, you aren't really capturing the benefit of rebase, and therefore I don't see it being that useful.

So, yes, you can do it, but I question the value of doing it.


*It's possible that reverting individual commits underneath the merge could require reworking conflicts that occurred at the time of that merge, whereas with rebase they would already be resolved and are more likely to revert cleanly.

  • Related