gitignore:忽略文件夹层次结构中除一种特定文件类型之外的所有文件

发布于 2024-12-10 05:25:31 字数 614 浏览 0 评论 0 原文

我想忽略文件夹下面和文件夹中的所有文件,但可能位于文件夹层次结构中某处的特定文件类型除外:

示例

/Test
/Test/unknown/folder/structure/below

现在我想忽略 Test 文件夹中及其下面的所有文件,除了某个名为 layout.css 的 css 文件,例如:

/Test/layout.css
/Test/fileto.ignore
/Test/another/folder/ig.nore
/Test/in/a/unknown/folder/layout.css
/Test/in/a/unknown/folder/ignore.me

.gitignore 应该忽略

/Test/fileto.ignore
/Test/another/folder/ig.nore
/Test/in/a/unknown/folder/ignore.me

我的 .gitignore 文件不起作用:

Test/
!layout.css

有什么建议吗?

I'd like to ignore all files below and in a folder except a specific filetype that could be somewhere in the folders hierarchy:

Example

/Test
/Test/unknown/folder/structure/below

Now I'd like to ignore all files in and below the Test folder except a certain css file named layout.css, e.g.:

/Test/layout.css
/Test/fileto.ignore
/Test/another/folder/ig.nore
/Test/in/a/unknown/folder/layout.css
/Test/in/a/unknown/folder/ignore.me

.gitignore should ignore

/Test/fileto.ignore
/Test/another/folder/ig.nore
/Test/in/a/unknown/folder/ignore.me

My .gitignore file does not work:

Test/
!layout.css

Any suggestions?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

紫轩蝶泪 2024-12-17 05:25:31

我可以通过将包含以下内容的 .gitignore 文件放入 Test/ 目录中来使您的示例正常工作。

*
!*/
!.gitignore
!layout.css

I was able to get your example to work by putting a .gitignore file in the Test/ directory with the following contents.

*
!*/
!.gitignore
!layout.css
淡紫姑娘! 2024-12-17 05:25:31

这是一个相当老的问题,但由于我现在仍在努力解决这个问题,我想我会分享该问题的实际解决方案。

问题是,虽然您不能在 Git 中提交空目录,就好像它们被忽略一样,但此规则不适用于 .gitignore

来自 https://git-scm.com/docs/gitignore

尾随的“/*”匹配里面的所有内容。例如,“abc/*
匹配目录“abc”内相对于位置的所有文件
.gitignore 文件,具有无限深度。

斜杠后跟两个连续的星号,然后斜杠匹配
零个或多个目录。例如,“a/**/b”匹配“a/b”,
“a/x/b”、“a/x/y/b”等等。

** 匹配里面的所有内容 - 字面上的所有内容 - 文件和目录。

这引出了 gitignore 文档中的另一点:

可选前缀“!”这否定了模式;任何匹配的文件
被先前模式排除的将再次被包含。 这不是
如果该文件的父目录是,则可以重新包含该文件
已排除。
Git 不会列出出于性能原因排除的目录
原因,因此包含文件上的任何模式都没有效果,无论
它们的定义位置。在第一个前面加一个反斜杠(“”)
“!”对于以文字“!”开头的模式,例如,
“!重要!.txt”。

如果模式以斜杠结尾,则出于以下目的将其删除
以下描述,但它只会找到与
目录。换句话说, foo/ 将匹配目录 foo 和路径
在其下方,但不会匹配常规文件或符号链接
foo (这与 pathspec 通常的工作方式一致
git)。

现在,假设我们有以下 dir 结构:

/path/to/git/repo
|-- .gitignore
|-- /cache
    |-- somefile
    |-- README    
    |-- /dir
        |-- somefile2
        |-- README

我们想要忽略 cache/ 中除 README 文件之外的所有文件。

如果我们像这样指定 gitignore:

/cache/**
!README

Git 将忽略除 /cache/README 之外的所有内容。另一个 README 不会显示,因为它的目录 /cache/dir/cache/** 排除,并且 !README 不会显示甚至适用于它。
为了解决这个问题,我们需要指定 gitignore 如下:

# Ignore everything inside cache/ dir
/cache/**
# Except for subdirectories(won't be commited anyway if there is no commited file inside)
!/cache/**/
# And except for README files
!README

Quite an old question, but since I was struggling with this issue even now, I figured I would share the actual solution to the problem.

The thing is, while you cannot commit empty directories in Git as if they were ignored, this rule does not apply to .gitignore.

From https://git-scm.com/docs/gitignore

A trailing "/*" matches everything inside. For example, "abc/*"
matches all files inside directory "abc", relative to the location of
the .gitignore file, with infinite depth.

A slash followed by two consecutive asterisks then a slash matches
zero or more directories. For example, "a/**/b" matches "a/b",
"a/x/b", "a/x/y/b" and so on.

** Matches everything inside - literally everything - files AND directories.

This leads us to another point in gitignore docs:

An optional prefix "!" which negates the pattern; any matching file
excluded by a previous pattern will become included again. It is not
possible to re-include a file if a parent directory of that file is
excluded.
Git doesn’t list excluded directories for performance
reasons, so any patterns on contained files have no effect, no matter
where they are defined. Put a backslash ("") in front of the first
"!" for patterns that begin with a literal "!", for example,
"!important!.txt".

If the pattern ends with a slash, it is removed for the purpose of the
following description, but it would only find a match with a
directory. In other words, foo/ will match a directory foo and paths
underneath it, but will not match a regular file or a symbolic link
foo (this is consistent with the way how pathspec works in general in
Git).

Now, let's say we have a following dir structure:

/path/to/git/repo
|-- .gitignore
|-- /cache
    |-- somefile
    |-- README    
    |-- /dir
        |-- somefile2
        |-- README

And we want to ignore all files inside cache/ except for README files.

If we specify gitignore like this:

/cache/**
!README

Git will ignore everything except for /cache/README. The other README won't show up because its directory /cache/dir was excluded with /cache/** and !README won't even apply to it.
To solve the issue we need to specify gitignore as this:

# Ignore everything inside cache/ dir
/cache/**
# Except for subdirectories(won't be commited anyway if there is no commited file inside)
!/cache/**/
# And except for README files
!README
权谋诡计 2024-12-17 05:25:31

为了实现您想要的目标,您需要使用一些否定排除。

基本思想是您需要排除您想要忽略的任何文件的每个父目录。

因此,如果您希望将 /Test/in/a/unknown/folder/layout.css 添加到您的 git 存储库中,那么您必须取消忽略 /Test/、/Test/in/、/Test/in/a /、/Test/in/a/unknown/ 和 /Test/in/a/unknown/folder/。

然后,当您最终到达包含一些被忽略的文件和一些未被忽略的文件的目录时,您需要单独指定每个文件,如下所示:

# Fille: .gitignore
!Test/
Test/*
!Test/layout.css
Test/fileto.ignore
!Test/another/
Test/another/*
!Test/another/folder/
Test/another/folder/*
!Test/in/
Test/in/*
!Test/in/a/
Test/in/a/*
!Test/in/a/unknown/
Test/in/a/unknown/*
!Test/in/a/unknown/folder/
Test/in/a/unknown/folder/ignore.me
!Test/in/a/unknown/folder/layout.css

因此,当您运行 $ git add-all 时,您将看到您想要的结果:

$ git status
On branch master

Initial commit

Changes to be committed:
  (use "git rm --cached <file>..." to unstage)

    new file:   .gitignore
    new file:   Test/in/a/unknown/folder/layout.css
    new file:   Test/layout.css

注意:您可以在 git add-all 是将文件添加到 git 存储库的最佳方式的解释。 href="http://lexsheehan.blogspot.com/2014/05/git-add-update.html" rel="noreferrer">http://lexsheehan.blogspot.com/2014/05/git-add-update .html

In order to accomplish what you want, you'll need to use some negative exclusions.

The basic idea is that you need to exclude every parent directory of any file that you want unignored.

So, if you want /Test/in/a/unknown/folder/layout.css to be added to your git repo, then you'll have to unignore /Test/, /Test/in/, /Test/in/a/, /Test/in/a/unknown/, and /Test/in/a/unknown/folder/.

Then, when you finally get to the directory with some ignored and some unignored files, you'll need to specify each individually as follows:

# Fille: .gitignore
!Test/
Test/*
!Test/layout.css
Test/fileto.ignore
!Test/another/
Test/another/*
!Test/another/folder/
Test/another/folder/*
!Test/in/
Test/in/*
!Test/in/a/
Test/in/a/*
!Test/in/a/unknown/
Test/in/a/unknown/*
!Test/in/a/unknown/folder/
Test/in/a/unknown/folder/ignore.me
!Test/in/a/unknown/folder/layout.css

So when you run $ git add-all you'll see your desired results:

$ git status
On branch master

Initial commit

Changes to be committed:
  (use "git rm --cached <file>..." to unstage)

    new file:   .gitignore
    new file:   Test/in/a/unknown/folder/layout.css
    new file:   Test/layout.css

Note: You can find an explanation of why git add-all is the best way to add files to a git repo at http://lexsheehan.blogspot.com/2014/05/git-add-update.html

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文