如何强制覆盖 git pull
上的本地文件?我的本地存储库包含一个文件名与服务器上相同的文件。
错误:未跟踪的工作树文件“example.txt”将被合并覆盖
git reset --hard origin/branch_to_overwrite
git branch <branch> -D
2. 重置为冲突前的提交:git reset <commit> --hard
3. 重新创建分支:git branch <branch>
4. 设置对服务器的跟踪:git --set-upstream-to=origin/<branch> <branch> 5. Pull:
git pull`
git config core.autocrlf false; git ls-files -z | xargs -0 rm; git checkout .
⚠ 重要提示:如果您有任何本地更改,它们将会丢失(如果它们被跟踪)。此外,无论是否使用 --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
...
.gitignore
git clean -dfx
。 -x
忽略 .gitignore。通常,您的构建产品将位于 .gitignore 中。
像刺猬一样,我认为答案很糟糕。但是尽管刺猬的回答可能会更好,但我认为它并没有它可以的那么优雅。我发现这样做的方法是使用带有定义策略的 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
更改)。
get fetch other-repo
; 2) git merge -s recursive -X theirs other-repo/master
git merge -X theirs origin/master
而不是这样做:
git fetch --all
git reset --hard origin/master
我建议执行以下操作:
git fetch origin master
git reset --hard origin/master
如果您要重置到原始/主分支,则无需获取所有遥控器和分支,对吗?
看起来最好的方法是先做:
git clean
要删除所有未跟踪的文件,然后继续使用通常的 git pull
...
git fetch origin && git reset --hard origin/master
git clean
是最佳答案吗?似乎删除文件不一定是 OP 想要的。他们要求“覆盖本地文件”而不是删除。
有些答案似乎很糟糕。通过遵循 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 add
-ing 整个存储库来模仿 --include-untracked
,然后立即隐藏它。
git stash apply
带回了我所有未跟踪的文件,但(正确地)合并已创建的文件除外:“已经存在,不签出。”工作完美。
git stash -u
。
您可能会发现此命令有助于丢弃本地更改:
git checkout <your-branch> -f
然后进行清理(从工作树中删除未跟踪的文件):
git clean -f
如果要删除除未跟踪文件之外的未跟踪目录:
git clean -fd
不要与 git pull
合并,试试这个:
git fetch --all
其次是:
git reset --hard origin/master
。
唯一对我有用的是:
git reset --hard HEAD~5
这将使您返回五个提交,然后
git pull
我通过查找 how to undo a Git merge 发现了这一点。
work around
的一个技巧,但非常有效。因为一些冲突可能只发生在几次提交中,所以恢复 5 次提交将确保与远程代码没有冲突。
所有这些解决方案的问题是它们要么太复杂,要么更大的问题是它们从网络服务器中删除了所有未跟踪的文件,这是我们不想要的,因为服务器上总是需要配置文件而不是在 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 merge origin/master
会更快,甚至可能更安全。因为如果有人在删除此脚本的文件期间推送了新的更改(这不太可能发生,但可能发生),整个拉取可能会失败。我把 pull
放在那里的唯一原因是因为有人可能不在 master 分支上工作,而是在其他一些分支上工作,我希望脚本是通用的。
.gitignore
中。
首先,尝试标准方式:
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 文件中的自定义规则 .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 日志的顶部。无需担心手动拉/合并。
在 What does "git pull --rebase" do? 中查找详细信息。
git pull -r
。
git add -A
、2) git commit -m
3) 最后是 git pull rebase
。谢谢你。
如果您不总是想粘贴分支名称或者您想在脚本中自动执行此操作,这是一个通用解决方案
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)'
alias gplf='git fetch && echo "HEAD was at $(git rev-parse --short HEAD)" && git reset --hard origin/$(git rev-parse --abbrev-ref HEAD)'
git fetch
其次是 git reset --hard origin/$(git rev-parse --abbrev-ref HEAD)
。我选择它是因为它的简单性和答案的最新性。
我有一个类似的问题。我不得不这样做:
git reset --hard HEAD
git clean -f
git pull
git clean
我总结了其他答案。您可以执行 git pull
而不会出错:
git fetch --all
git reset --hard origin/master
git reset --hard HEAD
git clean -f -d
git pull
警告:此脚本非常强大,因此您可能会丢失所做的更改。
git reset --hard HEAD
可能是多余的;我的本地手册页 (2.6.3) 在第二行中说 reset
git reset --hard origin/master
“在所有形式中都默认为 HEAD。”
根据我自己的类似经验,上面 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 覆盖它而烦恼,但是 clean 不会删除它,除非您添加 -x
。
我相信有两种可能的冲突原因,必须单独解决,据我所知,上述答案都没有涉及:
需要手动删除未跟踪的本地文件(更安全)或按照其他答案中的建议,通过 git clean -f -d
不在远程分支上的本地提交也需要删除。 IMO 实现这一目标的最简单方法是: git reset --hard origin/master (用您正在处理的任何分支替换“master”,然后首先运行 git fetch origin)
似乎这里的大多数答案都集中在 master
分支上;但是,有时我在两个不同的地方处理同一个特性分支,我希望一个 rebase 能够反映在另一个地方,而不需要太多的跳跃。
基于 RNA's answer 和 torek's answer to a similar question 的组合,我想出了这个非常有效的方法:
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 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
而已!
origin/<branch_to_force_pull>
。
要求:
跟踪本地更改,因此这里没有人会丢失它们。使本地存储库与远程源存储库匹配。
解决方案:
存储本地更改。获取一个干净的文件和目录,忽略 .gitignore 并硬重置为原点。 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
因此,您可以避免所有不需要的副作用,例如删除您想要保留的文件或目录等。
checkout -f
,这消除了所有有问题的未跟踪文件。然后我可以再次结帐我的目的地,最后合并没有问题。
尽管有最初的问题,但对于有类似问题但又不想丢失本地文件的人来说,最重要的答案可能会导致问题。例如,参见 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
我尝试了很多,但最终通过这些命令获得了成功。
git reset --hard origin/branch-name
git pull -f
这样的命令git reflog
恢复在硬重置之前未推送的提交,其中列出了所有提交,也包括那些没有基础的提交。在您使用git gc
清理本地副本之前,一切都会丢失