如何让 Git“忘记”一个被跟踪但现在在 .gitignore 中的文件?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1274057/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to make Git "forget" about a file that was tracked but is now in .gitignore?
提问by Ivan
There is a file that was being tracked by git
, but now the file is on the .gitignore
list.
有一个文件正被 跟踪git
,但现在该文件在.gitignore
列表中。
However, that file keeps showing up in git status
after it's edited. How do you force git
to completely forget about it?
但是,该文件在git status
编辑后不断显示。你如何强迫git
完全忘记它?
回答by CB Bailey
.gitignore
will prevent untracked files from being added (without an add -f
) to the set of files tracked by git, however git will continue to track any files that are already being tracked.
.gitignore
将阻止将未跟踪的文件(没有add -f
)添加到 git 跟踪的文件集中,但是 git 将继续跟踪任何已经被跟踪的文件。
To stop tracking a file you need to remove it from the index. This can be achieved with this command.
要停止跟踪文件,您需要将其从索引中删除。这可以通过这个命令来实现。
git rm --cached <file>
If you want to remove a whole folder, you need to remove all files in it recursively.
如果要删除整个文件夹,则需要递归删除其中的所有文件。
git rm -r --cached <folder>
The removal of the file from the head revision will happen on the next commit.
从头修订中删除文件将在下一次提交时发生。
WARNING: While this will not remove the physical file from your local, it will remove the files from other developers machines on next git pull
.
警告:虽然这不会从您的本地删除物理文件,但它会在下一个git pull
.
回答by Matt Frear
The series of commands below will remove all of the items from the Git Index (not from the working directory or local repo), and then updates the Git Index, while respecting git ignores. PS. Index = Cache
下面的一系列命令将从 Git 索引(不是从工作目录或本地存储库)中删除所有项目,然后更新 Git 索引,同时尊重 git 忽略。附注。索引 = 缓存
First:
第一的:
git rm -r --cached .
git add .
Then:
然后:
git commit -am "Remove ignored files"
Or one-liner:
或单线:
git rm -r --cached . && git add . && git commit -am "Remove ignored files"
回答by Konstantin
git update-indexdoes the job for me:
git update-index为我完成了这项工作:
git update-index --assume-unchanged <file>
Note:This solution is actually independent on .gitignore
as gitignore is only for untracked files.
注意:此解决方案实际上是独立的,.gitignore
因为 gitignore 仅适用于未跟踪的文件。
edit:Since this answer was posted, a new option has been created and that should be prefered. You should use --skip-worktree
which is for modified tracked files that the user don't want to commit anymore and keep --assume-unchanged
for performance to prevent git to check status of big tracked files. See https://stackoverflow.com/a/13631525/717372for more details...
编辑:由于发布了此答案,因此创建了一个新选项,应该首选。您应该使用--skip-worktree
which 用于用户不想再提交的已修改跟踪文件,并保持--assume-unchanged
性能以防止 git 检查大跟踪文件的状态。有关更多详细信息,请参阅https://stackoverflow.com/a/13631525/717372...
git update-index --skip-worktree <file>
回答by thSoft
git ls-files --ignored --exclude-standard -z | xargs -0 git rm --cached
git commit -am "Remove ignored files"
This takes the list of the ignored files and removes them from the index, then commits the changes.
这会获取被忽略文件的列表并将它们从索引中删除,然后提交更改。
回答by David Hernandez
I always use this command to remove those untracked files. One-line, Unix-style, clean output:
我总是使用这个命令来删除那些未跟踪的文件。一行,Unix 风格,干净的输出:
git ls-files --ignored --exclude-standard | sed 's/.*/"&"/' | xargs git rm -r --cached
It lists all your ignored files, replace every output line with a quoted line instead to handle paths with spaces inside, and pass everything to git rm -r --cached
to remove the paths/files/dirs from the index.
它列出了所有被忽略的文件,用带引号的行替换每个输出行来处理内部带有空格的路径,并将所有内容传递git rm -r --cached
给以从索引中删除路径/文件/目录。
回答by Joel Hooks
move it out, commit, then move it back in. This has worked for me in the past. There is probably a 'gittier' way to accomplish this.
将其移出,提交,然后将其移回。这在过去对我有用。可能有一种“gittier”方式来实现这一点。
回答by Seth Robertson
If you cannot git rm
a tracked file because other people might need it (warning, even if yougit rm --cached
, when someone else gets this change, their files will be deleted in their filesystem). These are often done due to config file overrides, authentication credentials, etc. Please look at https://gist.github.com/1423106for ways people have worked around the problem.
如果您无法git rm
跟踪文件,因为其他人可能需要它(警告,即使您git rm --cached
,当其他人获得此更改时,他们的文件将在其文件系统中删除)。这些通常是由于配置文件覆盖、身份验证凭据等导致的。请查看https://gist.github.com/1423106,了解人们解决该问题的方法。
To summarize:
总结一下:
- Have your application look for an ignored file config-overide.ini and use that over the committed file config.ini (or alternately, look for ~/.config/myapp.ini, or $MYCONFIGFILE)
- Commit file config-sample.ini and ignore file config.ini, have a script or similar copy the file as necessary if necessary.
- Try to use gitattributes clean/smudge magic to apply and remove the changes for you, for instance smudge the config file as a checkout from an alternate branch and clean the config file as a checkout from HEAD. This is tricky stuff, I don't recommend it for the novice user.
- Keep the config file on a deploy branch dedicated to it that is never merged to master. When you want to deploy/compile/test you merge to that branch and get that file. This is essentially the smudge/clean approach except using human merge policies and extra-git modules.
- Anti-recommentation: Don't use assume-unchanged, it will only end in tears (because having git lie to itself will cause bad things to happen, like your change being lost forever).
- 让您的应用程序查找被忽略的文件 config-overide.ini 并在提交的文件 config.ini 上使用它(或者,查找 ~/.config/myapp.ini 或 $MYCONFIGFILE)
- 提交文件 config-sample.ini 并忽略文件 config.ini,如有必要,请根据需要使用脚本或类似方式复制该文件。
- 尝试使用 gitattributes clean/smudge magic 为您应用和删除更改,例如将配置文件作为从备用分支的检出进行涂抹,并将配置文件作为从 HEAD 的检出进行清洁。这是棘手的事情,我不建议新手用户使用它。
- 将配置文件保留在专用于它的部署分支上,该分支永远不会合并到 master。当您想要部署/编译/测试时,您可以合并到该分支并获取该文件。除了使用人工合并策略和额外的 git 模块之外,这本质上是涂抹/清理方法。
- 反推荐:不要使用assume-unchanged,它只会以泪水结束(因为git lie会导致不好的事情发生,就像你的change永远丢失一样)。
回答by Dheeraj Bhaskar
Use this when:
在以下情况下使用它:
1. You want to untrack a lot of files, or
1. 您想取消跟踪大量文件,或
2. You updated your gitignore file
2. 你更新了你的 gitignore 文件
Source link:http://www.codeblocq.com/2016/01/Untrack-files-already-added-to-git-repository-based-on-gitignore/
源码链接:http : //www.codeblocq.com/2016/01/Untrack-files-already- added-to- git- repository-based- on-gitignore/
Let's say you have already added/committed some files to your git repository and you then add them to your .gitignore; these files will still be present in your repository index. This article we will see how to get rid of them.
假设您已经向 git 存储库添加/提交了一些文件,然后将它们添加到 .gitignore;这些文件仍将存在于您的存储库索引中。这篇文章我们将看到如何摆脱它们。
Step 1: Commit all your changes
第 1 步:提交所有更改
Before proceeding, make sure all your changes are committed, including your .gitignore file.
在继续之前,请确保已提交所有更改,包括 .gitignore 文件。
Step 2: Remove everything from the repository
第 2 步:从存储库中删除所有内容
To clear your repo, use:
要清除您的回购,请使用:
git rm -r --cached .
- rmis the remove command
- -rwill allow recursive removal
- –cachedwill only remove files from the index. Your files will still be there.
- rm是删除命令
- -r将允许递归删除
- –cached只会从索引中删除文件。您的文件仍将存在。
The rm
command can be unforgiving. If you wish to try what it does beforehand, add the -n
or --dry-run
flag to test things out.
该rm
命令可以是无情的。如果您想预先尝试它的功能,请添加-n
或--dry-run
标志来测试一下。
Step 3: Re add everything
第 3 步:重新添加所有内容
git add .
Step 4: Commit
第 4 步:提交
git commit -m ".gitignore fix"
Your repository is clean :)
您的存储库很干净:)
Push the changes to your remote to see the changes effective there as well.
将更改推送到您的遥控器以查看那里的更改也有效。
回答by drrlvn
I accomplished this by using git filter-branch. The exact command I used was taken from the man page:
我通过使用git filter-branch实现了这一点。我使用的确切命令取自手册页:
WARNING: this will delete the file from your entire history
警告:这将从您的整个历史记录中删除该文件
git filter-branch --index-filter 'git rm --cached --ignore-unmatch filename' HEAD
This command will recreate the entire commit history, executing git rm
before each commit and so will get rid of the specified file. Don't forget to back it up before running the command as it willbe lost.
此命令将重新创建整个提交历史记录,git rm
在每次提交之前执行,因此将删除指定的文件。在运行命令之前不要忘记备份它,因为它会丢失。
回答by JonBrave
What didn't work for me
什么对我不起作用
(Under Linux), I wanted to use the posts here suggesting the ls-files --ignored --exclude-standard | xargs git rm -r --cached
approach. However, (some of) the files to be removed had an embedded newline/LF/\n
in their names. Neither of the solutions:
(在 Linux 下),我想使用这里建议的ls-files --ignored --exclude-standard | xargs git rm -r --cached
方法的帖子。但是,(某些)要删除的文件\n
的名称中嵌入了换行符/LF/ 。两种解决方案都没有:
git ls-files --ignored --exclude-standard | xargs -d"\n" git rm --cached
git ls-files --ignored --exclude-standard | sed 's/.*/"&"/' | xargs git rm -r --cached
cope with this situation (get errors about files not found).
应对这种情况(获取有关未找到文件的错误)。
So I offer
所以我提供
git ls-files -z --ignored --exclude-standard | xargs -0 git rm -r --cached
git commit -am "Remove ignored files"
This uses the -z
argument to ls-files, and the -0
argument to xargsto cater safely/correctly for "nasty" characters in filenames.
它使用-z
参数LS-文件和-0
参数xargs的,以满足安全/正确的“讨厌的”文件名中的字符。
In the manual page git-ls-files(1), it states:
在手册页git-ls-files(1) 中,它指出:
When -z option is not used, TAB, LF, and backslash characters in pathnames are represented as \t, \n, and \\, respectively.
当不使用 -z 选项时,路径名中的 TAB、LF 和反斜杠字符分别表示为 \t、\n 和 \\。
so I think my solution is needed if filenames have any of these characters in them.
所以我认为如果文件名中有任何这些字符,我的解决方案是需要的。