我想在我的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"]
您只需添加一个新的子模块,并使用标准命令删除旧的子模块。(应该防止.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
...
诀窍似乎是理解子模块的.git目录现在保存在主存储库中,在.git/modules下,每个子模块都有一个指向它的.git文件。这是你现在需要的程序:
Move the submodule to its new home.
Edit the .git file in the submodule's working directory, and modify the path it contains so that it points to the right directory in the master repository's .git/modules directory.
Enter the master repository's .git/modules directory, and find the directory corresponding to your submodule.
Edit the config file, updating the worktree path so that it points to the new location of the submodule's working directory.
Edit the .gitmodules file in the root of the master repository, updating the path to the working directory of the submodule.
git add -u
git add <parent-of-new-submodule-directory> (It's important that you add the parent, and not the submodule directory itself.)
注意事项:
.gitmodules和.git/config中的[submodule "submodule-name"]行必须相互匹配,但不对应任何其他内容。
子模块的工作目录和.git目录必须正确指向对方。
.gitmodules和.git/config文件应该同步。
在我的例子中,我想将一个子模块从一个目录移动到另一个子目录,例如:"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
瞧。上面的例子没有改变目录深度,这对任务的复杂性有很大影响,也没有改变子模块的名称(这可能真的没有必要,但我这样做是为了与在该路径添加新模块时发生的情况保持一致)。
我昨天刚刚经历了这个考验,这个答案非常有效。为了清晰起见,以下是我的步骤:
确保子模块被签入并推入到它的服务器。你还需要知道它在哪个分支上。
您需要子模块的URL !使用更多的.gitmodules,因为一旦你删除了子模块,它就不存在了
现在你可以使用deinit, rm和submodule add
例子
Git子模块在:Classes/lib/mustIReally
移动到:lib/AudioBus
URL: http://developer.audiob.us/download/SDK.git
命令
git submodule deinit Classes/lib/mustIReally
git rm foo
git submodule add http://developer.audiob.us/download/SDK.git lib/AudioBus
# do your normal commit and push
git commit -a
注意:git mv不这样做。在所有。