#!/bin/bash # 《末日重生》项目Git版本管理脚本 # 提供自动提交、版本标签、定时同步功能 PROJECT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" LOG_FILE="$PROJECT_DIR/logs/git_version.log" CONFIG_FILE="$PROJECT_DIR/config/version_config.json" # 颜色输出 RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' BLUE='\033[0;34m' NC='\033[0m' # No Color # 初始化日志和配置 init() { mkdir -p "$(dirname "$LOG_FILE")" mkdir -p "$(dirname "$CONFIG_FILE")" if [ ! -f "$CONFIG_FILE" ]; then cat > "$CONFIG_FILE" << EOF { "auto_commit": true, "commit_pattern": "更新: {date} {time}", "commit_threshold": 3, "auto_tag": true, "tag_pattern": "v{version}", "tag_milestones": [5, 10, 20, 50, 100], "sync_enabled": true, "sync_schedule": "*/30 * * * *", "backup_enabled": true, "backup_retention": 7, "notifications": { "on_success": true, "on_failure": true } } EOF fi } # 日志函数 log() { local level="$1" local message="$2" local timestamp=$(date '+%Y-%m-%d %H:%M:%S') case $level in "INFO") color=$GREEN ;; "WARN") color=$YELLOW ;; "ERROR") color=$RED ;; *) color=$NC ;; esac echo -e "${color}[$timestamp] [$level] $message${NC}" echo "[$timestamp] [$level] $message" >> "$LOG_FILE" } # 检查Git状态 check_git_status() { log "INFO" "检查Git状态..." cd "$PROJECT_DIR" # 检查是否有未提交的更改 if [ -n "$(git status --porcelain)" ]; then changed_files=$(git status --porcelain | wc -l) log "INFO" "检测到 $changed_files 个未提交的文件" # 显示更改摘要 echo "📝 更改摘要:" git status --short echo "" return 0 # 有更改 else log "INFO" "没有未提交的更改" return 1 # 没有更改 fi } # 自动提交更改 auto_commit() { local message="$1" if [ -z "$message" ]; then local current_date=$(date '+%Y年%m月%d日') local current_time=$(date '+%H:%M:%S') message="更新: $current_date $current_time" fi log "INFO" "自动提交更改: $message" cd "$PROJECT_DIR" # 添加所有更改 git add . # 提交 if git commit -m "$message" > /dev/null 2>&1; then local commit_hash=$(git rev-parse --short HEAD) log "INFO" "✅ 提交成功 (commit: $commit_hash)" echo "提交信息: $message" echo "提交哈希: $commit_hash" return 0 else log "ERROR" "❌ 提交失败" return 1 fi } # 创建版本标签 create_version_tag() { local tag_name="$1" local tag_message="$2" if [ -z "$tag_name" ]; then # 自动生成标签名 local current_version=$(git tag | grep -E '^v[0-9]+\.[0-9]+\.[0-9]+$' | sort -V | tail -1) if [ -z "$current_version" ]; then current_version="v0.0.0" fi # 递增版本号 local major=$(echo "$current_version" | cut -d. -f1 | tr -d 'v') local minor=$(echo "$current_version" | cut -d. -f2) local patch=$(echo "$current_version" | cut -d. -f3) patch=$((patch + 1)) # 每10个小版本升级一个中版本 if [ $patch -ge 10 ]; then patch=0 minor=$((minor + 1)) fi # 每10个中版本升级一个大版本 if [ $minor -ge 10 ]; then minor=0 major=$((major + 1)) fi tag_name="v${major}.${minor}.${patch}" fi if [ -z "$tag_message" ]; then local chapter_count=$(find "$PROJECT_DIR/chapters" -name "*.md" | wc -l) local total_words=0 for chapter in "$PROJECT_DIR/chapters"/*.md; do if [ -f "$chapter" ]; then words=$(wc -w < "$chapter" 2>/dev/null || echo 0) total_words=$((total_words + words)) fi done tag_message="版本 ${tag_name} | 章节: ${chapter_count}章 | 字数: ${total_words}字" fi log "INFO" "创建版本标签: $tag_name" if git tag -a "$tag_name" -m "$tag_message" > /dev/null 2>&1; then log "INFO" "✅ 标签创建成功: $tag_name" echo "标签名称: $tag_name" echo "标签描述: $tag_message" return 0 else log "ERROR" "❌ 标签创建失败" return 1 fi } # 同步到远程仓库 sync_to_remote() { local force="$1" log "INFO" "同步到远程仓库..." cd "$PROJECT_DIR" # 检查远程仓库 if ! git remote get-url origin > /dev/null 2>&1; then log "ERROR" "❌ 未配置远程仓库" return 1 fi # 获取远程仓库信息 local remote_url=$(git remote get-url origin) log "INFO" "远程仓库: $(echo $remote_url | sed 's|https://.*@||')" # 拉取最新更改 log "INFO" "拉取远程更改..." if ! git pull --rebase origin master 2>&1 | grep -q "Already up to date"; then log "INFO" "✅ 已更新本地仓库" fi # 推送更改 log "INFO" "推送到远程仓库..." if [ "$force" = "true" ]; then if git push origin master --tags --force 2>&1; then log "INFO" "✅ 强制推送成功" else log "ERROR" "❌ 推送失败" return 1 fi else if git push origin master --tags 2>&1; then log "INFO" "✅ 推送成功" else log "WARN" "⚠️ 推送失败,尝试强制推送..." if git push origin master --tags --force 2>&1; then log "INFO" "✅ 强制推送成功" else log "ERROR" "❌ 强制推送失败" return 1 fi fi fi # 显示同步结果 local current_branch=$(git branch --show-current) local latest_commit=$(git log -1 --format="%h - %s" 2>/dev/null) local tag_count=$(git tag | wc -l) echo "" echo "📊 同步完成报告" echo "├─ 分支: $current_branch" echo "├─ 最新提交: $latest_commit" echo "├─ 版本标签: $tag_count 个" echo "└─ 远程仓库: $(echo $remote_url | sed 's|https://.*@||')" return 0 } # 自动备份 create_backup() { local backup_type="$1" log "INFO" "创建项目备份..." local backup_dir="$PROJECT_DIR/backups" local timestamp=$(date '+%Y%m%d_%H%M%S') mkdir -p "$backup_dir" case $backup_type in "full") # 完整备份 local backup_file="$backup_dir/full_backup_$timestamp.tar.gz" tar -czf "$backup_file" -C "$PROJECT_DIR" . log "INFO" "✅ 完整备份创建: $(basename $backup_file)" ;; "git") # Git包备份 local backup_file="$backup_dir/git_bundle_$timestamp.bundle" git bundle create "$backup_file" --all log "INFO" "✅ Git包备份创建: $(basename $backup_file)" ;; "chapters") # 章节备份 local backup_file="$backup_dir/chapters_$timestamp.tar.gz" tar -czf "$backup_file" -C "$PROJECT_DIR" chapters/ log "INFO" "✅ 章节备份创建: $(basename $backup_file)" ;; *) # 默认备份 local backup_file="$backup_dir/backup_$timestamp.tar.gz" tar -czf "$backup_file" -C "$PROJECT_DIR" chapters/ outlines/ assets/ log "INFO" "✅ 默认备份创建: $(basename $backup_file)" ;; esac # 清理旧备份 local retention_days=7 find "$backup_dir" -name "*.tar.gz" -mtime +$retention_days -delete 2>/dev/null find "$backup_dir" -name "*.bundle" -mtime +$retention_days -delete 2>/dev/null echo "备份文件: $backup_file" echo "备份大小: $(du -h "$backup_file" | cut -f1)" return 0 } # 项目状态报告 generate_status_report() { log "INFO" "生成项目状态报告..." cd "$PROJECT_DIR" local report_file="$PROJECT_DIR/progress/status_report_$(date '+%Y%m%d').md" mkdir -p "$(dirname "$report_file")" # 收集数据 local chapter_count=$(find chapters -name "*.md" | wc -l) local total_words=0 local latest_chapter="" local latest_chapter_time="" for chapter in chapters/*.md; do if [ -f "$chapter" ]; then words=$(wc -w < "$chapter" 2>/dev/null || echo 0) total_words=$((total_words + words)) # 找到最新章节 chapter_time=$(stat -c %Y "$chapter" 2>/dev/null || echo 0) if [ -z "$latest_chapter_time" ] || [ $chapter_time -gt $latest_chapter_time ]; then latest_chapter_time=$chapter_time latest_chapter=$(basename "$chapter" .md) fi fi done local commit_count=$(git rev-list --count HEAD 2>/dev/null || echo 0) local latest_commit=$(git log -1 --format="%h - %s (%ad)" --date=short 2>/dev/null || echo "无") local tag_count=$(git tag | wc -l) local latest_tag=$(git describe --tags --abbrev=0 2>/dev/null || echo "无") # 生成报告 cat > "$report_file" << EOF # 《末日重生》项目状态报告 ## 报告时间 $(date '+%Y年%m月%d日 %H:%M:%S') ## 创作进度 - **总章节**: ${chapter_count} 章 - **总字数**: ${total_words} 字 - **最新章节**: ${latest_chapter} - **平均每章字数**: $((total_words / chapter_count)) 字 ## 版本管理 - **提交次数**: ${commit_count} 次 - **最新提交**: ${latest_commit} - **版本标签**: ${tag_count} 个 - **最新版本**: ${latest_tag} ## 番茄平台适配 ### 字数要求 - 标准章节字数: 2500-3500字 - 当前平均: $((total_words / chapter_count)) 字 - 状态: $(if [ $((total_words / chapter_count)) -ge 2000 ] && [ $((total_words / chapter_count)) -le 3500 ]; then echo "✅ 符合标准"; else echo "⚠️ 需要调整"; fi) ### 更新要求 - 日更全勤要求: 4000字/天 - 当前总字数: ${total_words} 字 - 相当于: $((total_words / 4000)) 天的全勤更新量 ## Git状态 \`\`\`bash $(git status --short 2>/dev/null || echo "无未提交更改") \`\`\` ## 下一步计划 1. [ ] 继续创作第 $(($chapter_count + 1)) 章 2. [ ] 检查并优化现有章节 3. [ ] 更新项目大纲和设定 4. [ ] 同步到远程仓库 ## 健康检查 - [$(if [ $chapter_count -gt 0 ]; then echo "x"; else echo " "; fi)] 章节文件正常 - [$(if [ -d ".git" ]; then echo "x"; else echo " "; fi)] Git仓库正常 - [$(if git remote get-url origin >/dev/null 2>&1; then echo "x"; else echo " "; fi)] 远程仓库配置 - [$(if [ -f "$report_file" ]; then echo "x"; else echo " "; fi)] 报告生成正常 --- *报告自动生成于 $(date '+%Y-%m-%d %H:%M:%S')* EOF log "INFO" "✅ 状态报告生成: $(basename $report_file)" echo "报告文件: $report_file" return 0 } # 定时同步任务 setup_cron_job() { local schedule="$1" if [ -z "$schedule" ]; then schedule="*/30 * * * *" # 每30分钟 fi log "INFO" "设置定时同步任务: $schedule" # 创建定时任务脚本 local cron_script="/tmp/末日重生_定时同步.sh" cat > "$cron_script" << 'CRON_EOF' #!/bin/bash # 《末日重生》定时同步脚本 PROJECT_DIR="/root/.openclaw/workspace/projects/末日重生_囤货" LOG_FILE="/tmp/末日重生_同步日志.log" log() { echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" >> "$LOG_FILE" } log "INFO" "开始定时同步任务" cd "$PROJECT_DIR" # 检查是否有未提交的更改 if [ -n "$(git status --porcelain)" ]; then log "INFO" "检测到未提交的更改,自动提交..." # 自动提交 commit_message="定时更新: $(date '+%Y年%m月%d日 %H:%M:%S')" git add . if git commit -m "$commit_message" >/dev/null 2>&1; then commit_hash=$(git rev-parse --short HEAD) log "INFO" "✅ 自动提交成功: $commit_hash" else log "ERROR" "❌ 自动提交失败" fi fi # 同步到远程 log "INFO" "同步到远程仓库..." if git pull --rebase origin master >/dev/null 2>&1 && git push origin master >/dev/null 2>&1; then log "INFO" "✅ 同步成功" else log "WARN" "⚠️ 同步失败,下次重试" fi # 创建每日备份(只在特定时间) if [ "$(date '+%H')" = "03" ]; then # 凌晨3点 log "INFO" "创建每日备份..." tar -czf "/tmp/末日重生_备份_$(date '+%Y%m%d').tar.gz" -C "$PROJECT_DIR" . log "INFO" "✅ 备份创建完成" fi log "INFO" "定时同步任务完成" CRON_EOF chmod +x "$cron_script" # 添加cron任务 (crontab -l 2>/dev/null | grep -v "$cron_script"; echo "$schedule $cron_script") | crontab - log "INFO" "✅ 定时任务设置完成" echo "定时任务: $schedule" echo "任务脚本: $cron_script" return 0 } # 主菜单 show_menu() { echo "" echo "📚 《末日重生》项目版本管理系统" echo "=================================" echo "" echo "1. 🔍 检查项目状态" echo "2. 📝 自动提交更改" echo "3. 🏷️ 创建版本标签" echo "4. 🔄 同步到远程仓库" echo "5. 💾 创建项目备份" echo "6. 📊 生成状态报告" echo "7. ⏰ 设置定时同步" echo "8. 🚀 一键全流程" echo "9. 📋 显示帮助" echo "0. ❌ 退出" echo "" echo "=================================" } # 一键全流程 full_workflow() { log "INFO" "开始一键全流程..." echo "🚀 执行一键全流程" echo "----------------" # 1. 检查状态 if check_git_status; then echo "✅ 步骤1: 检查状态完成" else echo "ℹ️ 步骤1: 无未提交更改" fi # 2. 自动提交 if auto_commit "一键更新: $(date '+%Y年%m月%d日 %H:%M:%S')"; then echo "✅ 步骤2: 自动提交完成" else echo "⚠️ 步骤2: 提交跳过" fi # 3. 检查是否需要创建标签 local commit_count=$(git rev-list --count HEAD 2>/dev/null || echo 0) if [ $((commit_count % 10)) -eq 0 ]; then if create_version_tag; then echo "✅ 步骤3: 版本标签创建" else echo "⚠️ 步骤3: 标签跳过" fi fi # 4. 同步到远程 if sync_to_remote; then echo "✅ 步骤4: 远程同步完成" else echo "❌ 步骤4: 同步失败" fi # 5. 生成报告 if generate_status_report; then echo "✅ 步骤5: 状态报告生成" fi log "INFO" "一键全流程完成" echo "🎉 全流程执行完毕!" } # 显示帮助 show_help() { echo "" echo "📖 《末日重生》Git版本管理工具使用说明" echo "========================================" echo "" echo "主要功能:" echo " 🔍 检查状态 - 检查Git状态和未提交更改" echo " 📝 自动提交 - 自动提交所有更改到本地仓库" echo " 🏷️ 版本标签 - 创建版本标签,记录重要里程碑" echo " 🔄 远程同步 - 同步到Gitea远程仓库" echo " 💾 项目备份 - 创建项目备份文件" echo " 📊 状态报告 - 生成详细的项目状态报告" echo " ⏰ 定时同步 - 设置定时自动同步任务" echo " 🚀 一键流程 - 执行完整的版本管理流程" echo "" echo "使用方式:" echo " ./git_version_manager.sh [选项]" echo "" echo "选项:" echo " status 检查项目状态" echo " commit 自动提交更改" echo " tag 创建版本标签" echo " sync 同步到远程" echo " backup 创建备份" echo " report 生成报告" echo " cron 设置定时任务" echo " workflow 执行一键流程" echo " menu 显示交互菜单" echo " help 显示帮助" echo "" echo "示例:" echo " ./git_version_manager.sh status" echo " ./git_version_manager.sh workflow" echo " ./git_version_manager.sh menu" echo "" } # 主函数 main() { init case "$1" in "status") check_git_status ;; "commit") auto_commit "$2" ;; "tag") create_version_tag "$2" "$3" ;; "sync") sync_to_remote "$2" ;; "backup") create_backup "$2" ;; "report") generate_status_report ;; "cron") setup_cron_job "$2" ;; "workflow"|"auto") full_workflow ;; "menu") while true; do show_menu echo "请选择操作 (0-9): " read choice case $choice in 1) check_git_status ;; 2) auto_commit ;; 3) create_version_tag ;; 4) sync_to_remote ;; 5) create_backup ;; 6) generate_status_report ;; 7) setup_cron_job ;; 8) full_workflow ;; 9) show_help ;; 0) echo "再见!" exit 0 ;; *) echo "❌ 无效选择" ;; esac echo "" echo "按回车键继续..." read done ;; "help"|"--help"|"-h") show_help ;; *) echo "使用: $0 [命令]" echo "可用命令: status, commit, tag, sync, backup, report, cron, workflow, menu, help" exit 1 ;; esac } # 运行主函数 main "$@"