编辑
2025-08-20
默认分类
00

下面的脚本,可以实现镜像分支与二开分支的同步。

bash
# .cnb/.scripts/safe-sync-upstream.sh #!/bin/bash set -eo pipefail # 颜色定义 RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' NC='\033[0m' # No Color echo -e "${GREEN}🚀 开始安全同步上游仓库...${NC}" echo "---------------------------------" # 1. 基础配置 git config --global user.name "CI Sync Bot" git config --global user.email "ci@example.com" # 2. 添加上游仓库 if ! git remote | grep -q "upstream"; then git remote add upstream https://github.com/Kele-Bingtang/vitepress-theme-teek echo -e "${GREEN}✅ 已添加上游仓库${NC}" fi # 3. 分支定义(严格隔离) readonly UPSTREAM_BRANCHES=("main" "dev") readonly LOCAL_MIRROR_PREFIX="mirror_" readonly CUSTOM_BRANCHES=("master" "develop") readonly SYNC_DEFAULT_BRANCH=true # 是否同步默认分支 readonly DEFAULT_BRANCH="main" # 默认分支名称 readonly SYNC_SOURCE="master" # 同步源分支 # 4. 获取最新代码 echo -e "${GREEN}🔍 正在获取上游最新代码...${NC}" git fetch upstream --prune --quiet echo -e "${GREEN}✅ 已获取上游最新代码${NC}" echo "---------------------------------" echo -e "${GREEN}🔍 正在获取本地最新代码...${NC}" git fetch origin --prune --quiet echo -e "${GREEN}✅ 已获取本地最新代码${NC}" echo "---------------------------------" # 5. 保存当前分支 original_branch=$(git branch --show-current) trap '[[ -n "$original_branch" ]] && git checkout "$original_branch" 2>/dev/null || true' EXIT # 6. 创建本地镜像分支 create_mirror_branches() { for branch in "${UPSTREAM_BRANCHES[@]}"; do local mirror_branch="${LOCAL_MIRROR_PREFIX}${branch}" local upstream_ref="upstream/${branch}" echo -e "${YELLOW}🔄 正在同步镜像分支: ${mirror_branch}${NC}" if git rev-parse --verify -q "$mirror_branch" >/dev/null; then # 分支已存在,检查是否需要更新 if ! git diff --quiet "$mirror_branch" "$upstream_ref"; then git checkout -B "$mirror_branch" "$upstream_ref" --quiet git push origin "$mirror_branch" --force 2>/dev/null echo -e "${GREEN} ✅ 已更新: ${mirror_branch} -> $(git rev-parse --short HEAD)${NC}" else echo -e " 🔹 无需更新: ${mirror_branch} 已是最新" fi else # 分支不存在,创建新分支 git checkout -B "$mirror_branch" "$upstream_ref" --quiet git push origin "$mirror_branch" 2>/dev/null echo -e "${GREEN} ✅ 已创建: ${mirror_branch} -> $(git rev-parse --short HEAD)${NC}" fi done } # 7. 安全合并测试(改进版) safe_merge_test() { echo "DEBUG: 进入safe_merge_test: $1, $2" local custom_branch=$1 local mirror_branch="${LOCAL_MIRROR_PREFIX}${2}" # 添加标题输出(确保在函数开始时输出) echo -e "${YELLOW}🛡️ 检查分支: ${custom_branch}${NC}" # 保存当前分支 local current_branch=$(git symbolic-ref --short HEAD 2>/dev/null) local stash_created=0 local result=0 # 如果有未提交的更改,先stash if ! git diff --quiet || ! git diff --cached --quiet; then git stash push --quiet --include-untracked >/dev/null 2>&1 stash_created=1 fi # 检查本地分支是否存在 if git rev-parse --verify -q "$custom_branch" >/dev/null; then echo -e "${GREEN} ✅ 使用本地分支: ${custom_branch}${NC}" local temp_branch="temp_merge_${custom_branch}_$(date +%s)" if ! git checkout -b "$temp_branch" "$custom_branch" --quiet >/dev/null 2>&1; then echo -e "${RED} ❌ 创建测试分支失败${NC}" result=1 elif git merge --no-commit --no-ff "$mirror_branch" --quiet >/dev/null 2>&1; then echo -e "${GREEN} ✅ 可自动合并: ${custom_branch}${mirror_branch}${NC}" result=0 else echo -e "${RED}⛔ 存在合并冲突: ${custom_branch}${mirror_branch}${NC}" result=1 fi # 清理临时分支 git merge --abort --quiet >/dev/null 2>&1 || true git checkout "$current_branch" --quiet >/dev/null 2>&1 || true git branch -D "$temp_branch" --quiet >/dev/null 2>&1 || true # 检查origin分支是否存在 elif git rev-parse --verify -q "origin/$custom_branch" >/dev/null; then echo -e "${YELLOW} 🔄 从origin检出分支进行测试: ${custom_branch}${NC}" local temp_branch="temp_test_${custom_branch}_$(date +%s)" if ! git checkout -b "$temp_branch" "origin/$custom_branch" --quiet >/dev/null 2>&1; then echo -e "${RED} ❌ 检出分支失败: ${custom_branch}${NC}" result=1 elif git merge --no-commit --no-ff "$mirror_branch" --quiet >/dev/null 2>&1; then echo -e "${GREEN} ✅ 可自动合并: ${custom_branch}${mirror_branch}${NC}" result=0 else echo -e "${RED}⛔ 存在合并冲突: ${custom_branch}${mirror_branch}${NC}" result=1 fi # 清理临时分支 git merge --abort --quiet >/dev/null 2>&1 || true git checkout "$current_branch" --quiet >/dev/null 2>&1 || true git branch -D "$temp_branch" --quiet >/dev/null 2>&1 || true # 都不存在 else echo -e "${YELLOW} ⚠️ 分支 ${custom_branch} 在本地和origin均不存在,跳过合并测试${NC}" result=2 fi # 确保恢复原分支 [[ -n "$current_branch" ]] && git checkout "$current_branch" --quiet >/dev/null 2>&1 || true return $result } # 8. 执行合并操作(改进版) perform_merge() { local custom_branch=$1 local mirror_branch="${LOCAL_MIRROR_PREFIX}${2}" # 检查本地分支是否存在 if git rev-parse --verify -q "$custom_branch" >/dev/null; then if ! git diff --quiet "$custom_branch" "$mirror_branch"; then if git merge --no-edit --no-ff "$mirror_branch" >/dev/null 2>&1; then echo -e "${GREEN} ✅ 已合并更新: ${custom_branch}${mirror_branch}${NC}" return 0 else echo -e "${RED}💥 合并冲突: ${custom_branch}${mirror_branch}${NC}" return 1 fi else echo " 🔹 无需合并: ${custom_branch} 已包含所有更新" return 0 fi # 检查origin分支是否存在 elif git rev-parse --verify -q "origin/$custom_branch" >/dev/null; then echo -e "${YELLOW} 🔄 从origin检出分支进行合并: ${custom_branch}${NC}" # 创建并切换到分支 if git checkout -b "$custom_branch" "origin/$custom_branch" --quiet >/dev/null 2>&1; then if git merge --no-edit --no-ff "$mirror_branch" >/dev/null 2>&1; then echo -e "${GREEN} ✅ 已合并更新: ${custom_branch}${mirror_branch}${NC}" # 设置上游跟踪 git branch -u "origin/$custom_branch" >/dev/null 2>&1 return 0 else echo -e "${RED}💥 合并冲突: ${custom_branch}${mirror_branch}${NC}" return 1 fi else echo -e "${RED} ❌ 无法检出分支: ${custom_branch}${NC}" return 1 fi # 都不存在 else echo -e "${YELLOW} ⚠️ 分支 ${custom_branch} 在本地和origin均不存在,跳过合并${NC}" return 2 fi } # 9. 获取分支状态信息(改进版) get_branch_status() { local custom_branch=$1 local mirror_branch=$2 # 检查本地分支 if git rev-parse --verify -q "$custom_branch" >/dev/null; then if git diff --quiet "$custom_branch" "$mirror_branch"; then echo " ${custom_branch}${mirror_branch} 同步" else local behind_count=$(git rev-list --count "${custom_branch}..${mirror_branch}" 2>/dev/null || echo "未知") if [[ "$behind_count" -eq "0" ]]; then echo " ${custom_branch}${mirror_branch} 同步" else echo " ${custom_branch} 落后于 ${mirror_branch} (差异: ${behind_count} commits)" fi fi # 检查origin分支 elif git rev-parse --verify -q "origin/$custom_branch" >/dev/null; then # 创建临时分支进行比较 local temp_branch="temp_status_${custom_branch}_$(date +%s)" if git checkout -b "$temp_branch" "origin/$custom_branch" --quiet >/dev/null 2>&1; then if git diff --quiet "$temp_branch" "$mirror_branch"; then echo " ${custom_branch} (origin) 与 ${mirror_branch} 同步" else local behind_count=$(git rev-list --count "${temp_branch}..${mirror_branch}" 2>/dev/null || echo "未知") echo " ${custom_branch} (origin) 落后于 ${mirror_branch} (差异: ${behind_count} commits)" fi # 清理临时分支并恢复 git checkout - --quiet >/dev/null 2>&1 git branch -D "$temp_branch" --quiet >/dev/null 2>&1 else echo " ${custom_branch} -> 状态检查失败" fi # 都不存在 else echo " ${custom_branch} -> 分支不存在" fi } # 10. 同步默认分支(改进版) sync_default_branch() { local default_branch="main" local custom_branch="master" echo "---------------------------------" echo -e "${YELLOW}🔄 同步默认分支: ${default_branch} -> ${custom_branch}${NC}" # 检查 custom_branch 是否存在 if ! git rev-parse --verify -q "$custom_branch" >/dev/null; then echo " ⚠️ 二开分支 ${custom_branch} 不存在,跳过同步" return 1 fi # 处理 default_branch if git rev-parse --verify -q "$default_branch" >/dev/null; then # default_branch 已存在,进行同步 if ! git diff --quiet "$default_branch" "$custom_branch"; then git checkout "$default_branch" --quiet >/dev/null 2>&1 if git merge --no-edit --no-ff "$custom_branch" --quiet >/dev/null 2>&1; then echo -e "${GREEN} ✅ 已同步: ${default_branch}${custom_branch}${NC}" else echo -e "${RED} ❌ 同步失败: ${default_branch}${custom_branch}${NC}" git merge --abort --quiet >/dev/null 2>&1 fi else echo " 🔹 无需同步: ${default_branch} 已与 ${custom_branch} 同步" fi else # default_branch 不存在,创建并同步 git checkout -b "$default_branch" "$custom_branch" --quiet >/dev/null 2>&1 echo -e "${GREEN} ✅ 已创建: ${default_branch}${custom_branch}${NC}" # 如果远程存在 default_branch,设置跟踪 if git rev-parse --verify -q "origin/$default_branch" >/dev/null; then git branch -u "origin/$default_branch" >/dev/null 2>&1 echo -e "${GREEN} 📡 已设置远程跟踪: ${default_branch} -> origin/${default_branch}${NC}" fi fi # 恢复原分支 git checkout "$original_branch" --quiet >/dev/null 2>&1 return 0 } # 在主流程中调用(在最终状态报告前) sync_default_branch # ---------------------------- # 主执行流程 # ---------------------------- # A. 创建/更新镜像分支 create_mirror_branches # B. 安全合并检测 echo -e "${YELLOW}🔎 正在检查合并兼容性...${NC}" conflict_detected=0 skip_count=0 # 在主循环前添加调试 echo "DEBUG: 开始检查合并兼容性,分支数量: ${#CUSTOM_BRANCHES[@]}" for i in "${!CUSTOM_BRANCHES[@]}"; do echo "DEBUG: 准备检查分支 ${CUSTOM_BRANCHES[$i]} -> ${UPSTREAM_BRANCHES[$i]}" done for i in "${!UPSTREAM_BRANCHES[@]}"; do echo "---------------------------------" result=$(safe_merge_test "${CUSTOM_BRANCHES[$i]}" "${UPSTREAM_BRANCHES[$i]}") echo "$result" # 解析返回结果 if [[ "$result" == *"存在合并冲突"* ]]; then conflict_detected=1 elif [[ "$result" == *"均不存在"* ]]; then skip_count=$((skip_count + 1)) fi done # C. 执行合并(仅当无冲突且不是全部跳过) if [[ $conflict_detected -eq 0 && $skip_count -lt ${#CUSTOM_BRANCHES[@]} ]]; then echo "---------------------------------" echo -e "${GREEN}🚀 正在执行安全合并...${NC}" for i in "${!UPSTREAM_BRANCHES[@]}"; do perform_merge "${CUSTOM_BRANCHES[$i]}" "${UPSTREAM_BRANCHES[$i]}" done else echo "---------------------------------" if [[ $conflict_detected -eq 1 ]]; then echo -e "${RED}⚠️ 检测到冲突,已中止自动合并${NC}" elif [[ $skip_count -eq ${#CUSTOM_BRANCHES[@]} ]]; then echo -e "${YELLOW}⚠️ 所有二开分支均不存在,跳过合并${NC}" fi fi # D. 同步默认分支 if [[ "$SYNC_DEFAULT_BRANCH" == "true" ]]; then sync_default_branch "$DEFAULT_BRANCH" "$SYNC_SOURCE" fi # E. 最终状态报告 echo "=================================" echo -e "${GREEN}🌿 分支状态摘要:${NC}" echo "---------------------------------" echo -e "${YELLOW}【上游镜像分支】${NC}" for branch in "${UPSTREAM_BRANCHES[@]}"; do mirror_branch="${LOCAL_MIRROR_PREFIX}${branch}" echo " ${mirror_branch} -> $(git rev-parse --short ${mirror_branch} 2>/dev/null || echo '未知')" done echo "---------------------------------" echo -e "${YELLOW}【二开分支】${NC}" for branch in "${CUSTOM_BRANCHES[@]}"; do if git rev-parse --verify -q "$branch" >/dev/null; then echo " ${branch} -> $(git rev-parse --short ${branch})" elif git rev-parse --verify -q "origin/$branch" >/dev/null; then echo " ${branch} -> (仅存在于origin)" else echo " ${branch} -> 不存在" fi done echo "---------------------------------" echo -e "${YELLOW}【分支差异状态】${NC}" for i in "${!UPSTREAM_BRANCHES[@]}"; do mirror_branch="${LOCAL_MIRROR_PREFIX}${UPSTREAM_BRANCHES[$i]}" custom_branch="${CUSTOM_BRANCHES[$i]}" get_branch_status "$custom_branch" "$mirror_branch" done echo "---------------------------------" echo -e "${YELLOW}【远程分支状态】${NC}" git remote show origin 2>/dev/null | grep -E '^(Local|Remote) branch' -A1 | sed 's/^/ /' || echo " 远程状态检查跳过" echo "---------------------------------" echo "🕒 最后同步时间: $(date '+%Y-%m-%d %H:%M:%S')" echo "=================================" echo -e "${GREEN}✅ 同步完成。当前分支: ${original_branch}${NC}" echo "=================================" echo "当前仓库分支关系图: " echo "---------------------------------" git branch -avv 2>/dev/null | grep -E '^( |* )' | sed 's/^/ /' || echo " 无法获取分支关系图" echo "=================================" echo "🔧 请根据需要手动合并或更新分支。" echo "=================================" # 在脚本最后添加推送环节 echo "---------------------------------" echo -e "${YELLOW}🚀 推送二开分支到origin...${NC}" # 推送master分支 if git push origin master --quiet 2>/dev/null; then echo -e "${GREEN} ✅ 已推送: master → origin/master${NC}" else echo -e "${RED} ❌ 推送失败: master → origin/master${NC}" fi # 推送develop分支 if git push origin develop --quiet 2>/dev/null; then echo -e "${GREEN} ✅ 已推送: develop → origin/develop${NC}" else echo -e "${RED} ❌ 推送失败: develop → origin/develop${NC}" fi echo "---------------------------------"

本文作者:任浪漫

本文链接:

版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!