协慌网

登录 贡献 社区

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

我想推送我的本地文件,并将它们放在远程仓库中,而不必处理合并冲突。我只希望我的本地版本优先于远程版本。

如何使用 Git 做到这一点?

答案

您应该可以使用以下命令将本地修订版本强制为远程仓库

git push -f <remote> <branch>

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

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

更新 :我想加个旁注。如果您正在创建其他人可以查看的更改,那么创建具有这些更改的分支并定期重新设置基础以使它们与主要开发分支保持最新的情况并不少见。只是让其他开发人员知道这会定期发生,这样他们就会知道会发生什么。

更新 2 :由于观众数量的增加,我想添加一些有关upstream遇到强制推动时该怎么做的附加信息。

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

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

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

Unpacking objects: 100% (3/3), done.
From <repo-location>
 * branch            development     -> FETCH_HEAD
Auto-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选项作为 “更安全” 的强制推送, 如 Cupcake 在他的回答中提到的

如果 “远程” 上有新的提交,而您没有想到(技术上,如果尚未将其提取到远程跟踪分支中),则使用 “租用” 强制推送将使强制推送失败。您不想意外覆盖您甚至不知道的其他人的提交,而只想覆盖自己的提交:

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

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

你想强行推

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

如果您想对以下每个命令进行更详细的说明,请参阅下面的 “我的详细信息” 部分。基本上,您可以使用 4 种不同的方法来强制使用 Git 进行推送:

git push <remote> <branch> -f
git push origin master -f # Example

git push <remote> -f
git push origin -f # Example

git push -f

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

如果您想对每个命令进行更详细的说明,请参阅下面的 “我的长答案” 部分。

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

强制推送细节

指定遥控器和分支

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

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

省略分支

当省略推入分支的分支时,Git 将根据您的配置设置将其找出来。在 2.0 之后的 Git 版本中,新的仓库将具有默认设置以推送当前已签出的分支:

git push <remote> --force

在 2.0 之前的版本中,新存储库将具有默认设置以推送多个本地分支。有问题的设置是remote.<remote>.pushpush.default设置(请参见下文)。

省略遥控器和分支

当 remote 和 branch 都被省略时,仅git push --force的行为由push.default Git 配置设置决定:

git push --force
  • 从 Git 2.0 开始,默认设置simple基本上只会将当前分支推送到其上游远程对端。远程由分支的branch.<remote>.remote设置确定,否则默认为源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的更多详细信息:

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

  • 将您的新提交放入专门的分支
  • 重置masterorigin/master
  • 将您的专用分支合并到master ,始终保留专用分支的提交(这意味着在master上创建新的修订版本,以反映您的专用分支)。
    有关模拟git merge --strategy=theirs策略,请参见 “ 使一个分支像另一个分支的 git 命令 ”。

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