如果我从我的工作(父)目录创建初始提交会发生什么,但是有子库有独立签出的git repos?
我只是做了git add .
但是当带有嵌套Git repos的子目录没有被注册为父仓库的子模块时,这让我陷入了一种奇怪的境地。
所以:如何在最初的“git add”之后继续。在一个父工作目录中,哪里有子库与独立检出的嵌套git回购(为了获得正确的子模块)?
一个例子:
[imz@z super-existing-sub]$ ls
c sub
[imz@z super-existing-sub]$ ls -a sub/
. .. a .git
[imz@z super-existing-sub]$
因此,super-existing-sub/sub
内已存在预先存在的super-existing-sub
git repo。
我跑进super-existing-sub
后:
$ git init
$ git add .
如何正确注册预先存在的Git仓库作为子模块?
现在,Git以某种方式跟踪了它:
$ git status
On branch master
Initial commit
Changes to be committed:
(use "git rm --cached <file>..." to unstage)
new file: c
new file: sub
$
但是git submodule
有一些问题:
$ git submodule status
No submodule mapping found in .gitmodules for path 'sub'
$
如何将其转换为正确的子模块?
我试着按照答案中提出的方式(由Victor和我组成)进行,即git submodule add URL subdir
,但不幸的是,这打破了:
$ git submodule status
No submodule mapping found in .gitmodules for path 'wp-content/themes/liquorice'
$ git submodule add git@github.com:/nudgeme/Liquorice.git ./wp-content/themes/liquorice
'wp-content/themes/liquorice' already exists in the index
/sshx:kosmoplus:/home/kosmoplus/kosmoplus.ru.old $ git submodule status
No submodule mapping found in .gitmodules for path 'wp-content/themes/liquorice'
$
答案 0 :(得分:3)
(我总是使用git submodule init
让git识别它们,然后git submodule update
将子模块实际克隆到工作目录中。但这不是被问到的情况。)< / p>
要从父目录创建新的git仓库,您需要在父目录上运行git init
,然后git submodule add ./path/to/submodule/
。
注意:子模块的路径必须是绝对路径,因此您应该在路径前加上./
或者,如果您想要一个好的外部URL作为子模块的URL,您应该首先在./path/to/submodule/.git/config
中查找原始URL,然后您应该能够
git submodule add URL ./path/to/submodule/
在实践中还没有尝试过,但是git-submodule的联机帮助页说:
如果
<path>
确实存在并且已经是有效的Git存储库,则会将其添加到变更集而不进行克隆。提供第二个表单是为了便于从头开始创建一个新的子模块,并假设用户稍后将子模块推送到给定的URL。
答案 1 :(得分:3)
在维克多·约翰逊的回答的基础上,这里有一个bash oneliner,可以同时添加一整个子模块。
find . -name config | grep git/config | grep -v ProjectToExclude | grep -v AnotherProjectToExclude | xargs -n 1 -I % sh -c 'cat % | grep -m 1 url | sed "s/url = //g"; echo % | sed "s/.git\/config//g";' | xargs -n 2 echo git submodule add
假设您有一个包含许多git repos的文件夹,并且您希望父repo将它们全部作为子模块:
path/to/one_repo
path/to/one_repo/.git/config
path/to/another_repo
path/to/another_repo/.git/config
(etc.)
你想为每一个都运行git submodule add ./path/to/submodule/
。
<强> 1。此oneliner为每个可能的子模块打印该命令。以干运行方式运行它以查看哪些文件夹包含.git/config
个url =
文件。请注意,它假定第一次出现的url
是远程的 - 确保您理智地检查结果。
oneliner再次解释说:
find . -name config | # find all config files
grep git/config | # include only those that have "git/config" in their path
grep -v ProjectToExclude | # exclude config files with ProjectToExclude in their path
grep -v AnotherProjectToExclude | # ditto
xargs -n 1 -I % sh -c ' # one line at a time, execute the following commands, substituting the path for `%`
cat % | # print the config file contents
grep -m 1 url | # take the first line that contains `url`
sed "s/url = //g"; # remove the "url = " part
echo % | # print the path to the config file
sed "s/.git\/config//g"; # remove '.git/config' to keep only the project path
' | # summary: print the remote url on every 2nd line; the path on every 2nd line
xargs -n 2 echo git submodule add # take two lines at a time, print them with the command
请注意,您可以向管道添加任意数量的grep -v ProjectToExclude
以排除这些文件夹 - 再次运行oneliner以查看要执行的新命令列表,并注意ProjectToExclude
不再存在
这将打印出来:
git submodule add https://github.com/username/one_repo.git path/to/one_repo
git submodule add git@otherdomain.com:another_repo.git path/to/another_repo
(etc.)
<强> 2。然后,执行它以实现:删除命令末尾的echo
,以便最后一部分从
xargs -n 2 echo git submodule add
到
xargs -n 2 git submodule add
(而不是回显命令,我们实际上将执行它。)
第3。将其添加到git。您现在可以运行git status
来查看您刚刚完成的工作。
答案 2 :(得分:1)
参见TL;最后的DR。
让我们仔细阅读git submodule <URL> <path>
的手册页,并注意以下说法:
如果
<path>
确实存在并且已经是有效的Git存储库,则会将其添加到变更集而不进行克隆。提供第二个表单是为了便于从头开始创建一个新的子模块,并假设用户稍后将子模块推送到给定的URL。
让我们尝试在像我们这样的情况下使用它(在将父目录递归地添加到新的父存储库之后,而已经存在嵌套的Git存储库)。
首先,想法是在./path/to/submodule/.git/config
中查找原始网址,以获得有关子模块的元信息的真实外部URL,然后调用git submodule <URL> <path>
(希望如此)根据人工页面做我们想要的。
试试吧:
$ git submodule status
No submodule mapping found in .gitmodules for path 'wp-content/themes/liquorice'
$ git submodule add git@github.com:/nudgeme/Liquorice.git ./wp-content/themes/liquorice
'wp-content/themes/liquorice' already exists in the index
/sshx:kosmoplus:/home/kosmoplus/kosmoplus.ru.old $ git submodule status
No submodule mapping found in .gitmodules for path 'wp-content/themes/liquorice'
$
不幸的是,它破了。
好吧,让我们思考如何解决索引中已经存在的问题&#34;并不是我们想要的......
...我们可以简单地从索引中删除它!这很成功:
$ git submodule status
No submodule mapping found in .gitmodules for path 'wp-content/themes/liquorice'
$ git rm --cached ./wp-content/themes/liquorice
rm 'wp-content/themes/liquorice'
$ git submodule add git@github.com:/nudgeme/Liquorice.git ./wp-content/themes/liquorice
Adding existing repo at 'wp-content/themes/liquorice' to the index
$ git submodule status
9733c0ab3e4207352e3f51d612f2a1c9c4a0b63a wp-content/themes/liquorice (liquorice2.1-1-g9733c0a)
$
git rm --cached subdir
git submodule add URL subdir
这甚至可以成为一个简单的脚本来自动执行将现有嵌套repo作为子模块添加到父级中的任务,但我没有看到增加事物的重点。在这个级别,只需学习基本的Git命令,并使用和组合它们!