deepnote deepnote - 2 months ago 13
Git Question

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)

Answer

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.

A good explanation about rebase can be found here