忽略已经签入的目录内容?

248

我有一个Git仓库,仅用于保存多个项目中使用的图形和声音文件。它们都在一个没有子目录的目录中。现在我刚刚创建了一个脚本,将这些资产从另一个带有几级子目录的结构化目录复制过来。

现在我只想让(源)分层文件结构被Git跟踪,而(目标)扁平目录(所有文件都在一堆中)应该被忽略。

我已经将目标目录添加到.gitignore中,但Git仍然会跟踪其中的更改。我认为如果提交对目标目录中旧文件的删除,Git可能会停止跟踪新内容(由脚本复制),但实际并没有。

如何让Git忘记目标目录?


目录名是什么,你在.gitignore文件中放了什么? - mmmmmm
2
名称为DirNameIrrelevant,在.gitignore文件中我尝试了放置"DirNameIrrelevant"、"DirNameIrrelevant/"和"DirNameIrrelevant/*"。 - Felixyz
6个回答

551

这个命令将导致git取消跟踪您的目录和其下的所有文件,而不实际删除它们:

git rm -r --cached <您的目录>

-r选项导致删除您的目录下的所有文件。

--cached选项使文件仅从git索引中删除,而不是从您的工作副本中删除。默认情况下,git rm <file>将删除<file>


16
.gitignore用于确定git将会关注哪些未跟踪的文件,它与已经被跟踪的文件无关。如果用户想要跟踪被忽略的文件,git会允许他们这样做。可以使用add -f命令执行此操作,或者根据您的情况进行处理。正如Gordon所说,这可以防止您意外删除一堆文件——代码库是主列表,而不是.gitignore。这还可以手动跟踪一些通配符规则会忽略的内容,我发现这很有用。 - Cascabel
2
“-r”选项的作用不是“导致删除您目录下的所有文件”,而是递归遍历子目录。 - MrE
@Felixyz .gitignore规则不会使git排除/取消跟踪已经被跟踪的目录或文件。 - MinhajulAnwar
@MrE,递归地应用git rm到所有子目录中的每个文件会产生什么影响?;-) - Gordon Wilson
@GordonWilson,这只是语义上的区别。git rm 是用于删除文件,而 -r 则是递归子目录:两个不同的功能组合在一起确实会导致删除目录下的所有文件。如果我执行 git ls-tree -r 命令,则 -r 不会删除目录下的所有文件。 - MrE
显示剩余4条评论

87

如果您需要在本地仓库和远程仓库中都保留一个已跟踪的文件(已检入),但不希望继续跟踪文件的更改,可以通过以下方式实现:

git update-index --assume-unchanged path/to/file.txt

之后对该文件的任何更改都将不再显示在 git status 中。

要撤消此操作,请使用以下命令:

git update-index --no-assume-unchanged path/to/file.txt

3
虽然 OP 可能要求了一个目录,但这正是我所需要的——只关注对一个已签入文件的进一步更改;谢谢! - sdaau
4
要完全忽略一个目录,请使用“git update-index --assume-unchanged dirName/”。我找了一段时间才找到这个语法,这里需要使用“”。 - J-Dizzle
2
如何将其反转? - Rhys
5
要撤销此操作,请使用以下命令:git update-index --no-assume-unchanged dirname/**/* - JobJob
一旦你真正开始使用仓库,情况就会变得糟糕。我只进行了一次存储和弹出操作,我的更改就消失了。 - Trass3r

5

简而言之,清理你的git仓库并确保所有被忽略的项目都确实被忽略:

git rm -r --cached .
git add .
git commit -m "Clean up ignored files"

注意:您无需指定目录,这样可以清理整个远程存储库。
要深入了解,请阅读this

2

对于添加到git的名为blah/的子目录,以下两种方法似乎都可以忽略blah/中的新文件。在.gitignore中添加:

blah 
blah/*

0

不确定这是否算数或让我成为一个坏人,但是我还是要说。

  1. 我将 *Generated* 添加到根目录的 .gitignore 文件中
  2. 我提交了我想保留的文件作为 GeneratedFile.Whatever.ext.CheckedIn
  3. 我创建了一个 git 钩子,在 post checkout 时调用一个 PowerShell 脚本来执行以下操作:

dir *.CheckedIn -Recurse | %{ copy $_.FullName "$($_.FullName)".Replace("CheckedIn","") -EA SilentlyContinue}

我对自己有点内疚...但它确实有效。


-2

好的,看起来你必须先使用完全空的目录进行签入(既没有旧文件也没有新文件),之后添加的任何文件都将被忽略。如果在提交之前删除旧文件并添加新文件,则新文件将被添加到仓库中,尽管它们应该被忽略。

至少,在这种情况下,这对我有效。如果有人能够提供更多关于发生了什么的见解,那就太好了。


1
我们在别处说过的简短版本是:gitignore影响git所意识到的未跟踪数据,但不影响你告诉git该如何处理数据(例如添加到仓库中)。 - Cascabel
因此,被跟踪并现在已删除的文件应该被标记为已跟踪,这是有意义的,但我仍然不理解为什么添加的文件(如果在下一次提交之前完成)会被跟踪,而如果我1)忽略,2)删除文件,3)提交,4)添加新文件,则新文件不会被跟踪。 - Felixyz

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接