管理git跨分支忽略

时间:2020-08-31 18:27:07

标签: git

我通常会遇到这种情况:

  1. 我正在分支Foo中工作,该分支具有被忽略文件的整个文件夹,而在分支Bar中不存在。
  2. 我结帐分支Bar做其他工作。
  3. 我在工作副本中看到数千个新文件/未跟踪文件,这些文件在Foo分支中被git忽略了,但在Bar分支中没有被忽略。
  4. 如果在Bar中工作时,我尝试使用存储,它将所有这些文件都拉进其中-使隐藏的更改无法读取(而且确实很慢)。

虽然我可以为这些文件夹添加git忽略,但这些文件夹甚至不存在于Foo之外,因此这似乎很尴尬。

git还有其他解决方案吗?理想情况下,仅当使用它们的分支被检出时文件才会存在,但是我不想git添加它们,因为它们太多了并且它们修改得太频繁了;它将使git缓慢爬行。就像我希望他们在自己的分支中表现得好像git被忽略了一样,并让它们藏起来而没有。

2 个答案:

答案 0 :(得分:0)

Git从.gitignore以外的文件中读取忽略模式:

  • .git/info/exclude中的模式在该存储库中检出的任何分支中都将被忽略
  • ~/.config/git/ignore中的模式将在系统范围内被忽略

.gitignore从分支机构Foo复制到这些位置之一将导致在检出Bar时忽略这些文件。

您还可以考虑仅将分支.gitignore的{​​{1}}合并到分支Foo中。

答案 1 :(得分:0)

分支(或更确切地说,分支名称)在这里基本上无关紧要。重要的是 commits 。分支名称用于查找一个特定的提交,但是两个或多个分支名称可以标识相同的提交。

git还有其他解决方案吗?

您可以在此处使用多种方法。如果您的Git版本至少为2.5(最好至少为2.15),建议您从git worktree开始。但是首先,让我们用足够的细节定义问题,并使用一些特定于Git的术语,使解决方案本身有意义。

理想情况下,仅当使用它们的分支被检出时文件才会存在...

Git也与文件无关,尽管您当然需要文件来完成工作。但是您在工作树工作树中看到和使用的文件甚至不在 Git中,这在很大程度上感。提交(在Git中是 )包含文件,但格式特殊,只读,压缩和重复数据删除。除非工作从未写入任何文件,否则只读文件将无法让您完成工作。但是由于提交的文件是仅Git格式的文件,因此您可能也无法使软件读取它们。

因此,要使用 Git,您需要将Git的文件(以冻干,压缩和重复数据删除格式)复制到普通的日常读写文件中。这些读/写文件在您的工作树中。签出特定提交的操作(通常按分支名称)选择该特定提交作为当前提交。 Git将已提交的文件复制到您的工作树中,以便您可以查看和使用它们。

由于您的工作树是您的工作树,因此您可以创建许多在提交中没有的文件,并通过将它们列出在.gitignore文件或类似文件中,可以告诉您弄两件事:

  1. 不要抱怨这些所谓的 untracked 文件;和
  2. 不要将它们添加到Git的 index 临时区域

索引/暂存区(同一事物的两个术语)是Git进行新提交的方式:从复制到Git索引中的预冻干文件中进行。 git add命令告诉Git:制作此工作树文件的冻干/去重复副本,并将其放入索引中。 1

当然,通常会提交一个主.gitignore文件本身,因此您的工作树中的文件已从当前提交中删除。如果然后切换到具有不同提交.gitignore文件的不同提交,Git将把工作树副本替换为其他提交的副本。当然,这会更改上面发生两个操作的文件集。


1 请注意,重复数据删除意味着索引实际上从未包含文件的副本。而是保留文件的名称和文件内容的 blob哈希ID 。如果内容与任何现有的提交文件相匹配(每个索引“副本”最初都会执行此操作,因为Git会从您选择的提交中填入 的索引),那么这些文件都已被重复数据删除,因此索引只需列出要进入下一次提交的文件。这就是git commit的工作方式:运行git commit时,它只是打包索引中的列表。

还要注意git add的真正含义是使索引副本与工作树副本匹配。特别是,如果您已经删除了工作树副本,git add将删除索引副本。 (或者,您可以使用git rm同时删除两个副本,因此不需要git add删除的文件即可让Git看到删除。)


解决方案1:git worktree add

Git存储库随附一个默认的工作树。 2 但是,至少从Git 2.5版开始,您可以使用{ {1}}。每个工作树都有自己的索引。

在主/默认树之外具有单独的工作树,这意味着您可以签出多个分支。由于每个工作树都是独立的,因此工作树W1中任何未跟踪的文件(无论是否忽略)都不会以任何方式影响工作树W2中的任何未跟踪文件。因此,整个问题就消失了:使用主工作树W1在主分支B1上工作,并使用添加的工作树W2在分支B2上工作。如果您需要在更多分支上进行工作,请继续添加更多工作树。

完成工作树后,只需将其删除即可。您可以手动将其删除并使用git worktree add,或者如果您的git worktree prune包含子命令,则使用git worktree。请注意,在Git 2.5的git worktree remove中有一个非常讨厌的错误,直到Git 2.15才修复,如果您让添加的工作树闲置两周以上,则可能导致数据丢失。我建议升级Git版本,但是创建工作树,完成所有工作,然后在两周内删除它就足够了,或者您可以将对象修剪保护的最低年龄git worktree从其默认值2提高使用gc.pruneExpire的周值来延长保护时间。


2 一个 bare 存储库省略了工作树。不过,我们在这里不讨论这一点。


git config

除了工作树中的.git/info/exclude文件之外,Git还将读取并遵守.gitattributes中的排除项。该文件在任何提交中均 not -不能。 Git不会将.git/info/exclude中的文件添加到提交中,因此,无论您检出了哪个提交,您都可以在此处列出未处理的文件,并忽略它们。

.git

git clean命令具有删除未跟踪文件的选项(git clean-x)。在切换到其他分支之前使用它们会删除构建产品等。 请谨慎使用这些选项,因为未跟踪的文件不在Git中(根据定义,未跟踪的文件不在Git的索引中,因此不会在下一次提交中)因此无法使用Git恢复。

-Xgit stash -u

可以告知git stash -a命令进行一次三提交存储,而不是通常的两次提交存储,在第三次提交中,第三次提交包含未跟踪但未被忽略的文件({{1} })或所有未跟踪的文件(即使被忽略(git stash)。 -u进行了第三次提交后,它将使用-a或等效的命令删除在第三次提交中保存的文件。

我不喜欢这种方法,因为还原三个提交的存储库需要,该工作树必须“干净”,即不包含该第三次提交中的任何文件。使用git stash保存构建产品,更改某些内容(包括制作需要花费时间和/或精力的构建产品和配置文件),尝试使用git clean来还原保存的产品太容易了,然后使用git stash push -a进行清理,以使git stash apply可以正常工作……只是发现您刚刚清理的文件之一是 new ,而没有保存的存储空间,现在将需要大量时间和/或精力来重新构建它。