子模块,子树或其他依赖关系在Git? [英] Submodules, subtrees or something else for dependencies in Git?

查看:189
本文介绍了子模块,子树或其他依赖关系在Git?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个更大的项目的情况,有大量的模块/图书馆有各自的回馈。这些模块中的大多数都是与项目依赖关系的其他模块的依赖关系。现在已经到了主要项目有几个子项目,许多模块正在分享。一些依赖关系深入3-4级以上。



我已经看到可以更新/拉出项目内的子模块,但这只能用于第一级的子模块。让我们说这些子模块有自己的子模块(第二级),一些第一级子模块共享相同的二级子模块。另外,第二个lvl子模块有它们的子模块(lvl3)等等。现在我应该做的是首先推动第三级的更改,而不是更新第二级模块中的子模块,然后推送它们,现在我可以去第一级,更新和推送,最后更新我的项目子模块并推送它们。



现在这不仅仅是更多的工作,但仍然不能解决我的问题,为什么我需要这样的东西那就是当对那些依赖于彼此的人进行改变时,能容易地推拉多个存储库。很容易发生的是,一个团队中的某个人推送5个回馈中的4个更改,当其他成员拉出所有其他成员,除了这一个生产线停止,直到发现错误。



我该怎么办?也许有一些关于工作流的建议,有其他任何人遇到这个问题,或者是在Git中有一些解决这个问题的功能。

解决方案

推荐android使用的回购工具。它是通用的,可以使用任何git托管环境,并且不需要超级项目提交更新子项目,如子模块。



首先,安装客户端如下所述: https://source.android.com/source/downloading.html #installation-repo



然后创建一个清单存储库。清单是一个xml文件,用于描述应该检出的git仓库位置和路径。像这样:

  mkdir清单
cd清单
git init

创建清单文件 default.xml

 <?xml version =1.0encoding =UTF-8?> 
< manifest>
< remote name =githubfetch =ssh://git@github.com/>
< default remote =githubrevision =master/>
< project name =git / git.gitpath =git/>
< project name =libgit2 / libgit2.gitpath =vendor / libgit2/>
< / manifest>

然后添加,提交清单,然后推到某处:

  git add default.xml 
git commit -m我第一次在清单文件中尝试
git push git@github.com:myusername /现在你已经准备好使用 repo $ / code code>命令。

  mkdir myproject 
cd myproject
repo init -u git @ github。 com:myusername / manifestests.git
repo sync -j2

您的git存储库将被克隆。你现在可以像正常一样工作在每一个。在推送到任何项目之后,所有其他人都需要做的是一个 repo sync ,它们将被更新到最新版本(另见



注意事项



您可能需要重新组织项目。通常,您可能有其他模块作为子目录( myproject / vendor / dependency )。虽然您仍然可以使用repo维护此布局,但会导致使用另一个repo检出git仓库。使用 .gitignore 诡计可能是可行的,但我建议重新组织您的项目,所以存储库不需要彼此签出。



清单文件的简短说明



请参阅 https://gerrit.googlesource.com/git-repo/+/master/docs/manifest-format.txt ,以完整解释xml文件中的每个项目。



请参阅 https://source.android.com/source/using-repo.html ,以获取简单的命令参考。 repo help 也非常有用。注意:您应该忽略 repo upload ,除非您使用Gerrit。



< remote name =githubfetch =ssh://git@github.com/>



这就像添加一个远程在 git 中。这意味着我们可以使用给定的名称来引用URL。



< default remote =githubrevision =master/>



默认元素指定项目的默认选项。这相当于在每个项目上添加远程修订版本项目。这只是保存一些打字。



< project name =git / git.gitpath =git/>



这是真正的工作正在发生的地方。 repo sync 将使用该名称,并使用斜杠将其附加到远程。在这种情况下,remote是默认的 github ,所以它会得到url ssh://git@github.com/git/git.git 。它将在指定的修订版本(在这种情况下,默认值为 master )中将项目签到路径 git 。随后 repo sync 将检出最新的修订版本(在分支的情况下)。


I have a situation with a larger project that has lots of modules/libraries with their respective repos. Most of these modules are dependencies of other modules which are than dependencies of a project. And now it has come to the point where the main project has several sub-projects and many of modules are being shared. Some dependencies are more than 3-4 levels deep.

I have read that it is possible to update/pull submodules inside of a project, but that works only for 1st level of submodules. Let's say that those submodules have their own submodules (2nd level) and that some 1st level submodules share the same 2nd level submodules. Also, 2nd lvl submodules have their submodules (lvl3), etc. Now what I should do is to firstly push changes made in 3rd level, than update submodules in 2nd level modules and push those, now I can go to 1st level, update and push, and finally update my project submodules and push those.

This is now not only more work, but it still doesn't solve my problem why I need something like this and that is to be able to easily push and pull multiple repositories when changes were being made to those that dependent on each other. It can easily happen that someone in a team pushes changes in 4 of 5 repos, and when other members pull all except this one production line stops until error has been found.

What can I do about this? Maybe some advices about workflow, has anyone else encountered this problem or is there some feature in Git that solves this.

解决方案

I would recommend the repo tool that android uses. It is generic enough to work with any git hosting environment, and doesn't require super-project commits to update sub-projects like submodules does.

First, install the client as described here: https://source.android.com/source/downloading.html#installing-repo

Then create a manifest repository. A manifest is an xml file that describes git repository locations and paths they should be checked out to. Like this:

mkdir manifests
cd manifests
git init

Create a manifest file default.xml:

<?xml version="1.0" encoding="UTF-8"?>
<manifest>
  <remote name="github" fetch="ssh://git@github.com" />
  <default remote="github" revision="master" />
  <project name="git/git.git" path="git" />
  <project name="libgit2/libgit2.git" path="vendor/libgit2" />
</manifest>

Then add, commit the manifest, and push somewhere:

git add default.xml
git commit -m "My first try at a manifest file"
git push git@github.com:myusername/manifests.git master

Now you are ready to use the repo command.

mkdir myproject
cd myproject
repo init -u git@github.com:myusername/manifests.git
repo sync -j2

Your git repositories will be cloned. You can now work in each one like normal. After you push to any of the projects, all anyone else needs to do is a repo sync and they will be updated to the latest revision (also see repo start).

Caveats

You may have to reorganize your project. Typically you might have other modules as sub-directories (myproject/vendor/dependency). While you can still maintain this layout using repo, it will cause a git repository to be checked out with another repo. With .gitignore trickery it might be workable, but I would recommend reorganizing your project so repositories do not need to be checked out within each other.

A short explanation on manifest files

See https://gerrit.googlesource.com/git-repo/+/master/docs/manifest-format.txt for a complete explanation of each item in the xml file.

See https://source.android.com/source/using-repo.html for a simple command reference. repo help is also very useful. Note: you should ignore repo upload unless you are using Gerrit.

<remote name="github" fetch="ssh://git@github.com" />

This is just like adding a remote in git. It means we can refer to the url with a given name.

<default remote="github" revision="master" />

The default element specifies default options for the projects. This is equivalent of adding the remote and revision items on every project. This just saves some typing.

<project name="git/git.git" path="git" />

This is where the real work is happening. repo sync will take the name and append it to the remote using a slash. In this case the remote is the default github, so it will get the url ssh://git@github.com/git/git.git. It will checkout the project to the path git at the specified revision (in this case the default is master). Subsequent repo syncs will checkout the latest revision (in the case of a branch).

这篇关于子模块,子树或其他依赖关系在Git?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆