短松江月

Git 同步推送到外网和内网的方案

· simons ·
git

这是一个 Git 别名定义,它创建了一个名为 sync 的自定义 Git 命令。让我详细解释每个部分:

基本使用

git config --global alias.sync '!f() { 
    echo "Pushing to origin...";
    git push origin main || echo "Failed to push to origin";
    
    echo "";
    echo "Checking local remote...";
    if git remote | grep -q "^local$"; then
        echo "Pushing to local...";
        git push local main || echo "Failed to push to local";
    else
        echo "⚠️  Local remote not found. Skipping.";
        echo "   To add local: git remote add local /path/to/repo.git";
    fi
    
    echo "";
    echo "✨ Sync completed!";
}; f'

整体功能

这个命令会同时推送代码到两个远程仓库originlocal(如果存在)。

逐行解释

1. 定义函数

'!f() { ... }; f'
  • ! 表示后面是 shell 命令而不是 Git 命令
  • f() { ... } 定义了一个 shell 函数
  • f 最后调用这个函数

2. 推送到 origin

echo "Pushing to origin...";
git push origin main || echo "Failed to push to origin";
  • 显示提示信息
  • 尝试推送到 origin 仓库的 main 分支
  • || 如果推送失败,显示失败信息

3. 检查 local 远程仓库

if git remote | grep -q "^local$"; then
  • git remote 列出所有远程仓库
  • grep -q "^local$" 检查是否有名为 local 的远程仓库
  • -q 静默模式,不输出结果

4. 推送到 local(如果存在)

echo "Pushing to local...";
git push local main || echo "Failed to push to local";
  • 如果找到 local 远程仓库,尝试推送
  • 如果推送失败,显示失败信息

5. 如果没有 local 仓库

else
    echo "⚠️  Local remote not found. Skipping.";
    echo "   To add local: git remote add local /path/to/repo.git";
  • 显示警告信息
  • 提示如何添加 local 仓库

6. 完成提示

echo "";
echo "✨ Sync completed!";
  • 显示同步完成信息

使用示例

# 执行同步
git sync

# 输出示例:
Pushing to origin...
Everything up-to-date

Checking local remote...
Pushing to local...
Enumerating objects: 5, done.
Counting objects: 100% (5/5), done.
Writing objects: 100% (3/3), 285 bytes | 285.00 KiB/s, done.
Total 3 (delta 0), reused 0 (delta 0)
To /path/to/local/repo.git
   1234567..89abcde  main -> main

✨ Sync completed!

重要注意事项

  1. 分支固定为 main

    • 代码中硬编码了 main 分支
    • 如果你使用 master 分支,需要修改
  2. local 仓库需要提前配置

    # 需要先添加 local 远程仓库
    git remote add local /path/to/your/repo.git
  3. 这是一个全局别名

    • --global 表示对所有仓库生效
    • 如果只想对当前仓库生效,去掉 --global

潜在问题

问题1:分支名称不匹配

如果你的分支不是 main 而是 master

# 修复:使用当前分支
BRANCH=$(git branch --show-current)
git push origin $BRANCH

问题2:没有错误处理

当前版本只是显示错误信息,但不阻止继续执行。

改进版本建议

git config --global alias.sync '!f() { 
    # 获取当前分支
    BRANCH=$(git branch --show-current)
    
    echo "🔄 同步分支: $BRANCH";
    echo "";
    
    echo "📤 推送到 origin...";
    if git push origin $BRANCH; then
        echo "✅ 成功推送到 origin";
    else
        echo "❌ 推送到 origin 失败";
        return 1;  # 失败时退出
    fi
    
    echo "";
    echo "🔍 检查 local 远程...";
    if git remote | grep -q "^local$"; then
        echo "🏠 推送到 local...";
        if git push local $BRANCH; then
            echo "✅ 成功推送到 local";
        else
            echo "❌ 推送到 local 失败";
        fi
    else
        echo "⚠️  未找到 local 远程仓库";
        echo "   添加命令: git remote add local /path/to/repo.git";
    fi
    
    echo "";
    echo "✨ 同步完成!";
}; f'

这样更健壮,会:

  1. 自动检测当前分支
  2. 有更好的错误处理
  3. 显示更友好的提示

方案1:详细输出版本

git config --global alias.sync '!f() {
    echo "🚀 ========================================="
    echo "🌍 Git Sync - 开始同步"
    echo "=========================================="
    
    # 获取当前分支
    BRANCH=$(git branch --show-current)
    echo "📋 当前分支: \033[1;34m$BRANCH\033[0m"
    echo ""
    
    # 获取远程仓库列表
    echo "🔍 检测远程仓库..."
    REMOTES=$(git remote)
    echo "找到远程仓库: \033[1;33m$REMOTES\033[0m"
    echo ""
    
    # 检查 origin 是否存在
    if echo "$REMOTES" | grep -q "^origin$"; then
        echo "📤 开始推送到 origin/$BRANCH"
        echo "------------------------------------------"
        if git push origin $BRANCH; then
            echo "✅ \033[1;32m成功推送到 origin\033[0m"
        else
            echo "❌ \033[1;31m推送到 origin 失败\033[0m"
        fi
    else
        echo "⚠️  \033[1;33m未找到 origin 远程仓库\033[0m"
    fi
    echo ""
    
    # 检查 local 是否存在
    if echo "$REMOTES" | grep -q "^local$"; then
        echo "🏠 开始推送到 local/$BRANCH"
        echo "------------------------------------------"
        if git push local $BRANCH; then
            echo "✅ \033[1;32m成功推送到 local\033[0m"
        else
            echo "❌ \033[1;31m推送到 local 失败\033[0m"
        fi
    else
        echo "ℹ️  \033[1;36m未配置 local 远程仓库,跳过本地备份\033[0m"
        echo "   如需配置,请运行: git remote add local /path/to/backup.git"
    fi
    echo ""
    
    echo "✨ ========================================="
    echo "🎉 同步完成!"
    echo "=========================================="
}; f'

方案2:简洁彩色版本

git config --global alias.sync '!f() {
    echo -e "\033[1;36m🚀 Git 同步开始\033[0m"
    BRANCH=$(git branch --show-current)
    echo -e "📁 分支: \033[1;33m$BRANCH\033[0m"
    echo ""
    
    # 推送到 origin
    echo -e "\033[1;34m📤 推送到 origin...\033[0m"
    if git push origin $BRANCH; then
        echo -e "   \033[1;32m✓ 成功\033[0m"
    else
        echo -e "   \033[1;31m✗ 失败\033[0m"
    fi
    
    # 推送到 local(如果存在)
    if git remote | grep -q "^local$"; then
        echo -e "\033[1;35m🏠 推送到 local...\033[0m"
        if git push local $BRANCH; then
            echo -e "   \033[1;32m✓ 成功\033[0m"
        else
            echo -e "   \033[1;31m✗ 失败\033[0m"
        fi
    else
        echo -e "\033[1;90mℹ️  跳过 local (未配置)\033[0m"
    fi
    
    echo -e "\n\033[1;36m✨ 同步完成!\033[0m"
}; f'

方案3:进度指示版本

git config --global alias.sync '!f() {
    BRANCH=$(git branch --show-current)
    echo "🔄 同步分支: $BRANCH"
    echo ""
    
    # 推送到 origin
    echo -n "📤 正在推送到 origin... "
    if git push origin $BRANCH > /dev/null 2>&1; then
        echo "✅"
    else
        echo "❌"
        echo "   详细信息:"
        git push origin $BRANCH
    fi
    
    # 推送到 local(如果存在)
    if git remote | grep -q "^local$"; then
        echo -n "🏠 正在推送到 local... "
        if git push local $BRANCH > /dev/null 2>&1; then
            echo "✅"
        else
            echo "❌"
            echo "   详细信息:"
            git push local $BRANCH
        fi
    else
        echo "⏭️  跳过 local (未配置)"
    fi
    
    echo ""
    echo "🎯 同步完成"
}; f'

方案4:带时间和状态记录的版本

git config --global alias.sync '!f() {
    # 记录开始时间
    START_TIME=$(date +%s)
    echo "🕒 同步开始时间: $(date "+%Y-%m-%d %H:%M:%S")"
    echo ""
    
    BRANCH=$(git branch --show-current)
    echo "🌿 当前分支: $BRANCH"
    echo ""
    
    # 推送到 origin
    echo "📤 [1/2] 推送到 origin/$BRANCH"
    echo "--------------------------------"
    if git push origin $BRANCH; then
        ORIGIN_STATUS="✅ 成功"
    else
        ORIGIN_STATUS="❌ 失败"
    fi
    echo ""
    
    # 推送到 local
    LOCAL_STATUS="⏭️  跳过"
    if git remote | grep -q "^local$"; then
        echo "🏠 [2/2] 推送到 local/$BRANCH"
        echo "--------------------------------"
        if git push local $BRANCH; then
            LOCAL_STATUS="✅ 成功"
        else
            LOCAL_STATUS="❌ 失败"
        fi
    fi
    
    # 计算耗时
    END_TIME=$(date +%s)
    DURATION=$((END_TIME - START_TIME))
    
    echo ""
    echo "📊 同步报告"
    echo "=========="
    echo "• origin: $ORIGIN_STATUS"
    echo "• local:  $LOCAL_STATUS"
    echo "• 耗时:   ${DURATION}秒"
    echo "• 完成:   $(date "+%H:%M:%S")"
}; f'

方案5:交互式版本(询问确认)

git config --global alias.sync '!f() {
    BRANCH=$(git branch --show-current)
    
    echo "🔍 准备同步信息:"
    echo "   分支: $BRANCH"
    echo "   远程仓库: $(git remote | tr "\n" " ")"
    echo ""
    
    # 询问是否继续
    read -p "🚀 是否开始同步? [Y/n] " -n 1 -r
    echo ""
    if [[ $REPLY =~ ^[Nn]$ ]]; then
        echo "⏹️  已取消"
        return 1
    fi
    
    echo "🔄 开始同步..."
    echo ""
    
    # 推送到 origin
    echo "📤 推送到 origin..."
    if git push origin $BRANCH; then
        echo "   ✅ 完成"
    else
        echo "   ❌ 失败"
    fi
    
    # 推送到 local(如果存在)
    if git remote | grep -q "^local$"; then
        echo ""
        echo "🏠 推送到 local..."
        if git push local $BRANCH; then
            echo "   ✅ 完成"
        else
            echo "   ❌ 失败"
        fi
    fi
    
    echo ""
    echo "🎉 同步操作完成"
}; f'

推荐使用方案

我推荐使用方案1方案4

方案1 优点:

  • 输出格式清晰,有分隔线
  • 彩色显示,易于阅读
  • 显示详细信息

方案4 优点:

  • 包含时间戳和耗时统计
  • 有状态报告
  • 专业的工作流显示