我已经设置了一个远程非裸“主”存储库并将其克隆到我的计算机上。我做了一些本地更改,更新了我的本地存储库,并将更改推送回我的远程存储库。到那时为止一切都很好。
现在,我不得不更改远程仓库中的某些内容。然后我在本地仓库中更改了一些内容。我意识到不需要对远程仓库进行更改。因此,我尝试从本地存储库 git push
到远程存储库,但出现如下错误:
为了防止您丢失历史记录,非快进更新被拒绝在再次推送之前合并远程更改。有关详细信息,请参阅 git push --help 的“关于快进的说明”部分。
我想这可能是一个
git push --force
将强制我的本地副本将更改推送到远程副本并使其相同。它确实会强制更新,但是当我返回远程存储库并进行提交时,我注意到文件包含过时的更改(主远程存储库以前具有的更改)。
正如我在 comments to one of the answers 中提到的:
[我] 尝试强制,但是当返回主服务器以保存更改时,我得到了过时的暂存。因此,当我提交存储库时是不一样的。当我再次尝试使用 git push 时,我得到了同样的错误。
我该如何解决这个问题?
git push -force
more carefully。
git push --force
确实是另一种有效的强制推送方式,并且会像使用 Git 的默认 push.default config settings
的 git push origin master --force
一样推送分支,但具体推送哪些分支在 2.0 之前的 Git 版本与 2.0 之后的 Git 版本之间有所不同.
git push --force
这些天工作正常,FWIW...
git push --force-with-lease
效果更好 :),它将拒绝更新分支,除非它是您期望的状态。 (见developer.atlassian.com/blog/2015/04/force-with-lease)
做就是了:
git push origin <your_branch_name> --force
或者如果您有特定的回购:
git push https://git.... --force
这将删除您之前的提交并推送您当前的提交。
这可能不合适,但如果有人偶然发现这个页面,认为他们可能想要一个简单的解决方案......
短旗
另请注意,-f
是 --force
的缩写,因此
git push origin <your_branch_name> -f
也将工作。
如果 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 历史!
换句话说:
永远不要强制推送公共存储库。
不要这样做或任何可能破坏某人的吸引力的事情。
永远不要在某人可能已经提取的回购中重置或重写历史记录。
当然,即使这条规则也有非常罕见的例外,但在大多数情况下,不需要这样做,它会给其他人带来问题。
改为进行还原。
并且始终小心您推送到公共回购的内容。还原:
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(来自 revert 和 evil reset)将包含相同的文件。
编辑以添加更新信息和更多关于 push --force 的参数
考虑使用租赁而不是推送来推力,但仍然更喜欢还原
push --force
可能带来的另一个问题是,有人在你之前推送任何东西,但在你已经获取之后。如果您现在强制 rebased 版本,您将替换其他人的工作。
git 1.8.5(对问题的thanks to @VonC评论)中介绍的 git push --force-with-lease
试图解决这个特定问题。基本上,如果在您最近一次获取后修改了遥控器,它将带来错误并且不会推送。
如果您确实确定需要 push --force
,但仍想防止出现更多问题,这很好。我想说它应该是默认的 push --force
行为。但这远不是强迫 push
的借口。在你的 rebase 之前fetched 的人仍然会有很多麻烦,如果你改为 revert 就可以轻松避免。
由于我们谈论的是 git --push
个实例...
为什么有人要强行推动?
@linquize 在评论中带来了一个很好的推动力示例:敏感数据。您错误地泄露了不应推送的数据。如果您的速度足够快,您可以“修复”*
它,方法是强制推动顶部。
*
data will still be on the remote 除非您还执行 garbage collect 或 clean it somehow。它也有明显的潜力被其他已经获取它的人传播,但你明白了。
git push origin master --delete # do a very very bad bad thing git push origin master # regular push
这实际上完美地解决了我的问题(在只有我和我的朋友的回购中)。公共回购可能是错误的,但对于私人回购来说,这是一个救命稻草。
如果我在本地分支 A 上,并且我想强制将本地分支 B 推送到源分支 CI 可以使用以下语法:
git push --force origin B:C
git push --force origin B:C
。就我而言,似乎 git push --force origin C
只会从本地 master 推送到远程 C 分支,而不管我当前在哪个分支上。 git version 2.3.8 (Apple Git-58)
master
分支移动到新的 main
分支。刚刚使用 master:main
,它按我的需要工作!
使用以下命令:
git push -f origin master
-f
标志的位置......
首先,我不会直接在“主”存储库中进行任何更改。如果你真的想要一个“主”repo,那么你应该只推送它,不要直接改变它。
关于您遇到的错误,您是否尝试过从本地 repo 中的 git pull
,然后尝试从主 repo 中的 git push
?您目前正在做的事情(如果我理解得很好)是强制推送,然后在“主”存储库中丢失您的更改。您应该首先在本地合并更改。
git push -f
,但如果您再次更改主存储库,则必须返回本地存储库和 git pull
,以便它与最新更改同步。然后你可以做你的工作,然后再次推动。如果您遵循这种“推拉式”工作流程,您将不会遇到您抱怨的那种错误。
我真的建议:
只推送到主仓库
确保主 repo 是一个裸 repo,以便主 repo 工作树与其 .git 基础不同步时不会出现任何问题。请参阅“如何将本地 git 存储库推送到另一台计算机?”
如果您必须在主(裸)仓库中进行修改,请克隆它(在主服务器上),进行修改并推回它
换句话说,保持一个可从主服务器和本地计算机访问的裸仓库,以便从/向其拉取/拉取单个上游仓库。
我有同样的问题,但最终想通了。您最可能需要做的是运行以下两个 git 命令(将 hash 替换为 git commit 修订号):
git checkout <hash>
git push -f HEAD:master
这是我们在保留历史记录的同时替换公司 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
如果您使用 Github 访问令牌进行身份验证,请尝试以下操作:
git 远程设置 URL 来源 https://YourTokenNum@github.com/UserName/ProjectName
git push --force --set-upstream 原始主机
我的问题是——我做了:
git checkout arbitrary_commit
git push origin master --force
这不是正确的做法。相反,我不得不:
git reset HEAD~3
git push origin master --force
注意:数字 3
只是一个示例。你应该输入你自己的号码。
git push --force
可以完成这项工作,尽管 git push --force-with-lease
是一个更安全的命令
git push --force
覆盖远程分支,而 git push --force-with-lease
仅在您的本地副本知道远程分支上的所有提交时才覆盖远程分支。这种差异使得破坏其他人对项目的更改变得更加困难。
git push -f origin :这将在签入的 repo 中进行硬推送。
不定期副业成功案例分享
git push origin +master
代替,它允许您推送多个 refspecs 而不会强制它们全部。git push --force
,您最终可能会弄乱您的主分支(取决于您的推送默认行为)。这可能会很糟糕......有点......:Dgit push --force
的 default 行为基本上是强制将当前签出的分支推送到其远程计数器部分,因此,如果您已签出 master 分支,那么它与git push origin master --force
相同。如果您使用push.default
的matching
设置,情况会有所不同,这是 2.0 之前的 Git 版本的默认设置。matching
将 all 本地分支推送到具有相同名称的远程分支,因此强制推送绝对不是您想要做的......merge -s ours
为我工作