我正在使用Eclipse(这可能无关紧要),并且想从提交中排除Maven目标文件夹。
有lots个符号
/target/**
*/target/*
/target/**
target/
/target/
有什么区别?
它们每个的确切含义是什么?
答案 0 :(得分:3)
TL; DR:您可能想要/target/
。
让我们从工作树的清晰定义开始(从the gitglossary开始,其拼写为working tree):
实际签出文件的树。工作树通常包含HEAD提交树的内容,以及您已进行但尚未提交的所有本地更改。
我们需要记住,Git存储的内容以及与其他Git存储库的交换是 commits 。每次提交都会永久冻结一些文件集,以便您将来可以随时告诉Git 让我提交a123456...
并从那时起取回所有文件您已提交a123456...
。 (每个提交都有一个唯一的,笨拙的哈希ID,就像这样,您将在git log
输出和其他地方看到该ID。)
提交中的文件以特殊的,仅Git的,压缩的,重复数据消除的和只读的形式存储。我喜欢将这些文件称为“冻干”。它们实际上 不能更改。因此,它们适合存档,但对于完成任何实际的工作完全没有用。因此,Git需要能够提取任何给定的提交,将冻干的文件“补水”,然后将其转换为可以查看,使用和使用的普通日常文件。放置这些文件的位置是工作树或工作树。
工作树当然有一个顶层目录(或文件夹,如果您更喜欢该术语),在其中存储各种文件,包括主.gitignore
文件。该顶级目录可以具有子目录(子文件夹),并且每个子文件夹也可以具有自己的.gitignore
文件。例如,当您询问/target
与target
时,这一点很重要。
.gitignore
文件中的条目可以采用以下任何形式:
name
(没有特殊字符,例如*
)name.*
或*.txt
甚至name*txt
folder/
folder/*
folder/name
folder/name*txt
或任何这些变体folder/subfolder/
folder/subfolder/*
/name
或/folder/
或/folder/name
!
作为前缀,例如!/folder/name
这并不是一个详尽的列表(您已经列出了其他几种形式),而是为了说明一些基本原理:
folder/name
。/name
或/folder/
,也可以嵌入两者前导斜杠和斜杠,例如/folder/name
。*
和**
。!
为前缀。 gitignore条目的规则变得非常复杂,但开始时很简单。请记住,.gitignore
可以位于工作树的顶级文件夹中,也可以位于某些子文件夹中!
folder/name
和/folder/name
的含义相同:匹配 this 文件夹中名为folder/name
的文件(或文件夹),即,包含.gitignore
文件的位置。例如,与文件sub/folder/name
不匹配。您说:
我要排除Maven目标文件夹
这需要回答一个子问题:此Maven目标文件夹在哪里?这样的文件夹只有一个,还是子文件夹中有target/
个实体?(还有一个单独的问题,就是.gitignore
指令并不完全代表人们的想法它们的意思是,您需要注意 index 中的内容,但我们将其留给另一部分。)
如果这表示:在工作树的顶层target
中不包含任何内容,但请继续并包含例如名为sub/target/file
然后您应该使用:
/target/
作为工作树顶层.gitignore
中的完整规则。由于您已经知道/target
是一个文件夹,所以它有点多余,但是它清楚地表示您想忽略文件夹中名为target
的文件夹。您的工作树的顶层。
如果这表示: build-artifacts/target/
中不包含任何内容,则可以输入:
build-artifacts/target/
或:
/build-artifacts/target/
进入顶层.gitignore
;您可以输入或:
/target/
进入build-artifacts/.gitignore
。 build-artifacts/.gitignore
中的一个需要一个斜杠,因为/target/
没有 embedded 斜杠,而顶层.gitignore
的一个不需要一个斜杠,因为它有一个嵌入式斜线。
如果在第三只手(第一只脚?)上,要求忽略 any 文件夹路径中包含 的 all 个文件> target
组件-例如,您不仅要忽略target/file
,而且要忽略sub/target/file2
和sub/target/sub2/file3
-那么您应该使用:
target/
作为您的.gitignore
条目,可能在工作树的顶层。
.gitignore
文件与您的工作树中的内容有关,但是Git不会根据您的工作树 建立新的提交。取而代之的是,Git从它调用的中间事物(即 index 或 staging area )构建新的提交。 (这两个术语指的是同一实体。)
虽然索引还具有其他作用,但它的主要作用(尤其是出于我们此处的目的)是,该索引持有您提取的原始提交中的每个文件的副本,或者是更新的副本或全新文件。也就是说,如果您提取的提交仅具有两个文件文件file1
和folder/file2
,它们的索引将分别具有file1
和{{1 }}。
索引内的副本与提交内的副本具有相同的冻干格式。区别在于您可以替换索引中的副本,也可以将其添加或删除甚至删除。也就是说,您可以运行folder/file2
在工作树中获取git add file1
的有用版本,将其冻结干燥,然后将其填充到索引中。您可以使用file1
做同样的事情,还可以放置 new 文件,例如folder/file2
或folder2/file3
。简而言之,./file4
的作用是冻结文件的工作树版本并将其填充到索引中。
当您运行git add
时,Git只需打包索引中的所有内容然后,然后从中进行新的提交。因此,这就是为什么您必须一直git commit
归档文件的原因:每次更改工作树副本时,都需要更新索引副本,否则Git不会保存新版本:Git只会重新保存再次使用旧版本。 (为了节省空间,提交保存相同版本的旧文件的提交实际上只是重复使用旧的冻干文件。之所以可以这样做是因为 这些文件已被读取-只。找到旧副本并重新使用它总是安全的,因为根据定义,Git中的所有内容都会一直冻结。只能更改索引和工作树副本!)
换句话说,您可以将索引视为建议的下一次提交。您将文件复制到其中以更新建议的下一次提交。要从提议的下一次提交中完全删除文件,请使用git add
或git rm --cached
(不带git rm
):Git将从索引中删除文件,并且也许也来自工作树,现在您建议的下一次提交完全没有文件。
文件可以位于工作树的索引/临时区域和中。这种情况一直在发生。这样的文件称为 tracked 。内容不必匹配:只是文件现在位于索引 和工作树中,这样就可以跟踪工作树文件。
如果跟踪了文件(如果现在位于索引 中),那么您对--cached
所做的任何操作都将对其完全没有影响。要使其不被跟踪,必须将其从索引中删除。
如果您从索引中删除文件-或者由于您不在之前提交中而现在不在索引中,那么该文件将被 untracked 删除。 现在,.gitignore
条目很重要。 .gitignore
条目告诉Git:
不要抱怨此文件。通常,.gitignore
会对您发牢骚,告诉您该文件未跟踪,天哪,您不应该吗? git status
吗? git add
使Git关闭该文件。
不要自动添加此文件。如果您使用.gitignore
或git add .
或类似的名称,您会告诉Git: add git add *
修改为:添加所有内容-除了,这些未被跟踪的文件也会被忽略,请不要添加这些文件! < / p>
它具有第三种效果,即在某些情况下(极少见的情况)为Git授予 clobber 工作树文件的权限,并更改{{1} }与.gitignore
和git clean
一起使用。
实际上,不应将文件命名为-x
,而应将其命名为-X
。但是谁愿意一直输入呢?因此,.gitignore
。
关于.git-dont-whine-about-these-files-and-do-not-auto-add-them-either-and-maybe-occasionally-do-clobber-or-clean-them
条目还有更多的信息,但这已经足够长(可能太长)。摘要版本为:
.gitignore
仅影响未跟踪的文件; 如果您不想要前导斜线效果,但 do 需要嵌入的斜线,则必须将忽略项分配到子目录/子目录中文件夹,或使用.gitignore
表示法(作为前导组件)来匹配任意数量的路径组件。否则,根本不需要.gitignore
。
这里不介绍:一旦Git意识到不必读取一个工作树目录,就不必再去读取它了。结果,忽略子目录通常无法取消(使用**
规则)子目录中的所有 。