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

我有添加到.gitignore的文件夹application/。在application/文件夹内是文件夹application/language/gr。我如何包含此文件夹?

我试过这个了

application/!application/language/gr/
563740 次浏览

如果排除application/,那么它下的所有内容都将被排除在外(即使后来的一些负排除模式(“unignore”)可能与application/下的内容匹配)。

要做你想做的事情,你必须“忽略”你想“忽略”的任何东西的每个父目录。通常你最终会成对地为这种情况编写规则:忽略目录中的所有内容,但不忽略某些子目录。

# you can skip this first one if it is not already excluded by prior patterns!application/
application/*!application/language/
application/language/*!application/language/gr/

说明
后面的/*很重要:

  • 模式dir/排除了名为dir的目录和(隐式)其下的所有内容。
    使用dir/,Git将永远不会查看dir下的任何内容,因此永远不会将任何“un-排除”模式应用于dir下的任何内容。
  • 模式dir/*没有说明dir本身;它只是排除了dir下的所有内容。使用dir/*,Git将处理dir的直接内容,让其他模式有机会“取消排除”一些内容(!dir/sub/)。

@Chris Johnsen的回答很棒,但是对于较新版本的Git(1.8.2或更高版本),您可以利用双星号模式来获得更多速记解决方案:

# assuming the root folder you want to ignore is 'application'application/**/*
# the subfolder(s) you want to track:!application/language/gr/

这样,您就不必“Unignore”要跟踪的子文件夹的父目录。


在Git 2.17.0(不确定在此版本之前有多早。可能回到1.8.2)中,使用**模式与排除相结合,用于导致您的文件的每个子目录。例如:

# assuming the root folder you want to ignore is 'application'application/**
# Explicitly track certain content nested in the 'application' folder:!application/language/!application/language/gr/!application/language/gr/** # Example adding all files & folder in the 'gr' folder!application/language/gr/SomeFile.txt # Example adding specific file in the 'gr' folder

Git 1.9/2.0(Q1 2014)的Karsten Blees(kblees)中的提交59856de澄清了这种情况:

#0:澄清排除目录的递归性质

一个可选的前缀“!”,它否定了该模式;先前模式排除的任何匹配文件都将再次包含在内。

如果排除了该文件的父目录,则无法重新包含该文件。(*
*:除非在git 2.8+中满足某些条件,请参阅下文)
由于性能原因,Git没有列出排除的目录,因此包含文件上的任何模式都没有影响,无论它们在哪里定义。

在第一个“!”前面放一个反斜杠(“\”),用于以文字“!”开头的模式,例如“\!important!.txt”。

排除除特定目录foo/bar之外的所有内容的示例(注意/*-没有斜杠,通配符也将排除foo/bar中的所有内容):

 --------------------------------------------------------------$ cat .gitignore# exclude everything except directory foo/bar/*!/foo/foo/*!/foo/bar--------------------------------------------------------------

在您的案例中:

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

您必须先将文件夹列入白名单,然后才能将给定文件夹中的文件列入白名单。


2016年2月/3月更新:

请注意,在git 2.9. x/2.10(2016年中期?)中,如果该文件的父目录被排除如果重新包含的路径中没有通配符,则可能重新包含该文件。

Nguy n Thái Ng c Duy(#0)正在尝试添加此功能:

所以在git 2.9+中,这实际上可以工作,但最终被恢复了:

application/!application/language/gr/

关于这个问题有很多类似的问题,所以我将发布我之前写的内容:

我让它在我的机器上工作的唯一方法是这样做:

# Ignore all directories, and all sub-directories, and it's contents:*/*
#Now ignore all files in the current directory#(This fails to ignore files without a ".", for example#'file.txt' works, but#'file' doesn't):*.*
#Only Include these specific directories and subdirectories:!wordpress/!wordpress/*/!wordpress/*/wp-content/!wordpress/*/wp-content/themes/!wordpress/*/wp-content/themes/*!wordpress/*/wp-content/themes/*/*!wordpress/*/wp-content/themes/*/*/*!wordpress/*/wp-content/themes/*/*/*/*!wordpress/*/wp-content/themes/*/*/*/*/*

请注意,您必须显式允许要包含的每个级别的内容。因此,如果我在主题下有5个子目录,我仍然需要拼出来。

这是来自@Yarin的评论:https://stackoverflow.com/a/5250314/1696153

这些都是有用的主题:

我也试过

**/***/**

**/wp-content/themes/**

/wp-content/themes/**/*

这些对我来说都不管用。大量的试验和错误!

因此,由于许多程序员使用node。满足这个问题的用例是排除node_modules,除了一个模块module-a,例如:

!node_modules/
node_modules/*!node_modules/module-a/

只是另一个沿着目录结构走下去以获得您想要的内容的例子。注意:我没有排除Library/,而是排除了Library/**/*

# .gitignore fileLibrary/**/*!Library/Application Support/!Library/Application Support/Sublime Text 3/!Library/Application Support/Sublime Text 3/Packages/!Library/Application Support/Sublime Text 3/Packages/User/!Library/Application Support/Sublime Text 3/Packages/User/*macro!Library/Application Support/Sublime Text 3/Packages/User/*snippet!Library/Application Support/Sublime Text 3/Packages/User/*settings!Library/Application Support/Sublime Text 3/Packages/User/*keymap!Library/Application Support/Sublime Text 3/Packages/User/*theme!Library/Application Support/Sublime Text 3/Packages/User/**/!Library/Application Support/Sublime Text 3/Packages/User/**/*macro!Library/Application Support/Sublime Text 3/Packages/User/**/*snippet!Library/Application Support/Sublime Text 3/Packages/User/**/*settings!Library/Application Support/Sublime Text 3/Packages/User/**/*keymap!Library/Application Support/Sublime Text 3/Packages/User/**/*theme

> git add Library

> git status

On branch masterYour branch is up-to-date with 'origin/master'.Changes to be committed:(use "git reset HEAD <file>..." to unstage)
new file:   Library/Application Support/Sublime Text 3/Packages/User/Default (OSX).sublime-keymapnew file:   Library/Application Support/Sublime Text 3/Packages/User/ElixirSublime.sublime-settingsnew file:   Library/Application Support/Sublime Text 3/Packages/User/Package Control.sublime-settingsnew file:   Library/Application Support/Sublime Text 3/Packages/User/Preferences.sublime-settingsnew file:   Library/Application Support/Sublime Text 3/Packages/User/RESTer.sublime-settingsnew file:   Library/Application Support/Sublime Text 3/Packages/User/SublimeLinter/Monokai (SL).tmThemenew file:   Library/Application Support/Sublime Text 3/Packages/User/TextPastryHistory.sublime-settingsnew file:   Library/Application Support/Sublime Text 3/Packages/User/ZenTabs.sublime-settingsnew file:   Library/Application Support/Sublime Text 3/Packages/User/adrian-comment.sublime-macronew file:   Library/Application Support/Sublime Text 3/Packages/User/json-pretty-generate.sublime-snippetnew file:   Library/Application Support/Sublime Text 3/Packages/User/raise-exception.sublime-snippetnew file:   Library/Application Support/Sublime Text 3/Packages/User/trailing_spaces.sublime-settings

我发现只有这个实际上有效。

**/node_modules/*!**/node_modules/keep-dir

特别是对于较旧的Git版本,大多数建议都不会那么好。如果是这种情况,我会在目录中放置一个单独的. gitignore,无论其他设置如何,我都希望包含内容,并允许有需要的内容。

例如:/.gitignore

# ignore all .dll files*.dll

/dependency_files/.gitignore

# include everything!*

因此, /dependency_files中的所有内容(甚至. dll文件)都包含得很好。

我在这里发现了类似的情况,默认情况下,在laravel中,.gitignore忽略所有使用asterix的内容,然后覆盖公共目录。(这也是与主答案@Chris Johnsen相同的解决方案,只是可能更薄,更简洁。)

*!public!.gitignore

如果您运行OP场景,这是不够的。

如果您想提交public的特定子文件夹,例如在您的public/products目录中,您想包含一个子文件夹深度的文件,例如包含public/products/a/b.jpg,它们不会被正确检测到,即使您像这样专门添加它们!/public/products!public/products/*等。

解决方案是确保为每个路径级别添加一个条目,以覆盖所有路径级别。

*!.gitignore!public/!public/*/!public/products/!public/products/*!public/products/*/!public/products/*/!public/products/*/*

我想跟踪jQuery生产js文件,这起作用了:

node_modules/*!node_modules/jquerynode_modules/jquery/*!node_modules/jquery/dist/*

在WordPress中,这帮助了我:

wp-admin/wp-includes//wp-content/*!wp-content/plugins//wp-content/plugins/*!/wp-content/plugins/plugin-name/!/wp-content/plugins/plugin-name/*.*!/wp-content/plugins/plugin-name/**

我经常在CLI中使用这种解决方法,而不是配置我的.gitignore,我创建了一个单独的#1文件,在该文件中我定义了我想要包含的(子)目录,尽管目录直接或递归地被.gitignore忽略。

因此,我还使用

git add `cat .include`

在提交之前。

对于OP,我建议使用.include,其中包含以下行:

<parent_folder_path>/application/language/gr/*

注意:使用cat不允许使用别名(在.include内)来指定$HOME(或任何其他特定目录)。这是因为行homedir/app1/*当使用上述命令传递给git add时,显示为git add 'homedir/app1/*',并且将字符括在单引号(")中会保留引号中每个字符的文字值,从而防止别名(例如homdir)发挥作用(参见Bash单引号)。

这是我在repo这里中使用的.include文件的示例。

/home/abhirup/token.txt/home/abhirup/.include/home/abhirup/.vim/*/home/abhirup/.viminfo/home/abhirup/.bashrc/home/abhirup/.vimrc/home/abhirup/.condarc

添加一个额外的答案:

!/.vs/              <== include this folder to source control, folder only, nothing else/.vs/*              <== but ignore all files and sub-folder inside this folder!/.vs/ProjectSettings.json <== but include this file to source control!/.vs/config/       <== then include this folder to source control, folder only, nothing else!/.vs/config/*      <== then include all files inside the folder

这里是结果:

在此处输入图片描述

gitignore-指定要忽略的有意未跟踪的文件。

排除除特定目录foo/bar之外的所有内容的示例(注意/*-没有斜杠,通配符也将排除foo/bar中的所有内容):

$ cat .gitignore# exclude everything except directory foo/bar/*!/foo/foo/*!/foo/bar

WordPress的另一个例子:

!/wp-contentwp-content/*!/wp-content/pluginswp-content/plugins/*!wp-content/plugins/my-awesome-plugin

更多信息在这里:https://git-scm.com/docs/gitignore

最简单也可能是最好的方法是尝试手动添加文件(通常这优先于.gitignore样式规则):

git add /path/to/module

如果文件已经被忽略,您可能需要-f。您甚至可能想要-N打算增加标志,建议您添加它们,但不是立即添加。我经常对我还没有准备好阶段的新文件这样做。


这是一个答案的副本发布在很容易重复的QA上。我在这里重新发布它以增加可见性-我发现没有一堆gitignore规则更容易。

我的JetBrains IntelliJ IDEA. gitignore配置,我需要排除wholde.idea文件夹,除了.idea/runConfigurations

.idea!.idea/.idea/*!.idea/runConfigurations/

见:https://github.com/daggerok/gitignore-idea-runConfigurations

这对我有效:

**/.idea/**!**/.idea/copyright/!.idea/copyright/profiles_settings.xml!.idea/copyright/Copyright.xml

我想跟踪位于/etc/nagios/中的Nagios配置文件以及/usr/lib64/nagios/plugins/中的插件。为此,我在/中初始化了一个git存储库并使用了以下排除列表:

/*!etcetc/*!etc/nagios!usrusr/*!usr/lib64usr/lib64/*!usr/lib64/nagiosusr/lib64/nagios/*!usr/lib64/nagios/plugins

Git像这样沿着列表走:

/*             exclude everything under / ...!etc           but include /etc backetc/*             exclude everything under /etc/...!etc/nagios       but include /etc/nagios back!usr           but include /usr backusr/*             exclude everything under /usr/...and so on...

将名为.gitignore的文件添加到子文件夹,然后填写

!/Bin/

这对我有用!

这一评论类似,没有一个解决方案和模式适合我;强制git添加应该排除的文件和文件夹,有效:

git add -f .