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
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.
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 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
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.