Opposite/reverse of “git submodule absorbgitdirs”?

前端 未结 2 1807
梦毁少年i
梦毁少年i 2020-12-16 17:45

How can I do the reverse of git submodule absorbgitdirs? I.e. move a submodule\'s .git information out of superproject/.git/modules/

相关标签:
2条回答
  • 2020-12-16 18:18

    Note that this would make superproject/path/to// a nested Git repo, whose SHA1 would still be recorded by the parent project.

    To keep the exact same state, you can copy superproject/.git/modules/<module> and rename to superproject/path/to/<module>, and rename <module>/<module> to <module>/.git.

    Then you can use the git submodule deinit to remove the submodule:

    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
    

    I still want to be a submodule of superprojec

    Then its .git folder would be in superproject/.git/modules/<module>

    submodule absorbgitdirs does not leave any choice:

    If a git directory of a submodule is inside the submodule, move the git directory of the submodule into its superprojects $GIT_DIR/modules path and then connect the git directory and its working directory by setting the core.worktree and adding a .git file pointing to the git directory embedded in the superprojects git directory.

    I don't see in git config any configuration that might move $GIT_DI R/modules.

    absorbgitdirs was introduced in commit f6f8586 for Git 2.12 (Q4 2016)
    Its tests shows it expects to use GIT_DIR/modules.

    Older Git (before Git 1.7.8, Oct. 2011) had a .git directly inside the submodule folder.

    0 讨论(0)
  • 2020-12-16 18:21

    I wrote a script to do this. Add this to your ~/.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"
    

    and then run:

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

    If you run it without specifying any submodules, it will extract all of them.


    If you want to see what the code is doing, just change

    && gitextractsubmodules
    

    at the end to

    && type gitextractsubmodules
    

    and then run the command without arguments to make Bash pretty-print the function body.

    0 讨论(0)
提交回复
热议问题