Git在挤压后合并

Git在挤压后合并,git,Git,我有两个存储库A和B。我想将A合并到B中,而不需要整个历史记录,所以我做到了: git pull --squash A_URL master 这似乎奏效了。B no有一个初始提交和一个合并提交。 我继续在A上工作,然后试图再次将其合并到B中,但这次保留了历史记录 git pull A_URL master 问题是A的所有历史现在都显示在B中,甚至是最初被压扁的提交。有解决办法吗? 基本上,我只想得到最近的提交(从最初的挤压开始)。我认为,您至少有一个误解 让我们将其分解为以下几部分: 显示历

我有两个存储库A和B。我想将A合并到B中,而不需要整个历史记录,所以我做到了:

git pull --squash A_URL master
这似乎奏效了。B no有一个初始提交和一个合并提交。 我继续在A上工作,然后试图再次将其合并到B中,但这次保留了历史记录

git pull A_URL master
问题是A的所有历史现在都显示在B中,甚至是最初被压扁的提交。有解决办法吗?
基本上,我只想得到最近的提交(从最初的挤压开始)。

我认为,您至少有一个误解

让我们将其分解为以下几部分:

  • 显示历史记录的命令是
    git log
    。它通过遵循提交图工作。此图是在运行
    git log
    时根据每次提交中存储的信息构建的。大多数提交都有一个单亲提交,
    git log
    显示提交,然后是其父级,然后是其父级的父级,依此类推,形成一个有序的线性链。1但是,合并提交至少有两个父级提交,
    git log
    显示它们两个,以及它们的两个父级,还有那些父母的父母,等等
  • git pull
    命令仅仅是
    git fetch
    ,后面跟着另一个命令,通常是
    git merge
  • 虽然
    git-merge
    通常会进行合并提交,但
    git-merge-squash
    不会。这不仅仅是因为它抑制了提交本身(确实如此),更重要的是:当您手动运行
    git commit
    时得到的提交(您必须这样做才能完成压缩“合并”)不是合并提交。这一点之所以重要,部分是因为第1项,但也因为第4项
  • git merge
    确定合并内容的方法是使用提交图,该图与第1项中的图相同。这在很大程度上依赖于图中真实的合并
  • 使用
    git fetch
    的正常(或至少更典型)方法是使用命名的远程设备(或者只是“远程设备”,因为远程设备只是一个名称,“命名的名称”有点多余)。不过,这里可以使用原始URL,这就是您使用git fetch的方式。当您使用原始URL时,
    git fetch
    后面必须紧接着另一个命令,例如
    git merge
    ,当然这就是您的
    git pull
    为您所做的。(事实上,
    git-pull
    最初就是这样设计的,直到git社区普遍发现,对大多数实际用途来说,像
    origin
    这样的远程命名要好得多。然而,这种老方法就是为什么
    git-pull
    的解释和使用如此复杂。)

    在任何情况下,正如您所观察到的,合并两个图都会导致
    git log
    ,这两个图都按照设计工作;Git应该这么做的。您可以告诉
    git log
    不要这样做,但默认情况下是遵循两个图

    您的第一个
    pull
    运行了
    git merge--squash
    ,它将自合并基本提交5以来完成的一些工作复制到您的工作树中,并使您以常规的、非合并的方式手动提交

    您的第二个
    拉入
    ,没有
    --squash
    ,复制了一些工作,特别是自合并基本提交以来所做的工作,几乎可以肯定的是,相同的工作已经6复制到您的工作树中,并作为真正的合并提交提交

    任何后续的
    pull
    都只会将新工作复制到您的工作树中,现在您的分支的历史记录已经通过此
    pull
    -和真正的合并与其他存储库的历史记录合并。那部分就是你想要的。事实上,
    git log
    向您展示了另一段历史,这是您(显然)不想要的部分,但除非您使用其他技术,否则7您将被困在这一点上:这就是git的设计用途

    (请注意,后续的
    --squash
    合并或拉取将使您处于这种不太好的“重新扫描所有工作”状态,并且收益甚微,因为任何真正的合并已经以您不希望的方式合并了历史。)


    1Somewhat破坏了漂亮整洁的链,
    git log
    首先找出要显示的提交,然后按日期戳对它们进行排序,然后显示它们。这意味着,如果日期被意外或故意弄乱,你所看到的并不是发生的事情。为了避免这种情况,您可以告诉
    git log
    使用其他排序顺序;最简单的方法是添加
    --graph
    ,这将强制进行拓扑排序,并绘制实际提交图的文本模式表示

    2如果历史记录在大多数典型的Git提交图中重新连接,那么日志也会重新连接,也就是说,从这个时间点向后看,您只看到一个提交副本。Git首先选择所有要显示的提交,由于历史分支的原因,它可以多次选择任何一个提交,然后显示它们,只显示一次提交。(另见脚注1。)

    您可以告诉
    git log
    不要遵循多个历史记录:
    git log——第一个父项只遵循“主”历史记录。您可能希望使用此方法,而不是试图定义更奇特的工作流程。如果是这样的话,您可能还希望尽可能地坚持重设工作流程

    3特别是,合并必须找到一个合并基,合并基是历史合并的点。当您进行挤压“合并”时,您将更改从一个分支混合到另一个分支,但您不会合并它们的历史记录。这意味着未来的
    git merge
    将不得不再次合并这些更改,除非您采取一些额外的操作(即记录一个真正的合并提交)

    4它不必是立即的:
    git fetch
    将它所做的写入
    fetch\u HEAD
    ,直到下一个<