如何从错误的 git push-f 源代码主机恢复?

我只是使用 --force选项提交了错误的源代码到我的项目。

有可能恢复吗?我明白所有以前的分支已经被覆盖使用 -f选项,所以我可能已经搞砸了我以前的修订。

105196 次浏览

Git 通常不会丢弃任何东西,但是从中恢复可能仍然是棘手的。

如果你有正确的来源,然后你可以只是推到远程与 --force选项。Git 不会删除任何分支,除非你让它这么做。如果您实际上丢失了提交,那么请看一下 this useful guide to recovering commits。如果你知道 SHA-1的提交你想然后你可能没问题。

最好的做法是: 备份所有内容并查看本地存储库中还有哪些内容。如果可能,对远程执行相同操作。使用 git fsck看看你是否能恢复东西,最重要的是 DO NOT run git gc

最重要的是,永远不要使用 --force选项,除非你真的,真的想这样做。

我做了同样的事情,而撤消最后一次推只有一个文件。最终返回到存储库的原始状态。我使用 Linus 的 git 命令,因为我有 Linux 上的本地副本。幸运的是复制品还完好无损。

我所做的只是(在疯狂地多拷贝几份本地回购协议之后) :

git add .
git status

(它说,原产地/主人领先68提交,罚款... 这些都是我删除的提交)

git remote set-url origin <GIT_SSH_URL>
git push

一切都恢复到了我用力推之前的样子。 最重要的是要记住,永远不要做一个 git 检查。在你用力推之后。但是最佳实践是禁用推选项。我再也不会用它了。吸取教训吧!

如果您知道提交散列,那么很简单,只需重新创建您的分支。

5794458...b459f069 master -> master (forced update)

删除远程分支:

git push origin :master

then recreate your branch with the following commands:

git checkout 5794458
git branch master
git push origin master

The solution is already mentioned 给你

# work on local master
git checkout master


# reset to the previous state of origin/master, as recorded by reflog
git reset --hard origin/master@{1}


# at this point verify that this is indeed the desired commit.
# (if necessary, use git reflog to find the right one, and
# git reset --hard to that one)


# finally, push the master branch (and only the master branch) to the server
git push -f origin master

如果你不在当地的回购哪里强制推来,在原产地/主水平没有办法恢复。但是,如果你是 真幸运足以使用 GitHub企业级 GitHub,你可以看看 REST API 和检索丢失的提交作为补丁,例如:

  1. 列出事件并找到提交 sha1长格式

Https://api.github.com/repos/apache/logging-log4j2/events

  1. 下载丢失的提交并在 json path. files []/patch 中检索相关的补丁

Https://api.github.com/repos/apache/logging-log4j2/commits/889232e28f3863d2a17392c06c1dd8cac68485de

  1. 局部涂抹,然后再次推

Git 应用补丁补丁 & & git 提交-m“恢复提交”& & git 推送原始管理器

另一种恢复丢失的提交或者甚至找出丢失的提交的方法是查看 CI 机器,如果之前的推送不是来自本地回购的话。

如果您有一个在每次提交(或一系列连续提交)之后测试主分支的作业(您应该有这样的作业) ,那么您可以看看它最后测试的是什么。这就是你需要恢复的承诺。

CI 机器甚至可以保留回购的本地克隆,您可以从中执行这个恢复。

Source: probably 持续交付: 通过构建、测试和部署自动化发布可靠的软件(Addison-Wesley 签名系列(福勒))

Here you can read decisions https://evilmartians.com/chronicles/git-push---force-and-how-to-deal-with-it

第二个帮了我。 我做错了这些命令

1) (some-branch) git pull -> correct command was git pull origin some-branch


2) (some-branch) git push -f origin some-branch

在这些命令之后,我丢失了三次提交。为了恢复它们,我查看了终端,在那里我做了错误的“ git pull”,并看到了输出

60223bf... 0b258b 某支行 > 原产地/某支行

第二个 hash 0b258eb 正是我所需要的

git push --force origin 0b258eb:some-branch

是的,你可以在 git push -f your_branch之后恢复提交

来自文件 的文本:

修剪超过指定时间的项。如果此选项不是 specified, the expiration time is taken from the configuration setting ReflogExire,它的默认值为90天 删除条目,不管它们的年龄大小; ——過期 = 永不关闭 删除可到达的条目(但请参见——过期-不可到达)。

所以你可以这样做:

1-git reflog

enter image description here

2-你选择 Head _ Number 你想用 git reset –hard HEAD@{HEAD-NUMBER}恢复吗

enter image description here

3-你可以看到所有的提交在这个头由 git cherry -v branch_name

最后你应该强制按 git push -f branch_name

或者

1-从 GIT 客户端(接口)获取 SHA 的编号

git reset --hard commit_SHA

2- force push

git push -f your_branch

希望这个能帮上忙

对于像我这样处于非常糟糕的情况下的人(例如,如果在运行 git reset --hard时出现 bad object错误) :

作为最后的手段,我编写了从 GitHub API 中提取所有文件的 一个叫做“救树人”的剧本。以下是使用方法:

  1. 克隆 treesaver脚本和 cd
  2. 查找要通过访问还原的树的 SHA字符串 https://api.github.com/repos/<your_username_or_org>/<repo>/events.
  3. In the payload property corresponding to your push event, find the commit you'd like to revert to and click on its url.
  4. commit.tree下,复制 treeurl
  5. 运行 python3 main.py <tree_url> <path_to_save_to>

例如,在我的情况下,我会跑:

python3 main.py https://api.github.com/repos/anthonykrivonos/my-repo/git/trees/1234567 .

当然,公关欢迎。