[英]How do I force "git pull" to overwrite local files?
如何在git pull
上强制覆盖本地文件? 我的本地存储库包含一个与服务器上的文件名相同的文件。
错误:未跟踪的工作树文件“example.txt”将被合并覆盖
--hard
选项,任何尚未推送的本地提交都将丢失。 [*]如果您有任何 Git未跟踪的文件(例如上传的用户内容),这些文件不会受到影响。
首先,运行 fetch 以将所有origin/<branch>
引用更新为最新:
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
尝试这个:
git reset --hard HEAD
git pull
它应该做你想做的事。
警告: 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
...
像刺猬一样,我认为答案很糟糕。 但是尽管刺猬的回答可能会更好,但我认为它并没有它可以的那么优雅。 我发现这样做的方法是使用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
是该选项的值。 如果存在冲突,您选择使用their
更改(另一个选项是ours
的更改)。
而不是这样做:
git fetch --all
git reset --hard origin/master
我建议执行以下操作:
git fetch origin master
git reset --hard origin/master
如果您要重置到原始/主分支,则无需获取所有遥控器和分支,对吗?
看起来最好的方法是先做:
git clean
要删除所有未跟踪的文件,然后继续使用通常的git pull
...
警告,如果您的 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}
您可能会发现此命令有助于丢弃本地更改:
git checkout <your-branch> -f
然后进行清理(从工作树中删除未跟踪的文件):
git clean -f
如果要删除除未跟踪文件之外的未跟踪目录:
git clean -fd
不要与git pull
合并,试试这个:
git fetch --all
其次是:
git reset --hard origin/master
。
所有这些解决方案的问题是它们要么太复杂,要么更大的问题是它们从网络服务器中删除了所有未跟踪的文件,这是我们不想要的,因为服务器上总是需要配置文件而不是在 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
第一个命令获取最新数据。
第二个命令检查是否有任何文件正在添加到存储库中,并从本地存储库中删除那些会导致冲突的未跟踪文件。
第三个命令检出所有在本地修改的文件。
最后,我们拉取更新到最新版本,但这次没有任何冲突,因为仓库中未跟踪的文件不再存在,并且所有本地修改的文件已经与仓库中的相同。
首先,尝试标准方式:
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
中的自定义规则
在 .gitattributes 中有eol=lf
规则可能会导致 git 通过将 CRLF 行尾转换为某些文本文件中的 LF 来修改某些文件更改。
如果是这种情况,您必须提交这些 CRLF/LF 更改(通过在git status
中查看它们),或者尝试: git config core.autcrlf false
暂时忽略它们。
文件系统不兼容
当您使用不支持权限属性的文件系统时。 例如,您有两个存储库,一个在 Linux/Mac ( ext3
/ hfs+
) 上,另一个在基于 FAT32/NTFS 的文件系统上。
正如您所注意到的,有两种不同的文件系统,因此不支持 Unix 权限的文件系统基本上无法在不支持这种权限的系统上重置文件权限,所以无论如何--hard
你试试看,git 总是会检测到一些“变化”。
我有同样的问题。 没有人给我这个解决方案,但它对我有用。
我通过以下方式解决了它:
.git
目录。git reset --hard HEAD
git pull
git push
现在它起作用了。
在谈到之前答案中的拉/取/合并时,我想分享一个有趣且富有成效的技巧,
git pull --rebase
上面这个命令是我 Git 生活中最有用的命令,它节省了很多时间。
在将您的新提交推送到服务器之前,请尝试使用此命令,它会自动同步最新的服务器更改(使用 fetch + 合并)并将您的提交放在 Git 日志的顶部。 无需担心手动拉/合并。
如果您不总是想粘贴分支名称或者您想在脚本中自动执行此操作,这是一个通用解决方案
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)'
我有一个类似的问题。 我不得不这样做:
git reset --hard HEAD
git clean -f
git pull
我总结了其他答案。 您可以执行git pull
而不会出错:
git fetch --all
git reset --hard origin/master
git reset --hard HEAD
git clean -f -d
git pull
警告:此脚本非常强大,因此您可能会丢失所做的更改。
根据我自己的类似经验,上面 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
我遇到了同样的问题,出于某种原因,即使是git clean -f -d
也不会这样做。 原因如下:由于某种原因,如果 Git 忽略了您的文件(我假设是通过 .gitignore 条目),它仍然会担心用稍后的pull覆盖它,但是除非您添加-x
,否则clean不会删除它.
似乎这里的大多数答案都集中在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}"
享受!
我相信有两种可能的冲突原因,必须单独解决,据我所知,上述答案都没有涉及:
需要手动删除未跟踪的本地文件(更安全)或按照其他答案中的建议,通过git clean -f -d
不在远程分支上的本地提交也需要删除。 IMO 实现这一目标的最简单方法是: git reset --hard origin/master
(用您正在处理的任何分支替换“master”,然后首先运行git fetch origin
)
如何强制覆盖git pull
上的本地文件?
场景如下:
这是我得到的错误:
错误:未跟踪的工作树文件“public/images/icon.gif”将被合并覆盖
如何强制 Git 覆盖它们? 此人是一名设计师 - 通常,我会手动解决所有冲突,因此服务器具有他们只需要在其计算机上更新的最新版本。
一种更简单的方法是:
git checkout --theirs /path/to/file.extension
git pull origin master
这将使用 git 上的文件覆盖您的本地文件
我自己解决了这个问题:
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 可能会在前几次尝试中给您带来麻烦,所以请先在非关键项目上进行实验......
我有一个奇怪的情况, git clean
或git reset
都不起作用。 我必须通过在每个未跟踪文件上使用以下脚本从git index
中删除冲突文件:
git rm [file]
然后我就可以拉得很好了。
我知道一种更容易且痛苦更少的方法:
$ git branch -m [branch_to_force_pull] tmp
$ git fetch
$ git checkout [branch_to_force_pull]
$ git branch -D tmp
而已!
如何强制覆盖git pull
上的本地文件?
场景如下:
这是我得到的错误:
错误:未跟踪的工作树文件“public/images/icon.gif”将被合并覆盖
如何强制 Git 覆盖它们? 此人是一名设计师 - 通常,我会手动解决所有冲突,因此服务器具有他们只需要在其计算机上更新的最新版本。
要求:
解决方案:
使用忽略.gitignore并硬重置为origin的文件和目录进行获取。
git stash --include-untracked git fetch --all git clean -fdx git reset --hard origin/master
做就是了
git fetch origin branchname
git checkout -f origin/branchname // This will overwrite ONLY new included files
git checkout branchname
git merge origin/branchname
因此,您可以避免所有不需要的副作用,例如删除您想要保留的文件或目录等。
尽管有最初的问题,但对于有类似问题但又不想丢失本地文件的人来说,最重要的答案可能会导致问题。 例如,参见 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
。
将索引和头部重置为origin/master
,但不要重置工作树:
git reset origin/master
这四个命令对我有用。
git reset --hard HEAD
git checkout origin/master
git branch -D master
git checkout -b master
执行这些命令后检查/拉取
git pull origin master
我尝试了很多,但最终通过这些命令获得了成功。
我通读了所有答案,但我正在寻找一个命令来执行此操作。 这就是我所做的。 为 .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
不要使用git reset --hard
。 这将抹去他们可能完全不受欢迎的变化。 反而:
git pull
git reset origin/master
git checkout <file1> <file2> ...
您当然可以使用git fetch
而不是git pull
,因为它显然不会合并,但如果您通常拉,继续拉在这里是有意义的。
所以这里发生的是git pull
更新你的 origin/master 参考; 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
在 Windows 上,执行以下单个命令:
git fetch --all & git reset --hard origin/master
我使用此命令来删除阻止我执行拉取/合并的本地文件。 但小心点! 运行git merge …
首先查看是否只有您真正想要删除的那些文件。
git merge origin/master 2>&1 >/dev/null | grep ^[[:space:]] | sed s/^[[:space:]]//g | xargs -L1 rm
git merge
列出了所有这些文件。 它们前面有一些空白。2>&1 >/dev/null
将错误输出重定向到标准错误输出,因此它被grep
拾取。grep ^[[:space:]]
只过滤带有文件名的行。sed s/^[[:space:]]//g
从头开始修剪空白。xargs -L1 rm
在每个文件上调用rm
,删除它们。 小心处理:无论git merge
输出什么, rm
都会为每一行以空格开头的行调用。
我试图在 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 )
现在你准备好了。
您可以使用项目基础文件夹中的文件忽略该文件:
.gitignore
public/images/*
然后拉取更改,然后从 gitignore 文件中删除该行。
如果您正在处理您的代码并发现新更改是一个巨大的错误或不需要的,您可以简单地使用替代方法,例如:
git restore .
在哪里 。 表示目录中存在的所有文件。
该解决方案始终在运行。
cd $GIT_ROOT_DIRECTORY
git fetch origin/$TARGET_BRANCH
git rm -rf --cached .
git reset --hard origin/TARGET_BRANCH
git clean -df
git pull origin $TARGET_BRANCH
1:重置为先前的提交
git reset --hard HEAD
2:删除未跟踪的文件
git clean -f
3:拉取提交
git pull
资料来源:
解决此问题的另一种方法是首先使用git stash
存储任何未提交的更改,然后运行
git pull --rebase=interactive -s recursive -X theirs
在交互式变基中,您可以将所有本地不需要的提交更改为drop
,这将摆脱它们并将您留在远程分支的头部,而无需引入合并提交。
现在,如果您想要恢复本地存储更改,则可以运行git stash apply
。
“我的本地更改很小,或者我的更改不起作用。我只想将所有内容重置为原始状态。我知道我所有的本地更改都会丢失。”
如果是这样的话:
git reset --hard
git pull
尽管这个问题已经有很多答案,但最初的问题是解决这个问题
错误:未跟踪的工作树文件“public/images/icon.gif”将被合并覆盖
由于无法合并二进制文件,一个简单的答案是
git checkout public/images/icon.gif
这样,文件将恢复它在此分支中的先前状态。
如果我不想丢失我的更改或类似git checkout .
东西,我通常会做git stash
。 如果我不关心本地修改的文件。 IMO 比reset --hard
、 clean
... 简单得多,而且所有这些东西更适合像远程一样离开分支,包括提交、未跟踪的文件,而不仅仅是解决本地修改的文件。
执行 git pull 后,您将获得不匹配的文件列表。 如果文件数量不是很大,那么您可以签出这些文件,此操作将覆盖这些文件。
git checkout -- <文件名>
如果为了快速检查我修改服务器上的本地文件,我通常会这样做(没有推荐和可能的原因,你得到这个问题:D),我在找到解决方案后检查更改的文件。
我这样做是为了让它工作:
在我创建新分支的计算机上:
git push --all
在我希望新分支显示的计算机上:
git fetch --all
由于我经常需要一种快速的方法来通过命令提示符在 Windows 上重置当前分支,所以这里有一个快速的方法:
for /f "tokens=1* delims= " %a in ('git branch^|findstr /b "*"') do @git reset --hard origin/%b
使用 bash:
b=$(git branch|grep "*");b=${b#"* "};git reset --hard origin/$b
带有powershell:
$b=git branch | Select-String "\*";$b=$b -replace "\* ","";git reset --hard origin/$b
步骤 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>
替换为要覆盖的分支的名称。
注释:
git pull
,git reset --hard
将git reset --hard origin/<branch_to_overwrite>
而不首先从本地存储库中删除所有文件和文件夹,请注意任何仍然存在的垃圾文件可能会在以后git push
潜入远程存储库,即使那不是您的意图。git add -A .
如果您选择省略step 1 ,则在step 2中可以防止这种情况发生。 参考:
https://gitforwindows.org/
https://www.atlassian.com/git/tutorials/undoing-changes/git-reset
https://www.atlassian.com/git/tutorials/rewriting-history/git-reflog
我不确定为什么还没有人谈论FETCH_HEAD
。
git fetch origin master && git reset --hard FETCH_HEAD
如果你想把它放在一个别名中,命令是:
git config --global alias.fpull '!git fetch origin master && git reset --hard FETCH_HEAD'
对于那些不喜欢reset
的人,我喜欢这种方法:
git checkout branchname # go to your branch
git fetch origin branchname # fetch the remote
git checkout -b backup # optionally, mark your remote as a backup
git branch -f branchname origin/branchname # force your local branch to be equal to the fetched origin/branchname
git restore file_to_override_from_remote
git pull
我已经尝试了大部分我能在这里找到的东西,在我的情况下都没有。
有效的是git merge -X theirs
这个简单的命令就可以做到!
git 拉力--力
您可以尝试git pull --force
或者通过使用git stash
然后运行git pull
来隐藏您的提交。
我认为你也可以通过git push -f
/ git push --force
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.