如何强制“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,但它为我工作。

我解决了它:

  1. 删除所有文件。 只留下.git目录。
  2. git reset --hard HEAD
  3. git pull
  4. 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在某些情况下可能会失败?

  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的文件系统上。

    正如你注意到的,有两种不同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顶部。 无需担心手动拉/合并。

http://gitolite.com/git-pull-rebase查找详细信息;

似乎这里的大部分答案都集中在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 cleangit 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 

要求:

  1. 跟踪当地的变化,所以没有人在这里失去他们。
  2. 使本地存储库与远程存储库相匹配。

解:

  1. 藏匿本地的变化。
  2. 一个干净文件目录忽略.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