【问题标题】:why it is not a good practice to rebase again after merge?为什么合并后再次变基不是一个好习惯?
【发布时间】:2020-01-25 18:59:33
【问题描述】:

我正在阅读 Pro Git 书籍,但在变基时遇到了困难。

下面是场景:

第 1 步

第 2 步

我们可以看到遥控器做了一个变基,(不是一个好的做法,因为其他人可能会基于它工作)。

然后作者说:

如果您执行 git pull,您将创建一个包含两行历史记录的合并提交,您的存储库将如下所示:

我不明白为什么git pull会自动合并C4C7,因为我们知道通常git pull不会为你做合并,你必须自己合并,那么为什么在这种情况下会git pull为你合并?

编辑:

对不起,我打字和思考太快了,我说的是git fetch不会自动合并,git pull会合并,git pull = git fetch + git merge

所以我的问题是,为什么作者说:

当你重新定义东西时,你放弃了现有的提交并创建了相似但不同的新提交。如果你将提交推送到某个地方,而其他人将它们拉下来并基于它们进行工作,然后你用 git rebase 重写这些提交并再次推送它们,你的合作者将不得不重新合并他们的工作,当你尝试时事情会变得一团糟将他们的工作拉回到你的工作中。

我真的很困惑,如果开发人员在合并后没有做 rebase,所以我们将步骤 1 中的图片作为开始,那么开发人员在 C6 之后添加了一个名为 C8 的新提交,那么如果我在我的电脑上调用git pullC8 仍然需要与C7 合并,所以无论如何它都必须重新合并工作,这是无法避免的,事情会变得一团糟,所以有什么问题用那个?

【问题讨论】:

  • 谁说git pull 通常不做合并?这正是它的作用。它首先执行fetch,然后执行merge
  • @JonathanWakely 抱歉,我说的是 git fetch,我已经编辑了我的问题,请看一下,谢谢

标签: git


【解决方案1】:

我认为你只是误解了这本书的内容。

所以无论如何都要重新合并工作,这是无法避免的,事情会变得一团糟,那有什么问题呢?

这不是事情变得混乱,这只是在进行合并。合并并不混乱,合并很容易。没有问题。

混乱的情况是当其他人拥有你的 repo 的副本并且你通过 rebase 重写你的 repo 的历史时,然后你尝试从其他人的副本中合并。他们的副本仍然包含您的存储库中不再存在的旧提交,因为您具有通过变基创建的等效但不相同的提交。它会变得混乱,因为它会尝试合并不需要合并的提交。

您正在阅读书中关于变基后为什么事情会变得混乱的描述,然后尝试在没有变基的假设情况下理解它们。当然这没有意义,因为你考虑的是完全不同的情况。

【讨论】:

    【解决方案2】:

    git pull 视为git fetch [branch] && git merge [branch] 的别名

    【讨论】:

    • 对不起,我说的是 git fetch,我已经编辑了我的问题,请看一下,谢谢
    【解决方案3】:

    你应该在这里查看这个问题Git pull results in extraneous "Merge branch" messages in commit log用户戳很好地解释了合并发生的原因。

    【讨论】:

    • 对不起,我说的是 git fetch,我已经编辑了我的问题,请看一下,谢谢
    【解决方案4】:

    Mauricio Machado's answer 所示,默认情况下,git pull 实际上是fetchmerge 操作别名。

    您可能希望将 pull 配置为执行变基:

    $ git config --global pull.rebase true
    

    【讨论】:

    • 对不起,我说的是 git fetch,我重新编辑了我的问题,请看一下,谢谢
    【解决方案5】:

    变基是允许修改历史的操作之一。这意味着您不应该在与其他开发人员(例如开发分支)一起工作的公共分支上这样做。

    为什么?

    因为这很可能会导致冲突,我们不喜欢解决,因为这纯粹是手动操作。你可以在这里读更多关于它的内容: Atlassian Tutorial - Git merge conflicts

    另一方面,这并不意味着您根本不应该使用 rebase。我每天都使用它来将我的功能分支与开发同步。我也总是使用带有 --rebase 选项的 pull。

    【讨论】:

      【解决方案6】:

      事情可能会变得一团糟,因为如果您已经推送了一个提交,然后您在本地执行了一个影响该提交的变基,那么该提交将会改变。

      考虑一下:Merge 会在您前面添加东西,而 Rebase 会在您后面添加东西

      所以,如果你改变背后的东西,现在就会改变。

      提交只是一个指向先前提交的链表,我们称之为父母。如果您更改父母,那将更改提交本身,更改其 SHA,这意味着这是一个全新的提交。

      假设你有:

      [some-branch]   D -> E
                             \
        [HEAD] = A -> B -> C -> E
      

      你需要得到 D 你可以:

      重新定位

             [some-branch]   D -> E
                               \
        [HEAD] = A' -> B' -> C' -> D -> E
      

      合并

      [some-branch]   D -> E
                        \
             [HEAD] = D -> A -> B -> C -> E
      

      (我知道那里缺少合并提交)

      为什么会变得一团糟?因为如果您在获得 D 之前 推送了您的分支并且有人开始使用它,那么他们的本地分支和推送(远程)分支就会考虑到他们马上意识到发生了什么,因此分歧,并且修复它很混乱。

      为什么它更简洁?它不会创建合并提交,并且会产生更清晰易读的历史记录。只有当您完全确定您是该分支中唯一工作的人时才安全。

      要走的路吗?只需合并具有您想要的提交的分支,这将在最后一个提交之前创建一个新提交,因此一旦您推送,分支将兼容。

      【讨论】:

        猜你喜欢
        • 2020-01-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-01-11
        • 2018-04-07
        • 2016-01-03
        相关资源
        最近更新 更多