Git:如何忽略快进并将原点[branch]恢复到之前的提交?

Git: How to ignore fast forward and revert origin [branch] to earlier commit?

我用了
由于一些糟糕的提交,

1
git reset --hard dc082bc...

恢复到分支回到所需的先前状态。 这让我当地的分公司很好。 但是,我想将'origin'上的分支回滚到同一个commit,以便我可以重新开始。 谁能告诉我如何将原始分支(非主人)恢复到此提交?

我已经尝试过git push origin master,但它给出了以下错误

1
2
3
4
5
 ! [rejected]        branch -> branch (non-fast-forward)
error: failed to push some refs to '[email protected]:xxx/xxx.git'
To prevent you from losing history, non-fast-forward updates were rejected
Merge the remote changes before pushing again.  See the 'Note about
fast-forwards' section of 'git push --help' for details.


要添加到我之前的答案,并解决强制git push真的搞乱其他贡献者的本地回购这一事实,git 1.8.5(即将到来的2013年第4季度)将会看到一个新选项:

1
git push --force-with-lease

在此主题中查看该选项的来源:

if something happens at 'origin' to the branch you are forcing or deleting since you fetched to inspect it, you may end up losing other people's work.

Somebody who is unaware of the decision to rewind and rebuild the branch may attempt to push to the branch between the time you fetched to rebase it and the time you pushed to replace it with the result of the rebasing.

We can make these pushes safer by optionally allowing the user to tell"git push" this:

I am forcing/deleting, based on the assumption that the value of 'branch' is still at this object.
If that assumption no longer holds, i.e. if something happened to the branch since I started preparing for this push, please do not proceed and fail this push.

您可以在commit 28f5d17中查看--force-with-lease的完整文档

--force-with-lease will protect all remote refs that are going to be updated by requiring their current value to be the same as some reasonable default, unless otherwise specified;

For now,"some reasonable default" is tentatively defined as"the value of the remote-tracking branch we have for the ref of the remote being updated", and it is an error if we do not have such a remote-tracking branch.

这解释了该选项的"租赁"部分:

"force-with-lease": You assume you took the lease on the ref when you fetched to decide what the rebased history should be, and you can push back only if the lease has not been broken.

这已经在测试中,并在"git.git中的什么烹饪(2013年8月,#07;周三,28)"中提及:

By the way, the push that overrides the usual"must fast-forward" was done using the"force-with-lease" option that has been cooking in next, like so:

1
2
3
4
5
6
$ git fetch ko next
$ anchor=$(git rev-parse --verify FETCH_HEAD)
$ for remote in ko repo gph github2
  do
    git push --force-with-lease=refs/heads/next:$anchor $remote next
  done

注意:"git push --force-with-lease"已被教导如果推送报告
需要强制(或快进)。

所以这个命令在输出中用git 2.8更详细(2016年3月)

push: fix ref status reporting for --force-with-lease

The --force--with-lease push option leads to less detailed status information than --force.
In particular, the output indicates that a reference was fast-forwarded,
even when it was force-updated.

请注意忽略/绕过该选项,如Git 2.13(2017年第2季度)中所述。


您可以尝试git push --force强制推送。

1
--force

Usually, the command refuses to update a remote ref that is not an ancestor of the local ref used to overwrite it. This flag disables the check.
This can cause the remote repository to lose commits; use it with care.

因此,如果很多人已经从原点撤出了同一个分支,那么这可能会导致一些反驳问题。
可以在服务器端阻止该操作,就像ebneter指出的那样(在评论中):

Depending on how the remote is configured, though, this may not work
-- all of my central repos are configured with receive.denyNonFastForwards = true and receive.denyDeletes = true, in which case any such surgery has to be done on the remote server.

但是,在GitHub的情况下,管理其GitHub存储库的用户无法轻易获得此类设置。
所以,如果您错误地git push --force,那么剩下的就是向GitHub支持打开一个案例,让他们检查他们的本地(即"GitHub")reflog,看看他们是否可以恢复旧的提交。
(因为reflogs是本地的,就像我最近记得的那样。因此,如果没有'git gc'或'git prune'已经发生,那么在push --force期间被新的替换的提交仍然可见GitHub服务器端)

所以Marco Ceppi坚持(在评论中):

this could really mess up other contributors local repos if you force pushes - though are times that it is just a necessary evil (I've maybe had to do this two times in my lifespan of using Git)