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

当Git拒绝覆盖本地文件时,可以通过提交本地更改、使用`git fetch`和`git merge`结合特定选项来解决。一种常见做法是提交本地更改,然后使用`git merge origin/master -X theirs`来强制采用远程版本。另一种方法是使用`git reset --hard origin/master`,但这会丢失未提交的更改。确保在执行这些操作前备份重要文件,因为未推送的本地提交和未跟踪的文件可能会丢失。
摘要由CSDN通过智能技术生成

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

该场景如下:

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

这是我得到的错误:

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

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


#1楼

像刺猬一样,我认为答案很糟糕。 但是,尽管刺猬的答案可能更好,但我认为它并没有它的优雅。 我发现做到这一点的方法是通过使用已定义策略的“提取”和“合并”。 应该这样做,以便保留本地更改,只要它们不是您要强制覆盖的文件之一即可。

首先提交您的更改

 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”是该选项的值。 如果发生冲突,您选择使用“他们的”更改,而不是“您的”更改。


#2楼

看来最好的方法是先这样做:

git clean

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


#3楼

首先,尝试标准方法:

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总是检测到一些“变化”。


#4楼

所有这些解决方案的问题在于它们要么太复杂,要么甚至更大的问题在于它们从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
  • 第一条命令获取最新数据。

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

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

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


#5楼

而不是与git pull合并,请尝试以下操作:

git fetch --all

其次是:

git reset --hard origin/master


#6楼

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

git reset origin/master

#7楼

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

#8楼

而不是做:

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

我建议您执行以下操作:

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

如果您要重置为Origin / master分支,就不需要获取所有的遥控器和分支吗?


#9楼

似乎大多数答案都集中在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}"

请享用!


#10楼

这四个命令对我有用。

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

执行这些命令后进行检查/拉动

git pull origin master

我做了很多尝试,但最终在这些命令上获得了成功。


#11楼

尽管有最初的问题,但是对于有类似问题但又不想丢失其本地文件的用户,最重要的答案可能会引起问题。 例如,请参阅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


#12楼

尝试这个:

git reset --hard HEAD
git pull

它应该做您想要的。


#13楼

一种更简单的方法是:

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

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


#14楼

我总结了其他答案。 您可以执行git pull而不会出现错误:

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

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


#15楼

要求:

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

解:

  1. 隐藏本地更改。
  2. 干净的 文件目录忽略的.gitignore硬复位 原产获取

     git stash --include-untracked git fetch --all git clean -fdx git reset --hard origin/master 

#16楼

我知道一种更简单,更轻松的方法:

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

而已!


#17楼

做就是了

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

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


#18楼

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

git checkout <your-branch> -f

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

git clean -f

如果要除去未跟踪文件之外的其他未跟踪目录,请执行以下操作:

git clean -fd

#19楼

奖金:

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

git pull --rebase

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

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

“ git pull --rebase”做什么中找到详细信息


#20楼

我通读了所有答案,但我正在寻找一个命令来执行此操作。 这是我所做的。 为.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

#21楼

我自己通过以下方法解决了这个问题:

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可能会给您带来麻烦,因此,请首先在非关键项目上进行实验...


#22楼

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

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

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

现在可以了。


#23楼

我有一个类似的问题。 我必须这样做:

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

#24楼

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

#25楼

唯一对我有用的是:

git reset --hard HEAD~5

这将带您退回五次提交,然后

git pull

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


#26楼

我遇到了同样的问题,由于某种原因,即使是git clean -f -d也不会这样做。 这是为什么:由于某种原因,如果您的文件被Git忽略(我认为是通过.gitignore条目),它仍然会为以后的pull重写而烦恼,但是除非您添加-x ,否则干净不会删除它。


#27楼

我有一个奇怪的情况,无论是git clean还是git resetgit clean 。 我必须通过在每个未跟踪的文件上使用以下脚本从git index删除冲突的文件:

git rm [file]

然后我可以拉得很好。


#28楼

我相信有两种可能的冲突原因,必须分别解决,据我所知,上述答案均未涉及这两种问题:

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

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


#29楼

重要提示:如果您进行任何本地更改,它们将会丢失。 无论是否使用--hard选项,所有尚未推送的本地提交都将丢失。 [*]

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


我认为这是正确的方法:

git fetch --all

然后,您有两个选择:

git reset --hard origin/master

或如果您在其他分支机构:

git reset --hard origin/<branch_name>

说明:

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

然后git reset将master分支重置为您刚刚获取的分支。 --hard选项更改工作树中的所有文件以匹配origin/master文件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

#30楼

警告,如果您在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}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值