Created
February 24, 2026 12:24
-
-
Save SmileMachine/d309985e25891e724b3930367c0bf6b0 to your computer and use it in GitHub Desktop.
专为个人开发者 Monorepo/Worktree 打造的 Git 智能同步脚本:支持固定开发分支的循环复用,构建整洁的线性“气泡”历史。
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/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