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

git version-control overwrite git-pull git-fetch 鄙人很悲剧 | 2020-02-02 19:35:06


如何强制覆盖
git pull
上的本地文件?
场景如下:
一个团队成员正在修改我们正在处理的网站的模板
他们正在将一些图像添加到图像目录(但忘记在源代码管理下添加它们)
他们稍后将通过邮件发送图像,对我来说,
我正在添加受源代码管理的图像,并将它们与其他更改一起推送到GitHub
它们无法从GitHub中提取更新,因为Git不想覆盖它们的文件。
这是我得到的错误:
错误:未跟踪的工作树文件“public/images/icon.gif”将被merge覆盖用Git覆盖它们?这个人是一个设计师-通常,我会手动解决所有冲突,所以服务器有最新版本,他们只需在计算机上更新即可。





30 答案



重要提示:如果您有任何本地更改,它们将丢失。无论是否使用
--hard
选项,未推送的任何本地提交都将丢失。[*]
如果您有任何未被Git跟踪的文件(例如上载的用户内容),这些文件将不会受到影响。
我认为这是正确的方法:
git fetch --all

然后,您有两个选项:
git reset --hard origin/master

或者如果您在其他分支上:
git reset --hard origin/

说明:
git fetch
从远程下载最新版本,而不尝试合并或还原任何内容。
然后
git reset
将master分支重置为您刚刚获取的内容。
--hard
选项更改工作树中的所有文件以匹配
origin/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

2020-02-02 19:35:18
基受


试试这个:
git reset --hard HEAD
git pull

它应该做你想做的事情。

2020-02-02 19:35:18
依然Lost


警告:
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
...

2020-02-02 19:35:18
joycn


就像刺猬一样,我认为答案是可怕的。不过,虽然刺猬的回答可能更好,但我不认为它有可能那么优雅。我发现这样做的方法是使用“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”是选项名,“theirs”是该选项的值。您选择使用“他们的”更改,而不是“您的”更改(如果存在冲突)。

2020-02-02 19:35:18
爱德华


与其这样做,不如这样做:
git fetch --all
git reset --hard origin/master

我建议您这样做:
git fetch origin master
git reset --hard origin/master

如果您要重置到原点/主分支,则无需获取所有远程和分支,对吗?

2020-02-02 19:35:18
ianak


似乎最好的方法是首先执行以下操作:
git clean

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

2020-02-02 19:35:18
撸哥


警告,如果gitignore文件中有任何目录/*条目,则执行此操作将永久删除文件。
某些答案似乎很糟糕。按照David Avsajanishvili的建议,@Lauri的遭遇真是太可怕了。
更确切地说(git>v1.7.6):
git stash --include-untracked
git pull

以后您可以清理存储历史。
手动地,一个接一个地:
$ git stash list
stash@{0}: WIP on : ...
stash@{1}: WIP on : ...
$ git stash drop stash@{0}
$ git stash drop stash@{1}

野蛮地,同时:
$ git stash clear

如果你想回到你藏的东西:
$ git stash list
...
$ git stash apply stash@{5}

2020-02-02 19:35:18
CLOUDY


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

然后执行清理(从工作树中删除未跟踪的文件):
git clean -f

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

2020-02-02 19:35:18
永江衣玖


与其与
git pull
合并,不如尝试以下操作:
git fetch --all

然后是:
git reset --hard origin/master

2020-02-02 19:35:18
regsvr32


唯一对我有用的是:
git reset --hard HEAD~5

这将使您返回五次提交,然后使用
git pull

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

2020-02-02 19:35:18
paniponidash


所有这些解决方案的问题是要么太复杂,要么更大的问题是,它们会从web服务器上删除所有未跟踪的文件,这是我们不想要的,因为总是有需要的配置文件在服务器上而不是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

第一个命令获取最新数据。
第二个命令检查是否有任何文件正在添加到存储库中,并且从本地存储库中删除那些可能导致冲突的未跟踪文件。
第三个命令将签出所有本地修改过的文件。
最后,我们进行了一次拉取以更新到最新版本,但这次没有任何冲突,由于未被跟踪的文件在回购中不再存在,并且所有本地修改的文件已经与存储库中的文件相同。

2020-02-02 19:35:18
林大B


首先,尝试标准方法:
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/
之外)并再次拉取它。
为什么在某些情况下
git reset HEAD --hard
可能会失败?
.gitattributes file

中的自定义规则具有.gittattributes中的
eol=lf
规则可能会导致git通过将某些文本文件中的CRLF行尾转换为LF来修改某些文件更改。
如果是这种情况,则必须提交这些CRLF/LF更改(在
git status
中查看它们),或者尝试:
git config core.autcrlf false
暂时忽略它们。
当您使用不支持权限属性的文件系统时,文件系统不兼容性

在示例中,您有两个存储库,一个在Linux/Mac上(
ext3
/
hfs+
),另一个在基于FAT32/NTFS的文件系统上。
正如您所注意到的,有两种不同的文件系统,所以不支持Unix权限的系统基本上无法在不支持这种权限的系统上重置文件权限,因此,无论您如何尝试,git总是会检测到一些“变化”。

2020-02-02 19:35:18
椛不是小笨狼


我也有同样的问题。没有人给我这个解决方案,但它对我有效。
我解决了这个问题:
删除所有文件。只留下
.git
目录。
git reset --hard HEAD

git pull

git push

现在可以工作了。

2020-02-02 19:35:18
赤鏡緋炎


另外:
说到前面的答案中的pull/fetch/merge,我想分享一个有趣且高效的技巧,
git pull --rebase

这个命令是Git生命中最有用的命令,它节省了很多时间。
在将您的新提交推送到服务器之前,尝试这个命令,它将自动同步最新的服务器更改(使用fetch+merge),并将您的提交放在Git日志的顶部。不必担心手动拉合并。
在“git pull--rebase”中查找详细信息是什么?.

2020-02-02 19:35:18
嫂子其实我喜欢你


我也有类似的问题。我必须这样做:
git reset --hard HEAD
git clean -f
git pull

2020-02-02 19:35:18
moyong522


我总结了其他答案。您可以执行
git pull
而不会出错:
git fetch --all
git reset --hard origin/master
git reset --hard HEAD
git clean -f -d
git pull

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

2020-02-02 19:35:18
沙耶の触手


根据我自己的类似经验,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

2020-02-02 19:35:18
日用沙包


我认为冲突有两个可能的原因,必须分别解决,而且就我所知,上述任何一个答案都不能同时解决这两个问题:
需要删除未跟踪的本地文件,要么手动删除(更安全),要么按照其他答案的建议删除,通过
git clean -f -d

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

2020-02-02 19:35:18
雪碧


更简单的方法是:
git checkout --theirs /path/to/file.extension
git pull origin master

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

2020-02-02 19:35:18
lanslort


似乎这里的大多数答案都集中在
master
分支上;但是,有时我在两个不同的地方处理同一个特性分支,我希望一个特性分支中的回扣反映在另一个特性分支中,而不需要太多跳跃。
基于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}"

享受!

2020-02-02 19:35:18
EVA-X


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

2020-02-02 19:35:18
V-cum


我自己解决了这个问题:
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可能会在最初的几次尝试中给您带来麻烦,所以首先在非关键项目上进行实验…

2020-02-02 19:35:18
凉水凉水


我知道一种更简单、痛苦更小的方法:
$ git branch -m [branch_to_force_pull] tmp
$ git fetch
$ git checkout [branch_to_force_pull]
$ git branch -D tmp

就这样!

2020-02-02 19:35:18
快来看上帝啊


我有一个奇怪的情况,无论是
git clean
还是
git reset
都不起作用。我必须在每个未跟踪的文件上使用以下脚本从
git index
中删除冲突文件:
git rm [file]

然后我就可以很好地拉取了。

2020-02-02 19:35:18
人屠武安


这四个命令对我有效。
git reset --hard HEAD
git checkout origin/master
git branch -D master
git checkout -b master

在执行这些命令后检查/拉取
git pull origin master

我试了很多次,但最终获得了这些命令的成功。

2020-02-02 19:35:18
Avalonの钥


尽管有最初的问题,但最重要的答案可能会给有类似问题但不想丢失本地文件的人带来麻烦。例如,请参阅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

2020-02-02 19:35:18
レミリア


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

即可避免所有不必要的副作用,如删除要保留的文件或目录等。

2020-02-02 19:35:18
克拉托斯


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

2020-02-02 19:35:18
jr250


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

2020-02-02 19:35:18
八雲玖


要求:
跟踪本地更改,以便这里的任何人都不会丢失它们。
使本地存储库与远程源存储库匹配。
解决方案:
保存本地更改。
获取时清除文件和目录,忽略.gitignore并硬重置为源。
git stash --include-untracked
git fetch --all
git clean -fdx
git reset --hard origin/master

2020-02-02 19:35:18
ferdi


World is powered by solitude
备案号:湘ICP备19012068号