如何让.gitignore忽略所有子目录而不管它们的名称?

u3r8eeie  于 2023-02-07  发布在  Git
关注(0)|答案(2)|浏览(153)

我正在使用一个遗留应用程序,它在每次新用户登录时都会在源目录中创建一个新的子目录。到目前为止,它还没有受到源代码管理,所以我将它添加到Git并推送到我们公司的存储库--源代码加上几百个子目录。现在,每次我对代码进行更改并部署到生产环境时,我必须先git add自上次提交以来创建的所有子目录,然后在我可以下拉之前提交这些子目录。
所以,我的问题是,我如何命令.gitignore对 * 任何 * 子目录(旧的或新的)视而不见,除了那些与代码相关的子目录?

cs7cruho

cs7cruho1#

假设您的项目目录(我假设它也是您的存储库根目录)中有以下结构:

./
├── foo/
│   └── foo
├── bar/
│   └── baz
├── docs/
│   └── release/
│       └── 0.0.1
├── README.md
└── src/
    └── code

其中目录foo/bar/是生成结果的示例(您不想跟踪的),名称不可预测(或者难以单独地或以某种足够窄的模式显式地在.gitignore中列出),而docs/src/包含(仅)要跟踪的文件(和子目录),并且您还希望直接跟踪存储库根目录中的任何文件(例如当前的README.md)。
这可以通过存储库根目录中的以下.gitignore来实现:

# Ignore all subirectories (but not files in the repo root dir):
*/

# ... except for the actual project sub dirs:
!src/
!docs/

解释

请参阅the documentation(也可以通过git help gitignore获得)了解.gitignore中的模式如何工作以及它们如何相互作用。下面是上面解决方案中使用的模式(大部分直接复制或部分稍微修改自上述文档):
*匹配除斜杠以外的任何内容(/,它被用作目录分隔符)以及任何级别的任何目录名或文件名。这有点太宽泛了,因为我们不想忽略根目录中的文件。附加/使模式只匹配目录,因此*/匹配任何目录(在任何级别)。(忽略目录中的文件也会被忽略,因为Git不会跟踪目录本身。
所以对于*/,我们忽略了整个文件树,除了直接在根目录中的文件。
但这还是太多了,所以我们需要有选择地撤销一些忽略,我们可以通过其他模式来做到这一点:前缀! "否定"模式;由先前模式排除的任何匹配文件(此处,按*/)将再次被包括。但是,因为如果文件的父目录被排除,则不可能重新包括该文件(出于性能原因,Git不会列出被排除的目录,因此所包含文件上的任何模式都不会起作用,无论它们是在哪里定义的。docs/src/将只匹配顶级目录docssrc,而不是foo/src(如果存在的话)。

(等效)解决方案稍长,但更易于推理

上面描述的交互虽然有很好的文档记录,但对我来说似乎有些模糊,因此您可能更愿意通过预先添加/

# Ignore all subirectories (but not files in the repo root dir):
*/

# ... except for the actual source dirs:
!/src/
!/docs/

也可以用这种方式锚定第一个模式(不改变结果行为):

# Ignore all subirectories (but not files in the repo root dir):
/*/

# ... except for the actual source dirs:
!/src/
!/docs/
e5nszbig

e5nszbig2#

要忽略从给定点开始的所有子目录,只需在通配符的末尾加一个斜杠:

*/

但是,对于其他目录,这不应该阻止您进行下拉操作,除非这些目录在提交后被应用程序修改。
请注意,即使.gitignore忽略了一个文件,也可以显式地将其添加到索引中,然后提交它。在这种情况下,它将像所有其他常规文件一样被跟踪。
如果你仍然需要它们,你可能想使用git rm --cached在Git的历史记录中“从现在开始”将它们标记为已删除,而不是将它们从工作目录中删除。

相关问题