search

Home  >  Q&A  >  body text

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

举例:我的工程叫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有更新,能否正常。

PHP中文网PHP中文网2810 days ago809

reply all(2)I'll reply

  • 伊谢尔伦

    伊谢尔伦2017-04-21 11:18:19

    Git's submodule method will not add actual content to the warehouse, but will only retain the hash value of the corresponding submodule through the .gitmodules file.

    Since the code you really want to use is in a subdirectory, my plan is that you first extract this subdirectory into a separate repository (you can use the git-subtree.sh script), and then add this repository as a submodule (Or use git-subtree.sh directly to integrate the actual code into your project, so that others who clone it do not need to update the submodule). The disadvantage of this is that whenever there is an update in the upstream, the submodule repository needs to be updated accordingly.

    In addition: git-subtree.sh has been merged into git. It may not be in PATH and cannot be executed directly, but it should be in the git installation.

    Another idea:

    Create the bundles directory, add the original repository as submodule here, and then make a relative path soft link to the required subdirectory. Git can correctly handle the soft link. This may be a better method, as it does not require additional maintenance of synchronization with the upstream.

    ----------

    What you have done in the submodule directory is already the split operation of git-subree.sh. At this time, the warehouse is completely different from orgin. It is equivalent to re-establishing a warehouse with the subdirectory as the root. In this warehouse The object is only in your local area and is not included in origin's warehouse, so it will be invalid in the end. subdirectory-filter

    reply
    0
  • 黄舟

    黄舟2017-04-21 11:18:19

    It is not allowed to use a subdirectory in a warehouse as your submodule. git submodule only supports the entire warehouse.

    I found that many Xcode projects that rely on submodule will not remove the submodule project. Because they rely on static lib, when compiling, it will be compiled into a lib.a file according to the submodule project, and then linked to your project. If you remove the submodule's project file, then when compiling, xcode will treat the submodule's source as the same project. Compile the *.m file first, and then link.

    The git-subtree.sh mentioned above may be a solution. But I haven't tried it.

    Finally, I suggest you try cocoapods, hehe.

    reply
    0
  • Cancelreply