【问题标题】:Git - Merge and Rebase outputs same number of commitsGit - Merge 和 Rebase 输出相同数量的提交
【发布时间】:2015-12-19 06:57:19
【问题描述】:

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

让我解释一下我的表现。

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

第 2 步: 创建名为 - feature-one 的功能分支,以 base 作为主分支,添加虚拟文件并提交如下:

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"

第 3 步: 切换回 master 分支,并使用 git merge 将其中的 feature-one 分支合并,如下所示:

git checkout master
git merge feature-one

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

然后,我完成了相同的步骤,并使用 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"

第 4 步: 切换回 master 分支,并使用 git rebase 合并其中的 feature-one 分支,如下所示:

git checkout master
git rebase feature-one

现在,我可以再次在 master 中看到两个额外的提交(特征一第三次提交,特征一第四次提交)以及之前的三个提交。

我的期望是,一旦使用 master 重新定位,我将不会看到功能分支提交。

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

谁能解释一下?

谢谢。

【问题讨论】:

  • 1.我想第一个代码块git checkout -b feature的第一行的分支名称是feature-one,而不是feature,对吧?
  • @user3159253:是的,它是功能之一,错字已更正。

标签: git github merge rebase


【解决方案1】:

在第 3 步中,您执行了所谓的“快进”合并。在合并分支之前,master 不包含任何不在feature-one 中的提交,因此 git 只是将master 的状态“移动”到了feature-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不同。至少这些提交具有新的“提交时间”和不同的父提交,因此它们的“sha-1”肯定与 F1 和 F2 的不同。这就是为什么 rebase 可能被认为对 已发布 提交有害,即那些您已在某处发布并且某些人可以依赖它们的提交。但是,您可以(并且某些人应该)在内部使用它,在本地存储库中“使历史更性感”:),删除不必要的中间状态或更改等。rebase 非常适合在发布之前进行“清理”等。但是一旦它已发布,通过创建额外的提交来修复所有发现的错误会更安全。

【讨论】:

  • If you had a different commit in master before the merge, the picture would be different,是的,正如你所解释的那样发生了,但是 master 中的提交应该在创建 feature 分支之后完成,这意味着 master 的状态在创建 feature 分支后发生了变化。
【解决方案2】:

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

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

$ git merge --squash feature-one

【讨论】:

  • 让我困惑的是答案中的but this way a new dummy commit is added, if you want to avoid spaghetti-history and of course be sexier you can rebase
  • 使用--squash 是的,我可以合并多个提交消息,但我正在寻找的是避免功能分支的所有提交消息,我相信这是不可能的。
猜你喜欢
  • 1970-01-01
  • 2018-04-28
  • 2018-03-05
  • 1970-01-01
  • 2013-05-15
  • 2014-04-07
  • 2017-11-04
  • 2018-12-26
  • 2022-12-16
相关资源
最近更新 更多