您好,匿名用户
随意问技术百科期待您的加入

如何把一个工程中的某个目录添加为git submodule

0 投票

举例:我的工程叫My,目录树如下

My
|-- My
|   |-- Support
|   |-- main.m
|   |-- images
|   |-- My-Prefix.pch
|   |-- My-Info.plist
|   |-- MyAppDelegate.h
|   |-- MyAppDelegate.m
|
|-- My.xcodeproj

我希望把项目AFNetworking加成Submodule,他的目录树如下

AFNetworking
|-- AFNetworking // 这个是真正需要的目录
|-- AFNetworking.xcworkspace
|-- Example
|-- .gitignore
|-- AFNetworking.podspec
|-- CHANGES
|-- LICENSE
|-- README.md

我要把AFNetworking加成submodule

git submodule add https://github.com/AFNetworking/AFNetworking.git My/Support/AFNetworking

最终My的目录结构

My
|-- My
|   |-- Support
|   |   |-- AFNetworking
|   |       |-- AFNetworking // 这个是真正需要的目录
|   |       |-- AFNetworking.xcworkspace
|   |       |-- Example
|   |       |-- .gitignore
|   |       |-- AFNetworking.podspec
|   |       |-- CHANGES
|   |       |-- LICENSE
|   |       |-- README.md
|   |    
|   |-- main.m
|   |-- images
|   |-- My-Prefix.pch
|   |-- My-Info.plist
|   |-- MyAppDelegate.h
|   |-- MyAppDelegate.m
|
|-- My.xcodeproj

我希望得到的目录结构是

My
|-- My
|   |-- Support
|   |   |-- AFNetworking // 这个是真正需要的目录
|   |
|   |-- main.m
|   |-- images
|   |-- My-Prefix.pch
|   |-- My-Info.plist
|   |-- MyAppDelegate.h
|   |-- MyAppDelegate.m
|
|-- My.xcodeproj

我通过在子模块目录执行这个命令,达到了效果

git filter-branch -f --subdirectory-filter AFNetworking/AFNetworking -- --all

然后

git filter-branch -f --index-filter "git rm -r -f --cached --ignore-unmatch AFNetworking/AFNetworking" --prune-empty

然后回到父仓库commit并push
看起来一切完美了,但是我重新在clone的时候
这个Submodule的状态是挂的。。。完全clone不出来,AFNetworking只是个目录,没有文件内容
我用SourceTree打开这个工程,然后看通过submodule的方式打开AFNetworking,reset一下,目录结构就回到运行 filter-branch 命令之前的样子了
也就是说,这个效果只有我一个人在运行了 filter-branch 之后看的到,有没有什么办法,可以让大家都看到呢?
另外,我还不知道这样做了以后,如果submodule有更新,能否正常。

用户头像 提问 2013年 9月23日 @ 爹妈罩我去战斗 上等兵 (131 威望)
分享到:

1个回答

0 投票

git 的 submodule 方式不会向仓库添加实际的的内容的,只会通过 .gitmodules 文件保留相应的子模块的哈希值。

由于你要真正要用的代码处于一个子目录中,我的方案是你先把这个子目录提取成一个单独的仓库(可以使用 git-subtree.sh 这个脚本),然后再添加这个仓库为 submodule(或者直接使用 git-subtree.sh 把实际的代码集成到你的项目,这样别人克隆就不需要更新 submodule 了)。这样做的缺点就是每当上游有更新,就需要对 submodule 的仓库做相应更新。

另外:git-subtree.sh 已经合并入 git 了,可能并不在 PATH 中,不能直接执行,不过应该在 git 的安装中的。

另一个思路:

建立 bundles 目录,添加原仓库为 submodule 到此,然后对需要的子目录做相对路径软链接,git 能够正确处理软链接。这可能是比较好的一个办法了,不需要额外维护同上游的同步。

-----------

你在子模块目录中进行的 subdirectory-filter 已经是 git-subree.sh 的 split 操作了,这个时候该仓库已经和 orgin 完全不同了,等于重新建立了以该 subdirectory 为根的一个仓库,这个仓库中的对象只在你的本地,并不包含在 origin 的仓库中,所以最后才会无效的。

用户头像 回复 2013年 9月23日 @ Ashe 上等兵 (336 威望)
提一个问题:

相关问题

0 投票
1 回复 40 阅读
0 投票
1 回复 31 阅读
0 投票
1 回复 57 阅读
用户头像 提问 2012年 12月1日 @ Sagittarius 上等兵 (289 威望)
0 投票
1 回复 60 阅读
用户头像 提问 2012年 12月1日 @ Trundle 上等兵 (301 威望)
0 投票
1 回复 50 阅读
用户头像 提问 2012年 12月1日 @ Hepheastus 上等兵 (182 威望)

欢迎来到随意问技术百科, 这是一个面向专业开发者的IT问答网站,提供途径助开发者查找IT技术方案,解决程序bug和网站运维难题等。
温馨提示:本网站禁止用户发布与IT技术无关的、粗浅的、毫无意义的或者违法国家法规的等不合理内容,谢谢支持。

欢迎访问随意问技术百科,为了给您提供更好的服务,请及时反馈您的意见。
...