How do I move an existing Git submodule within a Git repository?

后端 未结 10 631
面向向阳花
面向向阳花 2020-11-29 14:39

I would like to change the directory name of a Git submodule in my Git superproject.

Lets suppose I have the following entry in my .gitmodules file:

相关标签:
10条回答
  • 2020-11-29 15:04

    You can just add a new submodule and remove the old submodule using standard commands. (should prevent any accidental errors inside of .git)

    Example setup:

    mkdir foo; cd foo; git init; 
    echo "readme" > README.md; git add README.md; git commit -m "First"
    ## add submodule
    git submodule add git://github.com/jquery/jquery.git
    git commit -m "Added jquery"
    ## </setup example>
    

    Examle move 'jquery' to 'vendor/jquery/jquery' :

    oldPath="jquery"
    newPath="vendor/jquery/jquery"
    orginUrl=`git config --local --get submodule.${oldPath}.url`
    
    ## add new submodule
    mkdir -p `dirname "${newPath}"`
    git submodule add -- "${orginUrl}" "${newPath}"
    
    ## remove old submodule
    git config -f .git/config --remove-section "submodule.${oldPath}"
    git config -f .gitmodules --remove-section "submodule.${oldPath}"
    git rm --cached "${oldPath}"
    rm -rf "${oldPath}"              ## remove old src
    rm -rf ".git/modules/${oldPath}" ## cleanup gitdir (housekeeping)
    
    ## commit
    git add .gitmodules
    git commit -m "Renamed ${oldPath} to ${newPath}"
    

    Bonus method for large submodules:

    If the submodule is large and you prefer not to wait for the clone, you can create the new submodule using the old as origin, and then switch the origin.

    Example (use same example setup)

    oldPath="jquery"
    newPath="vendor/jquery/jquery"
    baseDir=`pwd`
    orginUrl=`git config --local --get submodule.${oldPath}.url`
    
    # add new submodule using old submodule as origin
    mkdir -p `dirname "${newPath}"`
    git submodule add -- "file://${baseDir}/${oldPath}" "${newPath}"
    
    ## change origin back to original
    git config -f .gitmodules submodule."${newPath}".url "${orginUrl}"
    git submodule sync -- "${newPath}"
    
    ## remove old submodule
    ...
    
    0 讨论(0)
  • 2020-11-29 15:07

    Just use the shell script git-submodule-move.

    0 讨论(0)
  • 2020-11-29 15:11

    In my case, I wanted to move a submodule from one directory into a subdirectory, e.g. "AFNetworking" -> "ext/AFNetworking". These are the steps I followed:

    1. Edit .gitmodules changing submodule name and path to be "ext/AFNetworking"
    2. Move submodule's git directory from ".git/modules/AFNetworking" to ".git/modules/ext/AFNetworking"
    3. Move library from "AFNetworking" to "ext/AFNetworking"
    4. Edit ".git/modules/ext/AFNetworking/config" and fix the [core] worktree line. Mine changed from ../../../AFNetworking to ../../../../ext/AFNetworking
    5. Edit "ext/AFNetworking/.git" and fix gitdir. Mine changed from ../.git/modules/AFNetworking to ../../git/modules/ext/AFNetworking
    6. git add .gitmodules
    7. git rm --cached AFNetworking
    8. git submodule add -f <url> ext/AFNetworking

    Finally, I saw in the git status:

    matt$ git status
    # On branch ios-master
    # Changes to be committed:
    #   (use "git reset HEAD <file>..." to unstage)
    #
    #   modified:   .gitmodules
    #   renamed:    AFNetworking -> ext/AFNetworking
    

    Et voila. The above example doesn't change the directory depth, which makes a big difference to the complexity of the task, and doesn't change the name of the submodule (which may not really be necessary, but I did it to be consistent with what would happen if I added a new module at that path.)

    0 讨论(0)
  • 2020-11-29 15:15

    The given solution did not work for me, however a similar version did...

    This is with a cloned repository, hence the submodule git repos are contained in the top repositories .git dir. All cations are from the top repository:

    1. Edit .gitmodules and change the "path =" setting for the submodule in question. (No need to change the label, nor to add this file to index.)

    2. Edit .git/modules/name/config and change the "worktree =" setting for the submodule in question

    3. run:

      mv submodule newpath/submodule
      git add -u
      git add newpath/submodule
      

    I wonder if it makes a difference if the repositories are atomic, or relative submodules, in my case it was relative (submodule/.git is a ref back to topproject/.git/modules/submodule)

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