如何正确强制推送Git?

时间:2011-04-01 05:35:55

标签: git push git-push git-non-bare-repository

我已经设置了一个远程非裸“主”仓库并将其克隆到我的计算机上。我做了一些本地更改,更新了我的本地存储库,并将更改推送回我的远程仓库。事情很顺利。

现在,我不得不改变远程仓库中的东西。然后我在当地的回购中改变了一些东西。我意识到不需要改变远程仓库。所以我尝试从我的本地仓库git push到我的远程仓库,但我得到了一个错误:

  

为了防止您丢失历史记录,非快进更新了   拒绝在再次推送之前合并远程更改。见'注意   关于详细信息的git push --help的快进部分。

我认为可能是

git push --force

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

正如我在comments to one of the answers中提到的那样:

  

[我]尝试强制,但当回到主服务器保存更改时,我得到过时的暂存。因此,当我提交存储库时不一样。当我再次尝试使用git push时,我也会遇到同样的错误。

如何解决此问题?

8 个答案:

答案 0 :(得分:2074)

只是做:

git push origin <your_branch_name> --force

或者如果您有特定的回购:

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

这将删除您之前的提交并推送您当前的提交。

这可能不合适,但是如果有人偶然发现这个页面,认为他们可能想要一个简单的解决方案......

短旗

另请注意,-f--force的缩写,因此

git push origin <your_branch_name> -f

也可以。

答案 1 :(得分:227)

如果push --force不起作用,您可以执行 push --delete 。看看这个实例上的2 nd 行:

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推送公共存储库。
  • 不要这样做或任何可能打破某人pull
  • 的事情
  • repo 中的某个人可能已经拉过resetrewrite历史记录。

当然,即使是这条规则,也有极少数例外,但在大多数情况下,不需要这样做,而且会给其他人带来问题。

改为还原。

并且始终要小心你推向公共回购的内容。还原:

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.5thanks to @VonC对该问题的评论)中引入的

git push --force-with-lease试图解决这一具体问题。基本上,如果自最近一次获取后遥控器被修改,它将带来错误并且不会推送。

如果您确定需要push --force,但仍希望防止出现更多问题,那么这很好。我会说它应该是默认的push --force行为。但它仍远不是强迫push的借口。在 rebase 之前提取的人仍然会遇到很多麻烦,如果你已经还原,这很容易避免。

因为我们正在谈论git --push个实例......

为什么有人想强迫推?

@linquize在评论中带来了一个很好的推力示例:敏感数据。你错误地泄露了不应该推送的数据。如果你足够快,你可以通过强制推送来“修复” *

* data will still be on the remote,除非您同时执行garbage collectclean it somehow。其他已经取出的人也有明显的潜力传播,但你明白了。

答案 2 :(得分:18)

首先,我不会直接在“主”回购中进行任何更改。如果你真的想拥有一个“主要”回购,那么你应该只追求它,永远不要直接改变它。

关于您遇到的错误,您是否尝试过本地仓库中的git pull,然后git push尝试使用主仓库?你目前正在做什么(如果我理解得好)是强迫推动然后在“主”回购中失去你的变化。您应该首先在本地合并更改。

答案 3 :(得分:14)

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

git push --force origin B:C

答案 4 :(得分:11)

我真的建议:

  • 仅推送到主回购

  • 确保主要仓库为bare repo,以便主要仓库工作树与其.git基础不同步,从而不会出现任何问题。请参阅“How to push a local git repository to another computer?

  • 如果你必须在main(裸)repo中进行修改,克隆它(在主服务器上),进行修改并推回它

换句话说,保持从主服务器和本地计算机都可以访问裸存储库,以便从/向上拉/拉一个上游存储库。

答案 5 :(得分:7)

使用以下命令:

git push -f origin master

答案 6 :(得分:5)

这是我们在维护历史记录时替换公司gitHub存储库上的master的解决方案。

掌握企业存储库的

push -f通常被禁用以维护分支历史记录。这个解决方案对我们有用。

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并创建PR

答案 7 :(得分:0)

我也有同样的问题,但终于明白了。您最可能需要做的是运行以下两个git命令(用git commit修订号替换哈希):

git checkout <hash>
git push -f HEAD:master