如何正确强制推送Git?

Spy*_*ros 1206 git push git-push git-non-bare-repository

我已经设置了一个远程非裸"主"仓库并将其克隆到我的电脑上.我做了一些本地更改,更新了我的本地存储库,并将更改推送回我的远程仓库.到目前为止,情况还不错.

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

为防止您丢失历史记录,拒绝非快进更新在再次推送之前合并远程更改.有关git push --help详细信息,请参阅"关于快进的注意事项"部分.

我以为那可能是一个

git push --force
Run Code Online (Sandbox Code Playgroud)

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

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

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

我该如何解决这个问题?

Kat*_*tie 2194

做就是了:

git push origin <your_branch_name> --force
Run Code Online (Sandbox Code Playgroud)

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

git push https://git.... --force
Run Code Online (Sandbox Code Playgroud)

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

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

短旗

另外请注意,-f是短期的--force,所以

git push origin <your_branch_name> -f
Run Code Online (Sandbox Code Playgroud)

也会工作.

  • 您可以使用`git push origin + master`,它允许您推送多个refspec而不强制它们全部. (55认同)
  • @Jeewes从Git 2.0开始,`git push --force`的*default*行为基本上是强制将当前签出的分支推送到其远程计数器部分,所以如果你检查了master分支,那么它与`git push origin master --force`完全相同.如果你使用`push.default`的`matching`设置,这将是不同的,这是2.0之前的Git版本的默认设置.`matching`将*all*locals分支推送到具有相同名称的远程分支,因此强制推送肯定不是你想要做的... (8认同)
  • 请注意,如果你不小心只做`git push --force`,你最终可能会弄乱你的主分支(取决于你的推送默认行为)..这可能会吮吸......有点......:D (5认同)
  • push -f很好,但对于主服务器而言则不建议这样做,因为大多数公司存储库都已禁用-f作为主服务器。`merge -s ours'为我工作 (2认同)
  • 不要忘记您的帐户的远程存储库权限(阅读:Azure DevOps)可能不会授予强制推送的权限。在这种情况下,您需要管理员来设置您的权限。 (2认同)

cre*_*gox 238

如果push --force不起作用,你可以做到push --delete.看看这个实例的第二行:

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
Run Code Online (Sandbox Code Playgroud)

但要注意......

永远不要回到公共git历史!

换一种说法:

  • 永远不要force推动公共存储库.
  • 不要做这个或任何可能打破某人的事情pull.
  • 永远不要reset或有人可能已经撤回rewrite回购历史.

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

做一个还原.

并且要小心你推动公共回购.回复:

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
Run Code Online (Sandbox Code Playgroud)

实际上,两个原始HEAD(来自还原邪恶重置)都将包含相同的文件.


编辑以添加更新的信息和更多参数 push --force

考虑用租赁而不是推力推力,但仍然更喜欢还原

另一个问题push --force可能是当有人在你做之前推动任何东西时,但是在你已经取出之后.如果您现在推动您的重新定版版本,您将替换其他人的工作.

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

如果你真的确定push --force需要它,但仍然希望防止更多问题,这是很好的.我会说它应该是默认push --force行为.但它仍然远没有成为迫使一个人的借口push.谁的人获取你的前底垫中仍然有很多的烦恼,可能你已经很容易地避免的恢复来代替.

既然我们在谈论git --push实例......

为什么有人想强迫推?

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

*数据仍然会在遥控器上,除非你也做了垃圾收集,或以某种方式进行清洁.其他已经取得它的人也有明显的潜力传播,但你明白了.

  • 如果您有敏感数据,请强行推送 (3认同)
  • @Cawas:我认为他的意思是,如果你试图从存储库中删除敏感数据,那么你*希望*重写历史记录.如果还原,敏感数据仍然存在于先前的提交中.也就是说,如果其他人已从存储库中撤出,那么重写历史记录将无法帮助您阻止他们访问敏感数据 - 此时已经为时已晚. (3认同)
  • `git push origin master --delete#做一个非常非常糟糕的坏事git push origin master#regular push`这实际上完全解决了我的问题(只有我和我的朋友的回购).也许这对于公共回购是错误的,但对于私人回购而言,这是一个救生员. (3认同)
  • 这会在一些 repo 管理器中自动发生,也就是 auto-squash 等。在完成一个功能分支后强制推送以减少提交是常见的和预期的。 (2认同)

ubi*_*bik 18

首先,我不会直接在"主"回购中进行任何更改.如果你真的想要一个"主要"回购,那么你应该只推动它,永远不要直接改变它.

关于你得到的错误,你有没有尝试过git pull当地的回购,然后再git push回到主回购?你目前正在做的事情(如果我理解得很好)是强迫推动,然后在"主"回购中失去你的变化.您应该首先在本地合并更改.

  • 在这种情况下,请使用“git push -f”,但是如果您再次更改主存储库,则必须返回到本地存储库和“git pull”,以便它与最新更改保持同步。然后你就可以做你的工作,并再次推动。如果您遵循此“推拉”工作流程,您将不会遇到您所抱怨的那种错误。 (3认同)

Ice*_*nte 15

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

git push --force origin B:C
Run Code Online (Sandbox Code Playgroud)

  • 我发现即使我在本地B分支上,我仍然需要执行git push --force origin B:C。就我而言,无论我当前在哪个分支上,“ git push --force origin C”似乎只会从本地主节点推送到远程C分支。git版本2.3.8(Apple Git-58) (2认同)

Jac*_*ana 13

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

\n

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

\n


Von*_*onC 11

我真的建议:

换句话说,保持可以从主服务器和本地计算机访问裸存储库,以便从/向其提取/拉出单个上游存储库.

  • 我同意,但我怎样才能解决目前的问题呢? (2认同)

小智 10

使用以下命令:

git push -f origin master
Run Code Online (Sandbox Code Playgroud)

  • 它和其他人一样,你只是改变了`-f`标志的位置...... (11认同)
  • 也许多解释一下为什么这个答案比其他答案更可取,以及它的不同之处。 (2认同)

小智 10

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

git checkout <hash>
git push -f HEAD:master
Run Code Online (Sandbox Code Playgroud)


小智 6

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

  • git remote set-url origin https://YourTokenNum@github.com/UserName/ProjectName

  • git push --force --set-upstream origin master


Mai*_*cio 6

使用--force-with-lease可能是更好的选择:

git push <remote> <branch> --force-with-lease
Run Code Online (Sandbox Code Playgroud)

它确保在您修改分支之前没有人更新该分支,因此您不会覆盖他们的更改。


mih*_*hai 5

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

push -f掌握企业存储库通常会被禁用以维护分支历史记录.这个解决方案对我们有用.

git fetch desiredOrigin
git checkout -b master desiredOrigin/master // get origin master
Run Code Online (Sandbox Code Playgroud)
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
Run Code Online (Sandbox Code Playgroud)

推动您的分支机构desiredOrigin并创建PR


归档时间:

查看次数:

1179763 次

最近记录:

6 年,4 月 前