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

时间:2012-01-27 15:39:09

标签: 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.

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

5 个答案:

答案 0 :(得分:361)

您进入~/.janus并运行:

git submodule add <git@github ...> snipmate-snippets/snippets/

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

答案 1 :(得分:72)

请注意,从git1.8.4开始(2013年7月),您不必再返回根目录。

 cd ~/.janus/snipmate-snippets
 git submodule add <git@github ...> snippets

Bouke Versteegh comments您不必使用/.,如snippets/.snippets就足够了)

请参阅commit 091a6eb0feed820a43663ca63dc2bc0bb247bbae

  

子模块:删除顶级要求

     

使用新的rev-parse --prefix选项来处理为子模块命令提供的所有路径,从而删除从存储库的顶层运行的要求。

     

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

签名:John Keeping

取决于commit 12b9d32790b40bf3ea49134095619700191abf1f

  

这使得“git rev-parse”的行为就像从存储库的指定子目录中调用一样,区别在于它打印的任何文件路径都以前面的完整路径为前缀。工作树

     

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

答案 2 :(得分:17)

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

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

为了摆脱这种混乱,我不得不tell Git to stop tracking the subfolder(不删除文件):

proj> git rm -r --cached ./ui/jslib

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

proj> git submodule add ./ui/jslib

更新

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

proj> git submodule add git@bitbucket.org:user/jslib.git ui/jslib

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

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

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

答案 3 :(得分:14)

对于那些喜欢手动编辑配置文件的人来说,添加(或修改)以下内容也可以解决问题。

.git / config (个人配置)

[submodule "cookbooks/apt"]
    url = https://github.com/opscode-cookbooks/apt

.gitmodules (已提交共享配置)

[submodule "cookbooks/apt"]
    path = cookbooks/apt
    url = https://github.com/opscode-cookbooks/apt

同样见到这一点 - difference between .gitmodules and specifying submodules in .git/config?

答案 4 :(得分:2)

单行bash脚本,以帮助设置Chris上面的答案,因为我使用Vundle更新我的.vim脚本在角落里画了自己。 DEST是包含子模块的目录的路径。在执行git rm -r $DEST

之后执行此操作
DEST='path'; for file in `ls ${DEST}`; do git submodule add `grep url ${DEST}/${file}/.git/config|awk -F= '{print $2}'` ${DEST}/${file}; done

欢呼声