Rebase Basic Concept in Git

Rebasing is an alternate solution for the merging where rebasing differs by rewriting the commit history in order to produce a straight, linear succession of the commits.

When you rebase, Git finds the base of your branch and finds all the commits between the Head and the Base and replays those commits by pushing back to it.

Now, let us understand step by step how the Rebase will work, follow the steps as below. Here am working with my Git repository called starter-web-1/, which I have forked from scm-ninja/starter-web

Let's go to the Git Bash terminal, so am in my project folder and now am changing into my git repositories working directory cd starter-web-1/ , If you do an ls, you can see the number of files which are part of this project.
RBC-cd-ls

  • If you do a git status, you can see that we are on the clean working directory.
    RBC-git-status
  • And if you also check for the branch git branch, here we have our master only.
    RBC-git-branch

Let us create some feature branch and do some work on it and then switch back to the master branch.

And also we are going to do some work in the master branch and then rebase the changes back into the feature branch. Here I am going to create a new feature branch called myfeature and switching to that branch git checkout -b myfeature.
RBC-git-checkout-myfeature

  • So now, edit the humans.txt file and add some text under the Thanks section as thanks to all my students, save then exit.
    RBC-notepad-humans-txt
  • If you do a git status, Git tells that we have a modified file.
    RBC-git-status-modified-humans
  • Then I am going to do an express commit git commit -am "saying thanks to all my students".
    RBC-git-commit-am
  • Hence we are done with the immediate changes to the feature branch. Let us switch to the master branch git checkout master
    RBC-git-checkout-master
  • Do some modification to the README.md file on the master, notepad++ README.md and add some text towards the top as Adding the line for rebasing example save then exit.
    RBC-notepad-readme-file
  • If you do a git status, Git tells us that we have modified file called README.md.
    RBC-git-status-readme-file
  • Now you can do an express commit, git commit -am "Adding online to the README file for rebase example"
    RBC-gitcommit-am-readme-file
  • So, you can see the history by busing git log --oneline --decorate --all --graph , here you can notice that the master and the feature branches are in a separate line and you can also see that the graph line is diverging.
    RBC-git-log-oneline
  • Am still not done with rebasing on my feature branch, so to do that I can use rebase.
  • First, return to your myfeature branch git checkout myfeature
    RBC-git-checkout-back-to-myfeature
  • Let us rebase the changes which we have made on the master branch and see how it will affect our history.
  • So use the command git rebase master, and press enter and it will return that rebasing is re-writing our head, which is our current branch and we can re-apply any changes that we have made on the master branch.
    RBC-git-rebase-master
  • Once again we will do a git log git log --oneline --decorate --all --graph , you can see that we have master applied and then the changes to the feature applied.
    RBC-git-log-decorate

In order to make that happen, we have to rewind the change that happened on the myfeature and playback the changes in master on the myfeature branch.

And then apply the change that happened on the myfeature branch originally, in doing so it will be flattened our history. It is also going to allow us to fast-forward merge once we're done making changes on myfeature.

Let's make another modification on the README.md file before doing merge, We have the version of the README.md file on master, edit it by adding some text under Starter-web-project expand the paragraph by separating it with a comma save then exit.
RBC-git-notepad-readme-file

  • Do a git status, which tells me that, I am on the myfeature branch and have one modified file called README.md
    RBC-git-status-secondtime-modified-readme-file
  • Now let us do an express commit git commit -am "Adding another change after rebase".
    RBC-git-commit-readme-file
  • So, if you do a git log git log --oneline --decorate --all --graph, you can see that the myfeature branch has moved a couple of commits ahead of the master branch with our last commit at the top.
    RBC-git-log-all
  • So now, I am done with my feature branch, let's go back to the master branch and merge the myfeature branch back into the master git checkout master.
    RBC-git-checkout-back-to-master
  • Opening up our README file, you can see that the README file is reflected as of the last time we were on the master branch. I just wanted to show you that to make sure you understood that Git was changing these files in our current directory for us.
    RBC-recheck-readme-file
  • git status, tells me that we are the master branch, head with one commit.
    RBC-git-statuss
  • let's do a git diff master myfeature , so this compares the master branch with the myfeature branch.
    RBC-git-diff-master-myfaeture
  • Let us go ahead and merge changes, git merge myfeature, you can see that we have ended up with the Fast Forward merge.
    RBC-git-merge-myfeature
  • Once again if you do git log, git log --oneline --decorate --all --graph , you can see that the master is now caught up with the myfeature branch.
    RBC-git-log-graph
  • And hence the myfeature branch is no longer required and hence we can delete that, git branch -d myfeature
    RBC-delete-myfeature
  • So we had removed the myfeature branch if you check for the branch list, git branch, we have our master branch listed in the Git repository.
    RBC-git-branch-list

Synchronizing Changes Back to GitHub

Rebasing Conflict Setup

We have learned the basic concept of Rebasing, now let us know how to set up Rebase conflict.

  • Well, we will start off from where we had left, So I am currently in my Git repository Starter-web-1/.
  • And currently in Master branch, git branch.
    RCS-git-branch
  • Now, let us see the list of file that we work with. do an ls, you will see the list of files which are part of this project.
    RCS-git-ls
  • Let us do some modifications in the simple.html file, And add some text above title as shown in the below image, as "Adding changes before rebasing conflicts".save and then exit.
    RCS-notepad-simple-html
  • Let's do an express commit, git commit -am "Mb before rebase conflicts" , here Mb stands for the master branch.
    RCS-git-commit-one
  • Create a new branch called bigtrouble, git checkout -b bigtrouble
    RCS-git-checkout-bigtrouble
  • So, now we switched to the bigtrouble branch.
  • Go ahead and make some conflict changes, Thus edit the file simple.html and then save and close.
    RCS-notepad-simple-html-two
  • Do an express commit git commit -am "fb Adding some trouble to simple.html" , Here fb stands for feature branch.
    RCS-git-commmit-am
  • Then switch back to the master branch git checkout master
    RCS-giy-checkout-master
  • Once again edit the same file and make some changes, save then exit.
  • Now I have done some conflicting changes in this file on the master branch.
    RCS-notepad-three
  • Go ahead and commit these changes, git commit -am "fb conflicting changes brewing".
    RCS-git-commit-two
  • Now, if you do git status, we have a clean working directory.
    RCS-git-status
  • And if you check for the history, git log --oneline --graph --decorate --all
  • So you can see at the top that we have two commits, one on each branch and we have our bigtrouble branch and our master branch, which is diverged.
    RCS-git-log-oneline

Git Tracked Files

Abort a Rebase

We will have a look at how to abort the Rebase.

  • Let's start with where we left off.
  • So currently we are on the clean working directory of my Git Repository.
  • And on the Master branch with a clean working directory git branch.
    AB-git-branch
  • We also have a bigtrouble branch which we had created in the last section, so let us switch to a bigtrouble branch git checkout bigtrouble
    AB-git-checkout
  • Compare these two branches visually before Rebase git difftool master bigtrouble
  • So P4Merge, which is configured as my visual diff/mergetool comes up and shows me the differences between the master branch and the current branch.
    AB-git-difftool
  • So it looks like there's going to be several conflicts with the simple.html save and exit.
  • So let's go ahead and try the rebase git rebase master, as expected rebase resulted in the conflict.
    AB-git-rebase-master
  • So, one thing I wanted to show you that, we can simply abort the rebase, perhaps this is so complicated and would rather take a different approach.
  • So, to do this, we will issue git rebase with --abort parameter git rebase --abort and we are completely out of the rebase.
    AB-abort-rebase
  • If you do git status , we are still on the bigtrouble branch with a clean working directory.
    AB-git-status
  • And if we do git log --oneline --graph --decorate --all, You can see that nothing has changed and we still have the two branches that have diverged.
    AB-git-log

Git's History

Resolving Rebase Conflicts

In the last section, we learned about how to abort the rebase if it is complicated to resolve, let us try to resolve the rebase conflicts using mergetool.

  • Let's start now, so we are on the working directory of my Git repository.
  • And if you do a git status, Git tells that we are on a bigtrouble branch with a clean working directory.
    RRC- git-status
  • If we issue a git log command from the previous section, git log --oneline --graph --decorate --all , you can see that we have two branches which are diverged.
    RRC-git--log
  • Let's go ahead and do rebase to master branch git rebase master , so as expected we are in the conflicting state during the rebase.
    RRC-git-rebase-master
  • So we are going to treat this like a merge conflict and use visual mergetool to resolve this conflict.
  • So git mergetool, that will launch the visual mergetool that's configured with Git.
    RRC-git-mergetool
  • In this case, it's P4Merge and now am going to resolve these conflicts.
  • Once you resolve the conflicts, save and close.
  • If you do git status , you can see that you have simple.html as a modified file.
    RRC-git-status
  • Before committing changes add the simple.html file to the staging area git add simple.html
  • And then do a git status , Git tells that, you have fixed the conflicts and also it will give some suggestions.
    RRC-git-add-simple
  • Let's go ahead and continue rebasing git rebase --continue , thus, we had resolved the rebase conflicts.
    RRC-git-rebase-continue
  • Now, issue a git log --oneline --decorate --graph --all , you can see that we have our master commit and then bigtrouble commit.
    RRC-git-log-oneline
  • Once again modify the same file simple.html save and exit.
    RRC-git-modify-simple-html
  • And do another express commit git commit -am "Adding changes after rebasing conflict"
    RRC-git-commit
  • If you do a git status, we are on the clean working directory on a bigtrouble branch.
    RRC-git-statusss
  • If you issue git log --oneline --graph --decorate --all , you can see that we have two commits ahead of the master with our latest commit at the top.
    RRC-git-log-graph
  • So now we're done with all our changes on this branch and then we can now integrate these changes into the master branch.
  • Before that switch to the master branch git checkout master , thus we switched to the master branch.
    RRC-git-checkout-master
  • Now merge those changes here git merge bigtrouble , It will result in Fast Forward merge.
    RRC-git-merge-bigtrouble
  • If you do git log --oneline --graph --decorate -- all, you can see that the master and bigtrouble pointing to the same commit and that the branching graph is linear as well.
    RRC-git-decorate

Integration of Notepad++ with Git

Rebasing Remote Branches

Till now, you have learned different operations of rebasing on Local system, now let us understand how to rebase the Remote branches.

  • For this operation first, we have to synchronize Github with the local git repository. Best ever practice is to do pull operation to know whether everything is up-to-date git pull origin master.
    RRB-git-pull
  • As we expected, Git replies as we are already up-to-date.
  • Now, let us push our changes to GitHub git push origin master , hence it should be synchronized.
    RRB-git-push
  • If you do a git status, Git tells that we are up-to-date with origin/master, with a clean working directory.
    RRB-git-statuss
  • Now, understand how to rebase any incoming changes from GitHub onto your local repository.
  • Before that, edit the simple.html file, am going to add some text in the copyright section at the very end as shown below and save then exit.
    RRB-modify-simple
  • Go ahead and commit changes, here again, am going to do an express commit git commit -am "Local: updating simple.html copyright notice".
    RRB-git-commit
  • If you do a git status , Git tells us that we are on a clean working directory with one commit ahead on origin/master.
    RRB-git-statusss
  • Now, let us open the Github and edit the index.html file on GitHub itself, go to index.html and click on the file name.
    RRB-click-on index-html
  • Now the file content will open, just click on the edit button and then edit at the end as shown in the below image.
    RRB-editing-index-file
  • Am mainly doing this to show what this might look like if there was another developer contributing to GitHub while we working on our local repository.
  • Now, scroll down the Github page and there will be a dialogue box, written as commit changes, just enter your commit message in that git commit -am "Remote: minor change to the index.html" and then click on the commit changes, which is written in green color.
    RRB-remote-commit-message
  • And, if you click on the repository name on Github, you can see the commit message reflecting on that page.
    RRB-commit-message-on-starter-web-page
  • If I do a git status, Git tells that, we are just one commit ahead because the master branch is a local branch and it will indicate only local commits here.
    RRB-git-statussss
  • And hence, we need to update the references, so to do that, instead of using the git pull am going to use git fetch operation git fetch origin master.
    RRB-git-fetch-origin-master
  • Git fetch is a non-destructive command that simply updates the references between the remote repository and the local repository
  • So now, all the references are updated, move forward and do git status, Git tells that the origin/master and local branches have diverged.
    RRB-git-statusssss
  • Here I wanted to do a traditional merging, to keep my commits and my changes ahead of whatever on the Github but I want the benefit of any of the changes that may have occurred on Github.
  • So, to do that we can issue a git pull command with the parameter to cause a rebase during the process, git pull --rebase origin master and press enter.
    RRB-git-pull-rebase
  • Now, we rebased our changes on the top of our master branch on our local repository.
  • Thus, if we do a git status, we can see that our branch is ahead of origin/master by one commit.
    RRB-last-git-status
  • So, if we do git log --oneline --graph --decorate --all , we can see that we have origin/master and then our master branch.
    RRB-git-log

Git Editing File

Rebasing Section Cleanup

We have reached the end of the Rebase section, So, just do a bit of clean up over here.

  • If you check for your current location, you are on a clean working directory our Git repository starter-web-1/
  • If you do a git status , Git tells us that we are on a master branch with a clean working directory with one commit ahead of origin/master.
    CR-git-status
  • And, if we do a git branch, we can see that, we still have a bigtrouble branch, This branch is definitely no longer needed and hence go ahead and delete this branch git branch -d bigtrouble.
    CR-git-delete-bigtrouble
  • Once again, if we do git status, Git confirms that bigtrouble branch has deleted.
  • And the next step is to synchronize with Github, let us do a git pull operation git pull origin master , as expected, It replies as we are already up-to-date.
    CR-git-pull
  • Even though there is a different commit on GitHub than there is local, we have already incorporated those changes by using the rebase command in the previous section.
  • Let's go ahead and proceed with our git push git push origin master
    CR-git-push
  • Thus we have pushed all our changes to Github, go to the Github page and refresh, you can see that updating simple.html copyright notice which is originated from local Git repository.
    CR-github-page

Comment / Suggestion Section
Point our Mistakes and Post Your Suggestions