我知道.gitignore文件隐藏Git版本控制中的指定文件。

我如何告诉.gitignore忽略除我使用Git跟踪的文件之外的所有内容?类似于:

# Ignore everything:
*

# Do not ignore these files:
script.pl
template.latex

当前回答

这是一场灾难,在使用git 16年(2005年)之后,没有一种简单而明显的方法来排除位于目录层次结构深处的一个文件,否则应该忽略它。相反,我们需要采取疯狂的做法,比如反复挖掘结构,并以正确的顺序排除和包含目录。一年中你需要记住4次,这是不可能的。

唯一聪明但非常奇怪的选择是使用git add--force。当你不单独处理gitted回购协议时,某些事情注定会失败。

所以我编写了一个小bash函数来修复这个问题,以便于复制粘贴。让我先解释一下一行:

f=0; y='';for x in $(echo "uploads/rubbish/stuff/KEEP_ME/a.py" | tr '\/' '\n'); do y="$y/$x"; if [ $(($f)) -eq 0 ]; then y="$x"; f=1; fi; echo -e '!'"$y/\n$y/*"; done | sed '$d' |sed -z 's/..$//'; echo;

# output:
!uploads/
uploads/*
!uploads/rubbish/
uploads/rubbish/*
!uploads/rubbish/stuff/
uploads/rubbish/stuff/*
!uploads/rubbish/stuff/KEEP_ME/
uploads/rubbish/stuff/KEEP_ME/*
!uploads/rubbish/stuff/KEEP_ME/a.py

描述

有一个if语句用于调整第一个未获得/的项目。tr'\/''\n'-在标准POSIX路径中\n转换/to(以获取列表)y=“$y/$x”-在上一个目录之后添加下一个子目录(在列表中)。echo-e'!'“$y/\n$y/*”-打印2行子目录项,第一行用!前缀,第二个带/*后缀。sed“$d”-删除最后一行sed-z的/..$//'-从最后一行删除最后2个字符/*

然后我们创建函数:

function gitkeep () { f=0; y='';for x in $(echo "$1" | tr '\/' '\n'); do y="$y/$x"; if [[ f -eq 0 ]]; then y="$x"; f=1; fi; echo -e '!'"$y/\n$y/*"; done | sed '$d' |sed -z 's/..$//'; echo; }

# gitkeep "uploads/rubbish/stuff/KEEP_ME/a"

!uploads/
uploads/*
!uploads/rubbish/
uploads/rubbish/*
!uploads/rubbish/stuff/
uploads/rubbish/stuff/*
!uploads/rubbish/stuff/KEEP_ME/
uploads/rubbish/stuff/KEEP_ME/*
!uploads/rubbish/stuff/KEEP_ME/a

这里,我将算术if语句简化为if[[f-eq 0]];。

享受

其他回答

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

我在机器上实现这一点的唯一方法是这样做:

# 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 and files if you wish:
!wordpress/somefile.jpg
!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

这些是有用的主题:

否定模式如何在.gitignore中工作?gitignore排除规则实际上是如何工作的?

我也试过了

*
*/*
**/**

和**/wp内容/主题/**

或/wp内容/主题/**/*

这一切对我来说都不起作用。很多线索和错误!

让我们工具化!

正如@Joakim所说,要忽略文件,可以使用下面的方法。

# Ignore everything
*

# But not these files...
!.gitignore
!someFile.txt

但是如果文件位于嵌套目录中,那么编写这些规则有点困难。

例如,如果我们希望跳过所有文件,但不跳过位于aDir/aotherDir/someOtherDir/aDir/bDir/cDir中的.txt文件。那么,我们的.gitignore将是这样的

# Skip all files
*

# But not `aDir/anotherDir/someOtherDir/aDir/bDir/cDir/a.txt`
!aDir/
aDir/*
!aDir/anotherDir/
aDir/anotherDir/*
!aDir/anotherDir/someOtherDir/
aDir/anotherDir/someOtherDir/*
!aDir/anotherDir/someOtherDir/aDir/
aDir/anotherDir/someOtherDir/aDir/*
!aDir/anotherDir/someOtherDir/aDir/bDir/
aDir/anotherDir/someOtherDir/aDir/bDir/*
!aDir/anotherDir/someOtherDir/aDir/bDir/cDir/
aDir/anotherDir/someOtherDir/aDir/bDir/cDir/*
!aDir/anotherDir/someOtherDir/aDir/bDir/cDir/a.txt

这很难用手写。

为了解决这个问题,我创建了一个名为git do not ignore的web应用程序,它将为您生成规则。

Tool

https://theapache64.github.io/git-do-not-ignore/

Demo

样本输入

aDir/anotherDir/someOtherDir/aDir/bDir/cDir/a.txt

样本输出

!aDir/
aDir/*
!aDir/anotherDir/
aDir/anotherDir/*
!aDir/anotherDir/someOtherDir/
aDir/anotherDir/someOtherDir/*
!aDir/anotherDir/someOtherDir/aDir/
aDir/anotherDir/someOtherDir/aDir/*
!aDir/anotherDir/someOtherDir/aDir/bDir/
aDir/anotherDir/someOtherDir/aDir/bDir/*
!aDir/anotherDir/someOtherDir/aDir/bDir/cDir/
aDir/anotherDir/someOtherDir/aDir/bDir/cDir/*
!aDir/anotherDir/someOtherDir/aDir/bDir/cDir/a.txt

这是一场灾难,在使用git 16年(2005年)之后,没有一种简单而明显的方法来排除位于目录层次结构深处的一个文件,否则应该忽略它。相反,我们需要采取疯狂的做法,比如反复挖掘结构,并以正确的顺序排除和包含目录。一年中你需要记住4次,这是不可能的。

唯一聪明但非常奇怪的选择是使用git add--force。当你不单独处理gitted回购协议时,某些事情注定会失败。

所以我编写了一个小bash函数来修复这个问题,以便于复制粘贴。让我先解释一下一行:

f=0; y='';for x in $(echo "uploads/rubbish/stuff/KEEP_ME/a.py" | tr '\/' '\n'); do y="$y/$x"; if [ $(($f)) -eq 0 ]; then y="$x"; f=1; fi; echo -e '!'"$y/\n$y/*"; done | sed '$d' |sed -z 's/..$//'; echo;

# output:
!uploads/
uploads/*
!uploads/rubbish/
uploads/rubbish/*
!uploads/rubbish/stuff/
uploads/rubbish/stuff/*
!uploads/rubbish/stuff/KEEP_ME/
uploads/rubbish/stuff/KEEP_ME/*
!uploads/rubbish/stuff/KEEP_ME/a.py

描述

有一个if语句用于调整第一个未获得/的项目。tr'\/''\n'-在标准POSIX路径中\n转换/to(以获取列表)y=“$y/$x”-在上一个目录之后添加下一个子目录(在列表中)。echo-e'!'“$y/\n$y/*”-打印2行子目录项,第一行用!前缀,第二个带/*后缀。sed“$d”-删除最后一行sed-z的/..$//'-从最后一行删除最后2个字符/*

然后我们创建函数:

function gitkeep () { f=0; y='';for x in $(echo "$1" | tr '\/' '\n'); do y="$y/$x"; if [[ f -eq 0 ]]; then y="$x"; f=1; fi; echo -e '!'"$y/\n$y/*"; done | sed '$d' |sed -z 's/..$//'; echo; }

# gitkeep "uploads/rubbish/stuff/KEEP_ME/a"

!uploads/
uploads/*
!uploads/rubbish/
uploads/rubbish/*
!uploads/rubbish/stuff/
uploads/rubbish/stuff/*
!uploads/rubbish/stuff/KEEP_ME/
uploads/rubbish/stuff/KEEP_ME/*
!uploads/rubbish/stuff/KEEP_ME/a

这里,我将算术if语句简化为if[[f-eq 0]];。

享受

我的子文件夹有问题。

不工作:

/custom/*
!/custom/config/foo.yml.dist

作品:

/custom/config/*
!/custom/config/foo.yml.dist

我把它搞定了

# Vendor
/vendor/braintree/braintree_php/*
!/vendor/braintree/braintree_php/lib