所以我只是对我们的一个文件进行修补,我看到了一些不应该存在的代码(加上这个流氓代码引起的网页错误)。几个月前,代码已添加到补丁中,然后在一个月前通过恢复该提交而删除。所以它真的不应该存在。
我尝试了一些方法来追踪它的来源:
最后一个观察结果让我得出结论,所讨论的补丁是一个混乱,但是提交消息没有提到合并,我们的团队通常会保留git生成的合并消息。
那看起来是这样的吗?在解决冲突期间做出错误选择是否重新引入了代码?如果是这样,有没有更快的方法来找到这种东西?例如,git blame说代码来自我原来的补丁。但有没有办法让它直接告诉我它在修复后重新引入补丁X?如果git不知道它在合并期间是否受到影响,那么git如何跟踪每段代码的来源?是否能够告诉我在合并冲突期间有人搞砸了那段代码?我曾经认为合并本身应该出现在责任中。
答案 0 :(得分:4)
这看起来像是
的明确案例Git merge, then revert, then revert the revert
含义:您不应该真正还原合并提交,例如永远。 而是'重置 - 硬'到那之前的点。其他低级技术确实适用,但我建议如果你绝对无法承受非快速推送,那么即使查看那些技术(git重置为先前的提交将导致'强制'推动以后的新工作。)
还原的作用是还原内容。但是,原始合并提交仍将合并源显示为父提交。这个傻瓜认为远程分支已经完全合并,即使内容已被还原(!)。带来所有可能的恶劣后果。
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是'previousmergedbranch',所以你可以运行上面的命令。
有可能弹性提交(你还原)仍在等待合并(根据git)并且因此已经全部合并,撤消你的'revert'撤消...这种情况可能由于各种原因而发生(例如,原始提交已被手动转移或冲突的挑选,使得git无法检测到提交已经应用于合并目标)
我甚至不确定git是否会在合并(提交序列)中主动检测到一个非冲突('纯')的cherrypick;虽然它当然可以:
git log --left-right --oneline --cherry-pick --graph --boundary mergetarget...mergesource
这将显示git在合并时两个引用之间的'提交'中看到的delta作为delta。 git-log的手册页解释了--cherry-pick告诉git消除输出的提交,即使它们有不同的commit-id(hash)但是差异对于所有意图都是相同的目的。
[1] OT:这是一个难题:我们可以让软件变得更聪明,但只要漏洞抽象,就会出现问题:
一般的经验法则似乎是:最精细的工具将导致更少的问题。然而,当缩减中断时,狗屎将是精致的品种:)
答案 1 :(得分:0)
我遇到了这个问题,在一个没有与 master 合并的分支上添加了一个文件,后来又删除了一个文件,但是 master 已经合并回了 feature 分支,并且在切换到这个分支和从这个分支切换时文件不断重新出现。我用 rebase 压缩了两个提交来修复它,这两个提交添加和删除了“幻影”文件。我使用了我前一段时间编写的脚本来查找提交或可能已删除它们的分支中的“丢失文件”。
这是我用来查找文件的脚本:
git-find-file () {
for branch in $(git log --all --oneline --no-color -- "$1" | cut -c 1-9)
do
git branch --contains $branch
echo "found $1 in $branch"
done
}