Difference Between git merge and rebase – git merge和rebase的区别

最后修改: 2022年 5月 24日

1. Overview

1.概述

While working with git as our Version Control System (VCS), we may follow any of the branching strategies, but eventually, we may need to integrate changes from one of the feature branches to the main or main branch.

在使用git作为我们的版本控制系统(VCS)时,我们可以遵循任何一种分支策略,但最终,我们可能需要将某个特性分支的修改整合到主分支或主干分支。

In this tutorial, we’ll look at the two different ways in which we can integrate changes from one branch to another.

在本教程中,我们将看一下从一个分支到另一个分支的两种不同整合方式。

2. Git Rebase

2.Git Rebase

To put it simply, git rebase takes your entire feature branch and moves it to the tip of the main branch. It creates brand new commits for each commit in the original feature branch.

简单地说,git rebase 将你的整个特性分支移到主分支的顶端。它为原特性分支的每个提交创建全新的提交。

Let’s create a new repository and a feature branch in the repository to understand how to rebase works:

让我们创建一个新的版本库,并在该版本库中创建一个特性分支,以了解如何进行 rebase 工作。

git clone <your_repository_here>
git branch testBranch1
git branch testBranch2

Let’s create a new file in the testBranch1 feature branch and commit the changes:

让我们在testBranch1特性分支中创建一个新文件并提交修改。

git add .
git commit -m "<Commit_Message_Here>"
git push --set-upstream origin testBranch1
git log

Executing these commands will give us the output below:

执行这些命令将给我们带来以下输出。

git RebaseFeature Branch1 Merge Commit Log

Now, let’s try to rebase this branch on the main branch:

现在,让我们尝试在main分支上重新建立这个分支。

git rebase main

This will result in the following message:

这将导致出现以下信息。

Git Rebase Feature Branch 1 Post Commit

Since there are no commits in the main branch, we shouldn’t expect any changes, as evident above.

由于main分支中没有任何提交,我们不应该期望有任何变化,如上所述。

Now, let’s merge the feature branch onto the main branch:

现在,让我们把特性分支合并到主分支上。

git checkout main
git merge testBranch1
git push
git log

These commands will output the following:

这些命令将输出以下内容。

git Merge Feature Branch1 Rebase Merge Commit Log

There is no change to the commit ids from the feature branch while merging to the main branch. This is similar to what happens with fast-forward merge.

在合并到主分支的过程中,特性分支的提交id没有变化。这与快进合并的情况类似。

Since we have already merged testBranch1 to the main branch, testBranch2 is missing the commits from where it was cut.

由于我们已经将testBranch1合并到main分支,testBranch2缺少它被剪切的提交。

Let’s take a look at how testBranch2 is rebased and merged.

让我们看看testBranch2是如何被重新建立和合并的。

Let’s create a new file in the testBranch2 feature branch and commit the changes:

让我们在testBranch2特性分支中创建一个新文件并提交修改。

git checkout testBranch2
git add .
git commit -m "<Commit_Message_Here>"
git push --set-upstream origin testBranch2
git log

And after these command’s completion, we’ll see:

在这些命令完成后,我们将看到。

git Rebase Feature Branch2 Commit Log

Now let’s try to rebase this branch on the main branch:

现在,让我们试着把这个分支重新放在main分支上。

git rebase main

And this should give us a different message from the previous case:

而这应该给我们一个与前一个案例不同的信息。

git Rebase Feature Branch2 Rebase

Since there are some commits on the main branch, the feature branch was rebased on it. Now let’s merge the featureBranch2 on the main branch. We should expect the commit ids to be different for featureBranch2 before and after rebase:

由于 main 分支上有一些提交,所以特性分支被重新建立在它上面。现在让我们把 featureBranch2 合并到主分支上。我们应该期待featureBranch2在重基前和重基后的提交id不同:

git checkout main
git merge testBranch2
git push
git log

These commands will output the following:

这些命令将输出以下内容。

git Rebase Feature Branch 2 Rebase Merge Commit Log

The commit ids are different as expected, and if we take a look at the git log graph, we will see that the repo has a linear history:

提交的id和预期的不一样,如果我们看一下git日志图,我们会发现该 repo有一个线性的历史。

git log --graph --oneline

The above command shows a graph structure displaying commit info in a single line:

上面的命令显示了一个以单行显示提交信息的图形结构。

git Rebase Merge Branch Graph Final

3. Git Merge

3.Git 合并

Git merge will take the two branches we are merging, find the common base commit and then play the commit sequence from the two branches on the base commit to merge the branches.

Git 合并会将我们要合并的两个分支,找到共同的基础提交,然后在基础提交上播放两个分支的提交序列来合并分支

Let’s create a new repository and a couple of feature branches to understand how merge works:

让我们创建一个新的版本库和几个特性分支来了解合并的工作原理。

Clone the repository in your local machine and create a new feature branch:

在你的本地机器上克隆版本库并创建一个新的特性分支。

git clone <your_repository_here>
git branch testBranch1
git branch testBranch2

Let’s create a new file in the testBranch1 feature branch and commit the changes:

让我们在testBranch1特性分支中创建一个新文件并提交修改。

git add .
git commit -m "<Commit_Message_Here>"
git push --set-upstream origin testBranch1
git log

Executing these commands will give us the output below:

执行这些命令将给我们带来以下输出。

Git Merge Feature Branch 1 Commit Log

Now let’s merge this feature branch onto the main branch using the merge command:

现在让我们用合并命令把这个特性分支合并到main分支。

git checkout main
git merge testBranch1
git push
git log

These commands will output the following:

这些命令将输出以下内容。

git Merge Feature Branch1 Merge Commit Log

We can notice that the latest commit ids are the same as the previous image, but the HEAD pointer is pointing to the main branch.

我们可以注意到,最新的提交ID与之前的图片相同,但HEAD指针指向了main分支。

The above was a simple merge wherein there were no changes in the main branch while we were working on our feature branch.

以上是一次简单的合并,当我们在feature分支上工作时,main分支上没有任何变化。

Let’s look at another scenario where there are changes in both main and feature branches and how git handles them.

让我们看看另一种情况,即主分支和特性分支都有变化,以及git如何处理它们。

Let’s create a new file in the testBranch2 feature branch and commit the changes:

让我们在testBranch2特性分支中创建一个新文件并提交修改。

git checkout testBranch2
git add .
git commit -m "<Commit_Message_Here>"
git push --set-upstream origin testBranch2
git log

And after these command’s completion, we will get the following:

在这些命令完成后,我们将得到以下结果。

Git Merge Feature Branch 2 Commit Log

Now let’s merge this feature branch onto the main branch using the merge command:

现在让我们用合并命令把这个特性分支合并到main分支。

git checkout main
git merge testBranch2
git log

We can then see it in the terminal:

然后我们可以在终端看到它。

git Merge Feature Branch2 Merge Commit Log

There is a separate merge commit on which the HEAD is pointing now while the original commits are present for both the feature branches. The topmost commit also has an additional information key, “Merge”, which has the commit ids for both the branches.

现在有一个单独的合并提交,HEAD指向的是这两个特性分支的原始提交。最上面的提交也有一个额外的信息键,”Merge”,其中有两个分支的提交ID。

We can also check the branch graph and verify the history of the repository:

我们还可以检查分支图,验证版本库的历史。

git log --graph --oneline

The above command shows a graph structure displaying commit info in a single line:

上面的命令显示了一个以单行显示提交信息的图形结构。

Git Merge Branch Graph

4. Use Cases

4.使用案例

Whenever we require our repository history to be linear, we should go for rebasing. But we should be careful about using rebase instead of merging on commits outside our repositories as other collaborators may have their own work based on the existing commits.

每当我们要求我们的版本库历史是线性的,我们就应该去做 rebase。但我们应该小心使用 rebase 而不是合并我们仓库以外的提交,因为其他合作者可能会在现有提交的基础上有自己的工作。

Rebasing already pushed commits on a public repo will result in different commit ids, which might make git think that the other developers’ main branch and your rebased main branch have diverged. This could create a potentially difficult situation for merging/syncing if there are multiple collaborators.

在公共版本上重放已经推送的提交会导致不同的提交ID,这可能会让git认为其他开发者的主分支和你重放的主分支发生了分歧。如果有多个合作者,这可能会给合并/同步工作带来潜在的困难。

5. Conclusion

5.结论

In this article, we covered the basic difference between git merge and git rebase which every developer should know while working with git VCS.

在这篇文章中,我们介绍了git merge和git rebase的基本区别,每个开发者在使用git VCS时都应该知道。