题 如何强制“git pull”覆盖本地文件?


如何强制覆盖本地文件 git pull

场景如下:

  • 团队成员正在修改我们正在处理的网站的模板
  • 他们正在向images目录添加一些图像(但忘记在源代码管理下添加它们)
  • 他们稍后通过邮件发送图像给我
  • 我在源控件下添加图像并将其与其他更改一起推送到GitHub
  • 他们无法从GitHub中提取更新,因为Git不想覆盖他们的文件。

这是我得到的错误:

error: Untracked working tree file 'public/images/icon.gif' would be overwritten by merge

如何强制Git覆盖它们?这个人是设计师 - 通常我会手动解决所有冲突,因此服务器具有他们只需要在他们的计算机上更新的最新版本。


5217
2017-07-14 14:58


起源


任何读过这篇文章的人都认为他们可能会丢失文件,我一直在这个位置,发现Sublime Text的缓冲区已经救了我 - 如果我正在处理某些事情,那么通过尝试解决类似的问题或使用它来意外地删除所有内容关于这个问题的答案并且已经在Sublime中打开了文件(这很有可能)然后文件仍然存在Sublime,或者只是在那里,或者在撤消历史记录中 - Toni Leigh
git reset --hard origin/branch_to_overwrite - Andrew Atkinson


答案:


重要提示:如果您有任何本地更改,它们将丢失。有还是没有 --hard 选项,任何未被推送的本地提交都将丢失。[*]

如果您有任何文件  通过Git跟踪(例如上传的用户内容),这些文件不会受到影响。


我认为这是正确的方法:

git fetch --all

然后,您有两个选择:

git reset --hard origin/master

或者如果你在其他分支上:

git reset --hard origin/<branch_name>

说明:

git fetch 从远程下载最新版本而不尝试合并或重组任何内容。

然后 git reset 将master分支重置为刚刚获取的内容。该 --hard 选项更改工作树中的所有文件以匹配其中的文件 origin/master


维护当前的本地提交

[*]:值得注意的是,可以通过创建分支来维护当前的本地提交 master 在重置之前:

git checkout master
git branch new-branch-to-save-current-commits
git fetch --all
git reset --hard origin/master

在此之后,所有旧提交都将保留 new-branch-to-save-current-commits

未提交的更改

然而,未提交的更改(即使是暂存的)也将丢失。确保存储并提交您需要的任何内容。为此,您可以运行以下内容:

git stash

然后重新应用这些未提交的更改:

git stash pop

7301
2018-01-17 00:02



小心!如果您有本地未提交的提交,这将从您的分支中删除它们!此解决方案保持未在存储库中的未跟踪文件完整,但覆盖其他所有内容。 - Matthijs P
这是一个很受欢迎的问题,所以我想在这里澄清一下最热门的评论。我只是执行了本答案中描述的命令,并没有删除所有本地文件。只覆盖了远程跟踪的文件,并且此处的所有本地文件都保持不变。 - Red
这对我有用,我的本地文件没有被删除。 - Tastybrownies
如果您从远程分支名称与“master”不同的仓库中提取,请使用 git reset --hard origin/branch-name - Nerrve
考虑到这个问题和答案的赞成量,我认为git应该包含一个命令 git pull -f - Sophivorus


尝试这个:

git reset --hard HEAD
git pull

它应该做你想要的。


761
2018-05-09 19:45



我已经这样做了,一些不再存在的本地文件留在了磁盘上。 - Piotr Owsiak
我不认为这是正确的。以上将执行合并,而不是覆盖问题中请求的:“如何强制git覆盖它们?”我没有答案,我正在寻找它..此刻我切换到我希望保留“git checkout BranchWithCodeToKeep”代码的分支,然后做“git branch -D BranchToOverwrite”然后最后“git checkout -b BranchToOverwrite”。现在,您将在BranchToOverwrite分支上获得BranchWithCodeToKeep的确切代码,而无需执行合并。 - felbus
而不是使用'git pull'合并,尝试git fetch --all后跟'git reset --hard origin / master' - Lloyd Moore
是的,@ lloydmoore解决方案对我有用。可以做一个答案,而不仅仅是一个评论。 - Max Williams
这会将当前更改重置回拉到的最后一个分支提交。然后git pull合并来自最新分支的更改。这完全是我想要它做的..谢谢! - Codeversed


警告: git clean 删除所有未跟踪的文件/目录,无法撤消。


有时只是 clean -f 没有帮助。如果您有未跟踪的DIRECTORIES,还需要-d选项:

git reset --hard HEAD
git clean -f -d
git pull

警告: git clean 删除所有未跟踪的文件/目录,无法撤消。


381
2018-03-19 09:10



太棒了...把这个对着我的dotfiles repo ...在我的主目录中。很好,我没有什么重要的东西...... - Lauri
我认为场景描述清楚地表明他并不想丢弃内容。相反,他想要的是阻止git笨重地覆盖文件。 @Lauri,这不应该发生在你身上。不幸的是,人们似乎误解了场景描述的本质 - 请参阅我的建议。 - Hedgehog
最后。当make clean无法清理所有东西时,git clean -f -d很方便。 - earthmeLon
@crizCraig除非将它们添加进去 .gitignore - Bleeding Fingers
@earthmeLon,你可能想要的 git clean -dfx。该 -x 忽略.gitignore。通常,您的构建产品将位于.gitignore中。 - Paul Draper


像Hedgehog一样,我认为答案很糟糕。但是虽然刺猬的答案可能会更好,但我认为它并不像它那样优雅。我发现这样做的方法是使用“fetch”和“merge”与定义的策略。这应该使它保持本地更改,只要它们不是您试图强制覆盖的文件之一。

首先提交您的更改

 git add *
 git commit -a -m "local file server commit message"

然后获取更改并在发生冲突时覆盖

 git fetch origin master
 git merge -s recursive -X theirs origin/master

“-X”是选项名称,“他们的”是该选项的值。如果存在冲突,您选择使用“他们的”更改,而不是“您的”更改。


335
2018-04-11 20:13



这是我到目前为止看到的最佳答案。我没有尝试过,但与其他答案不同,这并不会试图破坏所有未跟踪的文件,这显然是非常危险的。 - huyz
同上 - 当我做一个非常大的合并(GitHub拉请求)时,这对我有用,我只想在我拥有的东西之上接受它。好答案!在我的例子中,最后两个命令是:1) get fetch other-repo; 2) git merge -s recursive -X theirs other-repo/master - quux00
问题:什么是-X?什么是'他们'? - AlxVallejo
这将覆盖与存储库文件而不是本地文件的任何冲突,对吗? - Nathan Fiscaletti
“-X”是选项名称,“他们的”是该选项的值。如果存在冲突,您选择使用“他们的”更改,而不是“您的”更改。 - Richard Kersey


而不是做:

git fetch --all
git reset --hard origin/master

我建议做以下事情:

git fetch origin master
git reset --hard origin/master

如果要重置为origin / master分支,是否需要获取所有遥控器和分支?


237
2018-04-26 13:48



您的回答正是您的代表所需要的。我必须问,这是否也会删除所有未跟踪的文件? - Nicolas De Jay
是的,我的大多数代表来自这里:)这也将删除所有未跟踪的文件。我忘记了一些事情,并在2天前痛苦地想起了...... - Johanneke
请参阅其他答案的评论: stackoverflow.com/a/8888015/2151700 - Johanneke
这并没有删除我未跟踪的文件;这实际上是我所期待的。是否有可能对某些人而不是对其他人有原因? - arichards
未经跟踪的文件不受git reset影响。如果你想要删除它们,那就去做吧 git add . 首先,之前 git reset --hard - Johanneke


看起来最好的方法是先做:

git clean

删除所有未跟踪的文件,然后继续平常 git pull...


122
2017-07-14 15:16



我尝试使用“git clean”来解决同样的问题,但它没有解决它。 git status表示“你的分支和'origin / master'分歧,#并分别有2个和9个不同的提交。”和git pull说了类似于你上面的东西。 - slacy
git clean是一种相当钝的工具,可能会丢掉很多你想要保留的东西。最好删除或重命名git抱怨的文件,直到拉取成功为止。 - Neil Mayhew
我认为这不起作用。难道没有办法通过强制git pull基本上做一个git clone remote吗? - mathtick
@mathick: git fetch origin && git reset --hard origin/master - Arrowmaster
是 git clean 这里最好的答案?似乎删除文件不一定是OP想要的。他们要求“覆盖本地文件”而不是删除。 - JohnAllen


警告,如果您的gitignore文件中有任何目录/ *条目,执行此操作将永久删除您的文件。

一些答案似乎很糟糕。根据David Avsajanishvili的建议,对@Lauri发生的事情感到可怕。

相反(git> v1.7.6):

git stash --include-untracked
git pull

之后您可以清理藏匿历史记录。

手动,一个接一个:

$ git stash list
stash@{0}: WIP on <branch>: ...
stash@{1}: WIP on <branch>: ...

$ git stash drop stash@{0}
$ git stash drop stash@{1}

蛮横,一劳永逸:

$ git stash clear

当然,如果你想回到你藏匿的东西:

$ git stash list
...
$ git stash apply stash@{5}

97
2018-02-11 23:00



不,我不这么认为。 Stashing只会移动未提交的文件。以上也移动(存储)git不跟踪的文件。这样可以防止已经添加到遥控器的文件被拉下来,这些文件尚未下载到您的机器上 - 但您已创建(!) - 。所有这些都没有破坏未提交的工作。希望有道理吗? - Hedgehog
如果你没有1.7.6,你可以模仿 --include-untracked 只是暂时的 git add - 你的整个回购,然后立即存储它。 - nategood
我同意Hedgehog。如果你在这里做了流行的答案,你很可能会发现你无意中杀死了很多你并不想丢失的东西。 - Guardius
我有其他未跟踪的文件 - 除了合并/拉动想要覆盖的文件之外,所以这个解决方案效果最好。 git stash apply 带回所有我未跟踪的文件,除了合并已经创建的那些(正确):“已经存在,没有结帐。”工作得很好。 - BigBlueHat
这是最干净的答案,应该是公认的答案。要保存一些打字,您可以使用简短形式: git stash -u。 - ccpizza


您可能会发现此命令有助于丢弃本地更改:

git checkout <your-branch> -f

然后进行清理(从工作树中删除未跟踪的文件):

git clean -f

如果除了未跟踪的文件之外还要删除未跟踪的目录:

git clean -fd

86
2017-08-05 18:06



我认为场景描述清楚地表明他并不想丢弃内容。相反,他想要的是阻止git笨重地覆盖文件。看看我的建议。 - Hedgehog
虽然这个答案可能不完全符合描述,但它仍然让我免受git错误的回车(带有autocrlf false的事件)。当git reset --hard HEAD没有给你留下“no”修改过的文件时,这些“-f”标志非常有用。谢谢你们。 - Kellindil


而不是合并 git pull, 尝试这个:

git fetch --all

其次是:

git reset --hard origin/master


72
2017-11-22 10:56