跟踪文件但将它们从 git 包中排除 [英] Track files but exclude them from a git bundle

查看:25
本文介绍了跟踪文件但将它们从 git 包中排除的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have a somewhat complex ansible workflow. I have two airgapped networks. I develop playbooks on both networks, so I have two somewhat independent ansible repositories managed by git. At the same time, most of the playbooks can be used in both places. To complicate matters, this is a one way transfer. I can transfer from network A to B, but not from B to A.

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

I have template files with information relevant to one network but not relevant on the other. I've designed it so that filenames should be the same (as well as variable names in Jinja2 templates). I want to be able to create a git bundle that excludes the files, so that when I pull from the bundle on the other network's repository, the files don't get overwritten. Because including the wrong information in the template files could conceivably break the entire environment, I need to track the Jinja2 template/variable files in Git.

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

Does anyone have a workflow recommendation, or a git command besides using .gitignore (because the files need to be tracked so I can roll back in emergencies) that will help me accomplish this?

推荐答案

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

There's no completely trivial way to do this.

从根本上说,一个文件在 Git 中被跟踪当且仅当它在索引中.索引(通常,最初)从某个提交填充,因此它是某个先前的提交,确定是否要跟踪文件.假设存在一组相似的提交 TU ,只是有一些文件不在提交 U 中,而在提交 .然后:

Fundamentally, a file is tracked in Git if and only if it is in the index. The index is (normally, initially) populated from some commit, so that it is some previous commit that determines if a file is to be tracked. Assume there exist sets of commits T and U that are similar except that there are some files not in commits U that are in commits T. Then:

git checkout any-T-sub-i-commit

导致文件在索引中(并因此被跟踪),同时:

results in the file(s) being in the index (and hence tracked), while:

git checkout any-U-sub-j-commit

导致文件不在索引中(因此未被跟踪).

results in the file(s) being not-in the index (and hence untracked).

对于像合并这样的操作来说,这同样适用于更普遍的方式:当您处理来自 set T 的提交时,您处理的是具有文件的提交;当您处理来自 set U 的提交时,您将处理缺少文件的提交.如果您将任何 Ti 提交与任何 Uj 提交合并,对任何此类文件的影响 - 无论是添加、删除或冲突——取决于合并基础提交是在 set T 还是 set U 中,以及在 commit T 中对这些文件的特定更改i 关于合并基础提交.

The same holds in a more general fashion for operations like merging: when you work with commits from set T, you work with the ones that have the files; when you work with commits from set U, you work with the ones that lack the files. If you merge any Ti commit with any Uj commit, the effect on any such file—whether it's added, removed, or conflicted—depends on whether the merge-base commit is in set T or set U, and the specific changes to those files within commit Ti with respect to the merge base commit.

当然,当文件移入或移出索引时,Git 也会同时将它们复制到工作树中或从工作树中删除它们(通常小心不要删除未保存但很宝贵的数据).因此,这意味着工作树文件将消失并重新出现,具体取决于您检查的是 T 提交还是 U 提交.

Of course, as files move into or out of the index, Git also copies them into, or removes them from, the work-tree at the same time (with the usual caution about not removing unsaved-but-precious data). So this means that the work-tree file will vanish and reappear depending on whether you check out a T commit or a U commit.

与此同时,让我们看看 bundle 是什么,至少在抽象意义上是这样.包的本质在于它至少包含 git fetchgit push 将通过网络发送的所有数据,在 git fetchgit push 通信过程,用于最小化此数据.(它可以包含额外的数据,这些数据将被简单地忽略.)这个最少的数据包含所有必须复制的对象——带注释的标签、提交、树和 blob——加上引用名称和它们的值.

Meanwhile, let's look at what a bundle is, at least in an abstract sense. The essence of a bundle is that it contains at least all the data that git fetch or git push would send across the wire, after the git fetch or git push communication process that serves to minimize this data. (It can contain extra data, which will simply be ignored.) This minimal data consists of all of the objects that must be copied—annotated tags, commits, trees, and blobs—plus the reference names and their values.

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

To exclude some set of files from the bundle, then, you need to bundle exclusively the U commits, and not any of the T commits. That's fine as far as it goes: if you have all branches duplicated, and distinguish between T commits and U commits by branch names, you can achieve this pretty easily. But the consequence is that every time you make a new T commit you must make a corresponding U commit, and vice versa. You have, in effect, doubled your workload.

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

The standard recommendation that applies to configuration files in general applies here as well: Do not commit any configuration, ever. Commit only sample or default or template configurations. Use some kind of wrapper to convert these sample configurations to real configurations. (The wrapper can also be committed, of course, if it's something you write yourself, such as a shell script or Python program or whatever.) You may now maintain, and version-control, these sample / default configurations. Cloning the repository obtains the samples, and updating from the clone—git fetch followed by a merge or rebase—updates the samples, but does not touch the actual configuration. Depending on how smart the wrapper is and what's available in your output format,1 it can even auto-detect that the sample/default input has changed, and warn or fail any runs that use the prescribed tool (i.e., the wrapper itself) until the real configuration is updated to match any required changes coming from the sample/default/template configuration.

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

This is still not trivial—in particular, you may have to write a wrapper, and educate users on the correct way to run your particular system. But it's as close to trivial as you are likely to achieve.

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

1In this particular case, your output is most likely the YAML files for ansible. This means you can hide all kinds of useful sample/default-config information in comments, for instance.

这篇关于跟踪文件但将它们从 git 包中排除的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆