it-swarm.cn

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

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

方案如下:

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

这是我得到的错误:

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

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

6088
Jakub Troszok

重要提示:如果您有任何本地更改,它们将丢失。无论有没有--hard选项,任何未被推送的本地提交都将丢失。[*]

如果您有任何文件由Git(例如上传的用户内容)进行 not 跟踪,则这些文件不会受到影响。


我认为这是正确的方法:

git fetch --all

然后,您有两个选择:

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
8139
RNA

试试这个:

git reset --hard HEAD
git pull

它应该做你想要的。

808
Travis Reeder

警告:git clean删除所有未跟踪的文件/目录,无法撤消。


有时只是clean -f没有帮助。如果您有未跟踪的DIRECTORIES,还需要-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
...
409
David Avsajanishvili

像Hedgehog一样,我认为答案很糟糕。但是虽然刺猬的答案可能会更好,但我认为它并不像它那样优雅。我发现这样做的方法是使用“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”是选项名称,“他们的”是该选项的值。如果存在冲突,您选择使用“他们的”更改,而不是“您的”更改。

347
Richard Kersey

而不是做:

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

我建议做以下事情:

git fetch Origin master
git reset --hard Origin/master

如果要重置为Origin/master分支,是否需要获取所有遥控器和分支?

251
Johanneke

看起来最好的方法是先做:

git clean

要删除所有未跟踪的文件,然后继续使用通常的git pull...

125
Jakub Troszok

警告,如果您的gitignore文件中有任何目录/ *条目,执行此操作将永久删除您的文件。

一些答案似乎很糟糕。根据David Avsajanishvili的建议,对@Lauri发生的事情感到可怕。

相反(git> v1.7.6):

git stash --include-untracked
git pull

之后您可以清理藏匿历史记录。

手动,一个接一个:

$ git stash list
[email protected]{0}: WIP on <branch>: ...
[email protected]{1}: WIP on <branch>: ...

$ git stash drop [email protected]{0}
$ git stash drop [email protected]{1}

蛮横,一劳永逸:

$ git stash clear

当然,如果你想回到你藏匿的东西:

$ git stash list
...
$ git stash apply [email protected]{5}
102
Hedgehog

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

git checkout <your-branch> -f

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

git clean -f

如果除了未跟踪的文件之外还要删除未跟踪的目录:

git clean -fd
88
Vishal

而不是与git pull合并,试试这个: 

git fetch --all

其次是:

git reset --hard Origin/master

82
Lloyd Moore

唯一对我有用的是:

git reset --hard HEAD~5

这将带你回五次提交然后再回来

git pull

我发现通过查找 如何撤消Git合并

55
Chris BIllante

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

  • 第二个命令检查是否有任何文件正在添加到存储库,并从本地存储库中删除那些未导致文件,这将导致冲突。

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

  • 最后我们做了一个更新到最新版本,但这次没有任何冲突,因为repo中的未跟踪文件不再存在,并且所有本地修改的文件已经与存储库中的相同。

51
Strahinja Kustudic

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

我通过以下方式解决了

  1. 删除所有文件。只留下.git目录。
  2. git reset --hard HEAD
  3. git pull
  4. git Push

现在它有效。

39
John John Pichler

首先,尝试标准方式:

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在某些情况下会失败?

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

34
kenorb

奖金:

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

git pull --rebase

以上命令是我Git生活中最有用的命令,可以节省大量时间。

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

“git pull --rebase”做什么?中查找详细信息。

33
Sazzad Hissain Khan

我遇到了类似的问题。我不得不这样做:

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

我总结了其他答案。您可以无错误地执行git pull

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

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

27
Robert Moon

根据我自己的类似经验,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
26
Rolf Kaiser

我认为有两种可能的冲突原因,必须单独解决,据我所知,上述答案都不涉及两者:

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

  • 还需要删除不在远程分支上的本地提交。 IMO最简单的方法是:git reset --hard Origin/master(用你正在处理的任何分支替换'master',然后先运行git fetch Origin

23
tiho

一种更简单的方法是:

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

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

20
maximus 69

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

请享用!

20
JacobEvelyn

我有同样的问题,出于某种原因,即使是git clean -f -d也不会这样做。原因如下:出于某种原因,如果您的文件被Git忽略(通过.gitignore条目,我认为),它仍然困扰用稍后覆盖 pull ,但是 clean 不会删除它,除非你添加-x

19
Tierlieb

我刚刚解决了这个问题:

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可能会让你在前几次尝试时遇到麻烦,所以首先要对非关键项目进行实验......

18
Simon B.

我有一个奇怪的情况,git cleangit reset都不起作用。我必须在每个未跟踪文件上使用以下脚本从git index中删除冲突文件:

git rm [file]

然后我能够拉得很好。

17
Chen Zhang

我知道一种更简单,更少痛苦的方法:

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

而已!

16
ddmytrenko

这四个命令对我有用。

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

执行这些命令后检查/拉出

git pull Origin master

我尝试了很多,但最终成功完成了这些命令。

13
vishesh chandra

做就是了

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

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

12
user2696128

尽管存在最初的问题,但最常见的答案可能会给遇到类似问题但又不想丢失本地文件的人带来问题。例如,请参阅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
Snowcrash

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

git reset Origin/master
11
user811773

要求:

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

解:

  1. 藏匿 本地更改。
  2. fetch with clean of files 目录 忽略 .gitignore hard reset to Origin

    git stash --include-untracked
    git fetch --all
    git clean -fdx
    git reset --hard Origin/master
    
9
vezenkov

我阅读了所有的答案,但我正在寻找一个命令来做到这一点。这就是我做的。为.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
9
Venkat Kotra

不要使用git reset --hard。这将抹去他们可能完全不受欢迎的变化。代替:

git pull
git reset Origin/master
git checkout <file1> <file2> ...

你当然可以使用git fetch而不是git pull,因为它显然不会合并,但如果你通常拉,那么继续拉这里是有道理的。

那么这里发生的是git pull 更新你的Origin/master引用 ; git reset 更新本地分支引用 on与Origin/master相同而不更新任何文件,因此您的签出状态不变;然后git checkout 根据需要将文件恢复到本地分支索引状态 。如果在实时和上游主服务器上添加了完全相同的文件,则索引已经与重置后的文件匹配,因此在通常情况下,您根本不需要执行git checkout

如果上游分支还包含要自动应用的提交,则可以遵循流程的细微变化:

git pull
git merge <commit before problem commit>
git reset <problem commit>
git checkout <file1> <file2> ...
git pull
8
Jim Driscoll

这是还原更改的最佳做法:

  • git commit提交您的分阶段更改,以便将它们保存在reflog(见下文)
  • git fetch获取最新的上游更改
  • git reset --hard Origin/master硬复位到Origin master分支

reflog记录在本地存储库中更新的分支和其他引用。或者简单地说 - reflog 你的变化的历史

因此,提交始终是一个很好的做法。提交附加到reflog,确保您始终可以检索已删除的代码。

7
Jordan Georgiev

我使用此命令来删除本地文件,阻止我进行拉/合并。不过要小心!首先运行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将错误输出重定向到标准输出,以便grepname__选择它。
  • grep ^[[:space:]]仅过滤带有文件名的行。
  • sed s/^[[:space:]]//g从头开始修剪空白区域。
  • xargs -L1 rm在每个文件上调用rmname__,删除它们。

小心处理:无论git merge输出什么,rmname__都将被调用 every line以空格开头。

5
Glutexo

我试图在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

现在你准备好了。

5
Helzgate

在Windows上,执行以下单个命令:

git fetch --all & git reset --hard Origin/master
3
Luca C.

您可以使用项目基本文件夹中的文件忽略该文件:

的.gitignore

public/images/*

然后拉出更改,然后从gitignore文件中删除该行。

3
Daniel Gaytán

git fetch --all && git reset --hard Origin/master && git pull

0
Suge

1:重置为先前的提交

git reset --hard HEAD

2:删除未跟踪的文件

git clean -f

3:拉出提交

git pull

资料来源:

0
abhijithvijayan

如果要以通用方式重置为远程跟踪分支,请使用:

git fetch
git reset --keep Origin/$(git rev-parse --abbrev-ref HEAD)

如果您还想重置本地更改:

git fetch
git reset --hard Origin/$(git rev-parse --abbrev-ref HEAD)
0
warch