这个问题可能重复,但我找不到完全相同的问题。
在我们的QA团队的git存储库中,我经常发现之前添加的测试用例丢失了。从主枝的histroy我不能……
这个相当“hacky”的解决方案可能有助于找到强制推送的修改提交,但我不确定它是否适用于所有可能的情况。
假设您在远程(裸)存储库中,您可以打印出存储在特定分支的reflog中的所有提交,并将它们与正常的提交进行比较 git log 。差异应该给你强制推送提交。
git log
请注意,对于裸回购, 必须启用reflogs 。
作为一个例子,假设你已经承诺掌握,推动,然后修改和强制推 - 两次。 那么你总共会有四次提交(如reflog所示),但实际日志中只有两次:
$ git log -g master | grep ^commit # Show reflog of master commit 3f52cea357aaa6ba9db86c1526b025a7ee2906c1 (refs/remotes/origin/master, refs/heads/master) commit 5afa0cfe6e16d4d45088aeb226ed052a5ad72b87 commit 0334c6f8ba13c1465c855cf0b7cf6c79df487740 commit 8bb40a9d6da838e151c8653b8d6be2b7afeb1902 $ git log master | grep ^commit # Show log of master commit 3f52cea357aaa6ba9db86c1526b025a7ee2906c1 (refs/remotes/origin/master, refs/heads/master) commit 0334c6f8ba13c1465c855cf0b7cf6c79df487740 $ git reflog # for reference - HEAD@{0, 2} were force pushes 3f52cea (HEAD -> refs/heads/master) HEAD@{0}: push 5afa0cf HEAD@{1}: push 0334c6f HEAD@{2}: push 8bb40a9
在bash中,我可以显示两者之间的差异(使用进程替换):
$ diff <(git log -g master | grep ^commit) <(git log master | grep ^commit) | grep "^<" < commit 5afa0cfe6e16d4d45088aeb226ed052a5ad72b87 < commit 8bb40a9d6da838e151c8653b8d6be2b7afeb1902
我正在将上面的两个输出区分开来并且管道输送到 grep ,这样我就可以看到修改后的提交。
grep
没有真正可靠的方法 git 本身就是检索那种信息。 (有些git托管软件可能会保留类似于垃圾推文的类似垃圾记录,但我不知道;如果你使用特定的托管软件包,你可以查阅它的文档。)
git
除了找到一个未接受新历史记录的克隆之外,即使它已经接受了新的历史记录,你也可以从克隆的reflog中获得所需的信息 - 但是reflog是本地的和临时的,所以这是不保证。
(根据您的遥控器托管方式而定 威力 也可以参考它的reflogs,如果它保留它们并且你可以访问它们。但即使是所有这些 IFS 打破你的方式,没有保证,因为reflogs是暂时的。)
这就是为什么 git push -f 是一种危险的工具;如果开发人员对git的理解没有进展到他们理解它有多危险的程度,那么就有可能变得生硬,那么开发人员不应该被授予访问强制推送到与其他开发人员共享的refs的权限。
git push -f
您可以配置一个git remote来拒绝所有非快进推送(即使强制);看到 receive.denyNonFastForwards 在里面 git config 文档。
receive.denyNonFastForwards
git config
如果您需要更细粒度的控制,您再次必须依靠托管软件来提供它。
您将无法获得强制推送历史记录,但您至少可以窥探您自己的被破坏的提交。从您的本地克隆,使用 git fsck :
git fsck
(master) :~/repo$ git fsck --lost-found Checking object directories: 100% (256/256), done. dangling blob 6edc1e217eaab8f72f67bcec2e4d1dfde299971e dangling commit 9847c5942bf477989112ece202988bc3f8caad05 (master) :~/repo$ git merge 9847c59 // ... conflicts likely appear ... //
从这里开始,您可以解决冲突并在适当的情况下推迟更改。如果您与提交的位置不同,则此方法不起作用,即使这样,如果已经过了足够的时间,您的本地提交可能会因修剪而丢失。