我想在我的Git超级项目中更改一个Git子模块的目录名称。

让我们假设我的.gitmodules文件中有以下条目:

[submodule ".emacs.d/vimpulse"]  
path = .emacs.d/vimpulse  
url = git://gitorious.org/vimpulse/vimpulse.git

我必须输入什么来移动。emacs。D /vimpulse目录到。emacs。D /vendor/vimpulse而不首先删除它(解释 这里和这里),然后重新添加。

Git真的需要子模块标签中的整个路径吗

[submodule ".emacs.d/vimpulse"]

或者也可以只存储子项目的名称?

[submodule "vimpulse"]

当前回答

最现代的答案来自Valloric的评论:

升级到Git 1.9.3(如果子模块包含嵌套子模块,则升级到2.18) Git mv old/submod new/submod 之后.gitmodules和子模块目录已经被提交(你可以用git status来验证这一点)。 使用git Commit提交更改-你就可以开始了!

完成了!

其他回答

只需使用shell脚本git-submodule-move。

对于我来说,运行git mv <old/path> <new/path失败:

Rename from 'old/path' to 'new/path' failed. Should I try again? (y/n)

在运行git deinit <old/path>后,我能够使用git mv。

您只需添加一个新的子模块,并使用标准命令删除旧的子模块。(应该防止.git内部的任何意外错误)

示例设置:

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>

移动jquery到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}"

大子模块的奖励方法:

如果子模块很大,并且您不想等待克隆,那么可以使用旧的子模块作为源来创建新的子模块,然后切换源。

示例(使用相同的示例设置)

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
...

在我的例子中,我想将一个子模块从一个目录移动到另一个子目录,例如:"AFNetworking" -> "ext/AFNetworking"以下是我遵循的步骤:

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

最后,我在git状态中看到:

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

瞧。上面的例子没有改变目录深度,这对任务的复杂性有很大影响,也没有改变子模块的名称(这可能真的没有必要,但我这样做是为了与在该路径添加新模块时发生的情况保持一致)。

最现代的答案来自Valloric的评论:

升级到Git 1.9.3(如果子模块包含嵌套子模块,则升级到2.18) Git mv old/submod new/submod 之后.gitmodules和子模块目录已经被提交(你可以用git status来验证这一点)。 使用git Commit提交更改-你就可以开始了!

完成了!