无论如何撤消git push -f?

lar*_*mbr 15 git

如果我push -f用来重叠最后一次提交,即A,在远程存储库上,其他人在推送之前已经拉了A.

无论如何要撤消这种情况,以免给别人带来麻烦?

push -f一个原始人 " 假装 "没有触及任何东西是否有用?

要么

git如何决定本地repo是否偏离远程跟踪?

cmb*_*ley 36

在推送之前有几种方法可以找出原始HEAD(ORIG_HEAD可能不是其中之一):

终端回滚

如果你有幸让终端打开,那么在推送时会有一些输出,如下所示:

...
To user@host:repo.git
 + abcdef0...1234567 HEAD -> branchname (forced update)
Run Code Online (Sandbox Code Playgroud)

在这里,abcdef0是以前的HEAD(你的A),1234567而你强迫它成为了.

git reflog

输出结果git reflog告诉您所做的事情的时间顺序.您基本上想要回到相关的行(在更改之前已经检出了您的分支)并从第一列中获取提交ID.

这里最有用的命令是git reflog show remotes/origin/branchname.这应该显示您的强制update(1234567)和前一个提交ID(abcdef0)作为前两行.

以前的参考

这里有几个提交引用可能很有用:

  • @{1}(或者branchname@{1},如果您不在该分支上)是该参考的先前值.仅在您未对本地分支机构进行任何其他提交时才有效.
  • 同样,remotes/origin/branchname@{1}将是遥控器上ref的先前值.仅在其他人未推送到遥控器时才有效.

检查您是否拥有正确的ID

如果您想确认您从上述某种方法中获取的ID是正确的,只需查看它:

git checkout abcdef0
Run Code Online (Sandbox Code Playgroud)

并环顾四周.如果git log看起来很熟悉(我还建议使用tig浏览您的存储库,甚至可以运行tig abcdef0以查看给定提交的日志),那么您可以确信您正在重置到正确的位置.

重置为先前的状态

获得之前的提交ID后,您可以重置为该ID并再次强制推送:

git checkout branchname # if you're not on it already
git reset --hard abcdef0
git push -f
Run Code Online (Sandbox Code Playgroud)

要不就:

git push -f origin abcdef0:branchname
Run Code Online (Sandbox Code Playgroud)

这将使分支的状态恢复到强制推送之前的状态.

有什么影响?

如果你强迫推动人们已经拉动了分支,如果你强行推回到原来那么他们将在随后更新时遇到问题.如果他们没有对该分支进行任何提交,他们可以只删除他们的本地分支并重新签出(在git fetch确认他们有最新的引用之后),或者以下将执行相同的操作:

git fetch
git checkout branchname # if you're not on it already
git reset --hard origin/branchname
Run Code Online (Sandbox Code Playgroud)

如果他们已经进行了本地提交,那么他们需要将这些更改重新定义到正确的历史记录中(并且可能解决任何冲突):

git fetch
git checkout branchname # if you're not on it already
git rebase --onto origin/branchname 1234567
Run Code Online (Sandbox Code Playgroud)

以上意思是"在1234567(正确的头部)之上重放所有提交(不origin/branchname正确的头部)."