Git - Merge 和 Rebase 输出相同数量的提交

Git - Merge and Rebase outputs same number of commits

我正在关注 this 答案以了解 git mergerebase 之间的区别 并在 Github 中创建了一个示例存储库以更好地理解它,但我看到的是 git 合并和变基操作的提交数量相同。

让我解释一下我的表现。

第 1 步: 我创建了一个项目并将其推送到 Github 存储库的 master 分支。

第 2 步: 创建了名称为 feature-one 的功能分支,将基础作为主分支,添加了虚拟文件并将其提交为如下:

git checkout -b feature-one
touch test.txt
git add .
git commit -m "feature-one first commit"

touch another-test.txt
git add .
git commit -m "feature-one second commit"

第三步:切换回master分支,使用git merge合并feature-one分支,如下:

git checkout master
git merge feature-one

现在我可以在 master 中看到两个额外的提交(feature-one 第一次提交,feature-one 第二次提交)以及初始提交。

然后,我完成了相同的步骤,并使用 git master 分支对其进行了重新设置,如下所示:

git checkout -b feature-one
touch test-rebase.txt
git add .
git commit -m "feature-one third commit"

touch another-test-rebase.txt
git add .
git commit -m "feature-one fourth commit"

第四步:切换回master分支,使用git rebase合并feature-one分支,如下:

git checkout master
git rebase feature-one

现在我又可以在 master 中看到两个额外的提交(功能-三分之一提交,功能-四分之一提交)以及前三个提交。

我的期望是,一旦与 master 重新建立基础,我将看不到功能分支提交。

现在我的问题是我的期望正确还是做错了什么?

谁能解释一下?

谢谢。

这是 git 的预期行为。 Rebase 在其他分支的更改之上应用本地提交。

如果您不想看到功能分支的单个提交,您需要在合并时压缩提交。

$ git merge --squash feature-one

在第 3 步中,您执行了所谓的 "fast-forward" 合并。在合并分支 master 之前不包含任何不在 feature-one 中的提交,因此 git 只是 "moved" masterfeature-one 的状态而没有创建一个额外的提交。

可以图形显示:

I - initial commit, the state of master branch before the merge
 \
  -> F1 -> F2 - the state of feature-one before the merge

合并后你得到:

I -> F1 -> F2 - the state of _both_ master and feature-one

如果在合并之前在 master 中有不同的提交,图片会有所不同:

I -> B1 - the state of master
 \
  F1 -> F2 - the state of feature-one

然后在合并期间(fast-forward 在这种情况下不适用)git 将创建另一个结果提交,其中包含来自 master 和 feature-one 的更改:

I -> B1 -> M1 - the state of master after the merge.
 \        /
  F1 -> F2 - the state of feature-one

变基是另一个功能。假设您有以下提交顺序:

I -> B1 - the state of master
 \
  F1 -> F2 - the state of feature-one

不希望 与多个父项进行合并提交,例如上面示例中的 M1。然后你可以要求 git 变基,将提交 F1 和 F2 移到 B1 上。 rebase 很像重新应用对应于 F1F2 的补丁,一个接一个。当然可能会有冲突,你必须一个一个地解决它们(而不是在合并的情况下一次)。

结果你会得到下图

I -> B1 -> F1' -> F2'  -- the state of _new_, re-written feature1
     |
      \_the state of master

请注意 F1' 和 F2' 与最初的 F1 和 F2 不同。至少这些提交有新的 "commit time" 和不同的父提交,所以他们的 "sha-1" 肯定与 F1 和 F2 的不同。这就是为什么变基可能被认为对 published 提交有害,即那些你已经在某处发布并且某些人可以依赖它们的提交。但是,您可以(有时应该)在内部使用它,在您的本地存储库中使用 "make the history sexier" :),删除不必要的中间状态或更改等。rebase 非常适合在发布之前从 "cleanup" 等. 但是一旦发布,通过创建额外的提交来修复所有发现的错误会更安全。