如何强制“git pull”覆盖本地文件?
如何在git pull
上强制覆盖本地文件?
情景如下:
- 团队成员正在修改我们正在处理的网站的模板
- 他们正在添加一些图像的图像目录(但忘记在源代码控制下添加它们)
- 他们通过邮件将图像发送给我
- 我在源代码控制下添加图像,并将其与其他更改一起推送到GitHub
- 他们不能从GitHub提取更新,因为Git不想覆盖他们的文件。
我得到的错误是:
错误:未经追踪的工作树文件“public / images / icon.gif”将被合并覆盖。
我如何强制Git覆盖它们? 这个人是一个devise师 – 通常我手工解决所有的冲突,所以服务器有最新的版本,他们只需要在他们的计算机上更新。
重要提示:如果您有任何本地更改,将会丢失。 有或没有 – --hard
选项,任何未被推送的本地提交将会丢失。 [*]
如果你有任何不被Git跟踪的文件(例如上传的用户内容),这些文件不会受到影响。
我认为这是正确的方法:
git fetch --all
那么,你有两个select:
git reset --hard origin/master
或者如果你在其他分支上:
git reset --hard origin/<branch_name>
说明:
git fetch
从远程下载最新版本,而不会尝试合并或重新绑定任何东西。
然后git reset
重置将主分支重置为您刚刚获取的内容。 --hard
选项更改工作树中的所有文件以匹配origin/master
文件中的文件
[*] :值得注意的是,在重置之前,可以通过从master
创build一个分支来维护当前的本地提交:
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 reset --hard HEAD git pull
它应该做你想要的。
警告: git clean
删除所有未跟踪的文件/目录,不能撤消。
有时只是clean -f
不起作用。 如果你没有跟踪DIRECTORIES,-d选项也需要:
git reset --hard HEAD git clean -f -d git pull
警告: git clean
删除所有未跟踪的文件/目录,不能撤消。
就像刺猬我认为答案是可怕的。 但是,虽然刺猬的答案可能会更好,但我不认为它是如此优雅。 我发现这样做的方式是通过使用“获取”和“合并”一个定义的策略。 这应该使得你的本地修改保留下来,只要它们不是你试图强制覆盖的文件之一。
首先做一个你的改变
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”是该选项的值。 你select使用“他们”的变化,而不是“你”的变化,如果有冲突。
而不是做:
git fetch --all git reset --hard origin/master
我build议做以下事情:
git fetch origin master git reset --hard origin/master
如果你打算重新设置原点/主分支,没有必要获取所有的遥控器和分支?
看起来最好的办法是先做:
git clean
要删除所有未跟踪的文件,然后继续通常的git pull
…
警告,如果您的gitignore文件中有任何目录/ *条目,这样做将永久删除您的文件。
这似乎是可怕的答案,根据大卫Avsajanishvili的build议,在@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
。
所有这些解决scheme的问题是,它们都是太复杂,或者更大的问题是,他们从Web服务器中删除所有未跟踪的文件,这是我们不想要的,因为总是需要configuration文件服务器,而不是在Git仓库。
这是我们正在使用的最干净的解决scheme:
# 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 eg 'merge origin/master') git pull
-
第一个命令获取最新的数据。
-
第二个命令检查是否有任何正在添加到存储库的文件,并从本地存储库中删除那些会导致冲突的未跟踪文件。
-
第三个命令检出本地修改的所有文件。
-
最后,我们将更新到最新版本,但是这次没有任何冲突,因为回收站中的未跟踪文件不再存在,所有本地修改的文件已经与存储库中的相同。
唯一对我有用的是:
git reset --hard HEAD~5
这会带你回5个提交,然后
git pull
我发现通过查找如何撤消Git合并 。
我有同样的问题。 没有人给我这个解决scheme,但它为我工作。
我解决了它:
- 删除所有文件。 只留下.git目录。
-
git reset --hard HEAD
-
git pull
-
git push
现在起作用了。
首先,尝试一下标准的方法:
git reset HEAD --hard # Remove all not committed changes
如果上面的内容不起作用,并且您不关心未跟踪的文件/目录(为了以防万一,请先备份),请尝试以下简单步骤:
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文件(excempt .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的文件系统上。正如你注意到的,有两种不同types的文件系统,所以不支持Unix权限的文件系统基本上不能在不支持这种权限的系统上重置文件权限,所以无论如何 -尝试,总是检测一些“变化”。
我有一个类似的问题。 我必须这样做:
git reset --hard HEAD git clean -f git pull
基于我自己的类似经验,上述Strahinja Kustudic提供的解决scheme是迄今为止最好的。 正如其他人所指出的那样,简单地进行硬重置将删除所有未被跟踪的文件,这些文件可能包含许多不想删除的内容,比如configuration文件。 更安全的是,只删除即将被添加的文件,对于这个问题,你可能也想签出任何即将被更新的本地修改的文件。
记住,我更新了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 pull
没有错误:
git fetch --all git reset --hard origin/master git reset --hard HEAD git clean -f -d git pull
警告 :这个脚本非常强大,所以你可能会失去你的改变。
我认为冲突有两个可能的原因,必须分开解决,据我所知,上述答案都不涉及两者:
-
未被跟踪的本地文件需要被手动删除(更安全),或者如其他答案中的build议,通过
git clean -f -d
-
不在远程分支上的本地提交也需要被删除。 IMO最简单的方法是:
git reset --hard origin/master
(用你正在工作的任何分支replacemaster,并首先运行一个git fetch origin
)
更简单的方法是:
git checkout --theirs /path/to/file.extension git pull origin master
这将覆盖您的本地文件在git上的文件
我有同样的问题,出于某种原因,即使是一个git clean -f -d
不会这样做。 这是为什么:由于某种原因,如果你的文件被Git忽略(通过一个.gitignore条目,我假设),它仍然困扰着用稍后拉动覆盖这个,但干净的不会删除它,除非你添加-x
。
奖金:
在上面的回答中,我想分享一个有趣和高效的技巧,
git pull --rebase
这个命令是我的git生命中最有用的命令,它节省了大量的时间。
在推送新服务器之前,请尝试使用此命令,它会自动同步最新的服务器更改(使用fetch + merge),并将您的提交置于git log顶部。 无需担心手动拉/合并。
似乎这里的大部分答案都集中在master
分支上; 然而,有时我在两个不同的地方工作在同一个function分支上,我希望在另一个地方能够反映出另一个的变化,而没有太多的跳跃。
基于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 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”分支,直到可以接受为止,然后通过以下方式合并回主:
git checkout master && git merge tmp
下一次,你可以通过查找“git stash branch”来更清晰地处理这个问题,虽然在前几次尝试中stash可能会给你带来麻烦,所以先做一个非关键项目的实验。
这四个命令对我有用。
git reset --hard HEAD git checkout origin/master git branch -D master git checkout -b master
在执行这些命令后检查/拉取
git pull origin master
我尝试了很多,但最终获得了这些命令的成功。
尽pipe原来的问题,最好的答案可能会导致问题的人有类似的问题,但不想丢失本地文件。 例如,见Al-Punk和crizCraig的评论。
以下版本将您的本地更改提交到临时分支( tmp
),检出原始分支(我假定它是master
分支)并合并更新。 你可以这样做,但我发现通常使用分支/合并方法通常更容易。
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
。
我有一个奇怪的情况,无论是git clean
或git reset
工程。 我不得不从git index
删除冲突的文件
git rm [file]
然后我可以拉好。
做就是了
git fetch origin branchname git checkout -f origin/branchname // This will overwrite ONLY new included files git checkout branchname git merge origin/branchname
所以你可以避免所有不需要的副作用,比如删除你想保留的文件或目录等。
将索引和头重置为origin/master
,但不要重置工作树:
git reset origin/master
要求:
- 跟踪当地的变化,所以没有人在这里失去他们。
- 使本地存储库与远程存储库相匹配。
解:
- 藏匿本地的变化。
-
取一个干净的文件和目录忽略.gitignore和硬重置到原点 。
git stash --include-untracked git fetch --all git clean -fdx git reset --hard origin/master
我知道一个更简单,更痛苦的方法:
$ git branch -m [branch_to_force_pull] tmp $ git fetch $ git checkout [branch_to_force_pull] $ git branch -D tmp
而已!
我读通过所有的答案,但我正在寻找一个单一的命令来做到这一点。 这是我做的。 添加一个git别名到.gitconfig
[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