提交项目
This commit is contained in:
@@ -0,0 +1,242 @@
|
||||
#!/bin/bash
|
||||
|
||||
# 配置文件
|
||||
CONFIG_FILE="submodule_config.ini"
|
||||
|
||||
# 定义颜色常量
|
||||
RED='\033[31mi'
|
||||
BLUE='\033[34m'
|
||||
YELLOW='\033[33m'
|
||||
GREEN='\033[32m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
# 函数:显示帮助信息
|
||||
show_help() {
|
||||
echo "Usage: $0 [-h] [-i] [-up]"
|
||||
echo " -h 显示帮助信息"
|
||||
echo " -i 根据.gitmodules初始化子模块"
|
||||
echo " -up 根据配置文件更新子模块"
|
||||
}
|
||||
|
||||
# 检查配置文件是否存在
|
||||
if [[ ! -f "$CONFIG_FILE" ]]; then
|
||||
echo -e "${RED}配置文件 $CONFIG_FILE 不存在!${NC}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# 检查 .gitmodules 文件是否存在
|
||||
if [[ ! -f ".gitmodules" ]]; then
|
||||
touch .gitmodules
|
||||
fi
|
||||
|
||||
# 普通数组和模拟的关联数组
|
||||
module_list=() # 用来存储模块名列表
|
||||
config_array=() # 用来存储键值对
|
||||
|
||||
# 函数:从 INI 文件中读取所有字段并存储在普通数组中
|
||||
parse_ini_all() {
|
||||
local section=""
|
||||
while IFS= read -r line || [[ -n "$line" ]]; do
|
||||
# 去除前后空格
|
||||
line="${line#"${line%%[![:space:]]*}"}" # 去掉前面的空格
|
||||
line="${line%"${line##*[![:space:]]}"}" # 去掉后面的空格
|
||||
|
||||
# 跳过注释和空行
|
||||
[[ "$line" =~ ^\s*(#|$) ]] && continue
|
||||
|
||||
# 如果是新的 section
|
||||
if [[ "$line" =~ ^\[(.*)\]$ ]]; then
|
||||
section="${BASH_REMATCH[1]}"
|
||||
module_list+=("$section") # 添加 module 名到 module_list 数组中
|
||||
elif [[ "$line" =~ ^([^=]+)=(.*)$ ]]; then
|
||||
key="${BASH_REMATCH[1]//[[:space:]]/}" # 去掉键的空格
|
||||
value="${BASH_REMATCH[2]//[[:space:]]/}" # 去掉值的空格
|
||||
|
||||
# 构造键值对并存储在数组中
|
||||
config_array+=("$section.$key=$value")
|
||||
fi
|
||||
done < "$CONFIG_FILE"
|
||||
}
|
||||
|
||||
# 函数:根据键获取值
|
||||
get_value() {
|
||||
local key=$1
|
||||
for entry in "${config_array[@]}"; do
|
||||
if [[ "$entry" == "$key="* ]]; then
|
||||
echo "${entry#*=}" # 输出值
|
||||
return
|
||||
fi
|
||||
done
|
||||
echo ""
|
||||
}
|
||||
|
||||
# 函数:检查远程仓库是否包含指定版本标签
|
||||
check_tag_exists() {
|
||||
local repo_url=$1
|
||||
local version_tag=$2
|
||||
|
||||
git ls-remote --tags "$repo_url" | grep -q "refs/tags/$version_tag"
|
||||
if [[ $? -ne 0 ]]; then
|
||||
echo -e "${RED}仓库: $repo_url 版本标签 $version_tag 不存在!${NC}"
|
||||
return 1
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
|
||||
# 函数:获取当前子模块的版本标签
|
||||
get_current_version() {
|
||||
local target_dir=$1
|
||||
cd "$target_dir" || return 1
|
||||
|
||||
# 尝试获取当前HEAD指向的标签名
|
||||
current_version=$(git tag --points-at HEAD)
|
||||
|
||||
# 如果没有标签名,则返回commit的SHA
|
||||
if [[ -z "$current_version" ]]; then
|
||||
current_version=$(git rev-parse HEAD)
|
||||
fi
|
||||
|
||||
cd - > /dev/null || return 1
|
||||
echo "$current_version"
|
||||
}
|
||||
|
||||
# 函数:初始化子模块
|
||||
init_submodule() {
|
||||
local module=$1
|
||||
local repo_url=$2
|
||||
local target_dir=$3
|
||||
local version_tag=$4
|
||||
|
||||
# 检查子模块路径是否已经存在
|
||||
if [[ -f "$target_dir/.git" ]]; then
|
||||
# 存在子模块,获取当前版本
|
||||
current_version=$(get_current_version "$target_dir")
|
||||
|
||||
# 如果当前版本和目标版本相同,直接返回
|
||||
if [[ "$current_version" == "$version_tag" ]]; then
|
||||
echo -e "${GREEN}子模块: $module 已经是版本: $version_tag 无需更新${NC}"
|
||||
return 0
|
||||
else
|
||||
if ! check_tag_exists "$repo_url" "$version_tag"; then
|
||||
return 1
|
||||
fi
|
||||
fi
|
||||
else
|
||||
# 子模块不存在,检查远程版本标签
|
||||
echo -e "${YELLOW}子模块: $module 不存在,添加子模块...${NC}"
|
||||
if ! check_tag_exists "$repo_url" "$version_tag"; then
|
||||
return 1
|
||||
fi
|
||||
|
||||
# 添加子模块
|
||||
git submodule add --force "$repo_url" "$target_dir"
|
||||
if [[ $? -ne 0 ]]; then
|
||||
echo -e "${RED}子模块: $module($target_dir) 添加失败!${NC}"
|
||||
return 1
|
||||
fi
|
||||
fi
|
||||
|
||||
# 子模块已存在或成功添加,尝试切换到指定版本
|
||||
cd "$target_dir" || return 1
|
||||
echo "子模块: $module 切换到版本: $version_tag"
|
||||
|
||||
# 更新标签并切换到指定的版本标签
|
||||
git fetch --tags > /dev/null 2>&1
|
||||
git checkout "tags/$version_tag" > /dev/null 2>&1
|
||||
if [[ $? -ne 0 ]]; then
|
||||
echo -e "${RED}$module 版本切换失败: $version_tag${NC}"
|
||||
cd - > /dev/null || return 1
|
||||
return 1
|
||||
fi
|
||||
|
||||
cd - > /dev/null || return 1
|
||||
echo -e "${GREEN}子模块: $module($target_dir) 初始化完成,版本: $version_tag\n${NC}"
|
||||
return 0
|
||||
}
|
||||
|
||||
# 函数:删除配置文件中已经不存在的子模块
|
||||
remove_deleted_submodules() {
|
||||
# 获取当前子模块列表
|
||||
current_submodules=$(git config --file .gitmodules --name-only --get-regexp path | sed 's/^submodule\.//;s/\.path$//')
|
||||
|
||||
for submodule in $current_submodules; do
|
||||
# 获取当前子模块的路径
|
||||
submodule_path=$(git config --file .gitmodules --get submodule."$submodule".path)
|
||||
|
||||
# 标志:是否在配置文件中找到该子模块
|
||||
found_in_config=false
|
||||
|
||||
# 遍历配置文件中的模块,检查是否存在
|
||||
for module in "${module_list[@]}"; do
|
||||
if [[ "$submodule_path" == "$(get_value "$module.target_dir")" ]]; then
|
||||
found_in_config=true
|
||||
break
|
||||
fi
|
||||
done
|
||||
|
||||
# 如果在配置文件中没有找到子模块,则删除它
|
||||
if [[ "$found_in_config" == false ]]; then
|
||||
echo -e "${YELLOW}子模块: $submodule_path 已从配置文件中删除,正在删除...${NC}"
|
||||
git submodule deinit -f "$submodule_path" > /dev/null 2>&1
|
||||
git rm -f "$submodule_path" > /dev/null 2>&1
|
||||
rm -rf .git/modules/"$submodule_path"
|
||||
echo -e "${GREEN}子模块: $submodule_path 已成功删除!${NC}"
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
update_submodule(){
|
||||
# 调用 parse_ini_all 函数,读取所有配置
|
||||
parse_ini_all
|
||||
|
||||
# 调用删除函数,清理已删除的子模块
|
||||
remove_deleted_submodules
|
||||
|
||||
# 遍历所有模块的 section
|
||||
for module in "${module_list[@]}"; do
|
||||
repo_url=$(get_value "$module.repo_url")
|
||||
target_dir=$(get_value "$module.target_dir")
|
||||
version_tag=$(get_value "$module.version_tag")
|
||||
|
||||
if [[ -z "$repo_url" || -z "$target_dir" || -z "$version_tag" ]]; then
|
||||
echo -e "${YELLOW}跳过无效配置:$module${NC}"
|
||||
continue
|
||||
fi
|
||||
|
||||
init_submodule "$module" "$repo_url" "$target_dir" "$version_tag"
|
||||
if [[ $? -ne 0 ]]; then
|
||||
echo -e "${RED}子模块 $target_dir 初始化失败,退出...${NC}"
|
||||
exit 1
|
||||
fi
|
||||
done
|
||||
|
||||
echo -e "${GREEN}所有子模块已成功同步到指定版本!${NC}"
|
||||
}
|
||||
|
||||
# 解析脚本参数
|
||||
case "$1" in
|
||||
-h )
|
||||
show_help
|
||||
exit 0
|
||||
;;
|
||||
-i )
|
||||
echo -e "${BLUE}根据.gitmodules初始化子模块...${NC}"
|
||||
|
||||
git submodule update --init --recursive
|
||||
|
||||
git submodule status
|
||||
echo -e "${GREEN}初始化子模块成功!${NC}"
|
||||
exit 0
|
||||
;;
|
||||
-up )
|
||||
echo -e "${BLUE}根据配置文件更新子模块...${NC}"
|
||||
|
||||
update_submodule
|
||||
|
||||
exit 0
|
||||
;;
|
||||
* )
|
||||
show_help
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
Reference in New Issue
Block a user