" git submodule absorbgitdirs"的相反/反转

时间:2017-06-15 05:35:07

标签: git git-submodules

如何反转git submodule absorbgitdirs?即将子模块的.git信息移出superproject/.git/modules/<module>并返回superproject/path/to/<module>/.git目录?

我仍然希望<module>成为superproject的子模块,我只是不想<module> .git superproject目录信息.git/modules 1}}&#39; s struct Resource { ... } typealias ResourceID = String final class ResourceManager { static let shared = ResourceManager() fileprivate var _resourcesDict = [ResourceID : Resource]() fileprivate let _queue = DispatchQueue(label: "ResourceManager_Queue", qos: .userInitiated) // Private init to ensure just one instance is created. fileprivate init() { } } extension ResourceManager { /// Calls the given closure on the main thread. /// If the required Resource is already cached, outputs that Resource. /// Otherwise, loads the Resource asynchronously, then caches it /// before finally providing it through the closure on the main thread. func resource(forResourceID resourceID: ResourceID, completionHandler: @escaping (Resource?) -> ()) { // #1. - SEE BOTTOM OF POST FOR REVISION // Resource already in the cache? Use that, job is done. if let resource = self._resourcesDict[resourceID] { self._queue.sync { DispatchQueue.main.async { completionHandler(resource) } } return } // #2. // Resource is not in the cache, so load it asynchronously. self._queue.async { let maybeResource = Resource(resourceID: resourceID) DispatchQueue.main.async { if let resource = maybeResource { self._resourcesDict[resourceID] = resource } completionHandler(maybeResource) } } } /// Given a resourceID, returns true if the resource is in our cache. func resourceIsLoaded(forResourceID resourceID: ResourceID) -> Bool { // #3. // Note: remember we are actually returning the queue. return self._queue.sync { return self._resourcesDict[resourceID] != nil } } } 目录。

2 个答案:

答案 0 :(得分:4)

请注意,这会使superproject / path /成为一个嵌套的Git仓库,其SHA1仍将由父项目记录。

要保持完全相同的状态,您可以复制superproject/.git/modules/<module>并重命名为superproject/path/to/<module>,并将<module>/<module>重命名为<module>/.git

然后您可以使用git submodule deinit删除子模块:

mv asubmodule asubmodule_tmp
git submodule deinit -f -- a/submodule    
rm -rf .git/modules/a/submodule

# if you want to leave it in your working tree
git rm --cached asubmodule
mv asubmodule_tmp asubmodule
  

我仍然想成为superprojec的子模块

然后其.git文件夹将位于superproject/.git/modules/<module>

submodule absorbgitdirs不做任何选择:

  

如果子模块的git目录在子模块内,则将子模块的git目录移动到其超级项目 $GIT_DIR/modules 路径中,然后通过设置连接git目录及其工作目录core.worktree并添加一个.git文件,指向嵌入在superprojects git目录中的git目录。

我没有在git config中看到任何可能会移动$GIT_DI R/modules的配置。

commit f6f8586为Git 2.12(2016年第4季度)引入了{p> absorbgitdirs Its tests shows它希望使用GIT_DIR/modules

较旧的Git(before Git 1.7.8,2011年10月)在子模块文件夹中直接有.git

答案 1 :(得分:2)

我写了一个脚本来做到这一点。将此添加到您的~/.gitconfig

[alias]
    extract-submodules = "!gitextractsubmodules() { set -e && { if [ 0 -lt \"$#\" ]; then printf \"%s\\n\" \"$@\"; else git ls-files --stage | sed -n \"s/^160000 [a-fA-F0-9]\\+ [0-9]\\+\\s*//p\"; fi; } | { local path && while read -r path; do if [ -f \"${path}/.git\" ]; then local git_dir && git_dir=\"$(git -C \"${path}\" rev-parse --absolute-git-dir)\" && if [ -d \"${git_dir}\" ]; then printf \"%s\t%s\n\" \"${git_dir}\" \"${path}/.git\" && mv --no-target-directory --backup=simple -- \"${git_dir}\" \"${path}/.git\" && git --work-tree=\"${path}\" --git-dir=\"${path}/.git\" config --local --path --unset core.worktree && rm -f -- \"${path}/.git~\" && if 1>&- command -v attrib.exe; then MSYS2_ARG_CONV_EXCL=\"*\" attrib.exe \"+H\" \"/D\" \"${path}/.git\"; fi; fi; fi; done; }; } && gitextractsubmodules"

然后运行:

git extract-submodules [<path>...]

如果运行时未指定任何子模块,它将提取所有子模块。


如果您想查看代码在做什么,只需更改

&& gitextractsubmodules

最后到

&& type gitextractsubmodules

然后运行不带参数的命令以使Bash漂亮地显示函数主体。