git得力推历史

问题描述 投票:2回答:3

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

在我们的QA团队的git存储库中,我经常发现之前添加的测试用例丢失了。从主分支的histroy我再也找不到我的提交了。

当我比较我的个人分支的日志和主分支的日志时,曾经找到了根本原因,并且这是某人的强制推动,并且该家伙承认他对git merge不是很熟悉但是赶紧推出如此使用的强制选项。

但是如果没有这样的分支来备份这些提交历史呢?几天之后,每个团队成员都已撤离,以致承诺历史永远消失。

即使有这样的备份分支,比较和了解谁推动力量也是非常耗时的。

有没有办法获得力推日志?请注意作为一名普通员工,我不是git服务器的所有者/管理员,但我关心我的提交,并希望对那些删除它们的人进行警告。

git push-notification git-push git-log
3个回答
2
投票

git本身没有真正可靠的方法来检索那种信息。 (有些git托管软件可能会保留类似于垃圾推文的类似垃圾记录,但我不知道;如果你使用特定的托管软件包,你可以查阅它的文档。)

除了找到一个未接受新历史记录的克隆之外,即使它已经接受了新的历史记录,你也可以从克隆的reflog中获得所需的信息 - 但是reflog是本地的和临时的,所以这是不保证。

(根据您的遥控器的托管方式,您可能也可以参考其reflog,如果它保留它们并且您可以访问它们。但即使所有这些ifs都破坏了您的方式,也不能保证,因为reflog是临时的。)

这就是为什么git push -f是一个危险的工具;如果开发人员对git的理解没有进展到他们理解它有多危险的程度,那么就有可能变得生硬,那么开发人员不应该被授予访问强制推送到与其他开发人员共享的refs的权限。

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

如果您需要更细粒度的控制,您再次必须依靠托管软件来提供它。


1
投票

您将无法获得强制推送历史记录,但您至少可以窥探您自己的被破坏的提交。从您的本地克隆,使用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 ... //

从这里开始,您可以解决冲突并在适当的情况下推迟更改。如果您与提交的位置不同,则此方法不起作用,即使这样,如果已经过了足够的时间,您的本地提交可能会因修剪而丢失。


1
投票

这个相当“hacky”的解决方案可能有助于找到强制推送的修改提交,但我不确定它是否适用于所有可能的情况。

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

请注意,对于裸回购,reflogs must be enabled

作为一个例子,假设你已经承诺掌握,推动,然后修改和强制推 - 两次。那么你总共会有四次提交(如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,这样我就能看到被修改的提交。

© www.soinside.com 2019 - 2024. All rights reserved.