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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/9035895/
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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-10 12:50:57  来源:igfitidea点击:

How do I add a submodule to a sub-directory?

gitgit-submodules

提问by Robert Audi

I have a git repo in ~/.janus/with a bunch of submodules in it. I want to add a submodule in ~/.janus/snipmate-snippets/snippets/, but when I run git submodule add <[email protected]:...>in the snipmate-snippetsdirectory, I get the following error message:

我有一个 git repo,里面~/.janus/有一堆子模块。我想在 中添加一个子模块~/.janus/snipmate-snippets/snippets/,但是当我git submodule add <[email protected]:...>snipmate-snippets目录中运行时,我收到以下错误消息:

You need to run this command from the toplevel of the working tree.

So the question is: How do I add a submodule to the snipmate-snippetsdirectory?

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

回答by BergmannF

You go into ~/.janusand run:

你进入~/.janus并运行:

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

If you need more information about submodules (or git in general) ProGitis pretty useful.

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

回答by VonC

Note that starting git1.8.4(July 2013), you wouldn't have to go back to the root directory anymore.

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

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

(Bouke Versteeghcommentsthat you don't have to use /., as in snippets/.: snippetsis enough)

Bouke Versteegh评论,你不必使用/.,如snippets/.snippets就够了)

See commit 091a6eb0feed820a43663ca63dc2bc0bb247bbae:

提交 091a6eb0feed820a43663ca63dc2bc0bb247bbae

submodule: drop the top-level requirement

Use the new rev-parse --prefixoption to process all paths given to the submodule command, dropping the requirement that it be run from the top-level of the repository.

Since the interpretation of a relative submodule URL depends on whether or not "remote.origin.url" is configured, explicitly block relative URLs in "git submodule add" when not at the top level of the working tree.

Signed-off-by: John Keeping

子模块:删除顶级需求

使用新rev-parse --prefix选项处理提供给 submodule 命令的所有路径,删除从存储库的顶级运行它的要求。

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

签字人:John Keeping

Depends on commit 12b9d32790b40bf3ea49134095619700191abf1f

取决于提交 12b9d32790b40bf3ea49134095619700191abf1f

This makes 'git rev-parse' behave as if it were invoked from the specified subdirectory of a repository, with the difference that any file paths which it prints are prefixed with the full path from the top of the working tree.

This is useful for shell scripts where we may want to cdto the top of the working tree but need to handle relative paths given by the user on the command line.

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

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

回答by Chris Moschini

I had a similar issue, but had painted myself into a corner with GUI tools.

我有一个类似的问题,但我用 GUI 工具把自己画到了一个角落里。

I had a subproject with a few files in it that I had so far just copied around instead of checking into their own git repo. I created a repo in the subfolder, was able to commit, push, etc just fine. But in the parent repo the subfolder wasn't treated as a submodule, and its files were still being tracked by the parent repo - no good.

我有一个包含几个文件的子项目,到目前为止我只是复制了这些文件,而不是检查他们自己的 git 存储库。我在子文件夹中创建了一个 repo,能够提交、推送等。但是在父仓库中,子文件夹不被视为子模块,并且父仓库仍在跟踪其文件 - 不好。

To get out of this mess I had to tell Git to stop tracking the subfolder(without deleting the files):

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

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

Then I had to tell it there was a submodule there (which you can't do if anything there is currently being tracked by git):

然后我不得不告诉它那里有一个子模块(如果 git 当前正在跟踪任何东西,你就不能这样做):

proj> git submodule add ./ui/jslib

Update

更新

The ideal way to handle this involves a couple more steps. Ideally, the existing repo is moved out to its own directory, free of any parent git modules, committed and pushed, and then added as a submodule like:

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

proj> git submodule add [email protected]:user/jslib.git ui/jslib

That will clone the git repo in as a submodule - which involves the standard cloning steps, but also several other more obscure config steps that git takes on your behalf to get that submodule to work. The most important difference is that it places a simple .git file there, instead of a .git directory, which contains a path reference to where the real git dir lives - generally at parent project root .git/modules/jslib.

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

If you don't do things this way they'll work fine for you, but as soon as you commit and push the parent, and another dev goes to pull that parent, you just made their life a lot harder. It will be very difficult for them to replicate the structure you have on your machine so long as you have a full .git dir in a subfolder of a dir that contains its own .git dir.

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

So, move, push, git add submodule, is the cleanest option.

因此,move、push、git add submodule 是最干净的选择。

回答by yoniLavi

For those of you who share my weird fondness of manually editing config files, adding (or modifying) the following would also do the trick.

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

.git/config(personal config)

.git/config(个人配置)

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

.gitmodules(committed shared config)

.gitmodules(提交的共享配置)

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

See this as well - difference between .gitmodules and specifying submodules in .git/config?

也看到这一点 - .gitmodules 和在 .git/config 中指定子模块之间的区别?

回答by Rick R

one-liner bash script to help facility Chris's answer above, as I had painted myself in a corner as well using Vundle updates to my .vim scripts. DESTis the path to the directory containing your submodules. Do this after doing git rm -r $DEST

单行 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 }'` ${DEST}/${file}; done

cheers

干杯