强制“git ush”覆盖远程文件

我想推送我的本地文件,并将它们放在远程存储库上,而无需处理合并冲突。我只希望我的本地版本优先于远程版本。

我如何用Git做到这一点?

1062827 次浏览

您应该能够通过使用以下命令将本地版本强制到远程存储库

git push -f <remote> <branch>

(例如git push -f origin master)。离开<remote><branch>将强制推送所有设置了--set-upstream的本地分支。

请注意,如果其他人共享此存储库,他们的修订历史将与新版本冲突。如果他们在变更点之后有任何本地提交,他们将变得无效。

更新:我想我应该加上一个附带说明。如果你正在创建其他人会审查的更改,那么创建一个包含这些更改的分支并定期重新基准以使它们与主开发分支保持最新并不少见。只是让其他开发人员知道这会定期发生,这样他们就知道会发生什么。

更新2:由于观众数量的增加,我想添加一些额外的信息,说明当你的upstream遇到强制推送时该怎么做。

假设我已经克隆了您的repo并添加了一些提交,如下所示:

D----E  topic/A----B----C         development

但是后来development分支被rebase击中,这将导致我在运行git pull时收到类似的错误:

Unpacking objects: 100% (3/3), done.From <repo-location>* branch            development     -> FETCH_HEADAuto-merging <files>CONFLICT (content): Merge conflict in <locations>Automatic merge failed; fix conflicts and then commit the result.

在这里,我可以修复冲突和commit,但这会给我留下一个非常丑陋的提交历史:

C----D----E----F    topic/              /A----B--------------C'  development

使用git pull --force可能看起来很诱人,但要小心,因为这会给你留下搁浅的提交:

D----E   topic
A----B----C'         development

所以最好的选择可能是执行git pull --rebase。这将需要我像以前一样解决任何冲突,但对于每个步骤,我将使用git rebase --continue而不是提交。最后,提交历史会看起来更好:

D'---E'  topic/A----B----C'         development

更新3:您也可以使用--force-with-lease选项作为“更安全”的力量Push,,就像纸杯蛋糕在他的答案

带有“租赁”的强制推送允许强制推送失败,如果有是您没有预料到的远程新提交(从技术上讲,如果您还没有将它们获取到您的远程跟踪分支中),其中如果您不想意外覆盖其他人的,则很有用你甚至还不知道的承诺,你只是想重写你自己的:

git push <remote> <branch> --force-with-lease

您可以通过以下方式了解有关如何使用--force-with-lease的更多详细信息阅读以下任何内容:

另一种选择(避免任何可能对其他贡献者造成问题的强制推送)是:

  • 将您的新提交放在专用分支中
  • origin/master上重置你的master
  • 将您的专用分支合并到master,始终保留来自专用分支的提交(意味着在master之上创建新的修订,这将反映您的专用分支)。
    请参阅“git命令使一个分支像另一个分支”以获取模拟git merge --strategy=theirs的策略。

这样,您可以将master推送到远程,而无需强制执行任何操作。

你想强行推

您基本上想要做的是强制推送您的本地分支,以覆盖远程分支。

如果您想对以下每个命令进行更详细的解释,请参阅下面的我的详细信息部分。使用Git强制推送基本上有4种不同的选项:

git push <remote> <branch> -fgit push origin master -f # Example
git push <remote> -fgit push origin -f # Example
git push -f
git push <remote> <branch> --force-with-lease

如果您想对每个命令进行更详细的解释,请参阅下面的长答案部分。

警告:强制推送将使用您正在推送的分支的状态覆盖远程分支。在使用它之前确保这是您真正想要做的,否则您可能会覆盖您实际想要保留的提交。

强制推送细节

指定远程和分支

您可以完全指定特定的分支和远程。-f标志是--force的简短版本

git push <remote> <branch> --forcegit push <remote> <branch> -f

省略分支

当省略推送分支时,Git会根据您的配置设置进行计算。在2.0之后的Git版本中,新的repo会有默认设置来推送当前签出的分支:

git push <remote> --force

而在2.0之前,新的repos将具有推送多个本地分支的默认设置。有问题的设置是remote.<remote>.pushpush.default设置(见下文)。

省略遥控器和分支

当省略远程和分支时,只有git push --force的行为由您的push.default Git配置设置决定:

git push --force
  • 从Git 2.0开始,默认设置simple基本上将只是将您当前的分支推送到其上游远程对应部分。远程由分支的branch.<remote>.remote设置确定,否则默认为原始存储库。

  • 在Git版本2.0之前,默认设置matching基本上只是将所有本地分支推送到远程上具有相同名称的分支(默认为原始)。

您可以通过阅读git help configgit-config(1)手册页面的在线版本来读取更多push.default设置。

使用--force-with-lease更安全地推动

带有“租赁”的强制推送允许强制推送失败,如果远程上有您没有预料到的新提交(从技术上讲,如果您还没有将它们获取到远程跟踪分支中),如果您不想意外覆盖其他人的提交,您甚至还不知道,并且您只想覆盖自己的提交,这很有用:

git push <remote> <branch> --force-with-lease

您可以通过阅读以下任何内容了解有关如何使用--force-with-lease的更多详细信息:

git push -f有点破坏性,因为它会重置团队中其他人所做的任何远程更改。更安全的选择是

git push --force-with-lease

--force-with-lease所做的是拒绝更新分支,除非它是我们期望的状态;即没有人更新了上游分支。在实践中,这通过检查上游ref是否是我们期望的来工作,因为ref是哈希,并隐式地将父链编码为它们的值。

您可以准确地告诉--force-with-lease要检查什么,但默认情况下会检查当前的远程ref。这在实践中意味着,当Alice更新她的分支并将其推送到远程存储库时,分支的ref指向头部将被更新。现在,除非Bob从远程拉取,否则他对远程的本地引用将过时。当他使用--force-with-lease进行推送时,git将针对新远程检查本地ref并拒绝强制推送。--force-with-lease有效地只允许您强制推送,如果在此期间没有其他人将更改推送到远程。安全带上是--force

为我工作:

git push --set-upstream origin master -f