我如何正确地强制推送Git?

我建立了一个远程非裸奔"主"版本库并将其克隆到我的电脑上。我在本地做了一些修改,更新了我的本地版本库,并将这些修改推送回我的远程版本库。在这之前,一切都很好。

现在,我不得不改变远程版本库中的一些东西。然后我又在本地版本库里改了一些东西。我意识到,对远程版本的修改是不需要的。于是我尝试从本地 repo git push到远程 repo,但我得到一个错误。

为了防止你丢失历史,非快进式更新被 拒绝在再次推送前合并远程修改。 请看'注意 about fast-forwards' git push --help一节了解详情。

我想,可能是一个

git push --force

会迫使我的本地副本向远程副本推送修改,并使其保持一致。它确实强制更新了,但当我回到远程 repo 并提交时,我注意到文件包含了过时的修改(远程主 repo 之前的修改)。

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

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

我怎样才能解决这个问题?

对该问题的评论 (5)
解决办法

就这样做。

git push origin  --force

或者如果你有一个特定的 repo。

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

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

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

简短标志

还要注意,-f--force的缩写,所以

git push origin  -f

也可以使用。

评论(12)

如果push --force不起作用,你可以做push --delete。 看看2nd 行。

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历史!

换句话说。

  • 永远不要在公共仓库上强行推送。
  • 不要做这样的事情,也不要做任何可以破坏别人的pull的事情。
  • 永远不要在repo重设重写历史,有人可能已经拉过了。

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

还是做一个revert吧。

而且一定要小心你推送到公共回帖的内容。 还原。

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的参数。

可以考虑用租赁代替推力,但还是更倾向于还原。

另一个push --force可能带来的问题是,当有人在你之前推送任何东西,但在你'已经获取之后。 如果你现在推送强制你的rebased版本,你会替换别人的工作。

git 1.8.5中引入的git push --force-with-lease([感谢@VonC][2]对问题的评论)试图解决这个具体问题。 基本上,它将带来一个错误,如果远程在你最近一次获取后被修改,则不会推送。

如果你真的确定需要push --force,但仍然想防止更多的问题,这是很好的。 我甚至会说这应该是默认的push --force行为。 但它'还是远远不能成为强迫push的借口。 在你的rebase之前fetched的人还是会有很多麻烦,如果你改成reverted的话,这些麻烦是可以轻松避免的。

既然我们说的是git -push实例......

为什么有人要强行推送?

[@linquize][3]在评论中带来了一个很好的推力例子。 敏感数据。 你'错泄露了不该推送的数据。 如果你'够快,你可以"修复"*在上面强行推送。

*除非你也做一个【垃圾收集】[5],或者【以某种方式清理】[6],否则【数据还是会在远程】[4]。 还有一个明显的可能性是,它可能会被其他'dfetched的人已经传播出去了,但是你懂的。

1:

[2]: https://stackoverflow.com/questions/3166713/git-how-to-ignore-fast-forward-and-revert-origin-branch-to-earlier-commit/18505634#18505634 [3]: https://stackoverflow.com/users/1031218/linquize [4]: http://git-scm.com/book/en/Git-Internals-Maintenance-and-Data-Recovery [5]: https://stackoverflow.com/questions/3162786/how-to-do-git-gc-on-git-remote-repository [6]: https://stackoverflow.com/a/8295172/274502

评论(10)

首先,我不会直接在"main" repo中做任何改动。如果你真的想拥有一个"main"版本库,那么你应该只推送到它,而不是直接改变它。

关于你得到的错误,你是否尝试过从你的本地 repo git pull,然后git push到主 repo?你现在所做的(如果我理解得好的话)是强制推送,然后失去你在"main" repo中的修改。你应该先在本地合并这些改动。

评论(4)

如果我'在我的本地分支A上,我想强制推送本地分支B到原点分支C,我可以使用以下语法。

git push --force origin B:C
评论(1)

我真的会推荐给。

  • 只推送到主 repo

  • 确保主版本是裸版本,这样就不会出现主版本的工作树与.git基地不同步的问题。参见"如何推送本地 git 仓库到另一台电脑上?&quot。

  • 如果你确实需要在主(裸)版本库中进行修改,克隆它(在主服务器上),做你的修改并推送回它

换句话说,保持一个可以从主服务器和本地计算机访问的裸仓库,以便有一个单一的上游仓库来拉/拉。

评论(1)

使用下面这个命令。

git push -f origin master
评论(3)

这是我们在企业gitHub版本库中替换master的解决方案,同时保持历史记录。

在企业版本库中,为了维护分支历史,通常会禁用 "push -f "来替换master。 这个解决方案对我们来说很有效。

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。

评论(0)

我也有同样的问题,但最后还是想明白了。 你最需要做的是运行以下两个 git 命令(用 git 提交的修订号代替哈希)。

git checkout <hash>
git push -f HEAD:master
评论(0)