没有完全简单的方法可以做到这一点。
从根本上说,当且仅当文件在索引中时,才会在 Git中跟踪文件。该索引(通常,最初)是从某个提交中填充的,因此它是某个先前的提交来确定是否要跟踪文件。假设存在类似的提交集T和U,除了一些不在提交U中的文件在提交T中。然后:
git checkout any-T-sub-i-commit
导致文件在索引中(并因此被跟踪),而:
git checkout any-U-sub-j-commit
导致文件不在索引中(因此未被跟踪)。
对于像合并这样的操作,这同样适用于更一般的方式:当您使用来自 set T的提交时,您使用的是拥有文件的提交;当您处理来自 set U的提交时,您将处理那些缺少文件的提交。如果您将任何T i提交与任何U j提交合并,则对任何此类文件的影响(无论是添加、删除还是冲突)取决于合并基础提交是在 set T还是 set U中,以及对提交T i中关于合并基础提交的那些文件。
当然,当文件移入或移出索引时,Git 也会同时将它们复制到工作树中或从工作树中删除(通常要注意不要删除未保存但宝贵的数据)。因此,这意味着工作树文件将消失并重新出现,具体取决于您是签出T提交还是U提交。
同时,让我们看看什么是捆绑包,至少在抽象意义上。捆绑的本质是它至少包含所有通过线路发送的数据,git fetch
或者在用于最小化这些数据的通信过程之后。(它可以包含额外的数据,这些数据将被简单地忽略。)这个最小的数据包含所有必须复制的对象——带注释的标签、提交、树和 blob——加上引用名称和它们的值。git push
git fetch
git push
那么,要从捆绑包中排除某些文件集,您需要专门捆绑U 提交,而不是任何T提交。就目前而言,这很好:如果您复制了所有分支,并通过分支名称区分T提交和U提交,您可以很容易地实现这一点。但结果是每次你进行新的T提交时,你都必须进行相应的U提交,反之亦然。实际上,您的工作量增加了一倍。
适用于配置文件的标准建议通常也适用于此处:永远不要提交任何配置。仅提交示例或默认或模板配置。 使用某种包装器将这些示例配置转换为真实配置。(当然,也可以提交包装器,如果它是您自己编写的东西,例如 shell 脚本或 Python 程序或其他任何东西。)您现在可以维护和版本控制这些示例/默认配置。克隆存储库获取样本,并从克隆更新——<code>git fetch 后跟合并或变基——更新样本,但不触及实际配置。根据包装器的智能程度以及输出格式中可用的内容,1它甚至可以自动检测样本/默认输入已更改,并警告或失败任何使用指定工具(即包装器本身)的运行,直到更新实际配置以匹配来自样本/默认的任何所需更改/模板配置。
这仍然不是微不足道的——特别是,您可能必须编写一个包装器,并教育用户以正确的方式运行您的特定系统。但这与您可能实现的一样接近微不足道。
1在这种特殊情况下,您的输出很可能是 ansible 的 YAML 文件。例如,这意味着您可以在评论中隐藏各种有用的示例/默认配置信息。