2

我有一个有点复杂的 ansible 工作流程。我有两个气隙网络。我在两个网络上开发剧本,所以我有两个由 git 管理的有点独立的 ansible 存储库。同时,大部分剧本都可以在这两个地方使用。更复杂的是,这是一种单向转移。我可以从网络 A 转移到 B,但不能从 B 转移到 A。

我有模板文件,其中包含与一个网络相关但与另一个网络无关的信息。我已经设计了它,以便文件名应该相同(以及 Jinja2 模板中的变量名)。我希望能够创建一个排除文件的 git 包,这样当我从其他网络存储库上的包中提取时,文件不会被覆盖。因为在模板文件中包含错误信息可能会破坏整个环境,所以我需要在 Git 中跟踪 Jinja2 模板/变量文件。

除了使用 .gitignore (因为需要跟踪文件以便我可以在紧急情况下回滚)之外,是否有人有工作流建议或 git 命令可以帮助我完成此任务?

4

1 回答 1

3

没有完全简单的方法可以做到这一点。

从根本上说,当且仅当文件在索引中时,才会在 Git中跟踪文件。该索引(通常,最初)是从某个提交中填充的,因此它是某个先前的提交来确定是否要跟踪文件。假设存在类似的提交集TU,除了一些不在提交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 pushgit fetchgit push

那么,要从捆绑包中排除某些文件集,您需要专门捆绑U 提交,而不是任何T提交。就目前而言,这很好:如果您复制了所有分支,并通过分支名称区分T提交和U提交,您可以很容易地实现这一点。但结果是每次你进行新的T提交时,你都必须进行相应的U提交,反之亦然。实际上,您的工作量增加了一倍。

适用于配置文件的标准建议通常也适用于此处:永远不要提交任何配置。仅提交示例默认模板配置。 使用某种包装器将这些示例配置转换为真实配置。(当然,也可以提交包装器,如果它是您自己编写的东西,例如 shell 脚本或 Python 程序或其他任何东西。)您现在可以维护和版本控制这些示例/默认配置。克隆存储库获取样本,并从克隆更新——<code>git fetch 后跟合并或变基——更新样本,但不触及实际配置。根据包装器的智能程度以及输出格式中可用的内容,1它甚至可以自动检测样本/默认输入已更改,并警告或失败任何使用指定工具(即包装器本身)的运行,直到更新实际配置以匹配来自样本/默认的任何所需更改/模板配置。

这仍然不是微不足道的——特别是,您可能必须编写一个包装器,并教育用户以正确的方式运行您的特定系统。但这与您可能实现的一样接近微不足道。


1在这种特殊情况下,您的输出很可能是 ansible 的 YAML 文件。例如,这意味着您可以在评论中隐藏各种有用的示例/默认配置信息。

于 2017-09-09T19:45:26.873 回答