两个 Git 存储库共享公共代码

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/28357350/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-09 02:53:24  来源:igfitidea点击:

Two Git repositories share common code

git

提问by Alex Napitupulu

So I have a project which has the client parts and the server parts. I would like the client and the server code to be in different Git repositories for clear separation of the code, however, they share some of the files and ideally, the shared files will always be identical in both client and server.

所以我有一个包含客户端部分和服务器部分的项目。我希望客户端和服务器代码位于不同的 Git 存储库中,以便清楚地分离代码,但是,它们共享一些文件,理想情况下,共享文件在客户端和服务器中始终相同。

How should I go about this? Is it better to have the third repository for the common code?

我应该怎么做?拥有公共代码的第三个存储库是否更好?

采纳答案by TimWolla

I will not give advice on “How you should go about this”. But I'll explain how to accomplish integrating a third repository with common code into the other repositories: This is a job for git submodules. git submodules allow you to reference a snapshot of a git repository at a specified path:

我不会就“你应该如何做这件事”给出建议。但我将解释如何将带有公共代码的第三个存储库集成到其他存储库中:这是 git 子模块的工作。git 子模块允许您在指定路径引用 git 存储库的快照:

git submodule add git://example.com/repository.git path

Afterwards create a commit. Now a snapshot of the given repository is referenced at path.

然后创建一个提交。现在,给定存储库的快照在path.

Populating the submodule

填充子模块

  1. Execute git submodule init
  2. Execute git submodule update
  1. 执行 git submodule init
  2. 执行 git submodule update

Every configured submodule will be updated to match the state it is supposed to look like.

每个配置的子模块都将更新以匹配它应该看起来的状态。

Updating a submodule to a later commit

将子模块更新到以后的提交

  1. Change into the directory of the submodule
  2. Perform a git pull/ git fetch+ git checkoutto update the submodule to the desired commit / tag
  3. Create a new commit to update the commit in the .gitmodulesfile
  1. 切换到子模块的目录
  2. 执行git pull/ git fetch+git checkout将子模块更新为所需的提交 / 标记
  3. 创建一个新的提交来更新.gitmodules文件中的提交

Take a look at the official manualfor further information on submodules.

有关子模块的更多信息,请查看官方手册

回答by Schwern

If they share common code, I see two sensible options. Separate the common code into its own project, or merge the server and client repositories to make working on them together easier.

如果他们共享通用代码,我会看到两个明智的选择。将公共代码分离到自己的项目中,或者合并服务器和客户端存储库,以便更轻松地一起处理它们。

Whether separating the common code is worth the extra effort is up to you. Does the common code make sense on its own, or is is just a bunch of functions specific to this product? For example, if you had an SSL or date parsing code in common that would make a good spin off project. Or maybe you've written special code for config file parsing, that can be worked on stand-alone even if nobody but your project will use it. If you're spinning off common code just because the two projects share it, don't bother, it will have no direction of its own. Spinning it off will just be a barrier to development for both the server and client teams.

分离公共代码是否值得付出额外的努力取决于您。通用代码本身是否有意义,还是只是针对该产品的一系列功能?例如,如果你有一个共同的 SSL 或日期解析代码,这将是一个很好的衍生项目。或者,您可能已经为配置文件解析编写了特殊代码,即使除了您的项目之外没有人会使用它,它也可以独立工作。如果您仅仅因为两个项目共享公共代码而剥离公共代码,请不要打扰,它没有自己的方向。剥离它只会成为服务器和客户端团队开发的障碍。

Whether you should merge the client and server is another consideration. It also comes down to whether it makes sense to consider them as separate products. Are they useful as separate products? Can different versions of the client and server work together, or must they be the same version? Do different people work on the client versus the server? The fact that you want to keep everything together in one super-repository says no.

是否应该合并客户端和服务器是另一个考虑因素。这也归结为将它们视为单独的产品是否有意义。它们作为单独的产品有用吗?不同版本的客户端和服务器可以一起工作,还是必须是同一个版本?不同的人在客户端和服务器上工作吗?您想将所有内容放在一个超级存储库中这一事实表明不可以。

If you do separate into multiple repositories (client, server, related projects) follow TimWolla's answer.

如果您确实分成多个存储库(客户端、服务器、相关项目),请遵循 TimWolla 的回答

If you're not sure, merge them all into one repository with server/, client/and common/top level directories. If their concerns are entangled, put them together. This will also make it easier to spot and migrate duplicated code. You may work on disentangling them and creating concrete "common" projects, and at that time they should be spun off into their own repositories.

如果您不确定,请将它们全部合并到一个带有server/,client/common/顶级目录的存储库中。如果他们的顾虑纠缠在一起,就把它们放在一起。这也将更容易发现和迁移重复的代码。您可能会致力于解开它们并创建具体的“公共”项目,届时它们应该被分拆到自己的存储库中。

回答by Todd A. Jacobs

TL;DR

TL; 博士

Just use Git submodules to hold your common code. That's the use case they're intended for. Other options exist, but mostly for repositories on the same filesystem and with little advantage when cloned over a network.

只需使用 Git 子模块来保存您的公共代码。这就是他们打算用于的用例。存在其他选项,但主要用于同一文件系统上的存储库,并且在通过网络克隆时几乎没有优势。

Common Code vs. Identical Files

通用代码与相同文件

The proper way to deal with common code is usually through submodulesor subtree merging. However, if you have file assets that are (and will remain) identical, then you can leverage symlinks on filesystems that support them. There are at least three downsides to this approach:

处理公共代码的正确方法通常是通过子模块子树合并。但是,如果您拥有(并将保持)相同的文件资产,那么您可以利用支持它们的文件系统上的符号链接。这种方法至少有三个缺点:

  1. Only one repository would have the "real" file. The other repository would only contain a symlink to a file that may or may not exist on a different filesystem.
  2. Windows systems don't have Linux/Unix-style symlinks, so interoperability may be an issue.
  3. Unless you're dealing with really large binary blobs, the space savings of shared links is probably minimal, and not worth the effort.
  1. 只有一个存储库将拥有“真实”文件。另一个存储库将只包含指向不同文件系统上可能存在或不存在的文件的符号链接。
  2. Windows 系统没有 Linux/Unix 样式的符号链接,因此互操作性可能是一个问题。
  3. 除非您正在处理非常大的二进制 blob,否则共享链接的空间节省可能很小,并且不值得付出努力。

You can also look into the use of alternatesto share objects between repositories on the same filesystem. The manual says (emphasis mine):

您还可以研究使用替代方法在同一文件系统上的存储库之间共享对象。手册说(强调我的):

You could be using the objects/info/alternates or $GIT_ALTERNATE_OBJECT_DIRECTORIES mechanisms to borrow objects from other object stores.A repository with this kind of incomplete object store is not suitable to be published for use with dumb transports but otherwise is OK as long as objects/info/alternates points at the object stores it borrows from.

您可以使用 objects/info/alternates 或 $GIT_ALTERNATE_OBJECT_DIRECTORIES 机制从其他对象存储中借用对象。具有这种不完整对象存储的存储库不适合发布以用于哑传输,但只要对象/信息/备用点指向它借用的对象存储,就可以。

This sort of advanced usage is usually used to speed up forking on systems like Atlassian Stash rather than for sharing specific blobs, but the tools are there if you want to juggle chainsaws.

这种高级用法通常用于在 Atlassian Stash 等系统上加速分叉,而不是共享特定的 blob,但如果您想玩电锯,这些工具就在那里。