这看起来像是一个确定的案例
git合并,然后revert,再revert再revert
意思是:你不应该真的像以前那样恢复合并提交。取而代之的是“重置--hard”到之前的点。其他低级技术确实适用,但我只建议在您绝对无法承受非快进推送的情况下查看这些技术(git 重置为较早的提交将导致在推送以后的新工作时“强制”推送)。
revert 所做的是恢复内容。但是,原始合并提交仍会将合并源显示为父提交。这个傻瓜会认为远程分支已完全合并,即使内容已被还原(!)。伴随着所有可能的恶劣后果。
git show-branch mybranch previouslymergedbranch`
git log --no-walk $(git merge-base -a mybranch previouslymergedbranch)
向您展示关系应该很有启发性
@Tesserex
好的......,我说“看起来像”:)
仍然有可能你已经被 git[1] 的奇妙但必然不完美的合并跟踪(碱基检测)所困扰。也许您可以在合并时查看 show-branch 和 merge-base 的输出。如果这是最后一次合并,您可以
git rev-list --merges --parents -1 mybranch
这应该返回三个 sha1: <mergecommit> <mergetarget> <mergesource>
。这里,mergecommit 只是发生合并的时候,mergetarget 是'mybranch',mergesource 是'previouslymergedbranch',所以你可以运行上面的命令。
有可能弹性提交(您已恢复)仍在等待合并(根据 git),因此已全部合并,撤消您的“恢复”撤消......这可能由于多种原因而发生(例如原始提交已手动传输或存在冲突的樱桃选择,使得 git 无法检测到该提交已应用于合并目标)
我什至不确定 git 是否会在合并(提交序列)中间主动检测非冲突(“纯”)cherrypick;虽然它肯定可以:
git log --left-right --oneline --cherry-pick --graph --boundary mergetarget...mergesource
这将向您展示 git 在合并时两个 ref 之间的“提交”中的增量。git-log 的手册页解释说 --cherry-pick 告诉 git 从输出中消除提交,即使它们具有不同的提交 ID(哈希),但差异对于所有意图和目的都是相同的。
[1] OT:这是个难题:我们可以让软件更智能,但只要有泄漏的抽象,就会有麻烦:
- git中的合并跟踪不是密封的
- git 合并补丁集以重放提交,但仅将所有数据存储在快照中;这在恢复合并提交时会出现,例如,当使用嫁接来“伪造”历史关系时
一般的经验法则似乎是:最精致的工具会导致更少的问题。然而,当抽象中断时,狗屎将只是精致的品种:)