chore: 可是实现从创建补丁,应用补丁,到回滚补丁整个流程的操作
This commit is contained in:
@@ -108,6 +108,13 @@ release_lock() {
|
||||
info "🔓 释放回滚锁"
|
||||
}
|
||||
|
||||
# 路径规范化函数 - 去除多余的斜杠
|
||||
normalize_path() {
|
||||
local path="$1"
|
||||
# 使用 sed 去除重复的斜杠
|
||||
echo "$path" | sed 's|/\+|/|g'
|
||||
}
|
||||
|
||||
# 清理函数
|
||||
cleanup() {
|
||||
local exit_code=$?
|
||||
@@ -197,19 +204,19 @@ list_rollback_points() {
|
||||
|
||||
# 文件可读性检查
|
||||
if [[ ! -r "$info_file" ]]; then
|
||||
warning "文件不可读: $info_file" >&2
|
||||
warn "文件不可读: $info_file" >&2
|
||||
continue
|
||||
fi
|
||||
|
||||
# 文件大小检查
|
||||
if [[ ! -s "$info_file" ]]; then
|
||||
warning "空文件: $info_file" >&2
|
||||
warn "空文件: $info_file" >&2
|
||||
continue
|
||||
fi
|
||||
|
||||
# 解析JSON
|
||||
if ! jq -e '.' "$info_file" >/dev/null 2>&1; then
|
||||
warning "无效的JSON文件: $info_file" >&2
|
||||
warn "无效的JSON文件: $info_file" >&2
|
||||
continue
|
||||
fi
|
||||
|
||||
@@ -229,7 +236,7 @@ list_rollback_points() {
|
||||
|
||||
# 验证备份文件
|
||||
if [[ ! -f "$backup_path" ]]; then
|
||||
warning "备份文件不存在: $backup_path (来自 $info_file)" >&2
|
||||
warn "备份文件不存在: $backup_path (来自 $info_file)" >&2
|
||||
continue
|
||||
fi
|
||||
|
||||
@@ -455,7 +462,17 @@ extract_backup() {
|
||||
info "✅ 备份文件提取完成"
|
||||
|
||||
# 验证提取内容
|
||||
local file_count=$(find "$extract_dir" -type f | wc -l)
|
||||
# 查找 changes.txt 文件是否存在, 如果存在,则说明找到了,如果不存在,则说明备份文件提取失败
|
||||
if [[ -f "$extract_dir/changes.txt" ]]; then
|
||||
info "找到 changes.txt 文件"
|
||||
else
|
||||
warn "❌ 备份文件中未找到 changes.txt 文件"
|
||||
return 1
|
||||
fi
|
||||
|
||||
# 查找解压目录下的contents目录,获得文件数量
|
||||
local contents_dir=$(normalize_path "$extract_dir/contents")
|
||||
local file_count=$(find "$contents_dir" -type f | wc -l)
|
||||
if [[ $file_count -gt 0 ]]; then
|
||||
info "找到 $file_count 个备份文件"
|
||||
return 0
|
||||
@@ -473,6 +490,7 @@ extract_backup() {
|
||||
perform_rollback() {
|
||||
local extract_dir="$1"
|
||||
local dry_run="${2:-false}"
|
||||
local rollback_info_file="${3:-}"
|
||||
|
||||
info "🔄 开始执行回滚操作 (干跑模式: $dry_run)"
|
||||
|
||||
@@ -484,12 +502,23 @@ perform_rollback() {
|
||||
local rollback_count=0
|
||||
local error_count=0
|
||||
local skip_count=0
|
||||
local deleted_count=0
|
||||
|
||||
# 查找所有备份文件
|
||||
find "$extract_dir" -type f | while read backup_file; do
|
||||
local relative_path="${backup_file#$extract_dir/}"
|
||||
# 首先处理新增文件的删除
|
||||
handle_added_files_deletion "$extract_dir" "$dry_run"
|
||||
deleted_count=$?
|
||||
|
||||
# 查找所有备份文件并恢复, 备份文件存放于contents目录下
|
||||
local contents_dir="$extract_dir/contents"
|
||||
contents_dir=$(normalize_path "$contents_dir")
|
||||
|
||||
find "$contents_dir" -type f | while read backup_file; do
|
||||
local relative_path="${backup_file#$contents_dir/}"
|
||||
relative_path=$(normalize_path "$relative_path")
|
||||
local target_file="$relative_path"
|
||||
target_file=$(normalize_path "$target_file")
|
||||
local target_dir=$(dirname "$target_file")
|
||||
target_dir=$(normalize_path "$target_dir")
|
||||
|
||||
if [[ "$dry_run" == "true" ]]; then
|
||||
info "📋 [干跑] 回滚文件: $relative_path → $target_file" >&2
|
||||
@@ -529,7 +558,8 @@ perform_rollback() {
|
||||
done
|
||||
|
||||
info "📊 回滚操作统计:"
|
||||
info " 成功: $rollback_count"
|
||||
info " 恢复文件: $rollback_count"
|
||||
info " 删除新增: $deleted_count"
|
||||
info " 失败: $error_count"
|
||||
info " 跳过: $skip_count"
|
||||
|
||||
@@ -547,6 +577,90 @@ perform_rollback() {
|
||||
fi
|
||||
}
|
||||
|
||||
# 处理新增文件的删除
|
||||
handle_added_files_deletion() {
|
||||
local extract_dir="$1"
|
||||
local dry_run="$2"
|
||||
|
||||
info "🗑️ 处理新增文件删除..."
|
||||
|
||||
local changes_file="$extract_dir/changes.txt"
|
||||
|
||||
if [[ ! -f "$changes_file" ]]; then
|
||||
warn "⚠️ changes.txt 文件不存在,无法处理新增文件删除"
|
||||
return 0
|
||||
fi
|
||||
|
||||
local error_count=0
|
||||
local skip_count=0
|
||||
local deleted_count=0
|
||||
|
||||
# 处理ADDED类型的文件
|
||||
while IFS='|' read -r change_type path extra_info; do
|
||||
if [[ "$change_type" == "ADDED" ]]; then
|
||||
local target_file=$(normalize_path "$path")
|
||||
|
||||
if [[ "$dry_run" == "true" ]]; then
|
||||
info "📋 [干跑] 删除新增文件: $target_file" >&2
|
||||
((deleted_count++))
|
||||
continue
|
||||
fi
|
||||
|
||||
# 检查文件是否存在
|
||||
if [[ -f "$target_file" ]]; then
|
||||
# 备份即将删除的文件
|
||||
local backup_target="$TEMP_DIR/added_files_backup/$path"
|
||||
backup_target=$(normalize_path "$backup_target")
|
||||
local backup_dir=$(dirname "$backup_target")
|
||||
backup_dir=$(normalize_path "$backup_dir")
|
||||
mkdir -p "$backup_dir"
|
||||
|
||||
if cp -p "$target_file" "$backup_target" 2>/dev/null; then
|
||||
debug "备份新增文件: $target_file"
|
||||
fi
|
||||
|
||||
# 删除新增文件
|
||||
if rm -f "$target_file"; then
|
||||
info "✅ 删除新增文件: $target_file" >&2
|
||||
((deleted_count++))
|
||||
|
||||
# 尝试清理空目录
|
||||
local target_dir=$(dirname "$target_file")
|
||||
target_dir=$(normalize_path "$target_dir")
|
||||
clean_empty_directories_rollback "$target_dir"
|
||||
else
|
||||
error_count=$((error_count+1))
|
||||
error "❌ 删除新增文件失败: $target_file" >&2
|
||||
fi
|
||||
else
|
||||
warn "⚠️ 新增文件不存在,无需删除: $target_file" >&2
|
||||
((skip_count++))
|
||||
fi
|
||||
fi
|
||||
done < "$changes_file"
|
||||
|
||||
return $deleted_count
|
||||
}
|
||||
|
||||
# 清理空目录(回滚版本)
|
||||
clean_empty_directories_rollback() {
|
||||
local dir="$1"
|
||||
|
||||
while [[ "$dir" != "/" ]] && [[ -d "$dir" ]]; do
|
||||
# 检查目录是否为空(只检查文件,不考虑隐藏文件)
|
||||
if [[ -z "$(ls -A "$dir" 2>/dev/null)" ]]; then
|
||||
if rmdir "$dir" 2>/dev/null; then
|
||||
debug "清理空目录: $dir"
|
||||
dir=$(dirname "$dir")
|
||||
else
|
||||
break # 目录删除失败,停止清理
|
||||
fi
|
||||
else
|
||||
break # 目录非空,停止清理
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
# 验证回滚结果
|
||||
verify_rollback() {
|
||||
local extract_dir="$1"
|
||||
@@ -562,16 +676,20 @@ verify_rollback() {
|
||||
local verification_passed=true
|
||||
local verified_count=0
|
||||
local failed_count=0
|
||||
|
||||
# 查找所有备份文件并恢复, 备份文件存放于contents目录下
|
||||
local contents_dir="$extract_dir/contents"
|
||||
contents_dir=$(normalize_path "$contents_dir")
|
||||
|
||||
# 检查所有备份文件是否已正确恢复
|
||||
find "$extract_dir" -type f | while read backup_file; do
|
||||
local relative_path="${backup_file#$extract_dir/}"
|
||||
find "$contents_dir" -type f | while read backup_file; do
|
||||
local relative_path="${backup_file#$contents_dir/}"
|
||||
local target_file="$relative_path"
|
||||
|
||||
if [[ ! -f "$target_file" ]]; then
|
||||
error "❌ 目标文件不存在: $target_file"
|
||||
verification_passed=false
|
||||
fail_count=$((fail_count+1))
|
||||
failed_count=$((failed_count+1))
|
||||
continue
|
||||
fi
|
||||
|
||||
@@ -579,7 +697,7 @@ verify_rollback() {
|
||||
if ! cmp -s "$backup_file" "$target_file"; then
|
||||
error "❌ 文件内容不匹配: $relative_path"
|
||||
verification_passed=false
|
||||
fail_count=$((fail_count+1))
|
||||
failed_count=$((failed_count+1))
|
||||
continue
|
||||
fi
|
||||
|
||||
@@ -797,7 +915,7 @@ rollback_patch() {
|
||||
fi
|
||||
|
||||
# 执行回滚操作
|
||||
if ! perform_rollback "$extract_dir" "$dry_run"; then
|
||||
if ! perform_rollback "$extract_dir" "$dry_run" "$rollback_info_file"; then
|
||||
send_rollback_notification "failure" "$rollback_info_json" "回滚操作失败"
|
||||
return 1
|
||||
fi
|
||||
|
||||
Reference in New Issue
Block a user