10

我用了

git reset --hard dc082bc ...
由于一些错误的提交,将分支恢复到所需的先前状态。这使我的本地分支机构恢复正常。但是,我想将 'origin' 上的分支倒回到同一个提交,以便我可以重新开始。谁能告诉我如何将原始分支(不是主分支)恢复到这个提交?

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

![拒绝] 分支 -> 分支(非快进)
错误:未能将一些引用推送到 'git@github.com:xxx/xxx.git'
为防止您丢失历史记录,拒绝了非快进更新
在再次推送之前合并远程更改。请参阅“关于
'git push --help' 的 fast-forwards 部分了解详细信息。
4

3 回答 3

31

为了补充我之前的答案git push,并解决强制可以真正搞砸其他贡献者的本地存储库的事实,git 1.8.5(即将到来的 2013 年第四季度)将看到一个新选项:

git push --force-with-lease

在此线程中查看该选项的来源:

origin如果自从您提取检查它以来,您强制或删除的分支发生了某些事情,您最终可能会丢失其他人的工作。

不知道回退和重建分支的决定的人可能会尝试在您提取以重新定位它的时间和您推送以用重新定位的结果替换它的时间之间推送到分支。

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

我正在强制/删除,基于“分支”的值仍然在这个对象上的假设。
如果该假设不再成立,即,如果自从我开始准备此推送以来分支发生了什么事,请不要继续并且使此推送失败。

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

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

目前,“一些合理的默认值”暂时定义为“我们拥有的远程跟踪分支的值,用于更新远程的 ref”,如果我们没有这样的远程跟踪分支,则会出现错误。

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

" 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

push 选项导致的--force--with-lease状态信息不如--force.
特别是,输出表明引用被快速转发,即使它被强制更新。


请注意该选项被忽略/绕过,如Git 2.13 (Q2 2017) 中所述

于 2013-08-29T08:18:51.703 回答
19

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

--force

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

因此,如果很多人已经从原点拉出同一个分支,这可能会导致他们一方出现一些变基问题
该操作可以在服务器端被阻止,就像ebneter指出的那样(在评论中):

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

但是,对于 GitHub,管理其 GitHub 存储库的用户不容易使用此类设置。
因此,如果您git push --force误操作,剩下的就是向 GitHub 支持打开一个案例,让他们检查他们的本地(即“GitHub”)引用日志,看看他们是否可以恢复旧的提交。
(因为 reflogs 是本地的,就像我最近记得的那样。所以在 a 期间被新的提交替换的提交只有在GitHub服务器端没有发生 ' ' 或 ' ' 的push --force情况下仍然可见)git gcgit prune

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

如果您强制推送,这可能真的会搞砸其他贡献者的本地存储库 - 尽管有时它只是一种必要的邪恶(在我使用 Git 的一生中,我可能不得不这样做两次)

于 2010-07-02T14:55:13.980 回答
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

参考

在 Git 中,origin/master 与 origin master 有什么区别?

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

于 2020-02-11T07:05:35.310 回答