无可争议(我认为)和无可争议(我认为):
- 如果您需要对某些文件集进行版本控制,则必须将它们放入版本控制系统中。
- 如果 VCS 是分布式的(与 Git 一样)并将所有文件发送到其他地方(与 Git 一样 — 它们在提交中并且只能共享整个提交),那么这不适合您的用例。李>
- 但您想对其余文件使用 Git。
结论:您至少需要两个 VCS 和/或存储库。
第二个 VCS 也可以是 Git,只要您确保不分发(至少以公开方式)第二个存储库。
子模块可以工作。子模块只不过是对其他 Git 存储库的引用:本质上是一个 URL 和一个特定的提交哈希 ID。但是,每个 Git 存储库都控制自己的工作树。如果文件必须混合在一起(“存在于同一个文件夹中”),并且您仍然想使用子模块,那么您有几个选择:
- 处理它(见下文);
- 不要将 Git 工作树用作您的实际工作区;
- 如果您的系统支持符号链接,并且涉及的文件不多,则让一个存储库包含指向实际位于另一存储库工作树中的文件的符号链接;或
- 不使用任何但符号链接,因此您明显统一的工作树只是指向所需子目录中文件的符号链接树。
请注意,如果您确实选择使用子模块,您可能希望将其构建为一个单一的超级项目,该超级项目除了持有两个持有感兴趣的提交的子模块(可能还有森林符号链接,如果你在这里使用最后一种方法)。这使得两个子模块彼此完全独立,因为子模块不知道它的超级项目。只有 第三个 存储库(即超级项目)会知道还有其他两个 Git 存储库涉及,并且超级项目将子模块安排在相对符号链接的位置(如果您使用那些)工作。
如果这太过分了,只需选择两个独立的 Git 存储库之一作为超级项目。另一个 Git 存储库将被克隆为超级项目的子目录。
关于“处理它”
假设存储库 A 的提交仅包含公共文件,存储库 B 的提交仅包含私有文件。当您同时克隆A 和B 时,您会得到两个不同的工作树。其中一个最多可以是path/to/files,但您希望A 和 B 中的文件都出现在path/to/files 中。如果 A 的工作树被命名为 path/to/files:
cd path/to; git clone url-of-A files
那么B的工作树肯定不是path/to/files,从B签出的文件不会最初出现在path/to/files中。例如,假设 B 根本不是子模块,而你现在——虽然还在 path/to 中——运行:
git clone url-of-B sensitive-files
您现在拥有files/*(将 Git-repo 克隆到 files/.git)持有从 repo A 提取的文件,sensitive-files/* 持有从 repo B 提取的文件。您现在可以手动或使用脚本,复制或符号链接在sensitive-files/* 中管理的文件,以便可以通过具有files/* 形式的名称访问它们。
files/* 中出现的副本或符号链接可以在 files/.gitignore 中列出,这样它们就不会被添加到 repo A 的提交中。或者,如果您正在使用符号链接,请注意A/sensitive-file-1 中的内容实际上只是路径名 ../sensitive-files/sensitive-file-1。将 symlink 提交到 repo A 可能是可以的,即使 repo A 可以从任何地方访问,因为获得它的副本的人只知道 A 中的程序可能读取和/或写入到一个名为sensitive-file-1 的文件。该文件的实际内容不在path/to/files 中,而是在path/to/sensitive-files 中,因此它们根本不会出现在repo A 中。