【问题标题】:How to tell git that two commits are the same?如何告诉 git 两个提交是相同的?
【发布时间】:2016-12-02 15:34:54
【问题描述】:

目前我有两个分支,分别命名为 A 和 B:

    B1-...many dirty checkouts...-B2
   /
--O-A1-A2-......................-A3

目前,B2 和 A3 是相同的(git diff A B 给出一个空输出)。

现在的问题是,这种状态是通过 A.I.e. 的部分结帐达到的。很多时候git checkout -- dir1 dir2... 发生了,而不是git merge

简单地将 B 合并到 A 完全废话 A,这是不可能的。

我不想失去 B 的历史。

我应该以某种方式告诉 git,分支 B 上的 git merge A 不应该做任何事情。

当然,我可以简单地将 B2 替换为 A3,但在这种情况下,我会丢失 B 的历史记录。

有没有可能?

【问题讨论】:

  • 我不明白你在做什么。如果没有差异,为什么合并会有问题?
  • 您是否要保留 B 历史记录并替换 A = B 历史记录?
  • @MadPhysicist “脏结帐”意味着发生了一些git checkout -- dir1git checkout -- dir2 和类似情况(以及它们之间的其他一些合并)。现在 A3 和 B2 完全一样,这就是为什么 diff 是空的,但 git 不知道。
  • 这里的工作目录和提交之间似乎有些混淆。
  • @MadPhysicist 不,工作目录完全没问题(我从来没有在没有完美同步的工作目录的情况下提交、合并等)。

标签: git merge git-merge git-rewrite-history


【解决方案1】:

这里可能会有所帮助的是git merge 中通过-s 选项的不同策略,例如ours

   ours
       This resolves any number of heads, but the resulting tree of the
       merge is always that of the current branch head, effectively
       ignoring all changes from all other branches. It is meant to be
       used to supersede old development history of side branches. Note
       that this is different from the -Xours option to the recursive
       merge strategy.

听起来这可能基本上只是将您所在的给定分支按原样创建,并创建一个带有附加头作为附加父级的提交;即看起来你正在尝试做的事情。

【讨论】:

  • 如我所见,它可能不会覆盖 B 的历史记录,对吗?
  • 没有什么会覆盖 git 中的历史记录,除了...非快进更改。
  • 这将是要走的路,但如果原始问题中的图表是正确的,这里有一点神秘,因为git merge 通过将合并基础与两个提示提交进行比较来工作。如果两个提示提交B2A3 是相同的,并且只有一个合并基O,那么两个差异将是相同的并且合并结果将是与B2B2 相同的树A3.
  • @torek 是的;这将是一个天真的三向合并下的情况,它不会查看两者之间的任何增量,例如cvs up -j rev1 -j rev2
  • @Kaz:这就是 Git 所做的。其他 VCS 必须查看每个 rev 以进行重命名和/或合并所有增量,但 Git 的设计跳过了所有这些。
【解决方案2】:

我找到了解决办法:

  1. 我用 git checkout B 结帐 B。

  2. 我使用git merge A 将 A 合并到 B。现在B在本地处于垃圾状态。

  3. 但现在我使用git checkout remotes/origin/B -- . 进行目录签出。这会将 B 恢复到所需的状态。

  4. 现在向上推 B (git push --all) 将根据需要更新合并箭头。

【讨论】:

  • 如果有人有更好的解决方案,我愿意接受。
  • "现在 B 在本地处于垃圾状态。" -- 为什么?如果diff A3 B2 没有显示任何差异,则B 指向与A3B2 相同(作为内容)的合并提交。也许您的工作树在开始之前没有处于干净状态?
  • @axiac 处于干净状态,但 B1 和 B2 之间的许多变化发生在 git merge 上,而其他变化发生在 git checkout A -- dir1 和类似情况下。结果是许多提交被 git 视为未合并,因此 A 上的 git merge B 导致 git 再次合并它们。它导致 A 的糟糕状态(可能只是运气我没有合并冲突)。
猜你喜欢
  • 2021-08-16
  • 2011-07-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-10-01
  • 2019-01-04
  • 2021-03-24
相关资源
最近更新 更多