以下是发生的事情:
我有两个远程git分支:master
和feature1
。出于某种原因,我必须使用git push --force
作为feature1
分支,但我不知道何时使用git push --force
它还会推送master
分支。然后,当我将本地master
分支推送到远程存储库时发生了灾难。
幸运的是,我当地的分店距离遥控器不太远。基本上,我的远程master
在本地master
之前合并了两个拉取请求。
所以我的问题是:我可以重新打开拉取请求并重新合并吗?我注意到有合并请求的提交版本,所以我担心如果我只是提出新的拉请求它会搞砸什么?理想情况下,我只想重做两个请求的合并。
还有其他方法可以从灾难中恢复过来吗?我了解到--force
是一个非常非常糟糕的选择。 :(
更新,发生的事情的例子:
我有以下分支:
master
feature1
origin/master
origin/feature1
我使用GitHub的Auto merge pull requests
整合了两个拉取请求。然后,我没有在本地计算机上获取master
分支。因此,我认为我的origin/master
是远程主人后面的两个版本。
然后我意外地使用了git -f push
,它覆盖了远程分支,现在我从远程存储库上的pull请求中丢失了提交。
如何在不弄乱其他贡献者的历史的情况下从中恢复?
答案 0 :(得分:73)
您可以通过重置为旧提交并发出另一个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
但是,请注意,这会将远程master
还原到git fetch
最近检索到的状态或等效状态。在您最后一次获取之后由其他人推送的任何提交都将丢失。但是,这些提交仍将在他们的 reflog中提供,因此他们可以使用上述步骤恢复它们。
答案 1 :(得分:20)
请注意,使用 Github ,您可以使用API恢复强制推送,即使您没有在本地克隆存储库(例如,当您没有reflog时),或者承诺。
首先,您必须获得之前的提交sha,即强制推送前的提交:
curl -u <username> https://api.github.com/repos/:owner/:repo/events
然后你可以从这个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
最后,您可以在本地克隆存储库,并再次强制推送到主控:
git clone repo@github
git checkout master
git reset --hard origin/<new-branch-name>
git push -f origin master
请注意,使用双因素身份验证时,您需要提供令牌(有关详细信息,请参阅here)。