Comparison between Git merge and Git rebase
The git rebase command may seem like Git wizardry to beginners, but if used carefully, it can actually make life easier for your development team. In this article, we compare git rebase with the related git merge command and identify all the possible opportunities to incorporate rebase into a typical Git workflow.
Concept Overview
The first thing to understand is that git rebase solves the same problem as git merge. Both commands are designed to integrate changes from one branch into another - they just do it in very different ways.
Consider what happens when we start working on a new feature in a dedicated branch, and then another team member updates the main branch with new commits. This results in a divergent history, which should be familiar to anyone who has used Git as a collaboration tool.
Now, suppose the new commits in main are related to the feature we are working on. To merge the new commits into our feature branch, we have two options: merge or rebase .
Using Merge
The simplest option is to merge the main branch into the feature branch using the following command:
$ git checkout feature
$ git merge main
Alternatively, this can be condensed into one line:
$ git merge feature main
This will create a new "merge commit" in the feature branch, tying the history of the two branches together.
Merge is nice because it is a non-destructive operation. The existing branch is not altered in any way. This avoids all the potential problems of rebase (discussed below).
On the other hand, this also means that every time you need to merge upstream changes, the feature branch will have an unrelated merge commit. If main is very active, this may seriously affect the history of the feature branch. Although you can use the advanced command git log to alleviate this problem, it will make it difficult for other developers to understand the history of the project.
Using Rebase
As an alternative to merging, we can rebase the feature branch onto the main branch using the following command:
$ git checkout feature
$ git rebase main
This moves the entire feature branch to the tip of the main branch, effectively merging all the new commits into the main branch. However, instead of using merge commits, rebase rewrites the project history by creating brand new commits for each commit in the original branch.
The main benefit of rebasing is that we get a cleaner project history. First, it eliminates the unnecessary merge commits required by git merge. Second, as you can see in the image above, rebasing also produces a perfectly linear project history - we can follow the tip of the feature all the way to the beginning of the project without any branches. This makes it easier to navigate our project using commands such as git log, git bisect, and gitk.
However, this pristine commit history has two tradeoffs: safety and traceability. If you don't follow the golden rules of rebasing, rewriting project history can have disastrous consequences for collaborative workflows. And, less importantly, rebasing loses the context provided by merge commits - we can't see when upstream changes were merged into a feature.
Interactive Rebase
Interactive rebasing gives us the opportunity to change commits as we move them to a new branch. This is more powerful than automatic rebasing, as we have full control over the branch's commit history. Typically, this is used to clean up a messy history before merging a feature branch into main.
To start an interactive rebase session, you can add the -r option to the git rebase-i
command :
$ git checkout feature
$ git rebase -i main
This will open a text editor listing all the commits that will be moved:
pick 33d5b7a Message for commit #1
pick 9480b3d Message for commit #2
pick 5c67e61 Message for commit #3
The above defines exactly what the branch will look like after the rebase is performed. By changing the pick command and/or reordering the entries, we can make the history of the branch look like anything we want. For example, if the second commit fixes a small problem in the first commit, we can use the fixup command to squash them into a single commit:
pick 33d5b7a Message for commit #1
fixup 9480b3d Message for commit #2
pick 5c67e61 Message for commit #3
When we save and close the file, Git will perform the rebase according to our instructions, resulting in a project history that looks like this:
Reducing insignificant commits like this makes our feature history easier to understand. This is something that git merge simply cannot do.
Golden rules for using rebase
Once you understand what rebase is, it is important to learn when not to rebase. The golden rule of git rebase is to never rebase on a public branch.
For example, consider what happens if you rebase main onto the feature branch:
The rebase moves all the commits in main to the tip of feature. The problem is that this only happens in your repository. All other developers are still using the program from the original main branch. Since the rebase creates brand new commits, Git thinks that your master branch's history is different from everyone else's.
The only way to synchronize the two main branches is to merge them back together, resulting in an extra merge commit and two sets of commits containing the same changes (the original, and the ones from the branch you rebased on). Needless to say, this is a very confusing situation.
So, before running git rebase, always ask yourself, "Is anyone else using this branch?" If the answer is yes, start thinking about making changes in a non-destructive way (such as the git revert command).
Force push
If you try to push the rebased main branch back to the remote repository, Git will prevent you from doing so because it conflicts with the remote main branch. However, we can --force
force the push by passing the -p flag, as shown below:
# 谨慎使用该命令!
$ git push --force
This will overwrite the remote master branch to match the rebased master branch in our repository, which can be very confusing to the rest of the team. Therefore, this command should be used very carefully and only when we know exactly what we are doing.
The only possible case where we should force push is when performing a local cleanup after pushing a private feature branch to a remote repository (for example, for backup purposes). Again, it is important that no one performs commits from the original version of the feature branch.
For reprinting, please send an email to 1244347461@qq.com for approval. After obtaining the author's consent, kindly include the source as a link.
Related Articles
Git installation and establishment of local warehouse service
Publish Date:2025/04/05 Views:89 Category:Git
-
Git is a distributed version control system: the client does not only extract the latest version of the file snapshot, but also completely mirrors the original code repository. It has the following advantages: a. Since every extraction oper
git remote operation——multiple remote repositories for one project
Publish Date:2025/04/05 Views:131 Category:Git
-
Multiple remote repositories for a git project In our git project, the command to operate the remote repository information is $ git remote # 查看当前所有的远程仓库的名称 $ git remote -v # 查看远程仓库的名称和远程仓
Git cherry pick command usage
Publish Date:2025/04/05 Views:190 Category:Git
-
git cherry-pick is a powerful command that allows us to select an arbitrary Git commit by reference and attach it to the HEAD of the current working branch. Cherry picking is the act of picking a commit from one branch and applying it to an
How to fix Git error Error: src refspec master does not match any
Publish Date:2025/04/05 Views:124 Category:Git
-
When using Git, we may encounter the error "src refspace master does not match any". Here's what the error means and how to fix it. What does src refspec master does not match any Mean in Git mean? We may encounter this error when we try to
Rebase local branch when pulling changes from remote repository branch in Git
Publish Date:2025/04/05 Views:144 Category:Git
-
This article will cover the basics of rebasing your local branch when pulling changes from a remote repository branch in Git. We use the version control system Git to track changes made to files. We commit changes in a local branch in our l
Undo Git Stash
Publish Date:2025/04/04 Views:187 Category:Git
-
This article explains how to make and save changes to a repository. Git allows you to save changes locally and push them to a server when needed. In Git, we don't use the term save , but commit . We use git add , git commit , and git stash
View a list of cache entries in Git
Publish Date:2025/04/04 Views:59 Category:Git
-
We often need to pause our work and focus on something else in our development environment. Therefore, we may need to temporarily save our current work and focus on a different one. We may want to resume our original work later. git stash T
Git stores specific files
Publish Date:2025/04/04 Views:115 Category:Git
-
This article will cover storing changes to only specific files in Git. In Git, when we make some changes in our working tree, we may have some changes which may or may not be staged in our local repo. We may now wish to save these changes f
Git Stash and Shelve in IntelliJ IDEA
Publish Date:2025/04/04 Views:113 Category:Git
-
git stash This article will distinguish between and when using IntelliJ IDEA git shelve . These two come into play when we want to switch between multiple tasks while working and return to them later. IntelliJ IDEA allows us to work on diff