Rebasing selective commits interactively

When you are working on a new feature and have branched from an old release into a feature branch, you might want to rebase this branch onto the latest release. When looking into the list of commits on the feature branch, you realize that some of the commits are not suitable for the new release. So, when you want to rebase the branch onto a new release, you will need to remove some commits. This can be achieved with interactive rebasing, where Git gives you the option to pick the commits you wish to rebase.

Getting ready

To get started with this example, you need to check the previously created branch, rebaseExample; if you don't have this branch, follow the steps from the Rebasing a few commits section and use the following command:

$ git checkout rebaseExample
Switched to branch 'rebaseExample'
Your branch is ahead of 'origin/stable-3.1' by 109 commits.
  (use "git push" to publish your local commits)

Notice that because we are tracking origin/stable-3.1, the Git checkout will tell us how far ahead we are in comparison with that branch.

How to do it

We will try to rebase our current branch, rebaseExample, on top of the origin/stable-3.1 branch by performing the following steps. Remember that Git will apply the commits that are not available on the branch we are rebasing to; so, in this case, there will be a lot of commits:

  1. Rebase the branch onto origin/stable-3.1 by using the following command:
    $ git rebase --interactive origin/stable-3.1
    
  2. What you will see now is a list of all the commits you will be rebasing onto the origin/stable-3.1 branch. These commits are all the commits between the origin/stable-3.1 and rebaseExample branches. The commits will be applied from top to bottom, so the commits will be listed in reverse order, at least compared to what you would normally see in Git. This actually makes good sense. The commits have the keyword pick to the left and then the abbreviated commit hash, and finally the title of the commit subject.

    If you scroll down to the bottom, you will see a list like the following one:

    pick 43405e6 My brand new fishtank
    pick 08d0906 Feed the fish
    # Rebase da6e87b..08d0906 onto da6e87b
    #
    # Commands:
    #  p, pick = use commit
    #  r, reword = use commit, but edit the commit message
    #  e, edit = use commit, but stop for amending
    #  s, squash = use commit, but meld into previous commit
    #  f, fixup = like "squash", but discard this commit's log message
    #  x, exec = run command (the rest of the line) using shell
    #
    # These lines can be re-ordered; they are executed from top to bottom.
    #
    # If you remove a line here THAT COMMIT WILL BE LOST.
    #
    # However, if you remove everything, the rebase will be aborted.
    #
    # Note that empty commits are commented out
    

    So, if we only want our fishtank commits to be based on top of the origin/stable-3.1 branch, we should remove all the commits except for our two commits.

  3. Remove all the lines except for the two commits at the bottom; for now, leave pick as the keyword. Save the file and close the editor, and you will get the following message from Git:
    Successfully rebased and updated refs/heads/rebaseExample.
    
  4. Now, with gitk, try to check whether we accomplished what we predicted. The next screenshot shows our two fishtank commits on top of the origin/stable-3.1 branch. The following screenshot is what we expected:
    How to do it

There's more…

The same thing could actually be achieved with a single small Git command. We have been rebasing commits from the origin/stable-3.2 branch to the rebaseExample branch onto the origin/stable-3.2 branch. This can also be achieved in the following manner:

$ git rebase --onto origin/stable-3.1 origin/stable-3.2 rebaseExample
First, rewinding head to replay your work on top of it...
Applying: My brand new fishtank
Applying: Feed the fish

The --onto origin/stable-3.2 flag tells Git to rebase onto origin/stable-3.2, and it has to be from origin/stable-3.1 to the rebaseExample branch. So, we end up having rebaseExample branch to the branch of the origin/stable-3.1 and the like. The next diagram shows before the rebase example where we have our two commits on top of origin/stable-3.2, then after the rebase where our commits are on top of origin/stable-3.1 as we wanted:

There's more…
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset