2

TLDR I want the parent branches (in a linear branch) to move along with the new commits during a rebase.


Initial setup: multiple feature branches (on top of each other) each one waiting to be merged into master

A--B--C--D <-master
   \
    E--F--G--H--I--J--K--L
       ^     ^     ^     ^
       |     |     |     feature_d
       |     |     feature_c
       |     feature_b
       feature_a

A review is made, a new commit M is added to feature_a, then it is merged into master:

A--B--C--D--N <-master
   \       /
    E--F--M <- feature_a
       \
        G--H--I--J--K--L
           ^     ^     ^
           |     |     feature_d
           |     feature_c
           feature_b

It's here where I want to do the rebase.

Desired result: rebase feature_d to master and move all parent branches along:

A--B--C--D--N <-master
   \       / \
    E--F--M   G'--H'--I'--J'--K'--L'
                  ^       ^       ^
                  |       |       feature_d
                  |       feature_c
                  feature_b

The way I know how to do this is "manual", i.e. normal rebase of feature_d followed by moving each branch pointer:

git checkout feature_d
git rebase master
git branch -f feature_b H'
git branch -f feature_c J'

This requires manually searching and referencing the new commits by their sha. It involves extra attention and is error prone. I am hoping for an automated process, something like this:

git checkout feature_d
git rebase master --magic-option-move-branches-to-new-commits
bolov
  • 72,283
  • 15
  • 145
  • 224
  • Does this answer your question? [How do I rebase a chain of local git branches?](https://stackoverflow.com/questions/20834648/how-do-i-rebase-a-chain-of-local-git-branches) – Daniel McIntosh Jul 08 '22 at 18:23
  • @DanielMcIntosh is right, this seems like a dupe of that question, unless I'm missing a specific part of the question not covered there. – hraban Oct 30 '22 at 19:43
  • You may want to consider updating your accepted answer to @hraban's now that Git supports it the simple way. – Keavon Dec 11 '22 at 05:56

2 Answers2

1

The magic option you're looking for was introduced in Git 2.38, it's --update-refs. In your example, you'd do:

$ git checkout feature_d
$ git rebase --update-refs master

See https://github.blog/2022-10-03-highlights-from-git-2-38/ for more info, and https://stackoverflow.com/a/74256185 for an example.

hraban
  • 1,819
  • 1
  • 17
  • 27
0

This solution it's not one magic command, but it it does avoid manual naming of commits. Rebase each branch on top of it's parent branch, starting with the oldest one:

git checkout feature_b
git rebase master

git checkout feature_c
git rebase feature_b

git checkout feature_d
git rebase feature_c

I wasn't expected this to work. Here is the explanation why it works: Git rebase skipping identical commits

bolov
  • 72,283
  • 15
  • 145
  • 224
  • I wasn't expected this to work. Here is the explanation why it works: https://stackoverflow.com/questions/58917743/git-rebase-skipping-identical-commits – bolov Mar 01 '20 at 03:12
  • Note that this works fine up until one of the commits that the first ("deepest" or "oldest") rebase copies has a merge conflict and the new commit you make has a different patch-id than the original. For this reason and others, it would be nice if Git had a fancy multi-branch rebase operation built in ... but Git doesn't, so this is usually the way to go anyway. – torek Mar 01 '20 at 05:37
  • (Note, by the way, that branch names have no parent/child relationship. You might *want* one here, and use one in your work, but *Git* has none.) – torek Mar 01 '20 at 05:44