Rebase is nothing but a Git utility which helps the developers to integrate their changes from one available branch to another. Also, there is one more Git command that is available which focuses on integration capability, i.e., git merge. When it comes to merging command, it is always forward moving, i.e. you have a code repository available and whenever the developer has completed a new feature development, the code will be pushed into the central code repository. To do this, developers use git merge command.
On the other hand, rebase is one command which is extensively used within the developer community where they have the ability to rewrite feature, i.e. as a developer, you can modify what you have already pushed into the central code repository.
What is Git rebase?
In this section of the article, we will discuss in detail and understand about git rebase function.
Actually, rebase command is used to while moving or combining a series of commits to a new base commit. The rebase function is very useful when it comes to feature branching workflow.
The primary usage of git rebase function:
In this section of the article, we will understand the primary usage of git rebase function and also the challenges that the developers will encounter if the code repository is not maintained at a standard level.
The primary reason for using rebasing functions is to maintain a clear and linear project history. This is very useful for the developers when it comes to merge feature developed code to the main repository. So whenever there is code needs to be merged, the developers will be able to get the latest code from the master branch and then merge the feature branch code. This will help to maintain a clean history of merge requests and the developers will always have the latest and greatest code available in the master branch.
[Related Page: Rewriting History]
Maintaining a clean history of the project logs will help the developers in the following situation.
- If a developer examines the project history log, using the git log command, the developers will be able to quickly understand the history of the project and also if there are any comments/ reasons it will be easy to recollect.
- If the developer wants to identify when the bug was identified within the code base, then he/she cannot go through this via git log command. They have to apply git bisect command to understand the commits that were pushed.
- As the project history is clean, the developer will be able to quickly go through all the commits that took place by using git bisect command. Understand the commits and the comments associated, the developer will be able to understand when the bug was introduced.
Details of Rebasing:
In this section of the article, we will discuss the two main rebase functions, i.e. Git rebase standard and Git rebase interactively.
The Git rebase standard and Git rebase interactive functions work in the same way, but the execution process is different where the developer will have options to control the commit history. So let us understand this in detail below:
Using git rebase in standard mode will take the commits in the current working branch automatically and it applies it to the head of the passed branch ( main branch). To do this,the devlopers has to use the following command.
For every commit reference, we will have the following details of the branch, for example:
ID, branch name, a tag, appropriate reference to the HEAD
Git rebase interactive is when the git rebase accepts an ---i argument, where “i” stands for ‘interactive”.
[Related Page: Working With Remotes]
So while executing git rebase with the -i flag initiates an interactive rebase session. While using this command, the developer will be able to alter the individual commits within the process. During the rebase process, the developer will be able to open an editor where he/she can enter comments for individual commits themselves. These comments actually determine how the commits are transferred to a new base. Once these commits are altered, git will be able to commit the change according to the specified order.
Further, the developer will be able to use the following rebase commands:
# p, pick = This is used to use commit function
# r, reword= This command is used while commit, but the commit message can be altered using this command.
#e , edit= This command is used for committing the changes if the developers see any changes when using this command they will be able to stop or amend for changes.
#d, drop = This command is used for removing a commit.
#x, exec= This is a shell command, which executes all the run command
So, why interactive rebasing is used?
- Using Interactive rebase function gives good control over the project history.
- This function is really important for developers because they can have a messy commit history. They can emphasize more on writing quality code and don’t have to worry about the commit history. So, once the developers have finished coding, they can revisit their commit history and do necessary modifications within the commit editor.
- It helps the developers to reduce or squash the unrelated commits and streamline their entire project history. Using this option, the developer can showcase that the entire feature development has been done within a limited planned commit. This is extremely important because it portrays the developer ability to finish a particular feature development.
[Related Page: Centralized Workflow In Git]
In this section of the article, we will discuss the usage of git rebase interactive function.
The Golden Rule of Rebasing:
In this section of the article, we will discuss the cases when the developer shouldn’t be using the rebase functions.
As discussed earlier, the git rebase command is very useful for the developer to maintain a clear commit history for a particular project. As the function is really powerful it can make or break the entire commit history of the project if not used properly.
So the golden rule of rebasing is to learn and understand when not to use it. To be more precise, never ever apply git rebase command on public branches. If applied this will create issues for you and the entire development team.
Let’s go through this by an example.
Subscribe to our youtube channel to get new updates..!
In the below screenshot, you can observe what happens to the rebased master on your feature branch.
Flow 1: Your commit history: The master branch includes the new feature that you have developed. So your master branch is different from that of your team. ( In this case, the feature commits are displayed in green dots and the new master is represented in blue dots)
Flow 2: Commit history of your team: The entire team commit history is clean and they are working on with a standard master branch. ( In this case, the commits are displayed in white dots which is clear and every other developer is working on the same master branch).
The rebase function moves all of your commits to the master and then to the new feature that you are developing. So, the entire action has happened on your repository. While the rest of the developers are still working on with the original master.
In this case, the Git will understand that your master branch has diverted from every other branch. So, to synchronize, you have to do unnecessary commits so that you can realign with the master branch as others. Well, this is a very confusing stage for the developers and causes issues within the development team, but this can still be remediated.
[Related Page: Git – Distributed Workflows]
Git Rebase VS Git Merge
The functions rebase and merge are used to integrate the changes from one branch to another branch, but the integration happens in a different way.
The process of integrating changes is depicted below in the screenshot.
In the above figure, you can see that the developer has two branches, i.e. 1) Master and 2 ) Feature.
If the developer is working on a new feature, then a new feature branch is created and all the developed code will be pushed into that specific feature branch. Later on, the feature branch can be merged into the latest master branch. This process of code integration is known as Merge.
When the developer uses Merge function, it actually takes the feature branch contents and directly integrates with the master branch content. This results in a change of the master branch. The branch history actually remains the same.
Also, when the developer uses a merge function, it adds a new commit to history.
Advantages and Disadvantages of Merge function:
In this section of the article, we will discuss the advantages and disadvantages of using the Merge function.
- The merge function is simple to use and it is familiar for most of the developers
- The developer will be able to see the complete history and the chronological order of commits
- The context of the branch is maintained.
- Using this function, the commit history might be polluted because of a lot of merge commits.
- Debugging using git bisect command can be hard.
[Related Page: Patch Workflows]
If the developer is working on a new feature, then a new feature branch is created and all the developed code will be pushed into that specific feature branch. Later on, the feature branch is rebased to the master branch. In this process, the feature branch is added to the last commit of the master branch. This process of code integration is known as Rebase.
- When the developer uses rebase function on a feature branch to master, the developer basically moves the base of the feature branch to the ending point of the master branch.
Advantages and Disadvantages of Rebase function:
In this section of the article, we will discuss the advantages and disadvantages of using Rebase function.
- Helps the developers to streamline the commit history
- The developers will manipulate a single commit easily. ( i.e. Reverting them)
- Can club multiple commits to a single commit, which will in return help the DevOps team.
- Using the squash command, it might confuse the developers and might be a chance to lose the context of the commits.
- Rebasing public repositories is not a good idea, especially when you are working with the team.
- Without proper knowledge of rebase command, it might lead to series issues. So it better not to use it if you are not completely aware of its functions.
Why would I need to rebase something?
Let’s say that you are a junior developer and working with a huge development team where others are constantly working and developing new features to enhance a particular application. In this scenario, you had to change something in the existing application so you download the latest code from the master branch and work on your changes.
After a few commits, you are all set and happy with the changes and want to push it to the master branch. But wait a minute, what if the other developers have changed something, for example:
- Developer 1: Has changed the navigation
- Developer 2: Has removed unwanted database fields
- Developer 3: Has added extra fields to a product
All these changes will impact the code that you have developed, so situations like these will help you understand the different commits that were done before you are pushing into the master. This will help you to avoid conflicts, missing out information on the changes that are worked by others etc.
This is one such classic example where the development team has to use rebase function to make sure their commit history for the project is clean.
Git rebase example:
In this section of the article, we will discuss a git rebase example which will help you understand how a rebase function is used in the real development world.
The entire process is explained by taking a scenario:
We have User 1 and User 2 both using the latest repository that they have downloaded from the master. At this point in time, we have two commits.
$git log 19abe80 -**(HEAD, master) ** added file2 8cb6ba4 - added file1
2. Now, User 2 started working on the project and has initiated two commits, so his repository will look below:
$git log 07c8c6d - ** (HEAD, master)** added file4 E404363- added fie 3 19abe80-**(Origin/master, origin/HEAD)** added file 2 8cb6ba4-added file 1
3. So now looking at the commit history, it is definitely ahead of the master/origin by 2 commits.
[Related Page: Undoing Changes]
4. Later, User 2 is now ready to push the changes to origin ( the original respository where the user has downloaded the code).
$ git push $ git log 07c8c6d - ** (HEAD, origin/master , origin/HEAD, master) * added file 4 e404363- added file3 19abe80-added file2 8cb6ba4-added file1
5. On the other side, User 1 is also working on the other changes and has two commits that he has already taken into consideration.
$ git log ef5b54f- **(HEAD, master)** added file 6 5f7cff8-added file5 19abe80-**(origin/master, origin/HEAD)** added file2 8cb6ba4-addedfile1
6. At this point, if User 1 is ready to push the changes, he will an error ,
$ git push ! [rejected] master -> master (non-fast-forward) Error: failed to push some refs to ‘...”
To prevent you from losing history, non-fast-forward updates were rejected Merge the remote changes (e.g. ‘git pull’) before pushing again. See the ‘Note about fast-forwards’ section of ‘git push --help’ for details.
7. So in this case, Git actually notice the difference between the files that is available in the origin master.
8. To resolve this scenario, User 1 first has to fetch the latest code from the origin ( master code resository).
This can be done by using the following command:
$ git fetch $ git log - - graph - -all *ef5b54f - ** (HEAD, master)** added file6 *5f7cff8 - added files5 | * 07c8c6d- **(origin/master, origin/HEAD)** added file4 | * e404363- added file 3 |/ *19abe80- added file2 *8cb6ba4- added file 1
Using -all to the log commands will show all the commits across all the branches.
Using -- graph shows the respective graphical representation of the branches.
[Related Page: Git Basic Concepts]
9. Further, the User 1 has to follow another step, i.e. they have to perform rebase option this will update all the new commits, in this case User 1 (ef5b54f and 5f7cff8), so when the rebase function is applied the origin/master commit will be (07c8c6d).
10. Since User 1 and User 2 files are independent (i.e. different files so there won’t be any conflicts).
So the origin/master will be like this:
$ git rebase origin/master First, rewinding head to replay your work on top of it Applying: added file5 Applying: added file6 $ git log -- graph -all *4fca7e8 - ** (HEAD, master) ** added files 6 *29ea4d2 - added files * 07c8c6d - **(Origin/master, origin/HEAD)** added file *e404363 - added file3 *19abe80- added file2 *8cb6ba4- added file1
11. Now, User 1 can definitely push the changes to the origin repository:
$ git push $ git log -- graph - all *4fca7e8 - ** (HEAD, origin/master, origin/HEAD, master )** added file 6 29ea4d2 - added file 5 07c8c6d - added file 4 E40363 - added file 3 19abe80- added file 2 8cb6ba4- added file 1
Resolving merge conflicts after a Git rebase:
Having conflicts within the code repository is quite common and this can be overcome by using specific options. Using git rebase, the developers will be able to move commits around but this might arise merge conflict in few cases.
A situation where the same file is accessed by two different developers and they had to change something in the same file ( that to the same line). While committing these changes to the origin/master Git wouldn’t be able to understand and apply the change accordingly.
If the developer has got into a merge conflict issue then using the below option will help the developers to remediate the problem.
Firstly you can execute git rebase -- abort: Using this command, the developer can undo the rebase action. Once the command is executed, Git actually gets you back to the earlier state ( code that the developer had developed in that specific branch).
The second option is to execute git rebase -- skip. This is used by the developer to completely skip the contents of the commit.
In order to streamline the project commit history and also to make sure that the developers have a clean and linear commit history, the rebase function can be used. Using these functions in an appropriate way will help to reduce the conflicts and also clears out the confusion between the development teams. Based on the golden rule of rebase usage, one has to take extreme care while applying to rebase function to the public master/origin, this should be avoided at all cases. So, use these git functions as needed.