Git:将单个文件从一个存储库镜像到另一个

时间:2021-02-08 08:16:04

标签: git continuous-integration repository mirror

假设我在存储库 A 中有两个存储库和一个参数文件。存储库 B 需要相同的文件,如果存储库 A 中的此文件有更新,则应使用存储库 B 中的 git pull 进行更新。不需要另一种方式(从 B 到 A)。

是否有一种简单的方法可以将存储库中的单个文件镜像到另一个存储库并使其保持最新状态? 解决方案还可以利用 CI 管道!

有什么想法可以解决这个问题吗?

1 个答案:

答案 0 :(得分:1)

<块引用>

是否有一种简单的方法可以将存储库中的单个文件镜像到另一个文件并使其保持最新状态?

简单也许在旁观者的眼中。我怀疑对于您的情况,答案是否定的,但也许您会认为以下内容很简单。

这里要记住的关键是 Git 不存储文件。 Git 存储提交。提交然后存储文件,但它是一揽子交易:每个提交都有每个文件的完整快照。你要么有一个提交——因此所有文件——或者你没有提交,因此没有文件。

这意味着如果您想处理单个文件,而不是整个文件集合,您有多种选择:

  • 在存储库 A 和 B 中使用不同的提交。A 中的提交有很多文件,包括这个参数文件。 B 中的提交有很多文件,包括这个参数文件。

    这为您提供了 B 中的两个子选项:

    • B 拥有 A 拥有的所有提交,以及只有 B 需要处理的特定于 B 的提交,每当 A 中有新提交时,您都会得到它(整个提交),然后在 B 中构建一个新的特定于 B 的提交采用最近的特定于 B 的提交并将此文件替换为一个新文件,然后提交结果。

    • 或者,B 没有来自 A 的所有提交。相反,当 A 中的此文件有更新时,您有一些软件 (1) 注意到;然后 (2) 通过提取一些现有的特定于 B 的提交、更新文件并进行新的特定于 B 的提交来生成新的特定于 B 的提交。

    你应该注意到这两个子选项大部分是相同的东西:区别在于存储库 B 是否只是自动包含来自存储库 A 的所有提交(Git 非常擅长:Git loves 将提交添加到其集合中),或者不。创建新的特定于 B 的提交的软件需要某种方式来发现 A 何时有一个新提交,该提交具有相关文件的不同版本,并且将所有 A 在本地提交到 B 中很容易,但会使 B 存储库“更胖”。

  • 或者——这就是事情变得有点棘手的地方——考虑将参数文件隔离到它自己的存储库 C。现在存储库 A 和 B 都可以克隆 C。当有一个新的参数文件,您将其添加到存储库 C 并提交。存储库 A 和 B 获取并更新其 C 的克隆,从而获得最新的参数文件。

    这是迄今为止最简单的方法,机械地。但它可能有一些其他机械问题:也许参数文件的名称不能轻易更改。如果您的操作系统提供符号链接(或等效链接),您可以将 A 和 B 中的“参数文件”作为符号链接,指向它们将保存 C 的克隆及其参数文件的位置。或者,您可以在下一个整体选项中使用复杂的技巧。

  • 这个“第三个存储库”方法有一个混合变体。这种混合变体的缺点是它使得生成和提交新的参数文件更加困难,并且一个简单的 git checkout 也不适用于两个存储库 A 和 B 中的:相反,您需要一个特殊的“结帐然后更新”序列。 (但 CI 系统往往非常擅长做这样的特殊工作。)

    在这里,不是将参数文件作为常规的“所有文件,包括参数文件”提交,而是进行参数文件提交,作为提交,仅包含一个参数文件。到目前为止,这与拥有第三个 C 存储库完全一样。

    是什么使它成为一个混合,但是,而不是第三个存储库,您只是在存储库 A 和 B 中的它自己的“孤立分支”上拥有这个文件。也就是说,而不是:

    git checkout main
    # now you have all files including the parameter file
    

    你会跑:

    rm paramfile                   # it's untracked: now it's gone
    git checkout paramfile-branch
    # now you have only one file: the parameter file, paramfile
    

    您现在可以更新文件并提交。然后你回到你的主分支(或任何其他分支),这里没有参数文件,所以现在你提取参数文件from paramfile-branch

    git show paramfile-branch:paramfile > paramfile  # or similar
    

    您在此分支中的 .gitignore 文件将 paramfile 列为被忽略(在 .gitignore 上的提交中根本没有 paramfile-branch 文件:在那里,它是一个 跟踪 文件,以及 only 文件)所以这只是一个临时文件,就 Git 而言。

    由于文件只在 repo A 中更新,因此 repo B 可以从 repo A 的 paramfile-branch 中获取,将结果哈希 ID 写入 repo B 的 paramfile-branch 名称:< /p>

    git fetch repo-A +paramfile-branch:paramfile-branch
    

    从这个分支中获取新的提交。

最后一种方法只是将“repo C”嵌入到存储库 A 和 B 中的一种方式,使用单个分支名称 (paramfile-branch) 来保存“repo C”中最后一次提交的哈希 ID(嵌入到 A 和 B 中)。