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

发布于 2022-08-24 12:29:32 字数 1849 浏览 16 评论 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有更新,能否正常。

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

几味少女 2022-08-31 12:29:32

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 的仓库中,所以最后才会无效的。

时光病人 2022-08-31 12:29:32

把一个仓库的里的子目录作为你的submodule这样的方式是不可以的。git submodule只支持整个仓库。

我发现很多依赖了submodule的xcode project都不会把submodule的project给去掉的。因为他们的是按照静态lib来依赖的,编译时会按照submodule的project先编译成lib.a文件,然后link到你的项目中。如果把submodule的project文件去掉,那么编译时,xcode会把submodule的source当做同一个项目来处理。先把*.m文件编译出来,然后再link。

楼上说得git-subtree.sh可能是个办法。不过我没尝试过。

最后还是建议你尝试cocoapods,嘿嘿。

画骨成沙 2022-08-31 12:29:32

hi gaosboy, 我通过git submodule将子仓库放到多层目录结构中报错了,报错截图如下,想问问你是怎么实现的?
clipboard.png

我在网上也找了答案, 截图如下
clipboard.png

 git rm -r src/routes清除同名模块
git submodule add http://quan.wang@stash.weimob.com/scm/h/jingxuan-manage-submodule.git src/routes

此时出现了新的报错, 截图如下

clipboard.png

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文