我已经设置了一个远程非裸机的"主"repo并将其克隆到我的计算机上。我做了一些本地更改,更新了本地存储库,并将更改推回到远程repo。到那时一切都很好。
现在,我必须在远程回购中更改一些内容。然后我在本地回购中做了一些改变。我意识到不需要更改远程回购。因此,我尝试从本地回购到远程回购,但得到了如下错误:
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.
我想那可能是
将强制本地副本将更改推送到远程副本并使其相同。它确实强制更新,但是当我返回到远程repo并提交时,我注意到文件包含过时的更改(主远程repo以前的更改)。
正如我在对其中一个答案的评论中提到的:
[I] tried forcing, but when going back to master server to save the changes, i get outdated staging. Thus, when i commit the repositories are not the same. And when i try to use git push again, i get the same error.
如何解决此问题?
- 您很快就能(2013年第4季度,Git1.8.5)更仔细地执行git push -force。
- 相关:强制git在push时覆盖远程文件。
- 正如我在自己的回答中所详述的,git push --force确实是强制推送的另一种有效方法,它将像使用git的默认push.default config settings推送分支一样推送git push origin master --force,尽管在2.0之前的git版本和2.0之后的git版本中,具体推送的分支不同。
- 江户十一〔一〕这几天工作得很好。
- git push --force-with-lease工作得更好:),它将拒绝更新分支,除非它是您期望的状态。(见developer.atlassian.com/blog/2015/04/force with lease)
只做:
1
| git push origin <your_branch_name> --force |
或者,如果您有特定的回购:
1
| git push https://git.... --force |
这将删除以前的提交并推送当前的提交。
这可能不合适,但如果有人偶然发现了这一页,他们可能会想要一个简单的解决方案…
短旗
同时注意,-f是--force的缩写,所以
1
| git push origin <your_branch_name> -f |
也会起作用。
- 您可以使用git push origin +master来代替,它允许您推多个refspec,而不强制所有refspec。
- 请注意,如果您不小心只执行了git push --force,那么最终可能会弄乱您的主分支(取决于您的推默认行为)。这可能很糟糕……一点。。D
- @jeewes从git版本2.0开始,git push --force的默认行为基本上是强制将当前签出的分支推到其远程计数器部分,所以如果您签出了主分支,那么它与git push origin master --force是相同的。如果您使用push.default的matching设置,则会有所不同,这是2.0之前Git版本的默认设置。matching将所有本地分支推到具有相同名称的远程分支,因此强制推送肯定不是您想做的…
- @天哪,但使用2.0吉特,违约更安全,或者至少不会比git push origin master --force更危险。
- i.imgur.com/xfqlb.jpg
- 噢,不是为Mee工作的!!)但是我用的是git push -f ,不是一样的吗??参见(需要更正?)stackoverflow.com/a/10728449/287948
- push-f很好,但不为master重新定义,因为大多数公司存储库都为master禁用了-f。江户十一〔11〕为我工作。
- 一般来说:git push -f 。
- 休斯敦大学。。。--force失败,"remote:error:denying non-fast-forward refs/heads/master(you should pull first)",但我无法拉,因为diff显示遥控器基本上有以前的内容,这表明拉将基本上清除我要推的所有内容!
- 不幸的是,在Gitlab上,你仍然有着悠久的历史。
如果push --force不起作用,你可以做push --delete。查看此实例上的第2行:
1 2 3
| 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历史上!
换言之:
- 永远不要推动公共存储库。
- 不要这样做或做任何可能破坏别人的东西。
- 不要在回购交易中有人已经退出的历史记录。
当然,即使是这个规则也有非常罕见的例外,但在大多数情况下,不需要这样做,它会给其他人带来问题。
改为执行还原。
而且要时刻小心你推动的公共回购。回复:
1 2 3
| 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 |
实际上,两个原点(从还原和邪恶重置)都将包含相同的文件。
编辑以添加更新的信息和更多关于
push --force的参数。考虑使用租赁而不是推的方式来推动力,但仍倾向于恢复。
另一个问题可能是,有人在你之前推什么东西,但在你已经取出之后。如果您现在强制您的重新调整版本,您将替换其他人的工作。
git 1.8.5中引入的git push --force-with-lease(感谢@vonc对这个问题的评论)试图解决这个具体问题。基本上,如果在最近一次获取之后修改了遥控器,它将带来一个错误而不是推送。
如果你真的确定需要一个push --force,这是很好的,但仍然想防止更多的问题。我要说的是,这应该是默认的push --force行为。但这还远不是强迫江户的借口。在你的钢筋网之前取钢筋的人仍然会有很多麻烦,如果你改回钢筋网,很容易避免这些麻烦。
既然我们讨论的是git --push个例子…
为什么会有人想强行推?
@Linqueze为评论提供了一个很好的推动力示例:敏感数据。你错误地泄露了不应该被推送的数据。如果你足够快,你可以通过顶推来"修复"*。
*除非您同时进行垃圾收集或以某种方式清理,否则数据仍将位于远程。还有一个明显的潜力就是它会被别人传播,而别人已经得到了它,但是你得到了这个想法。
- 看起来在这之后可以拉一下,但是hard stackoverflow.com/questions/9813816/&hellip;
- 问题是,@rogerdpack,如果它可行的话。它是。但总的来说,这是一场大灾难。有人做的越多(强制推送),从公共回购中更新(拉取)的频率越低,灾难就越大。它可以摧毁你所知道的世界!!!!111至少是由那个特定的知识库组成的世界。
- 如果你有敏感数据,强制推送它
- @Linqueze没有跟踪。我会说,如果你有敏感的数据,恢复它。
- @Cawas:我认为他是说,如果您试图从存储库中删除敏感数据,那么您需要重写历史。如果您恢复,敏感数据仍然在前面的提交中。这就是说,如果其他人已经从存储库中提取了数据,那么重写历史不会帮助您阻止他们访问敏感数据——此时已经太迟了。
- @斯图亚特戈洛德兹感谢你的澄清!我完全误解了那里的"敏感"——我只是在想"重要"而不是"机密"。
- 这确实很好地解决了我的问题(仅与我和我的朋友讨论)。也许这对公共回购来说是错误的,但对私人回购来说,这是一个救命稻草。
- 还有一种情况是,您没有推送到公共服务器。您正在推动其他一些回购来构建一个开发箱或其他东西,没有人对您的工作的旧版本感兴趣。
- 为什么会有人想强行推?可能有人已经做出了你想要完全放弃的承诺。stackoverflow.com/questions/37132584/&hellip;
- 这会自动发生在一些回购经理、A.K.A.Auto-squash等情况下。在完成一个功能分支后强制推送以减少提交是常见的和预期的。
首先,我不会直接在"主要"回购协议中做任何更改。如果你真的想有一个"主要"回购,那么你应该只推动它,永远不要直接改变它。
关于您所犯的错误,您是否从本地回购中尝试了git pull,然后从git push尝试了主回购?你目前正在做的(如果我理解的很好)是强制执行,然后在"主"回购中丢失你的更改。您应该先在本地合并更改。
- 是的,我试过拉,但因为拉我正在丢失数据。我想做我的主要回购,因为我的地方是,没有首先从主更新。
- 在这种情况下,使用git push -f,但如果您再次更改主回购,则必须返回本地回购和git pull,以便与最新更改同步。然后你可以做你的工作,再推一次。如果你遵循这个"推拉"的工作流程,你就不会得到你抱怨的那种错误。
- 是的,我知道这是我的错。/我会试试看,过一会儿再回来。
- 尝试强制,但当返回主服务器以保存更改时,我得到过时的暂存。因此,当我提交时,存储库是不同的。当我再次尝试使用git push时,我会得到同样的错误。
如果我在本地分支A上,并且要强制将本地分支B推送到源分支C,那么可以使用以下语法:
1
| git push --force origin B:C |
- 我发现即使我在当地的分支机构B,我仍然需要做git push --force origin B:C。在我的例子中,似乎git push --force origin C只会从本地主机推到远程C分支,而不管我现在在哪个分支上。git version 2.3.8 (Apple Git-58)
我真的建议:
换句话说,保持一个可以从主服务器和本地计算机访问的裸式回购,以便有一个单独的上游回购从/到拉/拉。
使用以下命令:
1
| git push -f origin master |
- 也许可以对为什么这个答案比其他答案更好给出更多的解释,以及是什么使它与众不同。
- 哦,很抱歉给您带来不便,我有同样的问题,这个命令解决了,我想我应该分享一下。
- 和其他人一样,你改变了-f旗的位置…
这是我们在维护历史记录的同时替换公司Github存储库上的master的解决方案。
在公司存储库上掌握push -f通常被禁用以维护分支历史。这个解决方案对我们有效。
1 2
| git fetch desiredOrigin
git checkout -b master desiredOrigin/master // get origin master |
1 2 3 4 5
| 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上,创建一个pr
我也有同样的问题,但最终还是解决了。您最可能需要做的是运行以下两个git命令(将hash替换为git commit修订号):
1 2
| git checkout <hash>
git push -f HEAD:master |