理解.gitignore masking和git clean

时间:2018-01-28 10:45:20

标签: git gitignore git-clean

我真的很难理解.gitignore文件是如何工作的......

这就是我的文件的样子:

custom/history
cache
*.log
custom/modules/*/Ext
upload
sugar-cron*
custom/application/Ext
custom/Extenstion/modules/*/Ext/Language
!custom/modules/*/Language/cs_CZ.*
!custom/modules/*/Language/en_us.*
custom/Extenstion/application/Ext/Language
!custom/Extenstion/application/Ext/Language/cs_CZ.*
!custom/Extenstion/application/Ext/Language/en_US.*
.htaccess
config.php
config_override.php
files.md5

这就是我的git状态:

apache@cb772759c68a sugarcrm$ git status
# On branch master
# Untracked files:
#   (use "git add <file>..." to include in what will be committed)
#
#    LOG.txt
#    deploy_backup/
nothing added to commit but untracked files present (use "git add" to track)

所以现在我想摆脱两个未跟踪的文件,但令我惊讶的是,还删除了一大堆其他文件。

apache@cb772759c68a sugarcrm$ git clean -fd
Removing Disabled/upload:/
Removing LOG.txt
Removing custom/Extension/modules/Bugs/Ext/Language/
Removing custom/Extension/modules/Cases/Ext/Language/
Removing custom/Extension/modules/EmailAddresses/
Removing custom/Extension/modules/EmailParticipants/
Removing custom/Extension/modules/ForecastManagerWorksheets/
Removing custom/Extension/modules/ForecastWorksheets/
Removing custom/Extension/modules/Forecasts/
Removing custom/Extension/modules/Meetings/Ext/Layoutdefs/
Removing custom/Extension/modules/Meetings/Ext/WirelessLayoutdefs/
Removing custom/Extension/modules/Meetings/Ext/clients/
Removing custom/Extension/modules/ModuleBuilder/
Removing custom/Extension/modules/OutboundEmail/
Removing custom/Extension/modules/PdfManager/
Removing custom/Extension/modules/ProjectTask/Ext/Language/
Removing custom/Extension/modules/Quotas/
Removing custom/Extension/modules/Quotes/Ext/Dependencies/
Removing custom/Extension/modules/Targets/
Removing custom/Extension/modules/Tasks/Ext/Language/
Removing custom/Extension/modules/TimePeriods/
Removing custom/application/
Removing custom/install/
Removing custom/modules/Administration/
Removing custom/modules/Bugs/
Removing custom/modules/Cases/
Removing custom/modules/Contracts/
Removing custom/modules/Emails/
Removing custom/modules/HHP_Products/
Removing custom/modules/KBContents/
Removing custom/modules/Project/
Removing custom/modules/ProjectTask/
Removing custom/modules/ProspectLists/
Removing custom/modules/Prospects/
Removing custom/modules/Quotas/
Removing custom/modules/Reports/
Removing custom/modules/RevenueLineItems/
Removing custom/modules/Schedulers/
Removing custom/modules/Tags/
Removing custom/modules/Teams/
Removing custom/modules/hhp_assignment_zip/
Removing custom/modules/hhp_zipcode/
Removing custom/working/modules/Calls/
Removing custom/working/modules/Leads/clients/
Removing deploy_backup/
Removing deploy_log/
Removing dist/identity-provider/tests/docker/saml-test/config/simplesamlphp/config/
Removing vendor/sugarcrm/identity-provider/tests/docker/saml-test/config/simplesamlphp/config/

第一点 - 删除的文件未在git status之后显示,所以很明显它们是gitignore的一部分&#34; mask&#34; ...任何人都可以解释,这些文件中的任何一个如何匹配任何一个gitignore的模式?就像vendor/sugarcrm/identity-provider/tests/docker/saml-test/config/simplesamlphp/config/ ...任何人都可以帮助我建立一个擅长gitignore吗?

第二点 - 我认为.gitignore&#34;保护&#34;来自git clean的这些未版本控制的文件,git字面上不对它们采取任何操作。所以很明显它会删除它们...我怎么能在使用git clean时删除未版本控制的文件?

编辑:我把git clean和git rm混淆了,我一直在谈论git clean

编辑2:事实证明,与.gitignore不匹配的已删除目录是&#34;空&#34;毕竟。 (他们有子目录,但目录树没有任何文件......)

2 个答案:

答案 0 :(得分:3)

TL; DR

您错误地解释了git clean默认删除的内容以及-d。 (注意:我自己并不是git clean的忠实粉丝;要删除珍贵的文件太容易了。)

作为phd notes,在.gitignore中列出文件,特别是禁用,默认情况下,git clean将其清除。但是,git clean(明显)比这更复杂。我们稍后会谈到这一点。

首先,让我们解决.gitignore条目的一个特点。如果您已经知道所有这些(但似乎没有人:-)),您可以跳到下面的git clean特定部分。

  1. 永远不会忽略跟踪的文件(现在位于索引中),以便匹配.gitignore或等效文件(例如.git/info/exclude)模式是无关紧要的。

    短语位于索引现在 就是这个意思。当您使用git addgit rm --cached添加或删除文件时,会更改其跟踪状态。您还可以使用git ls-files --stage转储索引中每个文件的完整列表及其临时数据模式,哈希和stage-slot-number,或者不使用--stage来获取名称

  2. Git找到的文件(不是目录),目前不在索引中,未跟踪。 Git不存储目录,因此目录永远不会出现在索引中。 1 跟踪或未跟踪纯粹是文件的属性。

  3. 未跟踪的文件也可以是被忽略的文件。如果是这样,即使您在命令行中明确命名,git add也不会添加它(尽管您可以明确地将其命名为使用--force来添加它)。

    这意味着文件(但不是目录)属于以下三种类别之一:已跟踪,未跟踪(仅限),或未跟踪和忽略。这对git status很重要,仅适用于git clean抱怨未跟踪的文件(不是未跟踪和忽略),也是git add .的片刻。

  4. 最后,当Git正在执行完整的目录树搜索/扫描时 - 例如在.gitignore中 - 并遇到可能能够跳过的目录(其中没有跟踪文件),Git将检查目录本身是否与git status模式匹配,如果是,不在其中。这加快了这些目录上有git add -Agit add . / custom/Extenstion/application/Ext/Language !custom/Extenstion/application/Ext/Language/cs_CZ.* !custom/Extenstion/application/Ext/Language/en_US.* (例如,如果您可以忽略整个供应商树或SDK,则会非常有用)。

  5. 规则4是为什么,如果你想忽略某些目录路径下面的特定文件路径,你必须指示Git专门不忽略该目录。如果忽略该目录,Git可能永远不会在里面目录。这尤其会影响这三行:

    custom/Extenstion/application/Ext/Language

    如果您忽略了整个目录custom/Extenstion/application/Ext/Language/cs_CZ.*,Git将不会在其中查看,并且永远不会找到任何匹配custom/Extenstion/application/Ext/Language/*的文件以取消忽略它。因此,除了目录本身之外,还需要处于忽略状态:您应该将第一行更改为读取cs_CZ.*,以便Git必须查看目录内部。以en_US.*git ls-files结尾的后续行将覆盖捷克语和美国英语文件的忽略状态。

    1 事实上,他们可以出现在索引中,但只是被视为特殊情况。 git clean -d,可以显示索引内容,跳过它们。

    使用d清楚地修改规则4

    Git只有在为空的情况下才能删除目录。这是一个通用的操作系统强制规则:如果目录d/f1包含一些文件d/f2d等,您将删除d而不删除文件首先,您遇到了文件问题。系统强制您首先删除目录中的文件。这也适用于子目录:如果d/sub存在,即使d/sub本身是空目录,也无法删除git clean 只能移除空目录。

    在没有-d的情况下运行custom/Extenstion/application/Ext/Language不仅会保留规则4,而且实际上扩展它。例如,在我们开始的例子中,Git注意到(1)custom/Extenstion/application/Ext/Language是一个目录; (2)目录匹配忽略模式;所以(3)如果git clean中没有文件已经被跟踪,Git可以并且将跳过整个目录(当然不会删除它,因为-d正在运行而没有xyzzy/)。

    假设另一个名为git clean的目录没有列在索引中的文件。此目录可能完全为空。在这种情况下,根据定义,其中没有未跟踪的文件;所以-d没有git clean应该对此无效。或者它可能有文件;根据定义,这些文件未被跟踪(因此可能未被跟踪和忽略),但您说不要删除目录,因此git status 仍然甚至无法查看内部。这是一个有点奇怪的情况: Git经常无法查看未知目录。 2 (你看到{{ 1}}:你必须使用git status -uall在神秘目录中找到文件。但git add -Agit add .必须向内看,除非该目录被忽略,这就是规则4在一般情况下有点复杂的原因。)

    然而,

    使用-d运行显然会完全抛出规则4。同样,为了删除目录,Git必须首先删除目录中的所有文件。要做到这一点,Git也必须枚举内容。因此,如果您告诉git clean使用-d,则完全禁用规则4似乎是合适的。路径名的目录将迫使Git扫描目录的内容。我们已经需要查看内部因为有跟踪文件,或者我们需要查看内部以删除文件以删除目录。

    2 请注意&#34;未知&#34;与&#34;未跟踪&#34;不同。它甚至都不是Git术语;我已在这里做到了。但是,正如我们所看到的,如果Git 定义短语&#34;未跟踪目录&#34;那么可能会很好。

    git clean移除

    运行git clean -n会显示它会删除的内容。此显示使用一些简写:删除目录意味着删除该目录中的所有文件,包括(递归)子目录和子文件。这比使用-f代替-n更安全,因为-f会显示删除的内容,-n会向您显示删除的内容。

    默认情况下,git clean会删除未跟踪的文件,但不是未跟踪和忽略的文件。也就是说,回到上面的第3点并查看文件的三个分类:git clean删除中间分类(仅限)。添加-X(大写X)告诉Git:不要删除未跟踪的文件;相反,删除未跟踪和忽略的文件。

    添加-x告诉Git:不要读取通常的ignore-directives文件,例如.gitignore 。此时, no 文件将被忽略,因此(无论跟踪哪些文件)都不能取消跟踪和忽略任何文件。将此与-X相结合是没有意义的, 3 因此git clean禁止您同时使用-x-X

    使用git clean运行-d会添加空目录删除。不过,在这里,事情变得尤为突出。似乎Git的跟踪,未跟踪,未跟踪和忽略的分类有点崩溃。 The documentation-d会:

      

    除了未跟踪的文件外,删除未跟踪的目录。

    但Git没有定义未跟踪目录。 &#34;履带岬&#34;仅属于文件的属性。我们确实在脚注中看到目录作为不可见的实体潜入索引(为了加速各种Git操作),但这并不意味着目录被跟踪。 / p>

    我们可以制作一个:#34;未跟踪目录&#34;可能是不包含跟踪文件的目录。我认为(但我没有证明自己很满意)这个定义有效并解释了git clean的行为。如果Git文档实际上正确定义了这一点,那将会有很大帮助。

    3 -x-X-e结合起来可能有一些实际用途,但Git仍然禁止这样做,至少截至今天。

答案 1 :(得分:1)

  1. .gitignore忽略添加和提交的文件。它不能保护它们不被清理,正好相反。

  2. 这些已清理的文件以下列方式与.gitignore相关:

    定制/扩展/模块/错误/外部/语言/ 定制/扩展/模块/案例/分机/语言/

  3. 匹配custom/modules/*/Ext规则。

    LOG.txt
    vendor/sugarcrm/identity-provider/tests/docker/saml-test/config/simplesamlphp/config/
    

    文件未添加到索引中,因此符合清理条件。

    1. 要避免清除未版本控制的文件,请不要运行git clean。手动删除不必要的文件。