简体   繁体   English

git repo子文件夹作为另一个repo的子树?

[英]Git repo subfolder as subtree of another repo?

My company is working on migrating from SVN to Git - part of the reason is to take advantage of deployment software that works using Git as a source. 我的公司正在努力从SVN迁移到Git-部分原因是要利用以Git为源的部署软件。 We're using a single repository (monorepo) for all components of our application stack. 我们正在为应用程序堆栈的所有组件使用单个存储库(monorepo)。

We're also looking at using PM2 for NodeJS app management/deployment. 我们也正在考虑将PM2用于NodeJS应用程序管理/部署。 Since this can use a git repository for deploying updates, we'd love to use it - but only a single subdirectory of our repository is really needed to be deployed. 由于它可以使用git存储库来部署更新,因此我们很乐意使用它-但实际上只需要部署存储库的一个子目录。

Is it possible to create a git repository that references just a single subdirectory of another git repo as a submodule / subtree? 是否可以创建一个git存储库,该存储库仅将另一个git repo的单个子目录作为子模块/子树引用?

Something like this - with Repo A being the main monorepo and Repo B being the repo containing only the NodeJS stuff from Repo A. 这样-仓库A是主要的monorepo,仓库B是仅包含仓库A中的NodeJS内容的仓库。

RepoA\
  Component1\
  Component2\
  DelphiApp\
  NodeJSApp\
  PHPStuff\
  Configurations\
  Utilities\
RepoB\
  NodeJSApp\ <--subtree/submodule back to NodeJSApp in RepoA

For git submodule , the short answer is no: 对于git submodule ,简短的回答是:

  • You either have a repository or you don't. 您要么有一个存储库,要么没有。

    • If you don't have the repository, you can clone it, and now you do. 如果您没有存储库,则可以克隆它,现在可以了。 But you have the repository , not some subdirectory of the repository. 但你有仓库 ,而不是仓库一些子目录。
  • Now that you do have the repository, you either have some commit in it, or you don't. 现在您已经有了存储库,或者在其中进行了提交,或者没有。

    (Commits are identified by hash IDs—those big ugly strings of letters and numbers—and since humans are bad at remembering random strings of letters-and-numbers, and for other purposes, each repository has some set of names that each remember one hash ID. The names are good for you , but what Git really needs is the hash ID.) (提交由哈希ID识别(哈希ID是那些难看的字母和数字大字符串),并且由于人类不善于记住随机的字母和数字字符串,并且出于其他目的,每个存储库都有一组名称 ,每个名称都记住一个哈希ID。名称对有好处,但是Git 真正需要的是哈希ID。)

    • If you don't have the commit, you can have your Git connect to another Git that also has the repository. 如果您没有提交,则可以将您的Git连接到另一个也具有存储库的Git。 Your Git can ask their Git about commits that they have, that you don't, and get those commits into your Git repository. 您的Git可以询问他们的Git有关您拥有的,您没有的提交,并将这些提交放入您的Git存储库。 Now, if they have the commit, so do you. 现在,如果他们有提交,您也可以。
  • Now that you have the repository and the commit, you have all the files. 现在您有了存储库和提交,就拥有了所有文件。 A commit is (or more precisely, contains / refers-to and obtains) a complete snapshot of every file. 提交是(或更准确地说,包含/引用并获得) 每个文件的完整快照。

You don't have to use all the files. 您不必使用所有文件。 You can extract only the files you care about. 您只能提取您关心的文件。 But that's a lot harder than just using git checkout name to get the commit whose hash ID is stored in name name , which gets you all the files. 但这比仅使用git checkout name来获取其哈希ID存储在name name的提交要困难得多,这将获取所有文件。 The easier way to go is probably the way to go. 更简单的方法可能就是方法。

Other options 其他选择

Note that Git has various procedures for dealing with subtrees. 请注意,Git具有处理子树的各种过程。 Some of them are captured into a contributed script called git subtree , for which there is a tutorial here that seems OK (at a quick glance). 他们中有些人被捕获到称为贡献脚本git subtree ,对此有一个教程在这里 ,似乎OK(快速浏览)。 Using git subtree to split out the library now and then can get you just what you want. 现在使用git subtree拆分库,然后可以得到所需的内容。 I don't recommend using subtrees in general though—it's better to split "library-like" code into a completely separate repository. 我一般不建议使用子树-最好将“类似库的”代码拆分为一个完全独立的存储库。

You can then either use multiple independent repositories, which is pretty simple to do, or use git submodule to select particular commits from the "library" repository, in either the "using-library" repository that has all the rest of the code, or in a "gets-submodules-only" superproject that has both the using-the-library and providing-the-library repositories as its (now two) submodules. 然后,您可以使用多个非常简单的独立存储库,也可以使用git submodule从具有所有其余代码的“ using-library”存储库中的“ library”存储库中选择特定提交,或者在“仅获取子模块”超级项目中,该项目同时具有“使用库”和“提供库”存储库作为其(现在是两个)子模块。 That is, you either have: 也就是说,您有:

  • superproject: contains Component1/* , Component2/* , DelphiApp/* , PHPStuff/* , Configurations/* , and Utilities/* , and refers to a submodule NodeJSApp/ , plus 超级项目:包含Component1/*Component2/*DelphiApp/*PHPStuff/*Configurations/*Utilities/* ,并引用子模块NodeJSApp/ ,以及
  • library: contains files * that will live in a NodeJSApp/ directory as controlled by the superproject 库:包含文件* ,这些文件将NodeJSApp/在超级项目控制的NodeJSApp/目录中

Or, you have: 或者,您有:

  • superproject: refers to a submodule app/ , and refers to a submodule app/NodeJSApp/ superproject: 引用子模块app/ ,并且引用子模块app/NodeJSApp/

  • app: a Git repository containing Component1/* , Component2/* , etc., but does not refer to NodeJSApp/ at all. app:一个Git存储库,其中包含Component1/*Component2/*等,但根本不引用NodeJSApp/ The superproject will extract these to app/ so that their full names will be app/Component1/* , app/Component2/* , etc. 超级项目会将它们提取到app/以便其全名将为app/Component1/*app/Component2/*等。

  • library: a Git repository containing files named * that make up the library. 库:一个Git存储库,其中包含构成库的名为*文件。 The superproject will extract these to app/NodeJSApp/ so that their full names will be app/NodeJSApp/* . 超级项目会将它们提取到app/NodeJSApp/以便其全名将为app/NodeJSApp/*

The only difference between these, besides being forced to find everything under app/ for the second approach, is that with the second approach, you'll manage the two independent Git repositories—one for the app itself, and one for the library—independently, then use the superproject to say: build the project by extracting hash app from the app Git repository, and hash lib from the library Git repository. 除了被迫在第二种方法中在app/下查找所有内容之外,它们之间的唯一区别在于,使用第二种方法,您将独立管理两个独立的Git存储库-一个用于应用程序本身,一个用于库。 ,然后使用子项目会说: 从库中的Git仓库提取应用Git仓库散列应用程序 ,哈希LIB生成项目。 That is, neither subproject needs to be aware of Git-ness and hash IDs: only the superproject has to care about that. 也就是说, 两个子项目都不需要知道Git-ness和哈希ID:只有超级项目才需要关心这一点。

With the first approach, you eliminate the need for the app/ top level directory, but now every commit you make in the main app records a hash ID that Git should extract in the library submodule before you build. 使用第一种方法,您不需要app/顶层目录,但是现在您主应用程序中进行的每次提交都记录了哈希ID,Git应该在构建之前将Git提取到库子模块中。 If you update the library, you then need to record the new hash ID in the superproject. 如果更新库,则需要在超级项目中记录新的哈希ID。 This is the same as before, except "the superproject" is the app itself , rather than a third Git repository that merely contains the two submodule references. 这与以前相同,只是“超级项目” 应用程序本身 ,而不是仅包含两个子模块引用的第三个Git存储库。

The two-Git-repositories, one that has files and acts as superproject to pick out a particular commit in the submodule, is the more common approach. 比较常见的方法是两个Git存储库,它具有文件充当超级项目以在子模块中挑选特定的提交。 It's sometimes more convenient. 有时更方便。 The "one superproject to supervise everything else" method sometimes makes more sense , but it's definitely less common. 有时,“一个监督其他所有项目的超级项目”方法更有意义 ,但这种情况绝对不常见。

yes, you can. 是的你可以。 Just do not use submodules. 只是不要使用子模块。 subtree or subrepo can help you there. 子树或子仓库可以为您提供帮助。 You can make the 'NodeJSapp' a subtree or a subrepo in repoA. 您可以将'NodeJSapp'设为repoA中的子树或子仓库。 It will efficiently map the directory to the corresponding one-directory repository. 它将有效地将目录映射到相应的单目录存储库。

This way you'd be able to use repo A as a main one with atomic operations, like branching, across the whole tree, including the NodeJSApp directory. 这样,您就可以将repo A用作主要操作,并在整个树上(包括NodeJSApp目录)进行原子操作(例如分支)。 You would need to push and pull it periodically into RepoB. 您需要定期将其推入RepoB。 Submodules do not work this way. 子模块不能以这种方式工作。 Subtrees do, but in some limited facion. 子树可以,但是在某些方面是有限的。 Subrepos could be the best available opensource choice. Subrepos可能是最佳的开源选择。

There are custom ways to do it as well. 也有一些自定义方法可以做到这一点。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM