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


766

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

如何使用Git做到这一点?


106
git push origin --force为你工作吗?


还不清楚您是否只想覆盖.git文件或关联的工作副本。如果它是git存储库,则git push是答案。如果要更新远程工作副本,则必须使用接收后挂钩
Pierre-Olivier Vares

由于某些原因对我有用的@Mike ...想知道OP发生了什么

强制推送不起作用的可能原因是,它可能已在远程仓库上被显式禁用(以确保没有任何东西因白痴和/或恶意破坏者而丢失):用于config receive.denyNonFastforwards查找。
Frank Nocke

Answers:


1085

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

git push -f <remote> <branch>

(例如git push -f origin master)。离开<remote><branch>强制推动已建立的所有当地分支机构--set-upstream

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

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

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

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

            D ---- E主题
           /
A ---- B ---- C发展

但是稍后用development击中分支rebase,这将导致我在运行时收到如下错误git pull

拆箱:完成100%(3/3)。
从<重新定位位置>
 *分支开发-> FETCH_HEAD
自动合并<文件>
冲突(内容):在<locations>中合并冲突
自动合并失败;解决冲突,然后提交结果。

在这里,我可以解决冲突和commit,但是那将给我留下非常丑陋的提交历史:

       C ---- D ---- E ---- F主题
      ///
A ---- B ------------- C'的发展

它可能看起来很诱人,git pull --force但是要小心,因为那样会使您陷入搁浅的提交中:

            D ---- E主题

A ---- B ---- C'的发展

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

            D'-E'主题
           /
A ---- B ---- C'的发展

更新3:您还可以将该--force-with-lease选项用作“更安全”的强制推送,如Cupcake在他的回答中所述

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

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

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


5
由于这是选定的答案,因此我将在此处评论。独自工作时,使用武力不是问题。例如,我的云主机以其自己的git开头。如果我在本地工作并构建一个项目,并且想将其放在我的云主机(OpenShift)上,那么我有两个单独的git项目。我的本地人和我的OpenShift之一。我可以根据自己的喜好获取本地语言,但是现在想在我的OpenShift上预览它。然后,您第一次使用-f标志推送到OpenShift 。本质上是将本地git放入OpenShift。
韦德

128

你想强行推

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

如果要对以下每个命令进行更详细的说明,请参阅下面的“我的详细信息”部分。基本上,您可以使用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

省略分支

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

git push <remote> --force

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

省略遥控器和分支

当同时取消remote和branch时,just的行为git push --force取决于您的push.defaultGit配置设置:

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

  • 在Git 2.0版之前,默认设置matching基本上只是将您的所有本地分支推送到遥控器上具有相同名称的分支(默认为起源)。

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

用以下方法更安全地推动 --force-with-lease

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

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

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


您是对的,但这实际上仅应在特殊情况下使用。
Scott Berrevoets 2014年

1
@ScottBerrevoets“ 我更愿意推送我拥有的内容,并让它远程覆盖而不是集成。 ”我给了OP他所要求的。

我知道,但是OP可能不知道这样做的后果。您从技术上回答了这个问题,但是我认为不这样做的警告并没有错。
Scott Berrevoets 2014年

1
@ScottBerrevoets我正在尝试让主持人将我的答案合并到规范中,因为我提到了新--force-with-lease选项;)


32

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

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

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


结果与“推力”有何不同?
alexkovelsky '18

6
@alexkovelsky任何强制推送都会重写历史记录,从而迫使存储库的其他用户重置其自己的本地存储库以匹配新推送的提交。这种方法仅创建新的提交,不需要强制推送。
VonC

1
我建议您在答案中添加标题:“您不想强行推动” :)
alexkovelsky

@alexkovelsky好点。我已经相应地编辑了答案。
VonC

4

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

{--force-with-lease}所做的是拒绝更新分支,除非它是我们期望的状态。即没有人更新上游分支。在实践中,这是通过检查上游ref是否符合我们的期望来实现的,因为ref是散列,并将父链隐式地编码为其值。您可以确切地告诉{--force-with-lease}要检查的内容,但是默认情况下会检查当前的远程引用。实际上,这意味着当Alice更新其分支并将其推送到远程存储库时,分支的ref指向头将被更新。现在,除非Bob从遥控器上拉出,否则他对遥控器的本地引用将是过时的。当他使用{--force-with-lease}进行推送时,git将对照新的远程服务器检查本地引用,并拒绝强制进行推送。{--force-with-lease}仅在没有其他人在过渡期间将更改推到远程的情况下才有效地强制推入。系上安全带可以{--force}。



0

使用tortoisegit的简单步骤

GIT给本地文件提交并推送到git仓库。

脚步 :

1)存储更改 存储名称

2)

3)藏起来

4)提交 1个或多个文件,并提供提交更改描述集作者和日期

5)

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.