GIT中merge 和rebase之间的区别
1. 概述
在使用 git 作为我们的版本控制系统 (VCS) 时,我们可能会遵循任何分支策略,但最终,我们可能需要将更改从一个功能分支集成到主分支或主分支。
在本教程中,我们将了解将更改从一个分支集成到另一个分支的两种不同方式。
2. Git rebase
简单地说, git rebase将你的整个功能分支移动到主分支的顶端。它为原始功能分支中的每个提交创建全新的提交。
让我们在存储库中创建一个新存储库和一个功能分支,以了解 rebase 的工作原理:
git clone <your_repository_here>
git branch testBranch1
git branch testBranch2
让我们在testBranch1功能分支中创建一个新文件并提交更改:
git add .
git commit -m "<Commit_Message_Here>"
git push --set-upstream origin testBranch1
git log
执行这些命令将为我们提供以下输出:
现在,让我们尝试在main分支上重新设置这个分支:
git rebase main
由于main分支中没有提交,我们不应该期望任何更改,如上所示。
现在,让我们将功能分支合并到主分支:
git checkout main
git merge testBranch1
git push
git log
合并到主分支时,功能分支的提交 ID 没有变化。这类似于快进合并所发生的情况。
由于我们已经将testBranch1合并到main分支,所以 testBranch2缺少从它被剪切的地方的提交。
下面我们来看看testBranch2是如何 rebase 和 merge 的。
让我们在testBranch2功能分支中创建一个新文件 并提交更改:
git checkout testBranch2
git add .
git commit -m "<Commit_Message_Here>"
git push --set-upstream origin testBranch2
git log
在这些命令完成后,我们将看到:
现在让我们尝试在main分支上重新设置这个分支:
git rebase main
这应该给我们一个与前一个案例不同的信息:
由于main分支上有一些提交,特性分支是基于它的。现在让我们在主分支上合并 featureBranch2。我们应该期望在 rebase 之前和之后featureBranch2的提交 id 是不同的:
git checkout main
git merge testBranch2
git push
git log
这些命令将输出以下内容:
提交 id 与预期的不同,如果我们查看 git 日志图,我们将看到 repo 具有线性历史记录:
git log --graph --oneline
上面的命令显示了一个在单行中显示提交信息的图形结构:
3. Git 合并
git merge 会将我们正在合并的两个分支,找到共同的基本提交,然后在基本提交上播放两个分支的提交序列以合并分支。
让我们创建一个新的存储库和几个功能分支来了解合并的工作原理:
在本地机器上克隆存储库并创建一个新的功能分支:
git clone <your_repository_here>
git branch testBranch1
git branch testBranch2
让我们在testBranch1功能分支中创建一个新文件并提交更改:
git add .
git commit -m "<Commit_Message_Here>"
git push --set-upstream origin testBranch1
git log
执行这些命令将为我们提供以下输出:
现在让我们使用 merge 命令将此功能分支合并到main分支:
git checkout main
git merge testBranch1
git push
git log
这些命令将输出以下内容:
我们可以注意到,最新的提交 id 与之前的图像相同,但 HEAD 指针指向main分支。
以上是一个简单的合并,在我们处理Feature分支时,main分支没有任何变化。
让我们看看另一个场景,主分支和特性分支都发生了变化,以及 git 如何处理它们。
让我们在testBranch2功能分支中创建一个新文件并提交更改:
git checkout testBranch2
git add .
git commit -m "<Commit_Message_Here>"
git push --set-upstream origin testBranch2
git log
在这些命令完成后,我们将得到以下信息:
现在让我们使用 merge 命令将此功能分支合并到main分支:
git checkout main
git merge testBranch2
git log
然后我们可以在终端中看到它:
HEAD 现在指向一个单独的合并提交,而两个功能分支都存在原始提交。最顶层的提交还有一个附加信息键“Merge”,其中包含两个分支的提交 ID。
我们还可以检查分支图并验证存储库的历史记录:
git log --graph --oneline
上面的命令显示了一个在单行中显示提交信息的图形结构:
4. 用例
每当我们要求我们的存储库历史是线性的时,我们都应该进行变基。但是我们应该小心使用 rebase 而不是合并我们存储库之外的提交,因为其他协作者可能基于现有提交有自己的工作。
在公共 repo 上重新定位已经推送的提交将导致不同的提交 ID,这可能会使 git 认为其他开发人员的主分支和您重新定位的主分支已经分歧。如果有多个协作者,这可能会给合并/同步带来潜在的困难。