Git:如何忽略快进并将原点 [branch] 恢复到较早的提交?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3166713/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Git: How to ignore fast forward and revert origin [branch] to earlier commit?
提问by igniteflow
I used
我用了
git reset --hard dc082bc...由于一些错误的提交,将分支恢复到所需的先前状态。这让我当地的分行恢复正常。但是,我想将 'origin' 上的分支倒回到同一个提交,以便我可以重新开始。谁能告诉我如何将原始分支(不是主分支)恢复到这个提交?
I've tried git push origin master, but it gives the following error
我试过 git push origin master,但它给出了以下错误
! [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.
回答by VonC
To add to my previous answer, and to address the fact that a forced git push
can really mess up other contributors' local repos, git 1.8.5 (upcoming Q4 2013) will see a new option:
为了补充我之前的答案,并解决一个强制git push
确实会弄乱其他贡献者的本地存储库的事实,git 1.8.5(2013 年第四季度即将推出)将看到一个新选项:
git push --force-with-lease
See the origin of that option in this thread:
在此线程中查看该选项的来源:
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.
如果在
origin
您提取检查后强制或删除的分支发生了某些事情,您可能最终会丢失其他人的工作。不知道回滚和重建分支的决定的人可能会尝试在您提取以重新设置分支的时间和您推送以使用重新设置的结果替换它的时间之间推送到分支。
我们可以
make these pushes safer
选择允许用户告诉“git push
”:我正在强制/删除,基于“分支”的值仍然在这个对象的假设。
如果这个假设不再成立,即如果自从我开始准备这次推送以来分支发生了一些事情,请不要继续并失败这次推送。
You can see the full documentation of --force-with-lease
in commit 28f5d17
您可以--force-with-lease
在提交 28f5d17 中查看完整文档
--force-with-lease
will protect allremote 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
除非另有说明,否则将通过要求它们的当前值与某些合理的默认值相同来保护所有将要更新的远程引用;目前,“一些合理的默认值”被暂时定义为“我们拥有的远程跟踪分支的值,用于更新远程的引用”,如果我们没有这样的远程跟踪分支,这是一个错误。
That explain the "lease" part of that option:
这解释了该选项的“租赁”部分:
"
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.
"
force-with-lease
": 你假设你在获取时已经租用了 ref 来决定重新定位的历史应该是什么,并且只有在租约没有被破坏的情况下你才能推迟。
This is already being tested, and mentioned in the "What's cooking in git.git (Aug 2013, #07; Wed, 28)":
这已经在测试中,并在“ 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 innext
, like so:
顺便说一下,覆盖通常的“必须快进”的推送是使用“
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
Note: "git push --force-with-lease
" has been taught to report if the push
needed to force (or fast-forwarded).
注意:“ git push --force-with-lease
”已被教导报告是否需要强制(或快进)推动。
So this command is more detailed in its output with git 2.8 (March 2016)
所以这个命令在 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.
推送:修复参考状态报告
--force-with-lease
该
--force--with-lease
推送选项导致小于详细的状态信息--force
。
特别是,输出表明引用是快进的,即使它被强制更新。
Beware of that option being ignored/bypassed, as explained in Git 2.13 (Q2 2017).
请注意该选项被忽略/绕过,如Git 2.13 (Q2 2017) 中所述。
回答by VonC
You can try git push --force
to force the push.
您可以尝试git push --force
强制推送。
--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.
通常,该命令拒绝更新不是用于覆盖它的本地 ref 的祖先的远程 ref。此标志禁用检查。
这可能会导致远程存储库丢失提交;小心使用它。
So if lots of people have already pulled the same branch from origin, that can cause some rebase issueon their side.
That operation can be blocked at the server side, like ebneterpoints out (in the comments):
所以如果很多人已经从原点拉取了同一个分支,那可能会导致他们这边出现一些rebase 问题。
该操作可以在服务器端被阻止,就像ebneter指出的那样(在评论中):
Depending on how the remote is configured, though, this may not work
-- all of my central repos are configured withreceive.denyNonFastForwards = true
andreceive.denyDeletes = true
, in which case any such surgery has to be done on the remote server.
但是,根据远程的配置方式,这可能不起作用
——我所有的中央存储库都配置了receive.denyNonFastForwards = true
和receive.denyDeletes = true
,在这种情况下,任何此类手术都必须在远程服务器上完成。
However, in the case of GitHub, such settings are not readily availablefor the user managing its GitHub repo.
So if you git push --force
by mistake, all you are left is opening a case to the GitHub support, for them to check their local (i.e. "GitHub") reflogs and see if they can restore old commits.
(Since reflogs are local, like I have been remembered recently. So commits which are replaced by new ones during a push --force
are only still visible, if no 'git gc
' or 'git prune
' already took place, at the GitHubserver side)
但是,在 GitHub 的情况下,管理其 GitHub 存储库的用户不容易获得此类设置。
因此,如果您git push --force
弄错了,剩下的就是向 GitHub 支持部门开一个案例,让他们检查他们的本地(即“GitHub”)引用日志,看看他们是否可以恢复旧的提交。
(因为 reflogs 是本地的,就像我最近被记住的那样。所以在GitHub服务器端push --force
,如果没有 ' git gc
' 或 ' git prune
' 已经发生,则在 a 期间被新提交替换的提交仍然可见)
So Marco Ceppiinsists (in the comments):
所以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)
如果您强制推送,这可能真的会弄乱其他贡献者的本地存储库 - 尽管有时它只是一种必要的邪恶(在我使用 Git 的生命周期中,我可能不得不这样做两次)
回答by xgqfrms
git reset
&& git push
with force overwrite
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
refs
参考
In Git, what is the difference between origin/master vs origin master?
在 Git 中,origin/master 与 origin master 之间有什么区别?