Git:如何检查是否删除了任何提交?

时间:2018-03-16 21:36:14

标签: git git-pull git-fetch

我想确保fetch从远程存储库中删除(或压缩)本地存储库中的提交。

另外,我需要向我透露,是否在远程存储库中删除(或压缩)了任何提交。

如何确保我的fetchpull不会删除任何提交(在我的本地PC上)?

另一个相关问题:如何让Git删除与删除的远程提交相对应的本地提交?

1 个答案:

答案 0 :(得分:2)

这个问题存在一些问题,也许这就是它投票的原因,但我们可以从中产生一些东西。

让我们来看看实际存储在Git存储库中的内容,在git fetch之前和之后绘制为图形,看看我的意思。

我们将从这开始:

          A   <-- master
         /
...--o--*   <-- origin/master
         \
          B--C   <-- origin/dev

在这里,在本地存储库中,在运行git fetch origin之前,我们有:

  • 一些共享提交,从提交*开始并向后工作;
  • 我们的A上提交的“我们的”提交master,而不是origin/master
  • 仅作为上游的两个提交,在devorigin/dev:提交BC

现在我们运行git fetch,它打印一些输出,由于某种原因我们看不到或忘记了。然后我们再次仔细检查我们的图表并发现:

          A   <-- master
         /
...--o--*--D   <-- origin/master
            \
             E   <-- origin/dev

也就是说,我标记为BC的两个提交根本不再可以从任何origin/*名称到达,而新提交D和{ {1}}已经出现了。名称E,即我们Git对其origin/master的记忆,现在标识提交master,而名称D标识提交origin/dev

合理的可能 - 但不可能从这个遗忘视图中确切地说 - 提交E是压缩提交DB的结果,可能还有一些额外的提交我们从来没有过。提交C可能是全新的。另一方面,我们只是不知道。

但我们可能有更多的信息。特别是,如果我们启用了reflog,我们将Eorigin/master@{1}。这些将分别指向提交origin/dev@{1}*,我们将通过C reflog保留CB

我们也可能有不同的起始图片。例如,我们的起始图像可能是这样的:

origin/master@{1}

在这种情况下,我们的结尾图片如下所示:

          A   <-- master
         /
...--o--*   <-- origin/master
         \
          B--C   <-- dev, origin/dev

知道什么

这里有几点需要注意:

  1. 我们永远不会失去我们自己的分支机构所指出的任何提交。
  2. 我们根本不会更新任何自己的分支名称。
  3. 我们会更新远程跟踪名称,但是当我们这样做时,如果启用了reflog,他们的之前的值将保存在我们的reflog中以获取这些名称。
  4. 因此:

      

    我想确保通过从远程存储库获取来从本地存储库中删除(或压缩)任何提交。

    这只是自动生效,如果“无提交”,则表示“除了远程跟踪名称之外,我没有其他提交名称”。

      

    另外,我需要向我透露,是否在远程存储库中删除(或压缩)了任何提交。

    在这里,您可以查看任何更新的远程跟踪名称之间的区别 - 请注意 A <-- master / ...--o--*--D <-- origin/master \ \ \ E <-- origin/dev \ B--C <-- dev 告诉您它正在更新的名称 - 以及它们保存的reflog值。例如,如果git fetchorigin/master已更新,您可以将origin/devorigin/master@{1}进行比较。

    此时,syntaxes中描述的一些特殊the gitrevisions documentation变得非常方便。特别是双点和三点差集和对称差分算子告诉我们我们想知道的是什么:

    origin/master

    生成添加到 git rev-list origin/master@{1}..origin/master 的提交列表,并且:

    origin/master

    生成从 origin / master中删除的提交列表。因为reflog名称指向它们,我们仍然在我们的存储库中拥有所有这些提交;在reflog条目到期之前,它们不会消失。

    我们可以使用三点语法和git rev-list origin/master..origin/master@{1} 或类似实体来枚举和识别添加和删除的提交,标记它们所在的对称差异的“侧面”:

    --left-right

    使用所有这些信息,我们可以自动猜测,如果我们真的关心,哪些提交可能是其他提交的rebase或squashes,但在某些情况下这是注定的努力(例如,已解决的合并冲突)。

      

    另一个相关问题:如何让Git删除与删除的远程提交相对应的本地提交?

    这很复杂,因为它取决于你的意思。但是,如果你的意思是我猜你的意思,那么git rev-list --left-right origin/master@{1}...origin/master 的{​​{1}}操作实际上就是为了解决这个问题。 fork-point代码使用上游分支的reflog。有关详细信息,请参阅Git rebase - commit select in fork-point mode