我如何正确强制Git推?

我已经build立了一个远程的非主要的“主”回购,并将其克隆到我的电脑。 我做了一些本地更改,更新了我的本地存储库,并将更改推回到我的远程仓库。 事情到此为止都没有问题。

现在,我不得不改变远程回购的东西。 然后,我改变了我本地回购的东西。 我意识到,远程回购的变化是不需要的。 所以我试图从我的本地回购git push到我的远程回购,但我有一个错误,如:

为防止您丢失历史logging,拒绝非快进更新在再次推送之前合并远程更改。 有关详细信息,请参阅git push --help的“快速转发注释”部分。

我以为这可能是一个

 git push --force 

将强制我的本地副本推送到远程更改并使其相同。 它强制更新 ,但是当我回到远程仓库并进行提交时,我注意到这些文件包含过时的更改(主远程仓库之前的更改)。

正如我在评论中提到的其中一个答案 :

[我]试图强迫,但当回到主服务器保存更改,我得到过时的分期。 因此,当我提交存储库是不一样的。 而当我尝试再次使用混帐推,我得到同样的错误。

我该如何解决这个问题?

做就是了:

 git push origin <your_branch_name> --force 

或者如果你有一个特定的回购:

 git push https://git.... --force 

这会删除以前的提交并推送当前的提交。

这可能是不正确的,但如果有人在这个页面上绊倒,认为他们可能想要一个简单的解决scheme…

短旗子

另请注意, -f--force缩写,所以

 git push origin <your_branch_name> -f 

也将工作。

如果push --force不起作用,你可以push --delete 。 看看这个实例的第二行:

 git reset --hard HEAD~3 # reset current branch to 3 commits ago git push origin master --delete # do a very very bad bad thing git push origin master # regular push 

但要小心…

永远不要回到公共git的历史!

换一种说法:

  • 千万不要force推送公共存储库。
  • 不要这样做或任何可以打断别人的东西。
  • 不要resetrewrite历史logging在某人可能已经拉。

当然,即使这个规则也有极less数的例外情况,但在大多数情况下,不需要这样做,这会给其他人带来麻烦。

做一个回复。

而且要小心你推到公共回购站的时候 。 回复:

 git revert -n HEAD~3..HEAD # prepare a new commit reverting last 3 commits git commit -m "sorry - revert last 3 commits because I was not careful" git push origin master # regular push 

实际上,起源HEAD(从回复和从邪恶重置 )将包含相同的文件。


编辑添加更新的信息和围绕push --force更多的参数

考虑用推力而不是推力来推动力量,但仍然更愿意回复

push --force可能带来的另一个问题是,在你做任何事之前有人推动任何事情,但是在你已经提取之后。 如果你现在强迫你的重塑版本,你会取代别人的工作

在git 1.8.5中引入的git push --force-with-lease ( 感谢@VonC对这个问题的评论)试图解决这个特定的问题。 基本上,它会带来一个错误,而不是推动,如果远程被修改,因为你最近的抓取。

如果你真的确定需要push --force ,但是仍然想要防止更多的问题,这是很好的。 我会尽可能地说它应该是默认的push --force行为。 但是,这还不是push 。的借口。 在重新组织之前获得的人仍然会有很多麻烦,如果你已经恢复,那么很容易避免。

而因为我们正在讨论git --push实例…

为什么会有人想要推动?

@linquize对评论带来了很好的推动力: 敏感数据 。 您错误地泄露了不应推送的数据。 如果你速度够快的话,你可以通过强行推送来“修复”它。

* 数据将仍然在远程,除非你也做垃圾收集 ,或以某种方式清理 。 那些已经拿到它的人也有明显的潜力,但是你明白了。

首先,我不会直接在“主”回购中做任何改变。 如果你真的想要一个“主”回购,那么你应该只是推动它,不要直接改变它。

关于你得到的错误,你有没有尝试从你的本地回购git pull ,然后git push到主要回购? 你现在正在做什么(如果我理解的很好)是强制推动,然后在“主”回购中失去你的变化。 您应该首先在本地合并更改。

如果我在本地分支A上,并且我想强制将本地分支B推送到原始分支CI,则可以使用以下语法:

 git push --force origin B:C 

我真的会build议:

  • 只推送到主要的回购

  • 确保主回购是一个裸回购 ,以便永远不会有任何问题的主回购工作树不与其同.git基地同步。 请参阅“ 如何将本地git存储库推送到另一台计算机? ”

  • 如果您必须在主(裸)回购中进行修改,请将其克隆(在主服务器上),然后进行修改并将其推回

换句话说,保持主服务器和本地计算机都可以访问一个裸回购,以便有一个上/下回购/回拉。

这是我们的解决scheme,用于replace公司gitHub存储库上的master,同时保留历史logging。

push -f掌握企业存储库往往被禁止维护分支机构的历史。 这个解决scheme为我们工作。

 git fetch desiredOrigin git checkout -b master desiredOrigin/master // get origin master 

 git checkout currentBranch // move to target branch git merge -s ours master // merge using ours over master // vim will open for the commit message git checkout master // move to master git merge currentBranch // merge resolved changes into master 

把你的分支推到desiredOrigin并创build一个PR

使用以下命令:

 git push -f origin master