Search code examples
gitrebasegit-rebase

git rebase a branch since it was created


At the moment when rebasing a branch (e.g. a feature branch before merging into master) I have to manually look up when the branch was created to tell git rebase the start-point for rebase.

I have the strong feeling that this can be automated — is there a way to tell git rebase to start when the branch was created?


Solution

  • Assuming you are working on the branch feature/foo which is based on the master branch.

            F--J--K--|feature/baz|
           /
    A--B--D--G--|master|
        \
         C--E--H--|feature/foo|HEAD|
    

    In order to rebase the work onto master there are different options:

    1. As explained by remram you can explicitly name the target commit using the --onto:

      // 1.1. Will move the flag `feature/foo`
      git rebase --onto master B feature/foo
      // 1.2. Will not move the flag `feature/foo`
      git rebase --onto master B H
      // 1.3. If the HEAD is at H
      git rebase --onto master B
      

      Since the --onto lets you define the target commit it is useful if you want to rebase feature/foo onto feature/baz which do not share a common branch base.

      // 1.4. Will rebase `feature/foo` onto `feature/baz`
      git rebase --onto feature/baz B feature/foo
      
                  /--|feature/baz|
                 /
          F--J--K--C'--E'--H'--|feature/foo|HEAD|
         /
      A--B--D--G--|master|
      
    2. As explained by Stefan Fleiter you do not have to name the ancestor if feature/foo is based on master:

      // 2.1. Explicitly naming feature/foo as the branch to be rebased onto master
      git rebase master feature/foo
      // 2.2. Assuming that feature/foo is currently checked out aka. HEAD
      git checkout feature/foo
      git rebase master
      
    3. If you do not feel comfortable with the rebase process since your former branch feature/foo "disappears" cherry-pick might be a feel-good alternative for you. The command allows to specify a range of commits and behaves very similar to rebase --onto. The difference is that the branch you are cherry-picking from will remain untouched.

      // 3.1.1. Start by creating a new branch where master is
      git checkout master
      git checkout -b feature/foo-cherried
      
              F--J--K--|feature/baz|
             /
      A--B--D--G
          \     \
           \     \-|master|feature/foo-cherried|HEAD|
            \
             C--E--H--|feature/foo|
      
      
      // 3.1.2. Pick a range starting at the common branch base
      git cherry-pick B..H
      
              F--J--K--|feature/baz|
             /
      A--B--D--G--C'--E'--H'--|feature/foo-cherried|HEAD|
          \     \
           \     \-|master|
            \
             C--E--H--|feature/foo|
      
      
      // 3.1.3. Later on if everything worked fine you can 
      // delete the unmerged branch feature/foo
      git branch -D feature/foo
      
              F--J--K--|feature/baz|
             /
      A--B--D--G--C'--E'--H'--|feature/foo-cherried|HEAD|
                \
                 \-|master|
      

    For more information about git rebase --onto I recommend a blog post here: