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

时间:2010-07-02 14:44:36

标签: git commit reverting

我用过

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

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

 ! [rejected]        branch -> branch (non-fast-forward)
error: failed to push some refs to 'git@github.com: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.

3 个答案:

答案 0 :(得分:26)

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

git push --force-with-lease

this thread中查看该选项的来源:

  

如果您在强制或删除分支的“origin”发生了某些事情,那么您可能最终会失去其他人的工作

     

不知道倒带和重建分支的决定的人可能会尝试在您获取它的时间和您推迟用更改结果替换它的时间之间推送到分支。

     

我们make these pushes safer可以选择允许用户告诉“git push”:

     

我强制/删除,基于“分支”的值仍在此对象的假设。
  如果这个假设不再成立,即自从我开始准备这个推动以来分支机构发生了什么事情,请不要继续这个推动。

您可以在commit 28f5d17

中查看--force-with-lease的完整文档
  

--force-with-lease将通过要求其当前值与某些合理的默认值相同来保护将要更新的所有远程引用,除非另有说明;

     

目前,“一些合理的默认值”暂定为“我们为更新遥控器的参考设置的远程跟踪分支的价值”,如果我们没有这样的遥控器,则会出现错误 - 跟踪分支。

解释该选项的“租约”部分:

  

force-with-lease”:当你决定重新定义历史应该是什么时,你假设你在ref上接受了租约,只有在租约没有被破坏的情况下你才能撤回。


这已经过测试,并在“What's cooking in git.git (Aug 2013, #07; Wed, 28)”中提及:

  

顺便说一下,使用force-with-lease中已经烹饪的“next”选项完成了覆盖通常“必须快进”的推送,如下所示:

$ 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月)

的输出中更加详细
  

推送:修复--force-with-lease

的参考状态报告      

--force--with-lease推送选项导致的状态信息不如--force   特别是,输出表明引用是快进的,   即使它是强制更新的。


请注意忽略/绕过该选项,如explained in Git 2.13 (Q2 2017)

答案 1 :(得分:18)

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

--force
  

通常,该命令拒绝更新远程ref,该远程ref不是用于覆盖它的本地ref的祖先。此标志禁用检查   这可能导致远程存储库丢失提交;小心使用它。

因此,如果很多人已从原点拉出相同的分支,那么可能会导致一些rebase issue。 可以在服务器端阻止该操作,如ebneter指出(在注释中):

  

根据遥控器的配置方式,这可能不起作用    - 我的所有中央回购都配置了 receive.denyNonFastForwards = true receive.denyDeletes = true ,在这种情况下,任何此类手术都必须在远程服务器上完成。

但是,对于GitHub,such settings are not readily available用于管理其GitHub仓库的用户。
因此,如果您错误地git push --force,则剩下的只有opening a case to the GitHub support,以便他们检查他们的本地(即“GitHub”)reflog,看看他们是否可以恢复旧的提交。
(由于reflog是本地的,like I have been remembered recently。因此,如果没有“push --force”或“git gc”,那么在git prune期间由新的提交替换的提交仍然可见发生在 GitHub 服务器端)

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

  如果你强行推动,这可能真的搞砸了其他贡献者的本地回购 - 虽然它只是一个必要的邪恶(我可能不得不在我使用Git的生命中这两次这样做)

答案 2 :(得分:0)

git reset && git push(强制覆盖)

# master commit uid
$ git reset --hard b9e3f7f2f66674901b467183dd81d493e50677f5

# git push branch_name --force

# local master
$ git push origin master --force

# remote master
$ git push origin/master -f

裁判

In Git, what is the difference between origin/master vs origin master?

https://git-scm.com/docs/git-reset