8512

How do I force an overwrite of local files on a git pull?

The scenario is the following:

  • A team member is modifying the templates for a website we are working on
  • They are adding some images to the images directory (but forgets to add them under source control)
  • They are sending the images by mail, later, to me
  • I'm adding the images under the source control and pushing them to GitHub together with other changes
  • They cannot pull updates from GitHub because Git doesn't want to overwrite their files.

This is the error I'm getting:

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

How do I force Git to overwrite them? The person is a designer - usually, I resolve all the conflicts by hand, so the server has the most recent version that they just need to update on their computer.

4

48 回答 48

11919

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

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


首先,运行 fetch 以将所有origin/<branch>refs 更新为最新:

git fetch --all

备份当前分支:

git branch backup-master

然后,您有两个选择:

git reset --hard origin/master

或者,如果您在其他分支上:

git reset --hard origin/<branch_name>

解释:

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

然后将git reset主分支重置为您刚刚获取的内容。该--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
于 2012-01-17T00:02:58.813 回答
1159

Try this:

git reset --hard HEAD
git pull

It should do what you want.

于 2010-05-09T19:45:21.437 回答
540

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


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

# WARNING: this can't be undone!

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

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

考虑首先使用-n( --dry-run) 标志。这将向您显示将被删除的内容而不实际删除任何内容:

git clean -n -f -d

示例输出:

Would remove untracked-file-1.txt
Would remove untracked-file-2.txt
Would remove untracked/folder
...
于 2011-03-19T09:10:18.727 回答
453

像刺猬一样,我认为答案很糟糕。但是尽管刺猬的回答可能会更好,但我认为它并没有它可以的那么优雅。我发现这样做的方法是使用fetchmerge使用已定义的策略。只要它们不是您尝试强制覆盖的文件之一,就应该这样做,以便保留您的本地更改。

首先提交您的更改

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

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

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

-X是选项名称,并且theirs是该选项的值。如果存在冲突,您选择使用their更改(另一个选项是更改)。ours

于 2012-04-11T20:13:09.083 回答
350

而不是这样做:

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

我建议执行以下操作:

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

如果您要重置到原始/主分支,则无需获取所有遥控器和分支,对吗?

于 2013-04-26T13:48:12.070 回答
147

It looks like the best way is to first do:

git clean

To delete all untracked files and then continue with the usual git pull...

于 2009-07-14T15:16:35.800 回答
124

警告,如果您的 gitignore 文件中有任何 directory/* 条目,这样做将永久删除您的文件。

有些答案似乎很糟糕。通过遵循 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}
于 2012-02-11T23:00:26.167 回答
107

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

git checkout <your-branch> -f

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

git clean -f

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

git clean -fd
于 2010-08-05T18:06:55.123 回答
98

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

git fetch --all

其次是:

git reset --hard origin/master.

于 2012-11-22T10:56:22.947 回答
71

唯一对我有用的是:

git reset --hard HEAD~5

这将使您返回五个提交,然后

git pull

我通过查找如何撤消 Git 合并发现了这一点。

于 2011-05-05T21:53:32.973 回答
69

所有这些解决方案的问题是它们要么太复杂,要么更大的问题是它们从网络服务器中删除了所有未跟踪的文件,这是我们不想要的,因为服务器上总是需要配置文件而不是在 Git 存储库中。

这是我们使用的最干净的解决方案:

# Fetch the newest code
git fetch

# Delete all files which are being added, so there
# are no conflicts with untracked files
for file in `git diff HEAD..origin/master --name-status | awk '/^A/ {print $2}'`
do
    rm -f -- "$file"
done

# Checkout all files which were locally modified
for file in `git diff --name-status | awk '/^[CDMRTUX]/ {print $2}'`
do
    git checkout -- "$file"
done

# Finally pull all the changes
# (you could merge as well e.g. 'merge origin/master')
git pull
  • 第一个命令获取最新数据。

  • 第二个命令检查是否有任何文件正在添加到存储库中,并从本地存储库中删除那些会导致冲突的未跟踪文件。

  • 第三个命令检出所有在本地修改的文件。

  • 最后,我们拉取更新到最新版本,但这次没有任何冲突,因为仓库中未跟踪的文件不再存在,并且所有本地修改的文件已经与仓库中的相同。

于 2012-11-05T23:32:52.923 回答
64

首先,尝试标准方式:

git reset HEAD --hard # To remove all not committed changes!
git clean -fd         # To remove all untracked (non-git) files and folders!

警告:仅当您没有提交上述命令时,它们才会导致数据/文件丢失!如果您不确定,请先备份整个存储库文件夹。

然后再拉一次。

如果上述方法没有帮助并且您不关心未跟踪的文件/目录(以防万一,请先进行备份),请尝试以下简单步骤:

cd your_git_repo  # where 'your_git_repo' is your git repository folder
rm -rfv *         # WARNING: only run inside your git repository!
git pull          # pull the sources again

这将删除所有 git 文件(除了.git/dir,你有所有提交的地方)并再次拉取它。


为什么git reset HEAD --hard在某些情况下会失败?

  1. 自定义规则.gitattributes file

    在 .gitattributes 中有eol=lf规则可能会导致 git 通过在某些文本文件中将 CRLF 行尾转换为 LF 来修改某些文件更改。

    如果是这种情况,您必须提交这些 CRLF/LF 更改(通过在 中查看它们git status),或者尝试:git config core.autcrlf false暂时忽略它们。

  2. 文件系统不兼容

    当您使用不支持权限属性的文件系统时。例如,您有两个存储库,一个在 Linux/Mac ( ext3/ hfs+) 上,另一个在基于 FAT32/NTFS 的文件系统上。

    如您所见,有两种不同的文件系统,因此不支持 Unix 权限的文件系统基本上无法在不支持该权限的系统上重置文件权限,所以无论您如何--hard尝试,git总是检测到一些“变化”。

于 2012-10-26T09:17:40.410 回答
55

我有同样的问题。没有人给我这个解决方案,但它对我有用。

我通过以下方式解决了它:

  1. 删除所有文件。只留下.git目录。
  2. git reset --hard HEAD
  3. git pull
  4. git push

现在它起作用了。

于 2011-01-12T23:58:39.267 回答
53

奖金:

在谈到之前答案中的拉/取/合并时,我想分享一个有趣且富有成效的技巧,

git pull --rebase

上面这个命令是我 Git 生活中最有用的命令,它节省了很多时间。

在将您的新提交推送到服务器之前,请尝试使用此命令,它会自动同步最新的服务器更改(使用 fetch + 合并)并将您的提交放在 Git 日志的顶部。无需担心手动拉/合并。

“git pull --rebase”做什么?.

于 2015-12-23T15:41:52.630 回答
36

如果您不总是想粘贴分支名称或者您想在脚本中自动执行此操作,这是一个通用解决方案

git fetch
git reset --keep origin/$(git rev-parse --abbrev-ref HEAD)

如果您也想重置本地更改:

git fetch
git reset --hard origin/$(git rev-parse --abbrev-ref HEAD)

您还可以使用以下命令添加 bash 别名:

alias gplf='git fetch && echo "HEAD was at $(git rev-parse --short HEAD)" && git reset --hard origin/$(git rev-parse --abbrev-ref HEAD)'
于 2018-05-25T06:31:39.287 回答
33

我有一个类似的问题。我不得不这样做:

git reset --hard HEAD
git clean -f
git pull
于 2011-01-14T15:18:49.410 回答
33

我总结了其他答案。您可以毫无错误地执行git pull

git fetch --all
git reset --hard origin/master
git reset --hard HEAD
git clean -f -d
git pull

警告:此脚本非常强大,因此您可能会丢失所做的更改。

于 2015-08-07T03:03:10.463 回答
30

根据我自己的类似经验,上面 Strahinja Kustudic 提供的解决方案是迄今为止最好的。正如其他人指出的那样,简单地进行硬重置将删除所有未跟踪的文件,其中可能包含许多您不想删除的内容,例如配置文件。更安全的是,只删除即将添加的文件,就此而言,您可能还希望检出任何即将更新的本地修改文件。

考虑到这一点,我更新了 Kustudic 的脚本来做到这一点。我还修正了一个错字(原文中缺少 ')。

#/bin/sh

# Fetch the newest code
git fetch

# Delete all files which are being added,
# so there are no conflicts with untracked files
for file in `git diff HEAD..origin/master --name-status | awk '/^A/ {print $2}'`
do
    echo "Deleting untracked file $file..."
    rm -vf "$file"
done

# Checkout all files which have been locally modified
for file in `git diff HEAD..origin/master --name-status | awk '/^M/ {print $2}'`
do
    echo "Checking out modified file $file..."
    git checkout $file
done

# Finally merge all the changes (you could use merge here as well)
git pull
于 2013-02-27T14:43:00.717 回答
24

我相信有两种可能的冲突原因,必须单独解决,据我所知,上述答案都没有涉及:

  • 需要手动删除未跟踪的本地文件(更安全)或按照其他答案中的建议,通过git clean -f -d

  • 不在远程分支上的本地提交也需要删除。IMO 实现这一目标的最简单方法是:(git reset --hard origin/master用您正在处理的任何分支替换“master”,然后git fetch origin首先运行)

于 2011-12-12T19:54:43.983 回答
24

我遇到了同样的问题,出于某种原因,即使 agit clean -f -d也不会这样做。原因如下:由于某种原因,如果 Git 忽略了您的文件(我假设是通过.gitignore条目),它仍然会担心用稍后的pull覆盖它,但是除非您添加.-x

于 2011-08-03T09:23:43.177 回答
23

似乎这里的大多数答案都集中在master分支上;然而,有时我在两个不同的地方处理同一个特性分支,我希望一个 rebase 反映在另一个地方,而不需要太多的跳跃。

基于RNA 的回答torek 对类似问题的回答的组合,我想出了这个非常有效的方法:

git fetch
git reset --hard @{u}

从分支运行它,它只会将您的本地分支重置为上游版本。

这也可以很好地放入 git 别名 ( git forcepull) 中:

git config alias.forcepull "!git fetch ; git reset --hard @{u}"

或者,在您的.gitconfig文件中:

[alias]
  forcepull = "!git fetch ; git reset --hard @{u}"

享受!

于 2014-02-25T17:19:29.147 回答
22

一种更简单的方法是:

git checkout --theirs /path/to/file.extension
git pull origin master

这将使用 git 上的文件覆盖您的本地文件

于 2015-05-05T08:03:29.883 回答
20

我有一个奇怪的情况,既不工作git clean也不git reset工作。git index我必须通过在每个未跟踪文件上使用以下脚本来删除冲突文件:

git rm [file]

然后我就可以拉得很好了。

于 2011-09-19T14:18:59.813 回答
20

我自己解决了这个问题:

git checkout -b tmp # "tmp" or pick a better name for your local changes branch
git add -A
git commit -m 'tmp'
git pull
git checkout master # Or whatever branch you were on originally
git pull
git diff tmp

最后一个命令列出了您的本地更改的列表。继续修改“tmp”分支,直到它可以接受,然后合并回master:

git checkout master && git merge tmp

下次,您可能可以通过查找“git stash branch”以更简洁的方式处理此问题,尽管 stash 可能会在前几次尝试中给您带来麻烦,因此请先在非关键项目上进行实验......

于 2010-12-03T15:00:41.050 回答
20

我知道一种更容易且痛苦更少的方法:

$ git branch -m [branch_to_force_pull] tmp
$ git fetch
$ git checkout [branch_to_force_pull]
$ git branch -D tmp

而已!

于 2015-09-05T18:23:16.437 回答
16

做就是了

git fetch origin branchname
git checkout -f origin/branchname // This will overwrite ONLY new included files
git checkout branchname
git merge origin/branchname

因此,您可以避免所有不需要的副作用,例如删除您想要保留的文件或目录等。

于 2015-10-19T09:54:39.250 回答
15

尽管有最初的问题,但对于有类似问题但又不想丢失本地文件的人来说,最重要的答案可能会导致问题。例如,参见 Al-Punk 和 crizCraig 的评论。

以下版本将您的本地更改提交到临时分支 ( tmp),检出原始分支 (我假设是master) 并合并更新。您可以使用 来执行此操作stash,但我发现简单地使用分支/合并方法通常更容易。

git checkout -b tmp
git add *; git commit -am "my temporary files"
git checkout master

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

我们假设另一个存储库origin master.

于 2014-10-22T17:31:53.413 回答
14

将索引和头部重置为origin/master,但不重置工作树:

git reset origin/master
于 2013-02-15T13:41:43.573 回答
14

这四个命令对我有用。

git reset --hard HEAD
git checkout origin/master
git branch -D master
git checkout -b master

执行这些命令后检查/拉取

git pull origin master

我尝试了很多,但最终通过这些命令获得了成功。

于 2014-03-20T04:24:02.043 回答
14

我通读了所有答案,但我正在寻找一个命令来执行此操作。这就是我所做的。为 .gitconfig 添加了一个 git 别名

[alias]
      fp = "!f(){ git fetch ${1} ${2} && git reset --hard ${1}/${2};};f"

运行你的命令

git fp origin master

相当于

git fetch origin master
git reset --hard origin/master
于 2016-07-08T13:11:14.203 回答
14

要求:

  1. 跟踪本地更改,因此这里没有人会丢失它们。
  2. 使本地存储库与远程源存储库匹配。

解决方案:

  1. 存储本地更改。
  2. 使用忽略.gitignore硬重置origin文件目录进行获取

    git stash --include-untracked
    git fetch --all
    git clean -fdx
    git reset --hard origin/master
    
于 2015-09-01T23:00:21.270 回答
9

不要使用git reset --hard. 这将抹去他们可能完全不受欢迎的变化。反而:

git pull
git reset origin/master
git checkout <file1> <file2> ...

您当然可以使用git fetch而不是git pull因为它显然不会合并,但如果您通常拉,继续拉在这里是有意义的。

所以这里发生的是git pull 更新你的原点/主参考git reset 在不更新任何文件的情况下将本地分支引用更新为与 origin/master 相同,因此您的签出状态保持不变;然后根据需要git checkout 将文件恢复到本地分支索引状态。如果在 live 和上游 master 上添加了完全相同的文件,则索引已经与重置后的文件匹配,因此在通常情况下您根本不需要这样做git checkout

如果上游分支还包含您想要自动应用的提交,您可以在流程上进行细微的变化:

git pull
git merge <commit before problem commit>
git reset <problem commit>
git checkout <file1> <file2> ...
git pull
于 2017-11-28T11:19:56.787 回答
8

这是还原更改的最佳做法:

  • git commit提交您的分阶段更改,以便将它们保存在reflog中(见下文)
  • git fetch获取最新的上游更改
  • git reset --hard origin/master硬重置到原始主分支

reflog 记录本地存储库中正在更新的分支和其他引用。或者简单地说 - reflog您更改的历史记录

因此,承诺始终是一种很好的做法。提交被附加到 reflog 以确保您始终有办法检索已删除的代码。

于 2016-08-12T15:56:12.160 回答
5

在 Windows 上,执行以下单个命令:

git fetch --all & git reset --hard origin/master
于 2018-04-10T07:22:30.020 回答
5

我试图在 Angular2-Webpack-Starter 上使用 Material2 分支并且玩得很开心。这是我可以下载和使用该分支的唯一方法。

git clone --depth 1 https://github.com/angularclass/angular2-webpack-starter.git

cd angular2-webpack-starter/

git checkout -b material2

打开项目文件夹并删除所有非隐藏文件和文件夹。留下所有隐藏的。

git add .

git commit -m "pokemon go"

git reset --hard

git pull origin material2

(当编辑器弹出时,点击 ':wq',然后按Enter

现在你准备好了。

于 2016-07-27T16:17:54.863 回答
5
于 2015-10-07T09:03:18.587 回答
4

您可以使用项目基础文件夹中的文件忽略该文件:

.gitignore

public/images/*

然后拉取更改,然后从 gitignore 文件中删除该行。

于 2010-11-09T16:57:30.783 回答
3

解决此问题的另一种方法是首先使用 stash 任何未提交的更改git stash,然后运行

git pull --rebase=interactive -s recursive -X theirs

在交互式变基中,您可以将所有本地不需要的提交更改为drop,这将摆脱它们并将您留在远程分支的头部,而无需引入合并提交。

现在,git stash apply如果您想要带回本地隐藏更改,则可以运行。

于 2021-08-10T19:03:40.247 回答
3

1:重置为先前的提交

git reset --hard HEAD

2:删除未跟踪的文件

git clean -f

3:拉取提交

git pull

资料来源:

于 2018-11-10T02:27:04.933 回答
2

尽管这个问题已经有很多答案,但最初的问题是解决这个问题

错误:未跟踪的工作树文件“public/images/icon.gif”将被合并覆盖

由于无法合并二进制文件,一个简单的答案是

git checkout public/images/icon.gif

这样,文件将恢复它在此分支中的先前状态。

git stash如果我不想丢失我的更改或者git checkout .我不关心本地修改的文件,我通常会这样做。IMO 比reset --hard, clean... 简单得多,而且所有这些东西更适合像远程一样离开分支,包括提交、未跟踪的文件,而不仅仅是解决本地修改的文件。

于 2020-07-24T11:23:48.890 回答
1

如果您正在处理您的代码并发现新更改是一个巨大的错误或不需要的,您可以简单地使用类似的替代方法:

git restore .

在哪里 。表示目录中存在的所有文件。

于 2022-02-03T20:42:41.067 回答
1

执行 git pull 后,您将获得不匹配的文件列表。如果文件数量不是很大,那么您可以签出这些文件,此操作将覆盖这些文件。

git checkout -- <文件名>

如果为了快速检查我修改服务器上的本地文件,我通常会这样做(没有推荐和可能的原因,你得到这个问题:D),我在找到解决方案后检查更改的文件。

于 2020-07-12T14:25:26.897 回答
0

我这样做是为了让它工作:

在我创建新分支的计算机上:

git push --all

在我希望新分支显示的计算机上:

git fetch --all
于 2019-08-30T08:53:31.807 回答
0

由于我经常需要一种快速的方法来通过命令提示符在 Windows 上重置当前分支,所以这里有一个快速的方法:

for /f "tokens=1* delims= " %a in ('git branch^|findstr /b "*"') do @git reset --hard origin/%b
于 2020-04-14T11:06:22.447 回答
0

步骤 1。(可选)
从本地存储库的根目录,保存备份并 清空当前文件夹

mkdir -p ../<branch>-bkp && mv --backup=t * ../<branch>-bkp

步骤 2。从远程存储库下载分支的所有文件和文件夹:

git checkout <branch> && git add -A . && git reset --hard origin/<branch> && git pull

您应该替换<branch>为要覆盖的分支的名称。

注释:

  • 您可能更喜欢手动备份和删除当前文件和文件夹,而不是第 1 步
    事实上,我建议使用操作系统 GUI 中的文件处理程序来执行此操作。
  • 如果您跳过第 1 步,请注意:您将丢失本地存储库中的所有工作!
  • 重要提示:git pull如果您在第 2 步中遗漏,
    则可能无法从远程存储库中获取最新版本
    根据下面的第二个参考,git reset --hard
    重置暂存区和工作目录以匹配最近的提交
    我的经历与这种说法相矛盾!
  • 如果您在git reset --hard origin/<branch_to_overwrite> 没有先从本地存储库中删除所有文件和文件夹的情况下运行,请注意任何仍然存在的垃圾文件可能会在稍后潜入远程存储库,git push即使这不是您的意图。如果您选择省略第 1 步,则第 2 步
    的额外内容可防止这种情况发生。git add -A .

参考资料:
https ://gitforwindows.org/
https://www.atlassian.com/git/tutorials/undoing-changes/git-reset
https://www.atlassian.com/git/tutorials/rewriting-history/git -reflog

于 2020-12-10T17:24:39.350 回答
-1

我已经尝试了大部分我能在这里找到的东西,在我的情况下都没有。

起作用的是git merge -X theirs

于 2020-12-01T18:20:31.140 回答
-4

您可以尝试或通过使用然后运行git pull --force来隐藏您的提交。git stashgit pull

于 2019-08-22T16:34:32.737 回答
-9

我想你也可以通过git push -f/git push --force

于 2020-10-19T07:46:21.977 回答