.gitignore排除文件夹但包含特定子文件夹

.gitignore排除文件夹但包含特定子文件夹

技术背景

在使用Git进行版本控制时,.gitignore文件用于指定那些不希望被Git跟踪的文件和文件夹。有时候我们需要排除某个文件夹,但同时包含该文件夹下的特定子文件夹,这就需要合理配置.gitignore文件。

实现步骤

基本规则

如果排除了application/,那么它下面的所有内容都会被排除,即使后续有否定排除模式(“取消忽略”)也可能无效。要实现排除文件夹但包含特定子文件夹,需要对要“取消忽略”的内容的每个父目录都进行“取消忽略”操作,通常会成对编写规则:忽略目录中的所有内容,但不忽略某些特定子目录。

示例规则

1
2
3
4
5
6
7
8
# 可以跳过这第一个规则,如果它之前没有被其他规则排除
!application/

application/*
!application/language/

application/language/*
!application/language/gr/

*模式

对于较新版本的Git(1.8.2及以后),可以使用双*模式实现更简洁的解决方案:

1
2
3
4
5
# 假设要忽略的根文件夹是 'application'
application/**/*

# 要跟踪的子文件夹
!application/language/gr/

Git 2.17.0及以后

使用**模式结合排除每个子目录直到目标文件的规则是有效的:

1
2
3
4
5
6
7
8
# 假设要忽略的根文件夹是 'application'
application/**

# 显式跟踪 'application' 文件夹中的特定内容
!application/language/
!application/language/gr/
!application/language/gr/** # 示例:添加 'gr' 文件夹中的所有文件和文件夹
!application/language/gr/SomeFile.txt # 示例:添加 'gr' 文件夹中的特定文件

核心代码

排除application文件夹但包含application/language/gr/子文件夹

1
2
3
4
application/**
!application/language/
!application/language/gr/
!application/language/gr/**

排除node_modules文件夹但包含node_modules/module-a子文件夹

1
2
3
!node_modules/
node_modules/*
!node_modules/module-a/

JetBrains IntelliJ IDEA .gitignore配置

1
2
3
4
.idea
!.idea/
.idea/*
!.idea/runConfigurations/

跟踪/etc/nagios//usr/lib64/nagios/plugins/

1
2
3
4
5
6
7
8
9
10
11
/*
!etc
etc/*
!etc/nagios
!usr
usr/*
!usr/lib64
usr/lib64/*
!usr/lib64/nagios
usr/lib64/nagios/*
!usr/lib64/nagios/plugins

最佳实践

手动添加文件

可以手动添加文件,这通常会优先于.gitignore规则:

1
git add /path/to/module

如果文件已经被忽略,可能需要使用-f选项;如果想表明有添加的意图但不立即添加,可以使用-N选项。

使用.include文件

在命令行中,可以创建一个单独的.include文件,定义尽管被.gitignore直接或递归忽略但仍要包含的(子)目录,然后在暂存文件时使用:

1
git add `cat .include`

常见问题

规则不生效

如果父目录被排除,就无法重新包含该目录下的文件,除非满足Git 2.8+的某些条件。另外,使用dir/dir/*有重要区别:

  • dir/排除名为dir的目录及其下的所有内容,Git不会查看dir下的任何内容,因此不会对其应用“取消排除”模式。
  • dir/*不排除dir本身,只排除dir下的所有内容,Git会处理dir的直接内容,给其他模式提供“取消排除”部分内容的机会。

旧版本Git问题

对于较旧版本的Git,很多建议可能效果不佳。这种情况下,可以在要包含内容的目录中放置一个单独的.gitignore文件,并在其中允许所需的内容。例如:

1
2
3
4
5
6
7
# /.gitignore
# 忽略所有 .dll 文件
*.dll

# /dependency_files/.gitignore
# 包含所有内容
!*

.gitignore排除文件夹但包含特定子文件夹
https://119291.xyz/posts/gitignore-exclude-folder-but-include-specific-subfolder/
作者
ww
发布于
2025年6月4日
许可协议