如何从 git push -force 中恢复?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/12568628/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-19 07:31:54  来源:igfitidea点击:

How to recover from a git push -force?

gitgithub

提问by Brian

Here is what happened:

这是发生的事情:

I have two remote git branches: masterand feature1. For some reason I have to use git push --forcefor the feature1branch, but I didn't know when I use git push --forceit will also push the masterbranch. Then, a disaster happened, as I pushed my local masterbranch to the remote repository.

我有两个远程 git 分支:masterfeature1. 出于某种原因,我必须使用git push --forcefeature1分支,但我不知道,当我使用git push --force它也将推动master分支。然后,当我将本地master分支推送到远程存储库时,发生了灾难。

Luckily, my local branch is not too far away from the remote. Basically, my remote masterhas two pull requests merged ahead of my local master.

幸运的是,我的本地分支离远程不太远。基本上,我的遥控器master在我的本地之前合并了两个拉取请求master

So my problem is: can I reopen the pull request and remerge? I noticed that there is commit version for merge request, so I am worried if I simply make new pull request it will mess up something? Ideally I just want to redo the merging of the two requests.

所以我的问题是:我可以重新打开拉取请求并重新合并吗?我注意到合并请求有提交版本,所以我担心如果我只是提出新的拉取请求,它会搞砸什么?理想情况下,我只想重做两个请求的合并。

Is there some other way to recover from this disaster? I learned the --forceis a really, really bad choice. :(

有没有其他方法可以从这场灾难中恢复过来?我了解到这--force是一个非常非常糟糕的选择。:(

Update, example of what happened:

更新,发生的事情的例子:

I have following branches:

我有以下分支机构:

master
feature1
origin/master
origin/feature1

I integrate two pull requests by using the GitHub's Auto merge pull requests. Then, I didn't fetch the masterbranch on my local machine. Thus, I think my origin/masteris two versions behind the remote master.

我使用 GitHub 的Auto merge pull requests. 然后,我没有master在本地机器上获取分支。因此,我认为 myorigin/master是远程 master 后面的两个版本。

Then I accidentally used git -f push, which overwrote the remote branch and now I lost the commits from the pull requests on remote repository.

然后我不小心使用了git -f push,它覆盖了远程分支,现在我丢失了远程存储库上拉取请求的提交。

How can I recover from it without messing up other contributors' history?

如何在不弄乱其他贡献者的历史记录的情况下从中恢复?

回答by user4815162342

You can always restore the previously observed state of master, by resetting to the old commit and issuing another push -f. The steps involved typically look like this:

您始终可以master通过重置为旧提交并发出另一个push -f. 涉及的步骤通常如下所示:

# 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

Note, however, that this restores remote masterto the state most recently retrieved by git fetchor equivalent. Any commits pushed by others after the last time you fetched will be lost. However, those commits will still be available in theirreflogs, so they can restore them using steps like the above.

但是请注意,这会将 remote 恢复master到最近由git fetch或等效物检索到的状态。在您上次获取之后由其他人推送的任何提交都将丢失。但是,这些提交仍将在reflog 中可用,因此他们可以使用上述步骤恢复它们。

回答by GHugo

Note that, with Github, you can use the API to recover a forced push even if you do not have the repository cloned locally (i.e., when you do not have a reflog), or the commit sha.

请注意,使用Github,即使您没有在本地克隆存储库(即,当您没有 reflog 时)或提交 sha,您也可以使用 API 来恢复强制推送。

First, you must get the previous commit sha, the one before the forced push:

首先,您必须获得之前的提交 sha,即强制推送之前的那个:

curl -u <username> https://api.github.com/repos/:owner/:repo/events

Then you can create a branch from this sha:

然后你可以从这个 sha 创建一个分支:

curl -u <github-username> -X POST -d '{"ref":"refs/heads/<new-branch-name>", "sha":"<sha-from-step-1>"}' https://api.github.com/repos/:owner/:repo/git/refs

Finally, you can clone the repository locally, and force push again to master:

最后,您可以在本地克隆存储库,并再次强制推送到 master:

git clone repo@github
git checkout master
git reset --hard origin/<new-branch-name>
git push -f origin master

Note that with two-factor authentication, you need to provide a token (see herefor more information).

请注意,使用双因素身份验证时,您需要提供令牌(有关更多信息,请参见此处)。

Credit: Sankara Rameswaran

图片来源:Sankara Rameswaran