将 git 仓库从 submodule 转换为 subtree

简介: 将 git 仓库从 submodule 转换为 subtree

三个脚本

Alexander Mikhailian

cat .gitmodules |while read i
do
  if [[$i == \[submodule*]]; then
    mpath=$(echo $i | cut -d\" -f2)
    read i; read i;
    murl=$(echo $i|cut -d\  -f3)
    mcommit=`eval "git submodule status ${mpath} |cut -d\  -f2"`
    mname=$(basename $mpath)
    echo -e "$name\t$mpath\t$murl\t$mcommit"
    git submodule deinit $mpath
    git rm -r --cached $mpath
    rm -rf $mpath
    git remote add $mname $murl
    git fetch $mname
    git branch _$mname $mcommit
    git read-tree --prefix=$mpath/ -u _$mname
fi
done
git rm .gitmodules
BASH

🐾Warning:

下文的两个脚本, 写死了 branch 是 master, 如果主分支不是 master, 需要做相应修改.

Nikita240 - Stack Overflow

📚️Reference:

我对它进行了修改和改进。现在,新的 subtree 将指向与旧 submodule 相同的提交。以前,脚本只是从目标存储库下载最新的提交,这可能会导致兼容性问题。

#!/bin/bash -x
# This script will convert all your git submodules into git subtrees.
# This script ensures that your new subtrees point to the same commits as the
# old submodules did, unlike most other scripts that do this.
# THIS SCRIPT MUST BE PLACED OUTSIDE OF YOUR REPOSITORY!!!!!!!!!!
# Otherwise, the script will interfere with the git commits.
# Save the script in your home directory as `~/subtrees.sh`
# `cd` into your repository
# Run `~/subtrees.sh`
# Enjoy!
# extract the list of submodules from .gitmodule
cat .gitmodules |while read i
do
if [[$i == \[submodule*]]; then
    echo converting $i
    read i
    # extract the module's prefix
    mpath=$(echo $i | grep -E "(\S+)$" -o)
    echo path: $mpath
    read i
    # extract the url of the submodule
    murl=$(echo $i|cut -d\= -f2|xargs)
    echo url: $murl
    # extract the module name
    mname=$(basename $mpath)
    echo name: $mname
    # extract the referenced commit
    mcommit=$(git submodule status $mpath | grep -E "\S+" -o | head -1)
    echo commit: $mcommit
    # deinit the module
    git submodule deinit $mpath
    # remove the module from git
    git rm -r --cached $mpath
    # remove the module from the filesystem
    rm -rf $mpath
    # commit the change
    git commit -m "Removed $mpath submodule at commit $mcommit"
    # add the remote
    git remote add -f $mname $murl
    # add the subtree
    git subtree add --prefix $mpath $mcommit --squash
    # commit any left over uncommited changes
    git commit -a -m "$mname cleaned up"
    # fetch the files
    git fetch $murl master
    echo
fi
done
git rm .gitmodules
git commit -a -m "Removed .gitmodules"
BASH

GaspardP - Stack Overflow

📚️Reference:

我稍微修改了一下,调用 subtree add 而不是 read-tree。它将从.gitmodule 中获取 submodule 的列表,并提取模块的前缀、名称和网址。然后它删除每个 submodule,并在同一位置添加它们作为 subtree。它还将每个 submodule 的 remote 添加为 remote,这样你就可以通过提供它的名字而不是它的网址来更新 subtree 了(即 git subtree pull -P Foo Foo master --squash 而不是git subtree pull -P Foo https://example.com/foo.git master --squash)。

如果你想把 subtree 的全部历史导入你的版本库,你可以去掉 --squash 参数。使用 --squash,将只导入 subtree 的 HEAD 到你的版本库。这可能是大多数人想要的。

#!/bin/bash -x
# extract the list of submodules from .gitmodule
cat .gitmodules |while read i
do
if [[$i == \[submodule*]]; then
    echo converting $i
    # extract the module's prefix
    mpath=$(echo $i | cut -d\" -f2)
    # skip two lines
    read i; read i;
    # extract the url of the submodule
    murl=$(echo $i|cut -d\= -f2|xargs)
    # extract the module name
    mname=$(basename $mpath)
    # deinit the module
    git submodule deinit $mpath
    # remove the module from git
    git rm -r --cached $mpath
    # remove the module from the filesystem
    rm -rf $mpath
    # commit the change
    git commit -m "Removed $mpath submodule"
    # add the remote
    git remote add -f $mname $murl
    # add the subtree
    git subtree add --prefix $mpath $mname master --squash
    # fetch the files
    git fetch $murl master
fi
done
git rm .gitmodules
BASH

📚️参考文档

相关文章
|
项目管理 开发工具 git
「译文」Git subtree: Git submodule 的替代品
「译文」Git subtree: Git submodule 的替代品
「译文」Git subtree: Git submodule 的替代品
|
安全 Java Unix
|
编译器 API 容器
Compose:从重组谈谈页面性能优化思路,狠狠优化一笔
Compose:从重组谈谈页面性能优化思路,狠狠优化一笔
1019 0
|
iOS开发
LLDB 调试命令、插件和技巧(上)
LLDB 调试命令、插件和技巧(上)
978 0
申请阿里云的免费企业邮箱
要申请阿里云的免费企业邮箱,您可以按照以下步骤操作: 访问阿里云企业邮箱免费版申请页面。
1004 5
|
存储 安全 调度
DPDK环形缓冲区(Ring)详解及性能优化
DPDK环形缓冲区(Ring)详解及性能优化
|
存储 人工智能 搜索推荐
详解MySQL字符集和Collation
MySQL支持了很多Charset与Collation,并且允许用户在连接、Server、库、表、列、字面量多个层次上进行精细化配置,这有时会让用户眼花缭乱。本文对相关概念、语法、系统变量、影响范围都进行了详细介绍,并且列举了有可能让字符串发生字符集转换的情况,以及来自不同字符集的字符串进行比较等操作时遵循的规则。对于最常用的基于Unicode的字符集,本文介绍了Unicode标准与MySQL中各个字符集的关系,尤其详细介绍了当前版本(8.0.34)默认字符集utf8mb4。
|
域名解析 安全 Android开发
阿里云企业邮箱怎么样?有没有免费版的?如何申请?
阿里云企业邮箱怎么样?有没有免费版的?如何申请?阿里云企业邮箱有着20年运营经验,用户认可度还是很高的,阿里云企业邮箱有收费版也有免费版,免费版配置50邮箱帐号、5GB邮箱空间和2GB个人网盘,免费时长最长可选5年,小编来详细说下阿里云企业邮箱免费版申请页面、企业邮箱配置及申请攻略。
4971 0
阿里云企业邮箱怎么样?有没有免费版的?如何申请?
|
Java 开发工具
Mac下安装多个版本的JDK并随意切换
Mac下安装多个版本的JDK并随意切换
705 0
Mac下安装多个版本的JDK并随意切换
|
开发工具 git
如何把其他代码托管平台git仓库迁移到github还保留历史日志记录?图解步骤,值得收藏!
我在其他的代码托管平台(不是github)有一套代码,不同代码托管平台之间没有相互迁移的功能,怎么将仓库代码提交到github仓库呢?我会讲解适合于所有不同托管平台Git仓库之间的迁移方法,所以就不要老是抱怨着为什么没有外部仓库迁移过来的功能了。
786 0
如何把其他代码托管平台git仓库迁移到github还保留历史日志记录?图解步骤,值得收藏!

热门文章

最新文章