Search code examples
gitrebase

Git rebase onto a tag when master and a branch is ahead of the current commits


I am having difficulties with Git. I am following a remote repo on my local machine. The master branch is being updated from the remote and I always sync with it to get the updates. And then my local branch ("feature" branch) is rebased onto the master branch to apply my local changes. The issue is I forgot to rebase my local branch onto master branch's version tag. instead I rebased onto the latest commit of master branch. Now I want to rebase my local branch to master's version tag branch without losing my local changes. Any ideas how to do it?

                          o -- o
                         /     ^ feature branch
o --- o --- o --- o --- o --- o --- o 
      ^ V2.0                        ^ master (origin/master)

I want to rebase my "feauture" branch like this:

        o -- o
       /     ^ feature branch
o --- o --- o --- o --- o --- o --- o 
      ^ V2.0                        ^ master (origin/master)

Solution

  • Checkout the git rebase manpage https://git-scm.com/docs/git-rebase.

    The remote branch origin/master (assuming your remote is called origin) is the upstream master. Rebase works by selecting a common ancestor between two branches and then cut off one part:

                              o -- o
                             /     ^ feature branch
    o --- o --- o --- o --- C --- o --- o 
          ^ V2.0                        ^ master (origin/master)
    

    Note that C is the common ancestor between the feature-branch and origin/master This is what git rebase later will use when we use git rebase origin/master feature-branch.

    Let's cut off the following:

                            [ X -- X ]
                             /     ^ feature branch
    o --- o --- o --- o --- C --- o --- o 
          ^ V2.0                        ^ master (origin/master)
    

    and attach it to v2.0. So let's do it:

    git stash          #  move local uncomitted changes away
    git checkout feature-branch
    git rebase --onto v2.0 origin/master
    git stash apply    # reapply uncommitted changes
    

    Rebase

    The rebase command will calculate the common ancestor between origin/master and your current branch. It will then cut off all the commits that are unique to your branch. (think about it as asking rebase for everything on feature-branch that is not also on origin/master). Now that we know what we cut off, we use the the --onto to specify the target. In our case a tag.