Git – Interactive Rebasing

Last time we saw about Merge conflicts . This time let us explore about Interactive rebase. Interactive rebase is one of the most important tools that one can use inorder to maintain a logical work tree, even after making so many amends.

What is interactive rebasing ?

git rebase like we saw earlier is one of the most important command in git. One of the options in git rebase is --interactive or -i.

Let us try using interactive git rebase on a repository.

$ alias gl="git log --oneline --graph --decorate"
$ gl
* dbee184 (HEAD -> masterv2) Merge branch 'new_branch' into masterv2
|\
| * 9060af7 (new_branch) added abc
| * 82c5aa6 added xyz
| * 5088a37 commit8
| * 2337e97 commit7
| * cb435f4 commit6
| * cf2aca1 commit5
* | 721d20f (masterv3) commit12
* | 5c29aed commit11
* | cfae35a Merge branch 'new_2' into masterv2
|\ \
| * | 1d61006 (new_2) stashed commits
* | | ee978d1 commit to a tag
* | | 90b68fc (tag: version_master) added thank
|/ /
* | 871d5ee commit9
|/
* 2b9e414 (tag: grand_parent) Adding gitignore
* dab6699 Adding change2
* f8a10f7 Adding change1
* 00a5cfe Initial commit

On trying git rebase -i on a commit , this happens

$ git rebase -i 871d5ee

The preferred editor will open with this

pick 90b68fc added thank
pick ee978d1 commit to a tag
pick 1d61006 stashed commits
pick 5c29aed commit11
pick 721d20f commit12
pick cf2aca1 commit5
pick cb435f4 commit6
pick 2337e97 commit7
pick 5088a37 commit8
pick 82c5aa6 added xyz
pick 9060af7 added abc

# Rebase 871d5ee..dbee184 onto 871d5ee (11 command(s))
#
# 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
# d, drop = remove commit
#
# 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

The initial list is the list of commits after the commit we mentioned in chronological order. The commented out lines are instructions on how to use interactive rebase.

List ?

The list is an editable list of commits that can be operated on. As mentioned in the instructions below, the lines can be reordered. If reordered the resultant tree will consist of the modified tree as per the modified list we mention here.

Removing elements off this list removes that particular commit.

The first column is the option that we are going to do with that commit. The second column is the checksum of the commit. The third column is the one line commit message.

Options

Options decide what eventually happens to that commit during rebasing.

If the option used is pick, then it will mean that we are using that commit as such without making any changes if possible.( If merge conflicts occur, git will still stop and ask you to merge it yourself. )

reword option can be used to edit the commit message of the particular commit. It is important to remember that once we reword a particular commit , it is no longer the same commit as the checksum of that particular commit will change. So other branches using the same commit will still have the old commit message.

edit option can be used to edit the repository during that commit. By saying ‘During that commit’, i mean that git will start to apply every operation from the top. When it encounters an edit, it will stop and ask the user to make changes to the repository if necessary. Making changes include changing the files in repository for the commit, Adding extra commits in the middle etc. We will see about this later in detail

squash and fixup are similar. squash is the operation where the particular commit will be merged or squashed with the previous commit. Merging in this sense is not similar to the merging we saw previously. Here, merging commits is like including changes of both the commits in a single one instead of 2 ( or more ). squash always applies to the previous commit. i.e.

Let us assume

pick 1434s11 some commit
squash 6547231 other one

will result in a commit with changes in both `1434s11` and `6547231` and with both the commits messages appended together. Squash requests the user to provide a custom commit message for the new form of the commit. Like this

# This is a combination of 2 commits.
# The first commit's message is:

commit11

# This is the 2nd commit message:

commit12

# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
#
# Date: Sat May 19 23:54:27 2018 +0530
#
# interactive rebase in progress; onto 871d5ee
# Last commands done (5 commands done):
# pick 7b9f1bc commit11
# squash 4e327c4 commit12
# Next commands to do (6 remaining commands):
# pick d819135 commit5
# pick 75e1cf8 commit6
# You are currently editing a commit while rebasing branch 'masterv2' on '871d5ee'.
#
# Changes to be committed:
# new file: file2
# new file: file3
# new file: new_repo
# new file: x11
# new file: x12
#

The user can completely erase every thing and provide a entirely new commit or choose to stay with the suggestion. After saving and quitting the editor,git squashes these two commits and creates a custom commit.

* 63700eb commit11

fixup is similar to squash except that , unlike squash fixup will ignore the commit for the second commit and will take the first commit’s message directly, thereby eliminating an unnecessary invocation of the text editor.

exec is a special command by which a command can be executed while parsing this. This should not / need not contain any commits in the same line

exec ls -lh

The above will execute ls -lh when encountering this and dump the output in the stdout. This can be helpful for diagnostic purposes and can be used to check whether anything fails when during the process.

To be Continued

We will continue discussing about interactive rebasing with an example in the next article.

1 thought on “Git – Interactive Rebasing”

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s