如何将子模块添加到子目录?

Rob*_*udi 282 git git-submodules

我有一个~/.janus/带有一堆子模块的git repo .我想添加一个子模块~/.janus/snipmate-snippets/snippets/,但是当我git submodule add <git@github.com:...>snipmate-snippets目录中运行时,我收到以下错误消息:

You need to run this command from the toplevel of the working tree.
Run Code Online (Sandbox Code Playgroud)

所以问题是:如何在snipmate-snippets目录中添加子模块?

Ber*_*nnF 402

你进入~/.janus并运行:

git submodule add <git@github ...> snipmate-snippets/snippets/
Run Code Online (Sandbox Code Playgroud)

如果您需要有关子模块(或一般git)的更多信息,ProGit非常有用.

  • 对我来说,这导致“索引中已经存在子项目”*(我使用子项目作为目录名称)*。相反,有帮助的是下面 VonC 的答案,即执行 `cd subprojects`,然后执行 `git submodule add &lt;get@github …&gt;` 而不带路径。 (5认同)
  • 添加分支时添加分支似乎是个好主意,否则 HEAD 很容易分离: git submodule add -b &lt;branch&gt; &lt;repository&gt; [&lt;submodule-path&gt;] (2认同)

Von*_*onC 78

请注意,启动git1.8.4(2013年7月),您不必再返回根目录.

 cd ~/.janus/snipmate-snippets
 git submodule add <git@github ...> snippets
Run Code Online (Sandbox Code Playgroud)

(Bouke Versteegh 评论说你不必使用/.,因为snippets/.:snippets就够了)

请参阅commit 091a6eb0feed820a43663ca63dc2bc0bb247bbae:

子模块:删除顶级要求

使用new rev-parse --prefix选项处理给予submodule命令的所有路径,从而从存储库的顶层删除它的运行要求.

由于相对子模块URL的解释取决于是否remote.origin.url配置了" git submodule add",因此当不在工作树的顶层时,在" "中显式阻止相对URL .

签约:John Keeping

取决于提交12b9d32790b40bf3ea49134095619700191abf1f

这使得' git rev-parse'的行为就好像是从存储库的指定子目录中调用它,区别在于它打印的任何文件路径都以工作树顶部的完整路径为前缀.

这对于我们可能希望cd在工作树顶部但需要处理用户在命令行上给出的相对路径的shell脚本很有用.


Chr*_*ini 17

我遇到了类似的问题,但是用GUI工具将自己画成了一个角落.

我有一个子项目,里面有几个文件,我到目前为止只是复制而不是检查他们自己的git repo.我在子文件夹中创建了一个repo,能够提交,推送等等.但是在父级repo中,子文件夹不被视为子模块,并且它的文件仍被父级仓库跟踪 - 没有好处.

为了摆脱这种混乱,我不得不告诉Git停止跟踪子文件夹(不删除文件):

proj> git rm -r --cached ./ui/jslib
Run Code Online (Sandbox Code Playgroud)

然后我不得不告诉它那里有一个子模块(如果git当前正在跟踪任何内容,你就无法做到):

proj> git submodule add ./ui/jslib
Run Code Online (Sandbox Code Playgroud)

更新

处理此问题的理想方法涉及更多步骤.理想情况下,现有的repo被移出到它自己的目录,没有任何父git模块,提交和推送,然后作为子模块添加,如:

proj> git submodule add git@bitbucket.org:user/jslib.git ui/jslib
Run Code Online (Sandbox Code Playgroud)

那将克隆git repo作为一个子模块 - 它涉及标准的克隆步骤,还有几个其他更加模糊的配置步骤,git代表你采取这些步骤来使子模块工作.最重要的区别是它在那里放置了一个简单的.git文件,而不是.git目录,其中包含真实git dir所在位置的路径引用 - 通常位于父项目root .git/modules/jslib.

如果你不以这种方式做事,他们会为你工作得很好,但是一旦你提交并推动父母,而另一个开发人员去拉那个父母,你只是让他们的生活更加艰难.只要你在一个包含自己的.git目录的目录的子文件夹中有一个完整的.git目录,他们就很难复制你机器上的结构.

所以,移动,推送,git add子模块,是最干净的选择.


yon*_*avi 16

对于那些与我分享我手动编辑配置文件的奇怪喜好的人来说,添加(或修改)以下内容也可以解决问题.

.git/config(个人配置)

[submodule "cookbooks/apt"]
    url = https://github.com/opscode-cookbooks/apt
Run Code Online (Sandbox Code Playgroud)

.gitmodules(已提交的共享配置)

[submodule "cookbooks/apt"]
    path = cookbooks/apt
    url = https://github.com/opscode-cookbooks/apt
Run Code Online (Sandbox Code Playgroud)

看看这个 - .gitmodules和.git/config中指定子模块之间的区别?