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

[英]How do I force “git pull” to overwrite local files?


How do I force an overwrite of local files on a git pull?

如何在git中强制覆盖本地文件?

The scenario is following:

的情况是:

  • A team member is modifying the templates for a website we are working on
  • 团队成员正在修改我们正在开发的网站的模板。
  • They are adding some images to the images directory (but forgets to add them under source control)
  • 他们正在向images目录中添加一些图像(但是忘记在源代码控制下添加它们)
  • They are sending the images by mail, later, to me
  • 他们稍后将这些图片邮寄给我
  • I'm adding the images under the source control and pushing them to GitHub together with other changes
  • 我在源代码控制下添加图像,并将它们与其他更改一起推到GitHub
  • They cannot pull updates from GitHub because Git doesn't want to overwrite their files.
  • 他们不能从GitHub上提取更新,因为Git不想覆盖他们的文件。

The errors I'm getting are:

我犯的错误是:

error: Untracked working tree file 'public/images/icon.gif' would be overwritten by merge.

错误:未跟踪工作树文件的公共/图像/图标。gif将被合并覆盖。

How do I force Git to overwrite them? The person is a designer - usually I resolve all the conflicts by hand, so the server has the most recent version that they just needs to update on their computer.

如何强制Git覆盖它们?这个人是设计师——通常我用手工解决所有的冲突,所以服务器有他们需要更新的最新版本。

37 个解决方案

#1


7033  

Important: If you have any local changes, they will be lost. With or without --hard option, any local commits that haven't been pushed will be lost.[*]

If you have any files that are not tracked by Git (e.g. uploaded user content), these files will not be affected.

如果您有任何文件没有被Git跟踪(例如上传的用户内容),这些文件将不会受到影响。


I think this is the right way:

我认为这是正确的方式:

git fetch --all

Then, you have two options:

然后,你有两个选择:

git reset --hard origin/master

OR If you are on some other branch:

或者如果你在其他部门:

git reset --hard origin/<branch_name>

Explanation:

git fetch downloads the latest from remote without trying to merge or rebase anything.

git fetch从远程下载最新的内容,不需要尝试合并或重设任何内容。

Then the git reset resets the master branch to what you just fetched. The --hard option changes all the files in your working tree to match the files in origin/master

然后git重置主分支到您刚才获取的内容。硬选项更改工作树中的所有文件以匹配源文件/主文件


[*]: It's worth noting that it is possible to maintain current local commits by creating a branch from master before resetting:

[*]:值得注意的是,在重新设置之前,可以通过从master创建一个分支来维护当前的本地提交:

git checkout master
git branch new-branch-to-save-current-commits
git fetch --all
git reset --hard origin/master

After this, all of the old commits will be kept in new-branch-to-save-current-commits. Uncommitted changes however (even staged), will be lost. Make sure to stash and commit anything you need.

在此之后,所有旧的提交都将保存在新分支到save-current提交中。然而,未提交的更改(甚至是分阶段的)将丢失。一定要隐藏和提交任何你需要的东西。

#2


747  

Try this:

试试这个:

git reset --hard HEAD
git pull

It should do what you want.

它应该做你想做的。

#3


376  

WARNING: git clean deletes all your untracked files/directories and can't be undone.

警告:git clean会删除所有未跟踪的文件/目录,并且无法还原。


Sometimes just clean -f does not help. In case you have untracked DIRECTORIES, -d option also needed:

有时候仅仅清理-f是没有用的。如果你有未跟踪的目录,-d选项也需要:

git reset --hard HEAD
git clean -f -d
git pull

WARNING: git clean deletes all your untracked files/directories and can't be undone.

警告:git clean会删除所有未跟踪的文件/目录,并且无法还原。

#4


330  

Like Hedgehog I think the answers are terrible. But though Hedgehog's answer might be better, I don't think it is as elegant as it could be. The way I found to do this is by using "fetch" and "merge" with a defined strategy. Which should make it so that your local changes are preserved as long as they are not one of the files that you are trying to force an overwrite with.

就像刺猬一样,我认为答案是可怕的。虽然刺猬的回答可能更好,但我认为它不像它可能的那样优雅。我发现这样做的方法是使用“fetch”和“merge”以及定义好的策略。它应该使您的本地更改得以保留,只要它们不是您试图强制覆盖的文件之一。

First do a commit of your changes

 git add *
 git commit -a -m "local file server commit message"

Then fetch the changes and overwrite if there is a conflict

 git fetch origin master
 git merge -s recursive -X theirs origin/master

"-X" is an option name, and "theirs" is the value for that option. You're choosing to use "their" changes, instead of "your" changes if there is a conflict.

“-X”是一个选项名称,“他们的”是该选项的值。如果有冲突,你选择使用“他们”的变更,而不是“你”的变更。

#5


236  

Instead of doing:

而不是做:

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

I'd advise doing the following:

我的建议是:

git fetch origin master
git reset --hard origin/master

No need to fetch all remotes and branches if you're going to reset to the origin/master branch right?

如果你要重置到原点/主分支,不需要取回所有的remotes和分支,对吗?

#6


120  

It looks like the best way is to first do:

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

git clean

To delete all untracked files and then continue with the usual git pull...

删除所有未跟踪的文件,然后继续使用通常的git拖拽……

#7


96  

Warning, doing this will permanently delete your files if you have any directory/* entries in your gitignore file.

警告,如果gitignore文件中有任何目录/*条目,那么这样做将永久删除文件。

Some answers seem to be terrible. Terrible in the sense of what happened to @Lauri by following David Avsajanishvili suggestion.

有些答案似乎很糟糕。@Lauri的可怕之处在于,他听从了David Avsajanishvili的建议。

Rather (git > v1.7.6):

(git > v1.7.6):

git stash --include-untracked
git pull

Later you can clean the stash history.

稍后你可以清理隐藏的历史。

Manually, one-by-one:

手动,一个接一个:

$ git stash list
stash@{0}: WIP on <branch>: ...
stash@{1}: WIP on <branch>: ...

$ git stash drop stash@{0}
$ git stash drop stash@{1}

Brutally, all-at-once:

残酷,使得:

$ git stash clear

Of course if you want to go back to what you stashed:

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

$ git stash list
...
$ git stash apply stash@{5}

#8


86  

You might find this command helpful to throw away local changes:

您可能会发现这条命令有助于消除本地更改:

git checkout <your-branch> -f

And then do a cleanup (removes untracked files from the working tree):

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

git clean -f

If you want to remove untracked directories in addition to untracked files:

如果您想删除未跟踪的目录,除了未跟踪的文件:

git clean -fd

#9


70  

Instead of merging with git pull, try this:

与其与git pull合并,不如尝试以下方法:

git fetch --all

git获取——所有

followed by:

紧随其后的是:

git reset --hard origin/master.

git重置——硬起源/主人。

#10


51  

The only thing that worked for me was:

唯一对我起作用的是:

git reset --hard HEAD~5

This will take you back five commits and then with

这将使您后退五次提交,然后进行

git pull

I found that by looking up how to undo a Git merge.

通过查找如何撤消Git合并,我发现了这一点。

#11


50  

The problem with all these solutions is that they are all either too complex, or, an even bigger problem, is that they remove all untracked files from the web server, which we don't want since there are always needed configuration files which are on the server and not in the Git repository.

所有这些解决方案的问题在于,他们都太复杂,或者,一个更大的问题,是他们删除所有从web服务器无路径的文件,我们不希望因为总有需要的配置文件在服务器上,而不是在Git存储库中。

Here is the cleanest solution which we are using:

下面是我们正在使用的最干净的解决方案:

# 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
  • The first command fetches newest data.

    第一个命令获取最新数据。

  • The second command checks if there are any files which are being added to the repository and deletes those untracked files from the local repository which would cause conflicts.

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

  • The third command checks-out all the files which were locally modified.

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

  • Finally we do a pull to update to the newest version, but this time without any conflicts, since untracked files which are in the repo don't exist anymore and all the locally modified files are already the same as in the repository.

    最后,我们对最新版本进行了更新,但是这次没有任何冲突,因为在repo中没有跟踪的文件已经不存在了,所有本地修改的文件都已经和存储库中的文件一样了。

#12


38  

I had the same problem. No one gave me this solution, but it worked for me.

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

I solved it by:

我解决了问题:

  1. Deleting all the files. Leave just the .git directory.
  2. 删除所有的文件。只留下。git目录。
  3. git reset --hard HEAD
  4. git重置,艰难的头
  5. git pull
  6. git拉
  7. git push
  8. git推

Now it works.

现在它的工作原理。

#13


32  

First of all, try the standard way:

首先,试试标准的方法:

git reset HEAD --hard # Remove all not committed changes

If above won't help and you don't care about your untracked files/directories (make the backup first just in case), try the following simple steps:

如果上面没有帮助,你也不关心你的未跟踪文件/目录(先做备份以防万一),试试以下简单的步骤:

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

This will REMOVE all git files (excempt .git/ dir, where you have all commits) and pull it again.

这将删除所有git文件(excempt .git/ dir,其中包含所有提交)并再次提取它。


Why git reset HEAD --hard could fail in some cases?

为什么git重设HEAD——在某些情况下会失败?

  1. Custom rules in .gitattributes file

    .gitattributes文件中的自定义规则。

    Having eol=lf rule in .gitattributes could cause git to modify some file changes by converting CRLF line-endings into LF in some text files.

    在.gitattribute中使用eol=lf规则可以使git修改一些文件更改,将CRLF行尾转换成一些文本文件中的lf。

    If that's the case, you've to commit these CRLF/LF changes (by reviewing them in git status), or try: git config core.autcrlf false to temporary ignore them.

    如果是这样,您必须提交这些CRLF/LF更改(通过在git状态中检查它们),或者尝试:git配置核心。autcrlf false暂时忽略它们。

  2. File system incompability

    文件系统incompability

    When you're using file-system which doesn't support permission attributes. In example you have two repositories, one on Linux/Mac (ext3/hfs+) and another one on FAT32/NTFS based file-system.

    当你使用不支持权限属性的文件系统时。例如,您有两个存储库,一个在Linux/Mac (ext3/hfs+)上,另一个在基于FAT32/NTFS的文件系统上。

    As you notice, there are two different kind of file systems, so the one which doesn't support Unix permissions basically can't reset file permissions on system which doesn't support that kind of permissions, so no matter how --hard you try, git always detect some "changes".

    正如您所注意到的,有两种不同的文件系统,因此不支持Unix权限的文件系统基本上不能重置不支持这种权限的系统上的文件权限,所以无论如何——无论如何——您尝试,git总是会检测到一些“更改”。

#14


27  

I had a similar problem. I had to do this:

我也有类似的问题。我必须这样做:

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

#15


26  

I summarized other answers. You can execute git pull without errors:

我总结了其他的答案。您可以在没有错误的情况下执行git拖动:

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

Warning: This script is very powerful, so you could lose your changes.

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

#16


25  

Based on my own similar experiences, the solution offered by Strahinja Kustudic above is by far the best. As others have pointed out, simply doing hard reset will remove all the untracked files which could include lots of things that you don't want removed, such as config files. What is safer, is to remove only the files that are about to be added, and for that matter, you'd likely also want to checkout any locally-modified files that are about to be updated.

基于我自己类似的经验,上面Strahinja Kustudic提供的解决方案是目前最好的。正如其他人指出的那样,简单地进行重设将删除所有未跟踪的文件,这些文件可能包含许多您不想删除的东西,比如配置文件。更安全的是,只删除即将添加的文件,因此,您可能还希望签出任何即将更新的经本地修改的文件。

That in mind, I updated Kustudic's script to do just that. I also fixed a typo (a missing ' in the original).

考虑到这一点,我更新了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

#17


22  

I believe there are two possible causes of conflict, which must be solved separately, and as far as I can tell none of the above answers deals with both:

我认为有两种可能的冲突原因,必须分别解决,就我所知,以上任何一项都不能解决这两个问题:

  • Local files that are untracked need to be deleted, either manually (safer) or as suggested in other answers, by git clean -f -d

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

  • Local commits that are not on the remote branch need to be deleted as well. IMO the easiest way to achieve this is with: git reset --hard origin/master (replace 'master' by whatever branch you are working on, and run a git fetch origin first)

    也需要删除不在远程分支上的本地提交。在我看来,实现这一点最简单的方法是:git复位——硬源/主(用您正在处理的任何分支替换‘master’,并首先运行git fetch origin)

#18


20  

An easier way would be to:

比较简单的方法是:

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

This will override your local file with the file on git

这会用git上的文件覆盖本地文件

#19


19  

Bonus:

In speaking of pull/fetch/merge in the previous answers, I would like to share an interesting and productive trick,

在前面的回答中,我想分享一个有趣而富有成效的技巧,

git pull --rebase

This above command is the most useful command in my Git life which saved a lot of time.

上面的命令是Git中最有用的命令,节省了很多时间。

Before pushing your newly commit to server, try this command and it will automatically synchronise the latest server changes (with a fetch + merge) and will place your commit at the top in the Git log. There isn't any need to worry about manual pull/merge.

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

Find details in What does "git pull --rebase" do?.

在“git pull—rebase”中查找详细信息。

#20


18  

I had the same problem and for some reason, even a git clean -f -d would not do it. Here is why: For some reason, if your file is ignored by Git (via a .gitignore entry, I assume), it still bothers about overwriting this with a later pull, but a clean will not remove it, unless you add -x.

我也有同样的问题,出于某种原因,即使是一个git clean -f -d也不会这么做。原因如下:由于某些原因,如果您的文件被Git忽略(我假设是通过.gitignore条目),那么它仍然需要在以后的拉入中重写这个文件,但是除非您添加-x,否则清理不会删除它。

#21


17  

It seems like most answers here are focused on the master branch; however, there are times when I'm working on the same feature branch in two different places and I want a rebase in one to be reflected in the other without a lot of jumping through hoops.

似乎大多数答案都集中在主分支上;然而,有时我在两个不同的地方处理相同的特性分支,我希望在一个分支中重新建立一个基础,并在另一个分支中反映出来,而不需要太多的跳圈。

Based on a combination of RNA's answer and torek's answer to a similar question, I've come up with this which works splendidly:

基于RNA的答案和torek对一个类似问题的回答,我想到了一个很棒的方法:

git fetch
git reset --hard @{u}

Run this from a branch and it'll only reset your local branch to the upstream version.

从一个分支运行它,它只会将本地分支重置为上游版本。

This can be nicely put into a git alias (git forcepull) as well:

这也可以很好地放入git别名(git forcepull)中:

git config alias.forcepull "!git fetch ; git reset --hard @{u}"

git配置别名。forcepull”!git获取;git重置,硬@ {你}”

Or, in your .gitconfig file:

或者,在你的。gitconfig文件中:

[alias]
  forcepull = "!git fetch ; git reset --hard @{u}"

Enjoy!

享受吧!

#22


17  

I just solved this myself by:

我自己解决了这个问题:

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

where the last command gives a list of what your local changes were. Keep modifying the "tmp" branch until it is acceptable and then merge back onto master with:

最后一个命令给出本地更改的列表。继续修改“tmp”分支,直到可以接受为止,然后合并到master:

git checkout master && git merge tmp

For next time, you can probably handle this in a cleaner way by looking up "git stash branch" though stash is likely to cause you trouble on the first few tries, so do first experiment on a non-critical project...

下次,你可以用更干净的方式来处理这个问题,通过查找“git存储分支”,尽管在最初的几次尝试中,隐藏可能会给你带来麻烦,所以在一个非关键的项目上做第一次实验……

#23


15  

I have a strange situation that neither git clean or git reset works. I have to remove the conflicting file from git index by using the following script on every untracked file:

我有一个奇怪的情况,git clean和git reset工作。我必须使用以下脚本从git索引中删除冲突文件:

git rm [file]

Then I am able to pull just fine.

这样我就能拉得很好了。

#24


13  

These four commands work for me.

这四个命令对我有效。

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

To check/pull after executing these commands

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

git pull origin master

I tried a lot but finally got success with these commands.

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

#25


12  

Despite the original question, the top answers can cause problems for people who have a similar problem, but don't want to lose their local files. For example, see Al-Punk and crizCraig's comments.

尽管有最初的问题,上面的答案可能会给有类似问题但不想丢失本地文件的人带来问题。例如,看看Al-Punk和crizCraig的评论。

The following version commits your local changes to a temporary branch (tmp), checks out the original branch (which I'm assuming is master) and merges the updates. You could do this with stash, but I've found it's usually easier to simply use the branch / merge approach.

下面的版本将本地更改提交给临时分支(tmp),检查原始分支(我假设它是master)并合并更新。您可以使用hidden来实现这一点,但我发现简单地使用分支/合并方法通常更容易。

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

where we assume the other repository is origin master.

我们假设另一个存储库是origin master。

#26


12  

Just do

只做

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

So you avoid all unwanted side effects, like deleting files or directories you wanted to keep, etc.

所以你可以避免所有不必要的副作用,比如删除你想保存的文件或目录等等。

#27


11  

Reset the index and the head to origin/master, but do not reset the working tree:

将索引和磁头重置为原点/主控,但不重置工作树:

git reset origin/master

#28


10  

Requirements:

要求:

  1. Track local changes so no-one here ever loses them.
  2. 追踪当地的变化,所以这里没有人会失去它们。
  3. Make the local repository match the remote origin repository.
  4. 使本地存储库与远程源存储库匹配。

Solution:

解决方案:

  1. Stash the local changes.
  2. 藏地方的变化。
  3. Fetch with a clean of files and directories ignoring .gitignore and hard reset to origin.

    删除文件和目录,忽略.gitignore并硬重设到原点。

    git stash --include-untracked
    git fetch --all
    git clean -fdx
    git reset --hard origin/master
    

#29


10  

I know a much more easier and less painful method:

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

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

That's it!

就是这样!

#30


9  

I read through all the answers but I was looking for a single command to do this. Here is what I did. Added a git alias to .gitconfig

我通读了所有的答案,但是我在寻找一个命令来完成这个任务。这是我所做的。添加一个git别名到.gitconfig。

[alias]
      fp = "!f(){ git fetch ${1} ${2} && git reset --hard ${1}/${2};};f"

Run your command as

运行命令

git fp origin master

equivalent to

相当于

git fetch origin master
git reset --hard origin/master
关注微信公众号

注意!

本站翻译的文章,版权归属于本站,未经许可禁止转摘,转摘请注明本文地址:https://www.itdaan.com/blog/2009/07/14/c1ef354f826a86db15f02bf8bf570750.html



 
粤ICP备14056181号  © 2014-2020 ITdaan.com