如何在gitignore中编写规则以忽略某个目录中除了目录以外的所有文件?

9
假设我有这样一个目录结构,请看下图:
uploads/
--dir1/
----one.txt
----two.txt
----dir2/
------one.txt
------two.txt

我希望跟踪uploads目录及其子目录,但不跟踪其中的任何文件,除了一个虚拟文件,因为git无法跟踪目录。我认为以下代码可以实现,但实际上并不能。
*
!.gitignore
1个回答

11
当你告诉Git忽略*时,它不会递归进入任何子目录(即使你有一个“取消忽略”模式可能匹配某个目录内的内容)。
但是,gitignore模式语言中有一些技巧可能会有所帮助。尾随斜杠强制该模式仅适用于目录。因此,您应该能够使用以下内容:
# .gitignore
*
!.keep
!*/

在下面的演示中,我使用上述的.gitignore,并在每个.keep文件旁边添加了另一个文件(名为do-not-keep)。您可以看到它适用于多级子目录,并且不显示其他文件。您需要通过某种独立的方法为每个目录安排自己的.keep(或其他名称)。
% git status --short -uall
?? a/.keep
?? a/b/.keep
?? a/b/c/.keep
?? a/b/c/d/.keep
?? e/.keep
?? e/f/.keep
?? e/f/g/.keep
?? h/.keep
?? h/i/.keep
?? j/.keep

这是使用Git 1.7.3.1完成的,但我预计其他版本也可以使用。
演示设置:
% git init
% mkdir -p a/b/c/d e/f/g h/i j
% zargs -i.. -- **/*(/) -- touch ../.keep ../do-not-keep
% tree -aI .git .                                       
.
|-- .gitignore
|-- a
|   |-- .keep
|   |-- b
|   |   |-- .keep
|   |   |-- c
|   |   |   |-- .keep
|   |   |   |-- d
|   |   |   |   |-- .keep
|   |   |   |   `-- do-not-keep
|   |   |   `-- do-not-keep
|   |   `-- do-not-keep
|   `-- do-not-keep
|-- e
|   |-- .keep
|   |-- do-not-keep
|   `-- f
|       |-- .keep
|       |-- do-not-keep
|       `-- g
|           |-- .keep
|           `-- do-not-keep
|-- h
|   |-- .keep
|   |-- do-not-keep
|   `-- i
|       |-- .keep
|       `-- do-not-keep
`-- j
    |-- .keep
    `-- do-not-keep

10 directories, 21 files

你难道不需要在子目录自己的.gitignore文件中列出!.gitignore,以便忽略文件本身被Git跟踪吗? - beporter
@beporter:通常我会手动跟踪它,使用 git add -f .gitignore(当它被跟踪时,无论它是否被忽略都没有关系)。但是,如果您不想采取这一次“强制”步骤,那么您可以添加额外的条目(或者更好的方法是,只取消忽略第一级.gitignore,即 !/.gitignore)。 - Chris Johnsen

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