ChatGPT解决这个技术问题 Extra ChatGPT

如何正确强制 Git 推送?

我已经设置了一个远程非裸“主”存储库并将其克隆到我的计算机上。我做了一些本地更改,更新了我的本地存储库,并将更改推送回我的远程存储库。到那时为止一切都很好。

现在,我不得不更改远程仓库中的某些内容。然后我在本地仓库中更改了一些内容。我意识到不需要对远程仓库进行更改。因此,我尝试从本地存储库 git push 到远程存储库,但出现如下错误:

为了防止您丢失历史记录,非快进更新被拒绝在再次推送之前合并远程更改。有关详细信息,请参阅 git push --help 的“关于快进的说明”部分。

我想这可能是一个

git push --force

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

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

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

我该如何解决这个问题?

您将很快(git1.8.5,2013 年第四季度)能够do a git push -force more carefully
As I detail in my own answergit push --force 确实是另一种有效的强制推送方式,并且会像使用 Git 的默认 push.default config settingsgit 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

A
Alex Zhukovskiy

做就是了:

git push origin <your_branch_name> --force

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

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

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

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

短旗

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

git push origin <your_branch_name> -f

也将工作。


您可以使用 git push origin +master 代替,它允许您推送多个 refspecs 而不会强制它们全部。
请注意,如果您不小心只做了 git push --force,您最终可能会弄乱您的主分支(取决于您的推送默认行为)。这可能会很糟糕......有点......:D
@Jeewes 从 Git 2.0 版开始,git push --forcedefault 行为基本上是强制将当前签出的分支推送到其远程计数器部分,因此,如果您已签出 master 分支,那么它与 git push origin master --force 相同。如果您使用 push.defaultmatching 设置,情况会有所不同,这是 2.0 之前的 Git 版本的默认设置。 matchingall 本地分支推送到具有相同名称的远程分支,因此强制推送绝对不是您想要做的......
push -f 很好,但不建议 master 使用,因为大多数公司存储库都为 master 禁用了 -f。 merge -s ours 为我工作
不要忘记您帐户的远程存储库权限(阅读:Azure DevOps)可能不会授予强制推送权限。在这种情况下,您需要管理员来设置您的权限。
C
Community

如果 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 collectclean it somehow。它也有明显的潜力被其他已经获取它的人传播,但你明白了。


@rogerdpack 的问题不在于它是否可行。这是。但它可以概括为一场大灾难。有人这样做(强制推送)越多,从公共回购中更新(拉取)的频率越低,灾难就越大。它可以摧毁你所知道的世界!!!111 至少是包含该特定存储库的世界。
如果您有敏感数据,请强制推送
@Cawas:我认为他的意思是,如果您尝试从存储库中删除敏感数据,那么您想重写历史记录。如果您还原,敏感数据仍然存在于较早的提交中。也就是说,如果其他人已经从存储库中提取,那么重写历史不会帮助您阻止他们访问敏感数据 - 到那时已经太晚了。
git push origin master --delete # do a very very bad bad thing git push origin master # regular push 这实际上完美地解决了我的问题(在只有我和我的朋友的回购中)。公共回购可能是错误的,但对于私人回购来说,这是一个救命稻草。
这会在某些 repo 管理器(也称为 auto-squash 等)中自动发生。在完成功能分支以减少提交后强制推送是常见且预期的。
I
IcedDante

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

git push --force origin B:C

我发现即使我在本地分支 B,我仍然需要执行 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,它按我的需要工作!
m
mustafa Elsayed

使用以下命令:

git push -f origin master

也许给出更多解释为什么这个答案比其他答案更可取,以及它的不同之处。
哦,很抱歉给您带来不便,我遇到了同样的问题,这个命令解决了它,我想我应该分享一下。
它和其他的一样,你只是改变了 -f 标志的位置......
u
ubik

首先,我不会直接在“主”存储库中进行任何更改。如果你真的想要一个“主”repo,那么你应该只推送它,不要直接改变它。

关于您遇到的错误,您是否尝试过从本地 repo 中的 git pull,然后尝试从主 repo 中的 git push?您目前正在做的事情(如果我理解得很好)是强制推送,然后在“主”存储库中丢失您的更改。您应该首先在本地合并更改。


是的,我尝试了拉动,但由于拉动,我正在丢失丢失的数据。我想像我的本地一样制作我的主要存储库,而无需先从主要更新。
在这种情况下使用 git push -f,但如果您再次更改主存储库,则必须返回本地存储库和 git pull,以便它与最新更改同步。然后你可以做你的工作,然后再次推动。如果您遵循这种“推拉式”工作流程,您将不会遇到您抱怨的那种错误。
是的,我知道这是我的错:/我会尝试一下,过一会儿再回来thanx
尝试强制,但是当返回主服务器以保存更改时,我得到了过时的暂存。因此,当我提交存储库时是不一样的。当我再次尝试使用 git push 时,我得到了同样的错误。
C
Community

我真的建议:

只推送到主仓库

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

如果您必须在主(裸)仓库中进行修改,请克隆它(在主服务器上),进行修改并推回它

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


您甚至可以推送到非裸 git 存储库吗?
@hd1 是的,因为 Git 2.4(2015 年第二季度):stackoverflow.com/a/42745909/6309,它引用了 stackoverflow.com/a/34575157/6309
B
Brian M.

我有同样的问题,但最终想通了。您最可能需要做的是运行以下两个 git 命令(将 hash 替换为 git commit 修订号):

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

m
mihai

这是我们在保留历史记录的同时替换公司 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


M
Maifee Ul Asad

如果您使用 Github 访问令牌进行身份验证,请尝试以下操作:

git 远程设置 URL 来源 https://YourTokenNum@github.com/UserName/ProjectName

git push --force --set-upstream 原始主机


t
tash

我的问题是——我做了:

git checkout arbitrary_commit
git push origin master --force

这不是正确的做法。相反,我不得不:

git reset HEAD~3
git push origin master --force

注意:数字 3 只是一个示例。你应该输入你自己的号码。


J
Jackie Santana

git push --force 可以完成这项工作,尽管 git push --force-with-lease 是一个更安全的命令

git push --force 覆盖远程分支,而 git push --force-with-lease 仅在您的本地副本知道远程分支上的所有提交时才覆盖远程分支。这种差异使得破坏其他人对项目的更改变得更加困难。


L
Lakshay Sharma

git push -f origin :这将在签入的 repo 中进行硬推送。


这已经在其他几个答案中提到过。