2

我刚刚将一大堆我不应该有的提交推送到一个裸仓库,它将它收到的所有更改的文件复制到我们的 web 根目录

GIT_WORK_TREE=/var/www git checkout -f

在一个post-receive钩子里。

因为一次推送了一大堆提交,所以我不知道 repo 收到的上一个健康提交的 id 是什么。

有什么办法可以撤消这个推送吗?

4

2 回答 2

2

这真的做不到。

git reflog,它显示了您已签出的提交以及在它们之间移动了哪些操作的完整历史记录,通常是使用 Git 存储库从无能导致的灾难中恢复的合适工具;您只需查看历史记录,直到看到在您做任何愚蠢和破坏性的事情之前所做的提交,然后检查该提交。

不幸的是,对于裸 repos,reflog默认是禁用的。除非您core.logAllRefUpdates在 repo 的配置中明确启用,git reflog否则只会返回没有输出。如果你觉得有必要阅读这个问题,很可能你还没有明确启用core.logAllRefUpdates.

正如 Matthieu Moy 所描述的,您仍然可以通过查看开发机器上的远程跟踪分支的 reflogs(或您推送到裸存储库的任何存储库)来获得所需的信息。但是,如果您无法访问进行最后一次健康推送的任何开发机器,那么即使是该选项也可能对您不可用。

如果这是你的情况,我怕你完蛋了。你唯一的办法——假设你对应该签出的提交有一些了解——是git log通过肉眼查看完整的提交历史并尝试检查你认为可能是你想要的提交。启用 reflog 或下次更加小心。

于 2015-05-10T13:07:33.223 回答
2

正如 Mark Amery 所说,reflog 很可能在服务器上被禁用。但是,如果您有您从中推送的存储库的副本,仍然有希望。当你进行推送时,Git 更新了一个远程跟踪分支(如refs/remotes/origin/master),并且可能更新了这个远程跟踪分支的 reflog。

在 的输出中,您应该找到与您的推送相对git reflog show origin/master应的条目。update by push之前的条目对应于您在推送之前的位置。

您还可以直接查看日志文件(例如.git/logs/refs/remotes/origin/master)并找到类似的条目

acb60f2759717796f807197f6997708528260255 59dbeca4120db70db34144ee14d05cc526b1f5ab Your Self <Your.Self@example.com> 1427137007 +0100  update by push

第一个 sha1 是你之前的位置,第二个是你之后的位置。

但是没有魔法:这只会给你这个存储库看到的远程跟踪的历史,而不是谁推送的详细历史。

于 2015-05-10T13:54:47.587 回答