我怎样才能排除除所有顶级点文件和子目录之外的所有内容?
How can I exclude everything but all top-level dot files and a subdirectory?
在使用 Git 跟踪我的基本配置文件时,我在编写 .gitignore 文件时遇到了问题。
我的目标是在我的存储库中包含两件事:
- 我的用户目录
~/
中的所有点文件,这是我的 gitroot。
- 隐藏文件夹
~/.vim/bundle
到目前为止,我已经尝试了以下方法,但无济于事。
.gitignore:
# Ignore everything
*
# Include top-level dot files.
!/.*
# Include vim plugins
!/.vim/bundle/*
这只会在我的 gitroot 中暂存点文件。
注.
我的gitroot是我的用户目录~/
.
更新
在下面的表格中,~/.vim
文件夹是暂存的:
# Ignore everything
*
# Include top-level dot files.
!/.*
# Include vim plugins
!/.vim
所以,我猜我应该以某种方式表达路径名 /.vim/bundle
。
前导斜杠表示相对于gitroot的绝对路径;将其删除到 select 所有点文件。
# Ignore everything
*
# Include all dot files.
!.*
# Include vim plugins
!/.vim/bundle/*
Here is 带有示例的方便简洁的参考。
您需要暂存然后提交 .gitignore
以使更改生效。令人高兴的是,您可以重复 git commit --amend
进行进一步的更改,以保持历史记录干净,直到您拥有想要的内容。
作为一个模糊相关的旁白,我经常看到人们试图将 "a folder of name folder
anywhere in the project" 与 /folder
匹配,而应该是 **/folder
.
我受到 this answer 的启发,编写了以下足够的 .gitignore
文件。 :)
# We use a whitelisting approach to track certain configuration files.
# Apparently, this needs to be done recursively because git can't see past a directory that is not
# included. Hence, if we want to include a subdirectory, we first need to include its upper
# directory, by the whitelisting procedure as shown below.
# Exclude all files and non-hidden directories.
/*
# Include all dotfiles.
!.*
# Exclude all hidden directories.
.*/
# Include the upper directory.
!/.vim
# Exclude all files and non-hidden directories.
/.vim/*
# Include the vim plugins.
!/.vim/bundle
TL;DR
您正在 运行 进行优化,这会破坏您的用例:一旦 Git 决定不查看目录内部,它永远不会在 [=] 中找到 文件116=] 它将添加的那个目录。要修复它,您至少需要一个规则:
!/.vim/bundle/
您可以使用不同的规则来击败所有优化:
!*/
这也应该可以解决问题(以更深入的搜索为代价,这会导致速度很慢)。
长
你有一个好的开始,但是你 运行 进入了一个有问题的优化(我认为 Git 的人正在尝试修复)。我们还必须假设您的 index(也称为临时区域)中当前的内容,因为索引内容会影响 Git 扫描目录的方式。让我们假设您的索引确实是空的,因为它会在 git init
-ing 一个新的存储库之后。这样,由于不存在现有索引条目,它们不会影响 Git 的正常目录扫描过程。
假设您的工作树包含名为 README
和 .profile
的文件,以及名为 d/
和 .vim/
的目录。您的 .gitignore
有三个规则。第一个是肯定规则 ("do ignore"),第二个和第三个是否定规则 ("don't ignore")。规则本身减去 !
是:
*
/.*
/.vim/bundle/*
现在,当 Git 处理 README
时,它首先检查匹配的 *
,然后检查不匹配的 /.*
,然后检查 /.vim/bundle/*
这也不匹配。最后一个匹配规则生效:即 *
表示 "do ignore" 所以 README
将被忽略。另一方面,文件 .profile
是前两条规则,所以第二条适用,它说 !
所以 .profile
未被跟踪但不会被忽略:git status
将发牢骚,git add .
会将其添加到索引中。
现在让我们考虑如何处理 d/
和 .vim/
。这些是目录,而不是文件:Git 不会保存它们,但它可能会或可能不会保存 在 中的文件。为此,它必须读取并检查其中的所有文件名。这非常昂贵,因此 Git 将首先尝试 跳过 整个目录。这就是我提到的有问题的优化。
无论如何,d/
匹配第一个规则,但不匹配其他两个。这意味着 Git 可以 完全跳过阅读 d/
。 git status
不会抱怨它并且 git add
不会扫描它。
到目前为止我们都很好。 .vim/
匹配第二条规则(但不是第三条)所以 Git 会在 .vim
.
里面查找
假设 .vim/
包含 .netrwhist
、after/
、bundle/
,也许还有一些其他目录。 .netrwhist
匹配 *
,不匹配 /.*
,不匹配 /.vim/bundle/*
,因此应用 *
匹配并被忽略。 after/
目录匹配 *
,不匹配 /.*
,也不匹配 /.vim/bundle/*
,因此未读。
现在我们遇到了问题:.vim/bundle/
是一个目录。 Git 根据您的 .gitignore
指令检查此路径名。 bundle/
匹配 *
。 .vim/bundle
与 /.*
不匹配,因为这意味着 顶级文件 ; .vim/bundle/
是目录,不在顶层。该路径也不匹配第三个指令 /.vim/bundle/*
,它要求这是 .vim/bundle/
内的文件或目录。所以 唯一匹配的指令是第一个,而 .vim/bundle
未读 就像 d/
一样。
这意味着 Git 从未在 .vim/bundle/
中找到任何文件或目录 。它从不根据任何内容检查文件(如果有的话),也从不扫描子目录以查找更多文件。您需要强制 Git 查看 .vim/bundle/
.
索引中的条目变化很大
如果索引中有一些路径名为.vim/bundle/a/b
的文件,Git将不得不扫描目录.vim/bundle/a
。所以放置在那里的任何 new 文件都会显示出来!我不确定在这种情况下 Git 是否会跳过 .vim/bundle/
本身(理论上它可以,但我认为实际上不会)。一旦您在索引中有了文件路径,该文件就会被 跟踪 并且它在任何 .gitignore
中的存在变得无关紧要。
但是请注意,索引 now 中的文件不一定在索引 tomorrow 中,如果您删除它们或如果您检查其他一些不存在这些文件的提交。整个事情有点棘手。
在使用 Git 跟踪我的基本配置文件时,我在编写 .gitignore 文件时遇到了问题。
我的目标是在我的存储库中包含两件事:
- 我的用户目录
~/
中的所有点文件,这是我的 gitroot。 - 隐藏文件夹
~/.vim/bundle
到目前为止,我已经尝试了以下方法,但无济于事。
.gitignore:
# Ignore everything
*
# Include top-level dot files.
!/.*
# Include vim plugins
!/.vim/bundle/*
这只会在我的 gitroot 中暂存点文件。
注.
我的gitroot是我的用户目录~/
.
更新
在下面的表格中,~/.vim
文件夹是暂存的:
# Ignore everything
*
# Include top-level dot files.
!/.*
# Include vim plugins
!/.vim
所以,我猜我应该以某种方式表达路径名 /.vim/bundle
。
前导斜杠表示相对于gitroot的绝对路径;将其删除到 select 所有点文件。
# Ignore everything
*
# Include all dot files.
!.*
# Include vim plugins
!/.vim/bundle/*
Here is 带有示例的方便简洁的参考。
您需要暂存然后提交 .gitignore
以使更改生效。令人高兴的是,您可以重复 git commit --amend
进行进一步的更改,以保持历史记录干净,直到您拥有想要的内容。
作为一个模糊相关的旁白,我经常看到人们试图将 "a folder of name folder
anywhere in the project" 与 /folder
匹配,而应该是 **/folder
.
我受到 this answer 的启发,编写了以下足够的 .gitignore
文件。 :)
# We use a whitelisting approach to track certain configuration files.
# Apparently, this needs to be done recursively because git can't see past a directory that is not
# included. Hence, if we want to include a subdirectory, we first need to include its upper
# directory, by the whitelisting procedure as shown below.
# Exclude all files and non-hidden directories.
/*
# Include all dotfiles.
!.*
# Exclude all hidden directories.
.*/
# Include the upper directory.
!/.vim
# Exclude all files and non-hidden directories.
/.vim/*
# Include the vim plugins.
!/.vim/bundle
TL;DR
您正在 运行 进行优化,这会破坏您的用例:一旦 Git 决定不查看目录内部,它永远不会在 [=] 中找到 文件116=] 它将添加的那个目录。要修复它,您至少需要一个规则:
!/.vim/bundle/
您可以使用不同的规则来击败所有优化:
!*/
这也应该可以解决问题(以更深入的搜索为代价,这会导致速度很慢)。
长
你有一个好的开始,但是你 运行 进入了一个有问题的优化(我认为 Git 的人正在尝试修复)。我们还必须假设您的 index(也称为临时区域)中当前的内容,因为索引内容会影响 Git 扫描目录的方式。让我们假设您的索引确实是空的,因为它会在 git init
-ing 一个新的存储库之后。这样,由于不存在现有索引条目,它们不会影响 Git 的正常目录扫描过程。
假设您的工作树包含名为 README
和 .profile
的文件,以及名为 d/
和 .vim/
的目录。您的 .gitignore
有三个规则。第一个是肯定规则 ("do ignore"),第二个和第三个是否定规则 ("don't ignore")。规则本身减去 !
是:
*
/.*
/.vim/bundle/*
现在,当 Git 处理 README
时,它首先检查匹配的 *
,然后检查不匹配的 /.*
,然后检查 /.vim/bundle/*
这也不匹配。最后一个匹配规则生效:即 *
表示 "do ignore" 所以 README
将被忽略。另一方面,文件 .profile
是前两条规则,所以第二条适用,它说 !
所以 .profile
未被跟踪但不会被忽略:git status
将发牢骚,git add .
会将其添加到索引中。
现在让我们考虑如何处理 d/
和 .vim/
。这些是目录,而不是文件:Git 不会保存它们,但它可能会或可能不会保存 在 中的文件。为此,它必须读取并检查其中的所有文件名。这非常昂贵,因此 Git 将首先尝试 跳过 整个目录。这就是我提到的有问题的优化。
无论如何,d/
匹配第一个规则,但不匹配其他两个。这意味着 Git 可以 完全跳过阅读 d/
。 git status
不会抱怨它并且 git add
不会扫描它。
到目前为止我们都很好。 .vim/
匹配第二条规则(但不是第三条)所以 Git 会在 .vim
.
假设 .vim/
包含 .netrwhist
、after/
、bundle/
,也许还有一些其他目录。 .netrwhist
匹配 *
,不匹配 /.*
,不匹配 /.vim/bundle/*
,因此应用 *
匹配并被忽略。 after/
目录匹配 *
,不匹配 /.*
,也不匹配 /.vim/bundle/*
,因此未读。
现在我们遇到了问题:.vim/bundle/
是一个目录。 Git 根据您的 .gitignore
指令检查此路径名。 bundle/
匹配 *
。 .vim/bundle
与 /.*
不匹配,因为这意味着 顶级文件 ; .vim/bundle/
是目录,不在顶层。该路径也不匹配第三个指令 /.vim/bundle/*
,它要求这是 .vim/bundle/
内的文件或目录。所以 唯一匹配的指令是第一个,而 .vim/bundle
未读 就像 d/
一样。
这意味着 Git 从未在 .vim/bundle/
中找到任何文件或目录 。它从不根据任何内容检查文件(如果有的话),也从不扫描子目录以查找更多文件。您需要强制 Git 查看 .vim/bundle/
.
索引中的条目变化很大
如果索引中有一些路径名为.vim/bundle/a/b
的文件,Git将不得不扫描目录.vim/bundle/a
。所以放置在那里的任何 new 文件都会显示出来!我不确定在这种情况下 Git 是否会跳过 .vim/bundle/
本身(理论上它可以,但我认为实际上不会)。一旦您在索引中有了文件路径,该文件就会被 跟踪 并且它在任何 .gitignore
中的存在变得无关紧要。
但是请注意,索引 now 中的文件不一定在索引 tomorrow 中,如果您删除它们或如果您检查其他一些不存在这些文件的提交。整个事情有点棘手。