Skip to content

Instantly share code, notes, and snippets.

@SmileMachine
Created February 24, 2026 12:24
Show Gist options
  • Select an option

  • Save SmileMachine/d309985e25891e724b3930367c0bf6b0 to your computer and use it in GitHub Desktop.

Select an option

Save SmileMachine/d309985e25891e724b3930367c0bf6b0 to your computer and use it in GitHub Desktop.
专为个人开发者 Monorepo/Worktree 打造的 Git 智能同步脚本:支持固定开发分支的循环复用,构建整洁的线性“气泡”历史。
#!/bin/bash
# ==============================================================================
# 🚀 git-sync: Git Worktree 智能同步脚本 (个人开发者 Monorepo 专用版)
# ==============================================================================
#
# 【脚本用途】
# 本脚本专为“个人开发者”量身打造,旨在简化 Monorepo 环境下的本地开发流。
# 不同于团队协作中的“一功能一分支”模式,本脚本鼓励为每个 Worktree 使用“固定
# 开发分支”(如 ios-dev)。通过自动化合并与重置,实现分支的循环复用。
#
# 【核心逻辑:循环开发模式】
# 1. 在固定分支上开发 -> 2. 运行本脚本合并至 main -> 3. 分支自动重置归位。
# 这种模式消除了频繁创建/删除分支的开销,保持本地环境极度纯净且高效。
#
# 【💡 完美主义者建议:前置变基】
# 为了获得最优雅的线性“气泡”历史,强烈建议在运行此脚本前执行:
# git rebase main
# 这样可以将你的提交平滑地移至 main 的顶部,避免交叉冲突,确保审计历史清晰美观。
#
# 【核心特性】
# 1. 📂 跨目录合并:自动识别 main 是否在其他 Worktree 签出,彻底解决分支占用报错。
# 2. 🫧 气泡模式:强制 --no-ff 合并,在 main 上为每个阶段性任务保留清晰边界。
# 3. 🛡️ 脏代码保护:严格检查未提交改动,确保本地 reset --hard 操作的安全性。
# 4. 🔄 循环复用:合并后自动重置固定分支到 main,瞬间清空“草稿纸”,开启新任务。
# 5. 🏠 个人模式:不涉及远程 PR 或团队冲突处理,追求极致的本地操作速度。
#
# 【使用方法】
# 1. 提交改动:git add . && git commit -m "..."
# 2. 推荐变基:git rebase main
# 3. 执行同步:./git-sync.sh "完成的功能描述"
#
# 【建议集成 (Justfile)】
# # 注意:如果使用下面的代码,本脚本(git-sync.sh)必须存放在仓库根目录
# git-sync msg="":
# @bash "$(git rev-parse --show-toplevel)/git-sync.sh" {{quote(msg)}}
# ==============================================================================
# --- 配置 ---
MAIN_BRANCH="main"
START_DIR=$(pwd)
MERGE_MSG=$1
# --- 1. 基础环境检查 ---
# 确保在 Git 仓库内
if ! git rev-parse --is-inside-work-tree > /dev/null 2>&1; then
echo "❌ 错误: 此目录不是 Git 仓库。"
exit 1
fi
# 获取当前分支
CURRENT_BRANCH=$(git symbolic-ref --short HEAD)
# 已经在 main 分支则退出
if [ "$CURRENT_BRANCH" == "$MAIN_BRANCH" ]; then
echo "⚠️ 已经在 $MAIN_BRANCH 分支,无需同步。"
exit 0
fi
# --- 2. 脏代码保护 ---
# 必须先提交所有改动,否则 reset --hard 会导致代码丢失
if [[ -n $(git status --porcelain) ]]; then
echo "❌ 错误: 存在未提交的改动。"
echo "提示: 请先 commit 或使用 git stash 暂存修改。"
exit 1
fi
# --- 3. 智能路径探测 ---
# 检查 main 分支是否在其他 Worktree 中被占用
MAIN_PATH=$(git worktree list | grep "\[$MAIN_BRANCH\]" | awk '{print $1}')
echo "🚀 启动同步流程: [$CURRENT_BRANCH] -> [$MAIN_BRANCH]"
# 定义合并函数,减少代码重复
do_merge() {
local branch=$1
if [ -n "$MERGE_MSG" ]; then
# 如果有自定义消息,使用 -m。格式:Merge branch 'xxx': 你的消息
echo "📝 使用自定义消息合并..."
git merge "$branch" --no-ff -m "Merge '$branch': $MERGE_MSG"
else
# 如果没有消息,使用默认模板
echo "🤖 使用默认消息合并..."
git merge "$branch" --no-ff --no-edit
fi
}
if [ -n "$MAIN_PATH" ]; then
# --- 情况 A: main 已在其他 Worktree 签出 ---
echo "📍 探测到 $MAIN_BRANCH 已在目录占用: $MAIN_PATH"
echo "🔄 正在跳转至该目录执行合并..."
cd "$MAIN_PATH" || exit
if ! do_merge "$CURRENT_BRANCH"; then
echo "❌ 冲突: 合并失败。请在 $MAIN_PATH 手动解决冲突。"
exit 1
fi
# 成功后回到原始 Worktree
cd "$START_DIR" || exit
else
# --- 情况 B: main 未被占用,直接在当前 Worktree 切换操作 ---
echo "🍃 $MAIN_BRANCH 当前空闲,执行就地合并..."
# 临时切换到 main
if ! git checkout "$MAIN_BRANCH"; then
echo "❌ 错误: 无法切换到 $MAIN_BRANCH。"
exit 1
fi
# 执行合并
if ! do_merge "$CURRENT_BRANCH"; then
echo "❌ 冲突: 合并失败。请手动解决冲突。"
exit 1
fi
# 切回原开发分支
git checkout "$CURRENT_BRANCH"
fi
# --- 4. 归位与对齐 (The Magic Step) ---
echo "✨ 合并成功。正在重置 $CURRENT_BRANCH 以对齐最新的 $MAIN_BRANCH..."
# 确保在当前 Worktree 的根部执行重置
WORKTREE_ROOT=$(git rev-parse --show-toplevel)
cd "$WORKTREE_ROOT" || exit
# 关键:让开发分支瞬间同步 main 的最新成果
git reset --hard "$MAIN_BRANCH"
# 回到用户最开始所在的那个子目录 (比如 ios/ 或 server/)
cd "$START_DIR" || exit
echo "✅ 同步完成!"
echo "🌿 当前分支: $CURRENT_BRANCH"
echo "💡 所有的跨端修改已入库,你可以继续在当前目录开发新功能了。"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment