The Git rebase command is often considered a Git wizard and should be avoided by beginners, but it can actually make it easier for development teams to use. In this article, we compare git rebase with the related Git merge command.
concept
The first thing to understand is that Git Rebase and Git Merge solve the same problem. Both of these commands aim to integrate changes from one branch to another – they just do it in different ways.
Imagine what happens when you start developing new functionality in a dedicated branch and another team member updates the Master branch with a new commit. This leads to a fork history that should be familiar to anyone who uses Git as a collaboration tool.
Now, let’s talk about when a new master commit is relevant to the feature you’re working on. To merge new commits into your feature branch, you have two options: Merge or rebase.
Merge
The easiest way is to merge the master branch into the feature branch:
git checkout feature
git merge master
Or, you can simplify it to a single line:
git merge master feature
This will create a new “Merge Commit” in the feature branch, which will link the histories of the two branches together to give you the branch structure shown below:
Merge is good because it is a non-destructive operation. The existing branch structure does not change in any way. This avoids all the potential pitfalls of Rebase (discussed below).
On the other hand, this also means that the feature needs to be merged every time an upstream change occurs, and there are unrelated merge commits. If the master changes too often, this can seriously contaminate your branch’s history. Although this problem can be mitigated with the advanced Git log option, it can make it difficult for other developers to understand the project’s history of changes.
Rebase
As an alternative to merge, you can rebase the feature branch onto the master branch using the following command:
git checkout feature
git rebase master
This moves the entire feature branch to the top of the Master branch, effectively integrating all new master commits. However, instead of using a Merge COMMIT, Rebase overwrites the project history by creating a new commit for each commit in the original branch.
The main benefit of Rebase is a clearer project history. First, it eliminates unnecessary Merge commit from Git merge. Second, as you can see in the figure above, Rebase also produces a perfectly linear project history – you can follow from the top of the feature branch to the beginning of the project without any forks. This makes it easier to navigate projects than commands like Git log, Git bisect, and gitk.
However, there are two trade-offs for this original commit history: security and traceability. Rewriting project history can have disastrous consequences for your collaborative workflow if you don’t follow Rebase’s golden rule. Second, rebase loses the context provided by the Merge Commit – you can’t see when the upstream changes are merged into the functionality.
Interactive Rebase
Interactive Rebase gives you the opportunity to change the submission as you move it to a new branch. This is more powerful than automatic Rebase because it provides complete control over the branch commit history. Typically, this is used to clean up a cluttered history before merging the feature branches into the Master branch.
To start an interactive session based, pass the I option to the git rebase command:
git checkout feature
git rebase -i master
This will open a text editor listing all submissions that are about to be moved:
pick 33d5b7a Message for commit #1
pick 9480b3d Message for commit #2
pick 5c67e61 Message for commit #3
The list gives an accurate overview of the branch after rebase is performed. By changing the pick command and/or reordering, you can make the history of the branch exactly what you want. For example, if the second commit fixes a small problem in the first commit, you can compress them into a single commit using the following fixup command:
pick 33d5b7a Message for commit #1
fixup 9480b3d Message for commit #2
pick 5c67e61 Message for commit #3
When you save and close the file, Git will rebase on your instructions, resulting in a project history like this:
Eliminating such meaningless submissions makes your history more readable. This is something that Git Merge cannot do.
Rebase’s Golden Rule
Once you understand what Rebase is, it’s important to know when not to use it. Git Rebase’s golden rule is never to use it in a public branch.
For example, consider what would happen if you rebase the master branch to your feature branch:
Rebase moves all master commits to the top of the feature. The problem is that this only happens in your warehouse. All other developers are still using the original version of Master. Because rebase causes completely new commits, Git will assume that the history of your Master branch is different from the history of everyone else.
The only way to synchronize the two Master branches is to merge them together, resulting in additional merge commits and two sets of commits containing the same changes (the original commit and the changes from the Rebase branch). This would be a very confusing situation.
Therefore, before you run Git Rebase, always ask yourself, “Is anyone else using this branch?” If the answer is yes, take your hands off the keyboard and consider doing it in a non-destructive way (for example, git Revert). Otherwise, you can rewrite history as much as you like.
Forced to push
If you try to push a rebase master branch to a remote repository, Git will prevent you from doing so because it conflicts with the remote master branch. However, you can force a push by passing the –force flag, as shown below:
Be very careful with this command!
git push --force
This overrides the remote master branch to match the rebase branch and confuses the rest of the team. Therefore, use this command very carefully only if you know exactly what you are doing.
workflow
Rebase can be integrated into your existing Git workflow as much or as little as your team needs. In this section, we’ll look at the benefits of Rebase at all stages of feature development.
The first step in any workflow git rebase is to create a dedicated branch for each function. This gives you the necessary branching structure to take advantage of Rebase safely:
The local clearing
One of the best ways to add Rebase to your workflow is to clean up what’s going on locally. By periodically performing interactive Rebase, you can ensure that every commit in the functionality is targeted and meaningful. This allows you to write code without worrying about breaking it up to isolate multiple commits – you can fix it later.
When git rebase is called, there are two base options: a parent branch of a feature (such as master), or a historical commit within a feature. We saw an example of the first option in the Interactive Reps section. The latter option is great when you only need to fix the last few commits. For example, the following command is only for the last three commits of interactive Rebase.
git checkout feature
git rebase -i HEAD~3
By specifying HEAD~3 as the new base, you’re not actually moving the branch – you’re just interactively overwriting the three subsequent commits. Note that this does not merge the upstream changes into the feature branch.
If you want to override the entire functionality using this method, git merge-base can be used to find the original base of the feature branch. The following returns the original base commit ID, which you can then pass to Git rebase:
git merge-base feature master
The use of interactive Rebase is a good way to introduce git rebase workflows because it only affects local branches. The only thing other developers will see is your finished product, which should be a concise and easy-to-understand branch history.
But again, this only applies to private function branches. If you collaborate with other developers through the same branch, the branch is public and you can override its history.
Merge upstream changes into the feature
In the concepts section, we learned how feature branches can merge master upstream changes using Git Merge or Git rebase. Merge is a safe option to preserve the entire history of the repository, whereas Rebase creates a linear history by moving the feature branch onto top of the master.
This use of Git rebase is similar to local cleanup (and can be performed simultaneously), but it includes those master upstream commits in the process.
Remember, rebase to remote branch not master. This can happen when collaborating with another developer to use the same functionality and you need to incorporate their changes into your repository.
For example, if you and another developer named John add a commit to the feature branch, after retrieving the remote branch from John’s repository, your repository might look like this:
You can solve this bifurcation problem by changing upstream from the master integration in the same way: either merge the local feature with John /feature, or rebase the local feature into John /feature.
Note that this rebase does not violate the golden rule, as only your local feature submission is moved – all previous content is unaffected. This is like “Adding my changes to what John has already done.” In most cases, this is more intuitive than synchronizing with remote branches via merge.
By default, the Git pull command does the merge, but you can force it to integrate with the remote branch Rebase by passing it the –rebase option.
Integrate verified features
After a feature is approved by your team, you can choose to rebase it to the top of the Master branch, then merge it into the main code base.
This is similar to merging upstream changes into a functional branch, but since you are not allowed to override commits in the master branch, you must eventually use git Merge for integration. However, by performing Rebase before the merge, you can ensure that the merge produces a perfectly linear history. This also gives you the opportunity to compress any subsequent commits that are added during the pull request.
If you are not familiar with Git rebase, you can always perform it in a temporary branch. This way, if you accidentally mess up the feature’s history, you can look at the original branch and try again. Such as:
Git checkout feature git checkout -b temporary-branch git rebase -i master temporary-branch
conclusion
That’s all you need to know about Rebase your branch. If you prefer a linear history that commits cleanly and eliminates unnecessary merges, then you should use Git rebase instead of Git Merge when inheriting changes from another branch.
On the other hand, if you want to keep a complete history of your project and avoid the risk of overwriting public commits, you can still use Git Merge. Both options are perfectly acceptable, but at least having the option to leverage Git Rebase has its benefits.
Click on the link to the original English text
More articles are welcome to visit http://www.apexyun.com
Public id: Galaxy 1
Contact email: [email protected]
(Please do not reprint without permission)