对Git子模块进行非子模块化,将所有代码带回核心存储库的最佳实践是什么?
当前回答
基于VonC的回答,我创建了一个简单的bash脚本。最后的add必须使用通配符,否则它将撤销子模块本身先前的rm。重要的是要添加子模块目录的内容,而不是在add命令中命名目录本身。
在一个名为git- integration -submodule的文件中:
#!/usr/bin/env bash
mv "$1" "${1}_"
git submodule deinit "$1"
git rm "$1"
mv "${1}_" "$1"
git add "$1/**"
其他回答
从git 1.8.5(2013年11月)开始(没有保留子模块的历史):
mv yoursubmodule yoursubmodule_tmp
git submodule deinit yourSubmodule
git rm yourSubmodule
mv yoursubmodule_tmp yoursubmodule
git add yoursubmodule
将:
注销和卸载(即删除子模块的内容)(deinit,因此mv先), 清理你的。gitmodules (rm), 并删除父repo (rm)索引中表示子模块SHA1的特殊条目。
一旦子模块的删除完成(deinit和git rm),您可以重命名文件夹为原来的名称,并将其作为常规文件夹添加到git repo中。
注意:如果子模块是由旧Git(< 1.8)创建的,您可能需要删除子模块本身中嵌套的.git文件夹,正如Simon East所评论的那样
如果你需要保留子模块的历史,请参阅jsears的答案,它使用git filter-branch。
我发现从子模块获取本地提交数据更方便,否则我就会丢失它们。(无法推送,因为我没有遥控器)。所以我添加了submodule/。Git为remote_origin2,从该分支中提交并合并。 不确定我是否仍然需要子模块远程作为起源,因为我对git还不够熟悉。
下面是@gyim的回答的一个稍微改进的版本(IMHO)。他在主工作副本中做了很多危险的改变,我认为在独立的克隆上操作,然后在最后将它们合并在一起要容易得多。
在一个单独的目录中(使错误更容易清理并再次尝试)检出顶部回购和子回购。
git clone ../main_repo main.tmp
git clone ../main_repo/sub_repo sub.tmp
首先编辑subrepo以将所有文件移动到所需的子目录中
cd sub.tmp
mkdir sub_repo_path
git mv `ls | grep -v sub_repo_path` sub_repo_path/
git commit -m "Moved entire subrepo into sub_repo_path"
注意头部
SUBREPO_HEAD=`git reflog | awk '{ print $1; exit; }'`
现在从主回购中删除子回购
cd ../main.tmp
rmdir sub_repo_path
vi .gitmodules # remove config for submodule
git add -A
git commit -m "Removed submodule sub_repo_path in preparation for merge"
最后,合并它们
git fetch ../sub.tmp
# remove --allow-unrelated-histories if using git older than 2.9.0
git merge --allow-unrelated-histories $SUBREPO_HEAD
并完成了!安全而且没有任何魔法。
我找到的最佳答案是:
http://x3ro.de/2013/09/01/Integrating-a-submodule-into-the-parent-repository.html
这篇文章很好地解释了这个过程。
对我们来说,我们为两个项目创建了两个存储库,它们是如此耦合,以至于将它们分开没有任何意义,所以我们合并了它们。
我将首先展示如何合并每个主分支,然后解释如何将其扩展到你得到的每个分支,希望它能帮助到你。
如果你让子模块工作,你想把它转换成一个目录,你可以这样做:
git clone project_uri project_name
这里我们做了一个干净的克隆来工作。对于这个过程,您不需要初始化或更新子模块,所以跳过它。
cd project_name
vim .gitmodules
使用您喜欢的编辑器(或Vim)编辑.gitmodules以删除您计划替换的子模块。你需要删除的线条应该看起来像这样:
[submodule "lib/asi-http-request"]
path = lib/asi-http-request
url = https://github.com/pokeb/asi-http-request.git
保存文件后,
git rm --cached directory_of_submodule
git commit -am "Removed submodule_name as submodule"
rm -rf directory_of_submodule
在这里,我们完全删除了子模块关系,这样我们就可以就地创建将另一个repo带入项目。
git remote add -f submodule_origin submodule_uri
git fetch submodel_origin/master
这里我们获取要合并的子模块存储库。
git merge -s ours --no-commit submodule_origin/master
这里我们开始两个存储库的合并操作,但在提交之前停止。
git read-tree --prefix=directory_of_submodule/ -u submodule_origin/master
在这里,我们将子模块中的master内容发送到添加目录名前缀之前的目录
git commit -am "submodule_name is now part of main project"
在这里,我们完成了在合并中提交更改的过程。
完成此操作后,您可以推送,并重新开始使用任何其他分支来合并,只需签出存储库中将接收更改的分支,并更改您在合并和读取树操作中引入的分支。
推荐文章
- 如何获得Git存储库中的Git存储库名称?
- 当git说它正在“解析delta”时,它实际上在做什么?
- Git命令将一个文件夹移动到另一个文件夹
- 在单个文件中重新启动/撤消冲突解决方案
- Visual Studio代码如何解决合并冲突与git?
- 无法推送到远程分支,无法解析到分支
- Git:如何将数据库重置为特定的提交?
- 如何在合并期间使用Git和命令行保存本地文件或远程文件?
- 能够用一个命令推到所有git遥控器?
- 重新基于Git合并提交
- 忽略已经签入目录的内容?
- 如何从windows cmd保存git提交消息?
- (Mac) -bash: __git_ps1:命令未找到
- 如何删除多个已删除的文件在Git仓库
- 使用vimdiff查看所有' git diff '