使用 Git 的项目中的项目
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/720669/
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
Projects within projects using Git
提问by SamGoody
How do I set up a Git project to contains other projects?
如何设置 Git 项目以包含其他项目?
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.
例如。我正在开发一个在线地图应用程序。我们开发了一个 GPS 工具和一个在 SF 的装备。我们同时开发了一个 Python Geomapping 脚本以及一个不同的关注点(只关心 geomapping)。我们自己的核心文件将两者结合起来,并在它们的基础上构建我们需要的应用程序。
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.
每个项目都必须单独存在——对 GPS 感兴趣的人只对 GPS 感兴趣——但是包括所有其他项目的“父”项目必须作为项目可访问。
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?
此外,如果可能的话,如果每个项目都可以包含一两个重叠的脚本,那就太好了。一个 Git 项目是否可以包含一个不属于其“根”的文件,以便当任一团队更新此文件时,双方都可以受益?
Is this doable with Git? With Mercurial? Does the host (GitHub, Gitorious) matter?
这对 Git 可行吗?用水银?主机(GitHub、Gitorious)重要吗?
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.
我有将 Subversion 用于“父”的想法——忽略 .git 文件夹,并为项目使用 Git(忽略 .svn 文件夹)——但这只是最后的手段。
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.
- 用户下载时,zip 不包含子模块(此处和此处)。当甚至合作者尝试设置项目时也是如此。这是一个节目塞子。
- 子模块被冻结 - 它们不会(轻松)获取指向的项目的最新版本。
- 在下面的精彩答案和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.)
子树合并(由 Paul 在下面介绍给我)不会做:很难从合并到的项目中更新 [子树的] 源,并且该源必须驻留在项目的“根”文件夹之外该项目。作为一个网络应用程序,至关重要的是我的所有页面都在内部链接到其中的一个文件夹,并且测试和更新直接在该文件夹中完成。(希望这对其他人来说是清楚和有用的。)
Still studying setting up 'remote branches' but other ideas are still welcome.
仍在研究设置“远程分支”,但仍然欢迎其他想法。
采纳答案by Paul
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:
有两种可能性可以将子项目作为独立的 git 存储库保存到您的主(集成)存储库中:
Using subtree mergeto bring your external projects into separate subdirectoriesin 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 branchin 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.
使用子树合并将外部项目放入包含核心文件的主存储库中的单独子目录中。这使得从外部项目更新主项目变得容易,但将更改发送回外部项目变得复杂。我认为这是包含项目依赖项的好方法,但它不适用于共享文件。 另一个简单的解释(链接已修复)。
将每个项目设置为您的主存储库中的远程分支,并从它们中的每一个合并到您的
master
(集成)分支中,该分支也包含您的核心文件。这需要一些纪律:如果您对主 repo 中的外部项目进行任何更改,则必须在分支中进行更改,然后合并到 master 中;并且您永远不想合并到项目分支中。这使得将更改发送回外部项目变得容易,并且是 Git 中完全可以接受的分支用法。您的共享脚本可以作为主目录中的另一个独立分支进行处理,您的外部合作伙伴可以将其作为远程分支拉取和推送到该分支。
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.
如果您尝试在同一目录中运行 SVN 和 Git,那么在任一系统中都很难使用分支,因为 SVN 通过复制文件目录来进行分支,而 Git 会跟踪指针。两个系统都不会自动看到您在另一个系统中创建的分支。我认为“解决方案”比它的价值更麻烦。
回答by richq
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.
我使用 git 将我自己的 github 托管项目和我想使用的外部 UI 库拼接在一起。该库托管在 sourceforge 上的 subversion 存储库中。
I used git-submodule and git-svn and it worked reasonably well. The downsides were:
我使用了 git-submodule 和 git-svn,它运行得相当好。缺点是:
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.
为了与库存储库保持同步,我必须执行新的提交来更新子模块 git hash“指针”。这是因为 git 子模块与 svn:externals 不同,它被固定到特定的提交 ID。如果你真的想固定一个稳定版本,这可能不是一个实际的缺点,我正在使用 WIP 的代码。
带有子模块的 git repo 的初始拉取需要一个额外的步骤“git submodule init”。这对您来说不是问题,但对于使用您的代码的其他人来说,他们必须记住或被告知在编译/运行/测试您的代码之前执行此步骤。
如果你使用命令行,很容易用 git-add 搞砸你的存储库。这是因为您键入
git add subm<tab>
以完成到git add submodule
,但它会自动完成以git add submodule/
- 请注意尾部斜杠。如果您使用尾部斜杠执行该命令,那么它会闪电战子模块并添加其包含的所有文件。这可以通过使用 git-gui 来缓解,git add .
或者只是训练自己删除斜杠(这发生在我身上的次数太多了,我训练自己删除它)子模块提交可能会弄乱 git rebase -i。我忘记了确切的细节,但如果你有一个“脏”的子模块并且你运行一个 rebase-interactive,那就特别糟糕了。通常情况下,对于脏树,您不能变基,但不会检查子模块。在一个 rebase 组中有多个子模块提交也会导致问题。最后一个子模块哈希被提交到列表中的第一个选择,这在以后修复非常棘手。这可以通过更仔细的工作流程解决(即仔细决定何时进行子模块提交......)但可以是 PITA。
The steps to set this up were something along the lines of:
设置它的步骤大致如下:
- Run
git svn clone https://project.svn.sourceforge.net/svnroot/project/project/trunk
- Push that as a "real" git project to e.g. github
- Now in your own git repository, run
git submodule init
git submodule add git://github.com/project subproject
- Push that out too, to your own repo this time.
- 跑
git svn clone https://project.svn.sourceforge.net/svnroot/project/project/trunk
- 将其作为“真正的”git 项目推送到例如 github
- 现在在您自己的 git 存储库中,运行
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:
每次您需要更新地理映射代码时,您将运行如下代码:
cd subproject
git svn rebase
git svn push # this updates the git mirror of the subproject
cd ..
git add subproject # careful with the trailing slash!
git commit -m "update subproject"
git push # this pushes the commit that updates the subproject
I've not seen to many tutorials on a git submodule work flow, so I hope this helps you decide.
我没有看过很多关于 git 子模块工作流程的教程,所以我希望这能帮助你做出决定。
回答by SamGoody
From the little I've read about Externals, it appears to be a port of SVN 'externals' to GIT.
从我对Externals 的了解来看,它似乎是 SVN 'externals' 到 GIT 的一个端口。
This solves some of problems with GIT submodules, including updating to the latest version automatically.
这解决了 GIT 子模块的一些问题,包括自动更新到最新版本。
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.
虽然我没有 SVN 外部或这个项目的经验,但对于某些人来说,它可能是比其他任何人都更好的解决方案。
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)
或者,以下软件(看起来可以与 GitHub 一起使用)。对于某些人来说,可能是另一种剥猫皮的方法: Braid(Softpedia 页面)
回答by Caotic
git-submodule might be what you are looking for:
git-submodule 可能就是你要找的:
http://book.git-scm.com/5_submodules.html
http://book.git-scm.com/5_submodules.html
回答by Bob Aman
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.
这取决于您所从事的项目类型,以及需要与 SCM 交互的工具(如果有)。例如,Rails 经常使用 Capistrano 进行部署,而 Capistrano 对相对于存储库根目录的目录结构做出了某些假设。在这种情况下,如果您有多个相互关联的 rails 应用程序,则需要使用子模块。每个应用程序都有自己的存储库,然后你有一个更大的存储库,将每个独立的存储库作为子模块进行管理。
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.
在 git 中很难在维护版本历史记录的同时提取存储库的某些子部分作为它自己的独立实体,因此提前计划是个好主意。
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.
至于你的具体问题,老实说,我认为这是一个完美的例子,说明了几个子模块是理想的。关于共享脚本,如果由于某种原因这实际上是一个证明有问题的问题,您始终可以使用符号链接。