git获取强制推送历史记录

git获取强制推送历史记录,git,push-notification,git-push,git-log,Git,Push Notification,Git Push,Git Log,这个问题可能重复,但我没有找到完全相同的问题 在我们QA团队的git存储库中,我经常发现我之前添加的测试用例丢失了。从主要分支的历史来看,我再也找不到我的承诺了 当我比较我个人分支的日志和主分支的日志时,发现了根本原因,这是某人的强制推送,这家伙承认他对git merge不太熟悉,但匆忙推送使用了强制选项 但是如果没有这样的分支来支持这些提交历史呢?而且每个团队成员在几天后都会退出,所以提交历史将永远消失 即使有这样一个备份分支,比较和了解是谁进行了强制推送也是非常耗时的 有什么方法可以得到力推

这个问题可能重复,但我没有找到完全相同的问题

在我们QA团队的git存储库中,我经常发现我之前添加的测试用例丢失了。从主要分支的历史来看,我再也找不到我的承诺了

当我比较我个人分支的日志和主分支的日志时,发现了根本原因,这是某人的强制推送,这家伙承认他对git merge不太熟悉,但匆忙推送使用了强制选项

但是如果没有这样的分支来支持这些提交历史呢?而且每个团队成员在几天后都会退出,所以提交历史将永远消失

即使有这样一个备份分支,比较和了解是谁进行了强制推送也是非常耗时的


有什么方法可以得到力推日志吗?请注意,作为一名普通员工,我不是git服务器的所有者/管理员,但我关心我的提交,希望删除这些提交的人受到警告。

git本身没有真正可靠的方法来检索此类信息。(某些git托管软件可能会保留类似reflog的强制推送记录,但我不知道有任何记录;如果您使用特定的托管软件包,可以查阅其文档。)

除了查找尚未接受新历史记录的克隆外,您还可以从克隆的重登录中获取所需的信息,即使在克隆接受新历史记录后也是如此,但重登录是本地的和临时的,因此不能保证这一点

(根据您的远程设备的托管方式,您可能还可以参考其重登录,如果它保留重登录以及您是否可以访问它们。但即使所有这些“如果”都破坏了您的方式,也无法保证,因为重登录是临时的。)

这就是为什么git push-f是一个危险的工具;冒着直言不讳的风险,如果开发人员对git的理解没有发展到他们理解git有多危险的程度,那么不应该授予该开发人员访问与其他开发人员共享的强制推送引用的权限

您可以将git remote配置为拒绝所有非快进推送(即使是强制推送);请参阅git config文档中的
receive.denynonfastforts


如果您需要更细粒度的控制,您将不得不再次依赖宿主软件来提供它。

您将无法获得强制推送历史记录,但您至少能够监视自己被破坏的提交。从本地克隆,使用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 ... //
从这里,您可以解决冲突,并在适当的情况下推迟更改。如果您所在的系统与进行提交的系统不同,则此方法不起作用。即使如此,如果时间足够长,您的本地提交可能会由于修剪而丢失。

此相当“黑客”的解决方案可能有助于查找强制推送的修改提交,尽管我不确定它是否在所有可能的情况下都能起作用

假设您在远程(裸)存储库中,您可以打印出存储在特定分支的reflog中的所有提交,并将它们与正常的
git日志的提交进行比较。这种差异应该给你力量

请注意,对于裸回购

例如,假设您已承诺掌握、推送、修改和强制推送-两次。 那么您总共有四次提交(如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 reflog
(在您的“中央”服务器上)?可能在寻找?@andree您的意思是日志总是在服务器上吗?如果我们在本地
pull
,那么提交日志将与服务器相同,对吗?不适用于reflog。reflog是存储库克隆的本地版本。@LeiYang也要向您的同事学习,我们不应该使用
--force
,而应该使用
--force with lease
,以防止无意中丢失提交(即使您有100天的时间,默认情况下在
reflog
中检索所有已删除提交的开发人员的提交).您所说的
远程(裸)
是什么意思?如果我是一个无法访问git服务器机器的普通用户,那么可以得到它吗?用作某种集中式服务器的git存储库通常是。我介绍的解决方案只有在您具有远程存储库的shell访问权限时才有效。
$ diff <(git log -g master | grep ^commit) <(git log master | grep ^commit) | grep "^<"
< commit 5afa0cfe6e16d4d45088aeb226ed052a5ad72b87
< commit 8bb40a9d6da838e151c8653b8d6be2b7afeb1902