41

这是发生的事情:

我有两个远程 git 分支:masterfeature1. 出于某种原因我必须使用git push --forceforfeature1分支,但我不知道我什么时候使用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了,它覆盖了远程分支,现在我丢失了远程存储库上拉取请求的提交。

我怎样才能在不破坏其他贡献者历史的情况下从中恢复?

4

2 回答 2

88

使用 github 时,请参阅GHugo 的答案,它提供了一个使用 github 的万无一失的过程。如果您在内部(或其他非 github)安装,请继续阅读。

您始终可以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 中可用,因此他们可以使用上述步骤恢复它们。

于 2012-09-24T17:06:35.807 回答
42

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

首先,您必须获取上一个提交 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

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

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

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

学分:桑卡拉·拉梅斯瓦兰

于 2017-04-07T06:54:26.933 回答