我试图从git中移除以前跟踪过的目录,该目录有效,但随后每个git add .
,git add -A
等都会添加回来。这里&#39我做了什么:
在项目根目录中添加.gitignore:
node_modules
运行以下命令:
git rm -r --cached node_modules
git commit -a -m "removed node_modules"
git push origin master
到目前为止一切顺利,这将从远程存储库中删除该目录。问题是当我稍后运行git status
时,它告诉我node_modules目录未跟踪,并在将来的提交中继续添加它。
我缺少什么和/或如何找到问题的根源?
来自here:
默认情况下,git add命令不会添加被忽略的文件。 ... git add命令可用于使用-f(强制)选项添加被忽略的文件。
评论中的其他信息:
我正在跟踪.gitignore文件。
git check-ignore node_modules/
按预期返回node_modules /。
不使用子模块。
更新
我已按照上述步骤创建了一个似乎可以复制问题的示例:
https://github.com/awhitehouse104/SampleRepo
解决:
总结下面的答案和评论,问题在于我的.gitignore文件的编码。我曾使用echo 'node_modules' > .gitignore
在Windows 8上创建文件,它以带有BOM的UTF-16形式出现(根据下面的答案)。经过一些谷歌搜索后,似乎这是PowerShell的默认编码,我可以确认保存为UTF-8似乎已经解决了这个问题。
tldr; 可能不会使用这种创建.gitignore文件的方法或准备更改编码
echo 'node_modules' > .gitignore
答案 0 :(得分:12)
您可能在!
行之后的.gitignore
文件中有一个否定规则(包含再次规则,以node_modules
开头的规则)。
git check-ignore
在文档中存在错误/含糊不清。您希望如果git check-ignore node_modules/
打印node_modules/
,则忽略node_modules/
。但实际上,如果该路径名匹配任何忽略模式(正面或负面),它会打印一个路径名。确保唯一的方法是使用-v
(--verbose
)选项,这将使git check-ignore
打印匹配模式。
此外,如果git check-ignore -v
表示目录被忽略,则并不一定意味着忽略该目录中的所有文件。示例回购:
/
.git/
.gitignore
node_modules/
bar
foo
$ cat .gitignore
/node_modules/*
!/node_modules/foo
$ git check-ignore -v node_modules/
.gitignore:1:/node_modules/* node_modules/
^ positive pattern => ignored
$ git check-ignore -v node_modules/foo
.gitignore:2:!/node_modules/foo node_modules/foo
^ negative pattern => not ignored
$ git add -A
$ git status
# On branch master
# Changes to be committed:
# (use "git reset HEAD <file>..." to unstage)
#
# new file: node_modules/foo
#
因此,如果git check-ignore -v node_modules/
说node_modules/
被忽略,请执行git add -A node_modules/
然后针对已添加的单个文件运行git check-ignore -v --no-index
,以发现添加的原因。
更新:我没想到:您的.gitignore
文件位于&#34; UTF-16带有BOM(字节顺序标记)&#34;编码:
$ cat .gitignore | hexdump -vC
00000000 ff fe 6e 00 6f 00 64 00 65 00 5f 00 6d 00 6f 00 |..n.o.d.e._.m.o.|
00000010 64 00 75 00 6c 00 65 00 73 00 0d 00 0a 00 |d.u.l.e.s.....|
这就是为什么git可能无法处理它的原因。将文件保存为UTF-8而不使用BOM,这应解决问题。但我也建议提交针对git check-ignore
的错误报告 - 在这个角落的情况下,它的输出显然与git实际忽略的不一致。
答案 1 :(得分:7)
将文件添加到git ignore,然后
git update-index --assume-unchanged <file>
答案 2 :(得分:6)
你可以做到
git check-ignore -v --no-index path/with/unexpected/result
了解为什么git add
添加或未添加该路径。
特别值得一提的是,您要检查实际添加的内容,而不是目录。
此外,请find . -name .git
。子模块是嵌套的repos,.gitmodules
,子模块命令很方便,但它们只是帮助它们。
答案 3 :(得分:0)
另一种方法,如果你不想使用 git rm --cached
rm -Rf node_modules
git add -u
git commit -m "stop tracking node_modules"
npm install
# done
还要注意node_modules和node_modules /之间的区别,你似乎有正确的。 (感谢umläute关于此的说明)
答案 4 :(得分:0)
gitignore - 指定要忽略的故意未跟踪文件。
$ HOME / .config / git / ignore,$ GIT_DIR / info / exclude,.gitignore
gitignore文件中的每一行都指定一个模式。在决定是否忽略路径时,Git通常会检查来自多个源的gitignore模式,具有以下优先顺序,从最高到最低(在一个优先级内,最后一个匹配模式决定结果):
要忽略整个目录,您应该使用/**
,
尾随/ **匹配内部的所有内容。例如,abc / **匹配目录“abc”中的所有文件,相对于.gitignore文件的位置,具有无限深度。
或者
您可以通过将此行添加到根.gitignore文件来忽略整个目录:
<强> / DIR_NAME 强>
相反,您可以添加包含以下内容的/logs/.gitignore文件:
<强> [^。] * 强>
目录将保留在您的仓库中,但/目录中的所有文件都将被忽略。简单!
您需要遵循的步骤是,
将其从项目目录中删除(不实际删除):
git rm --cached folder / *
排除除特定目录foo / bar之外的所有内容的示例(注意/ * - 没有斜杠,通配符也会排除foo / bar中的所有内容):
$ cat .gitignore
# exclude everything except directory foo/bar
/*
!/foo
/foo/*
!/foo/bar
答案 5 :(得分:0)
我创建了一个存储库来尝试复制您的问题,我从http://www.stackoverflow.com/questions/11451535/gitignore-not-working得到了第一个答案。
如果你好奇,请点击这里:https://github.com/IAMZERG/so_project_gitignore
尝试将其添加到.gitignore中:
** / directory_to_remove
之后,运行git rm --cached directory_to_remove -r
git status应显示您删除了要删除的目录中的一堆文件。 然后,提交并推送到你的遥控器,一切都应该是金色的......也许吧?
答案 6 :(得分:0)
我遇到了类似的问题。确保我的编码是ANSI并且行结尾是Unix(LF)解决了我的问题。
答案 7 :(得分:0)
我找到了一种向.gitignore添加文件的方法,即使它们已经提交过一次。这有点残酷,但效果很好。
将不同的文件添加到.gitignore
从git项目中移出这些文件
Rescan&amp; StageChanged,这些操作会告诉您这些文件已被删除
提交
将您的文件移回您的项目,他们将不再被追踪!