使用 Git 的项目内的项目
如何设置 Git 项目来包含其他项目?
例如。 我正在开发一个在线地图应用程序。 我们与旧金山的一家公司一起开发了一款 GPS 工具。 我们同时开发了一个 Python Geomapping 脚本,同时还有一个不同的关注点(只关心地理映射)。 我们自己的核心文件将两者结合起来,并在它们的基础上构建我们需要的应用程序。
每个项目都必须单独存在 - 对 GPS 感兴趣的人只对 GPS 感兴趣 - 但包含所有其他项目的“父”项目必须可作为项目访问。
我花了一些时间试图理解子模块,但它们似乎对于所需的内容有太多的独立性。
另外,如果可能的话,如果每个项目都可以包含一两个重叠的脚本,那就太好了。 一个 Git 项目是否可以包含一个不属于其“根”部分的文件,以便当任一团队更新该文件时,双方都可以受益?
这可以用 Git 实现吗? 与水银? 主机(GitHub、Gitorious)重要吗?
我有使用 Subversion 作为“父级”的想法 - 忽略 .git 文件夹,并使用 Git 作为项目(忽略 .svn 文件夹) - 但这只是最后的手段。
编辑:
解释为什么我不需要子模块:
- 当用户下载时,zip不包含子模块(此处 & 此处)。 当合作者尝试设置项目时也是如此。 这是一个表演终结者。
- 子模块被冻结 - 它们无法(轻松)获取所指向的项目的最新版本。
- 其他原因在下面精彩的答案和NoPugs 的独白中指出。
子树合并(由 Paul 在下面向我介绍)是行不通的:很难从合并到的项目中更新[子树]的源代码,并且该源代码必须位于子树的“根”文件夹之外该项目。 作为一个网络应用程序,至关重要的是我的所有页面都内部链接到其中的文件夹,并且测试和更新直接在该文件夹中完成。 (希望这对其他人来说是清楚且有用的。)
仍在研究设置“远程分支”,但仍然欢迎其他想法。
How do I set up a Git project to contains other projects?
eg. I am working on an online mapping app. We developed a GPS tool together with an outfit in SF. We simultaneously developed a Python Geomapping script together with a different concern (that only cares about geomapping). Our own core files unite the two, and build upon them for the app we need.
Each of the projects must exist by itself - the folks that have interest in the GPS only have interest in GPS - but the "parent" project which includes all of the others must be accessible as a project.
I've spent some time trying to understand submodules, but they appear to have too much independence for what is needed.
Also, if possible, it would be nice if each of those projects could contain one or two overlapping scripts. Could one Git project include a file that is not part of its 'root' so that when this file is updated by either team both can benefit?
Is this doable with Git? With Mercurial? Does the host (GitHub, Gitorious) matter?
I have the idea of using Subversion for the 'parent' - ignoring the .git folders, and using Git for the projects (ignoring .svn folders) - but that is only a last resort.
edit:
To explain why I don't want Submodules:
- When users download, the zip does not include the submodules (here & here).
Ditto when even collaborators try to setup the project. This is a show stopper. - Submodules are frozen - they do not (easily) pick up the latest version of the project that is being pointed to.
- Other reasons as pointed out in the fantastic answers below and in this monologue at NoPugs.
Subtree-merging (introduced to me by Paul, below) will not do: It is difficult to update the source [of a subtree] from within the project it is merged into, and that source must reside outside of the 'root' folder of the project. Being a web app, it is vital that all my pages link internally to a folder within them, and that testing and updates be done directly within that folder. (Hope this is clear and useful to others.)
Still studying setting up 'remote branches' but other ideas are still welcome.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
我还没有发现子模块对于我从事过的(小型)项目特别有用。 设置完成后,处理整个项目需要向几乎每个命令添加额外的参数,并且语法并不完全规则。 我想如果我从事具有更多子模块的更大项目,我会认为这是一个更有利的权衡。
有两种可能性可以将子项目保留为独立的 git 存储库,您可以将其拉入主(集成)存储库:
使用子树合并 kernel.org/pub/software/scm/git/docs/howto/using-merge-subtree.html" rel="noreferrer">将外部项目放入包含核心的主存储库中的单独子目录文件。 这使得从外部项目更新主项目变得容易,但将更改发送回外部项目变得复杂。 我认为这是包含项目依赖项的好方法,但它不适用于共享文件。 另一个简单的解释(链接已修复)。
将每个项目设置为主存储库中的远程分支,并将每个项目合并到还包含核心文件的
master
(集成)分支中。 这需要一些纪律:如果您对主存储库中的外部项目进行任何更改,则必须在分支中进行更改,然后合并到主库中; 并且您永远不想合并到项目分支中。 这使得将更改发送回外部项目变得很容易,并且是 Git 中分支的完全可接受的使用。您的共享脚本可以作为主目录中的另一个独立分支进行处理,您的外部合作伙伴可以将其作为远程分支从中提取和推送。
如果您尝试运行 SVN & 如果 Git 位于同一目录中,则在任一系统中都很难使用分支,因为 SVN 通过复制文件目录来进行分支,而 Git 则跟踪指针。 两个系统都不会自动看到您在另一个系统中创建的分支。 我认为“解决方案”带来的麻烦大于其价值。
I haven't found submodules to be particularly useful on the (small) projects I've worked on. Once you've set them up, working on the whole project requires adding additional parameters to almost every command and the syntax isn't completely regular. I imagine if I worked on larger projects with more submodules, I'd see it as a more beneficial tradeoff.
There are two possibilities that keep the sub-projects as independent git repos that you pull from into your main (integration) repo:
Using subtree merge to bring your external projects into separate subdirectories in your main repo that includes your core files. This makes it easy to update the main project from the external projects, but complicated to send changes back to the external projects. I think of this as a good way to include project dependencies, but it wouldn't work so well with shared files. Another simple explanation (link fixed).
Set up each project as a remote branch in your main repo and merge from each of them into your
master
(integration) branch that also contains your core files. This requires some discipline: if you make any changes to the external projects in your main repo, they must be made in the branch and then merged into the master; and you never want to merge into the project branches. This makes it easy to send changes back to the external projects and is a perfectly acceptable use of branches in Git.Your shared scripts can be handled as another independent branch in your main directory which your external partners can pull from and push to as a remote branch.
If you try to run SVN & Git in the same directory, you make it very hard to use branching in either system, because SVN does branching by copying file directories while Git tracks pointers. Neither system would automatically see branches you make in the other. I think that 'solution' is more trouble than it is worth.
我使用 git 将我自己的 github 托管项目和我想要使用的外部 UI 库拼接在一起。 该库托管在 sourceforge 上的 subversion 存储库中。
我使用了 git-submodule 和 git-svn 并且效果相当好。 缺点是:
为了与库存储库保持同步,我必须执行新的提交来更新子模块 git 哈希“指针”。 这是因为 git 子模块与 svn:externals 不同,被固定到特定的提交 ID。 如果您确实想要固定稳定版本,这可能不是一个实际的缺点,我正在使用 WIP 的代码。
带有子模块的 git 存储库的初始拉取需要“git submodule init”的额外步骤。 这对您来说不是问题,但对于使用您代码的其他人来说,他们必须记住或被告知在编译/运行/测试您的代码之前执行此步骤。
如果你使用命令行,很容易用 git-add 搞砸你的存储库。 这是因为您输入
git add subm
来完成git add submodule
,但它会自动完成到git add submodule/
-请注意结尾的斜杠。 如果您执行带有尾部斜杠的命令,那么它会快速扫描子模块并添加其包含的所有文件。 通过使用 git-gui、git add .
或只是训练自己删除斜杠(这发生在我身上很多次,我训练自己删除它)可以缓解这种情况子模块提交可能会搞砸git rebase -i。 我忘记了确切的细节,但如果你有一个“脏”子模块并且运行了 rebase-interactive,那就特别糟糕了。 通常,对于脏树,您无法变基,但不会检查子模块。 在变基组中提交多个子模块也会导致问题。 最后一个子模块哈希被提交给列表中的第一个选择,这在以后修复起来非常棘手。 这可以通过更仔细的工作流程来解决(即仔细决定何时进行子模块提交...),但可能是 PITA。
设置此步骤的步骤大致如下:
或多或少就是这样。 您将有一个新目录“subproject”,在您的情况下它将是地理映射库。
每次您需要更新地理映射代码时,您都会运行以下内容:
我还没有看到很多关于 git 子模块工作流程的教程,所以我希望这可以帮助您做出决定。
I've used git to stitch together my own github hosted project and an external UI library that I wanted to use. The library is hosted in a subversion repository on sourceforge.
I used git-submodule and git-svn and it worked reasonably well. The downsides were:
In order to keep up to date with the library repository, I had to perform a new commit to update the submodule git hash "pointer". This is because git submodules, unlike svn:externals, are pinned to a particular commit id. This may not be an actual downside if you actually want to pin a stable version, I was working with code that was WIP.
The initial pull of a git repo with submodules requires an additional step with "git submodule init". This is not an issue for you, but for others using your code they will have to remember or be told to perform this step before compiling/running/testing your code.
If you use the command line it is easy to screw up your repository with git-add. This is because you type
git add subm<tab>
to complete togit add submodule
, but it auto-completes togit add submodule/
- note the trailing slash. If you execute the command with the trailing slash, then it blitzes the submodule and adds all its contained files instead. This is mitigated by using git-gui,git add .
or just training yourself to delete the slash (it happened to me enough times that I trained myself to remove it)Submodules commits can mess up git rebase -i. I forget the exact details, but it is especially bad if you have a "dirty" submodule and you run a rebase-interactive. Normally with a dirty tree you can't rebase, but submodules are not checked. Having several submodule commits in a rebase group also causes problems. The last submodule hash gets committed to the first pick on your list, and this is pretty tricky to fix later. This can be worked around with a more careful workflow (i.e. carefully deciding when to do your submodule commits...) but can be a PITA.
The steps to set this up were something along the lines of:
git svn clone https://project.svn.sourceforge.net/svnroot/project/project/trunk
git submodule init
git submodule add git://github.com/project subproject
That is it, more or less. You will have a new directory "subproject", which in your case would be the geomapping library.
Each time you need to update the geomapping code, you would run something like:
I've not seen to many tutorials on a git submodule work flow, so I hope this helps you decide.
git-submodule 可能就是您正在寻找的:
http://book.git-scm.com /5_submodules.html
http://git-scm.org/gitwiki/GitSubmoduleTutorial< /a>
git-submodule might be what you are looking for:
http://book.git-scm.com/5_submodules.html
http://git-scm.org/gitwiki/GitSubmoduleTutorial
从我读过的关于 Externals 的内容来看,它似乎是 SVN 'externals 的一个端口'到吉特。
这解决了 GIT 子模块的一些问题,包括自动更新到最新版本。
虽然我没有 SVN 外部或这个项目的经验,但对于某些人来说,它可能是比其他发布的解决方案更好的解决方案。
或者,可以使用以下软件(看起来可以与 GitHub 一起使用)。 对于某些人来说,可能是另一种剥猫皮的方法:
编织 (Softpedia 页面)
From the little I've read about Externals, it appears to be a port of SVN 'externals' to GIT.
This solves some of problems with GIT submodules, including updating to the latest version automatically.
While I have no experience with SVN externals or with this project, it might be a better solution for some than any of the others posted.
Alternatively, the following software (looks like it can be used with GitHub). May be another way for some to skin the cat:
Braid (Softpedia page)
这取决于您正在从事什么类型的项目,以及需要哪些工具(如果有)与您的 SCM 交互。 例如,Rails 经常使用 Capistrano 进行部署,Capistrano 对目录结构相对于存储库根的外观做出某些假设。 在这种情况下,如果您有多个相互关联的 Rails 应用程序,则需要使用子模块。 每个应用程序都有自己的存储库,然后您就有一个更大的存储库,将每个独立存储库作为子模块进行管理。
即使您没有做出此类假设的工具,如果有一天您可能想要独立使用较大项目的一小部分或重用,那么良好的存储库设计也要求您将事情分解一点一些独立项目中的一些大段代码。
在 git 中,在维护版本历史记录的同时提取存储库的某些子部分作为其自己的单独实体是很困难的,因此提前计划是个好主意。
至于你的具体问题,老实说,我认为这是一个完美的例子,说明几个子模块是理想的。 关于共享脚本,如果由于某种原因这实际上是一个被证明有问题的问题,您始终可以使用符号链接。
It depends on what kind of project you're working on, and what tools, if any, need to interact with your SCM. Rails, for example, often uses Capistrano to deploy, and Capistrano makes certain assumptions about what your directory structure will look like relative to the root of your repository. In this case, if you have several interrelated rails apps, you need to use submodules. Each app gets its own repository, and then you have a larger repository that manages each of the independent repositories as submodules.
Even if you don't have tools that make these kind of assumptions, good repository design requires that you break things up a bit if there's even the slightest possibility that some day you might want to use a subsection of a larger project independently, or reuse some large swath of code within some independent project.
Extracting out some subsection of a repository as its own separate entity while maintaining version history is difficult in git, and so it's a good idea to plan ahead.
As for your specific question, honestly, I'd call that a perfect example of where a couple submodules would be ideal. With regard to sharing scripts, if for some reason that's actually an issue that proves problematic, you can always use a symlink.
我使用这些“外部”子组件,使它们相当独立,遵循 https://github.com/jmnavarrol/simplest-git-subrepos (免责声明:我是其作者)。
事实上,我正在使用 Python 端口,因此我能够添加 Bash 中困难的功能,例如子存储库配置文件是 YAML,例如:
这允许两个“修复”版本分发以及轻松开发,适用于“主”项目和“相关”项目。
I work with those "external" subcomponents by making them fairly independant, following the tracks of https://github.com/jmnavarrol/simplest-git-subrepos (disclaimer: I'm its author).
I'm in fact working of a Python port so I'm able to add features difficult in Bash, like the subrepos config file being YAML, something like, i.e.:
This allows both "fixing" versions for distribution as well as easy development, both for "master" and "related" projects.