Преглед изворни кода

chore: 从仓库移除 backups 目录

tukuaiai пре 1 месец
родитељ
комит
1a00ac4560
3 измењених фајлова са 0 додато и 401 уклоњено
  1. 0 53
      backups/README.md
  2. 0 83
      backups/一键备份.sh
  3. 0 265
      backups/快速备份.py

+ 0 - 53
backups/README.md

@@ -1,53 +0,0 @@
-# 快速备份工具
-
-基于 `.gitignore` 规则的项目备份工具,自动排除不需要的文件。
-
-## 功能特性
-
-- 自动读取 `.gitignore` 规则
-- 支持取反规则(`!` 语法)
-- 目录级剪枝优化
-- 生成 `.tar.gz` 压缩包
-- 零依赖(仅使用 Python 内置模块)
-
-## 文件结构
-
-```
-backups/
-├── 快速备份.py    # 核心备份引擎
-├── 一键备份.sh    # Shell 启动脚本
-└── README.md      # 本文档
-```
-
-## 使用方法
-
-```bash
-# 方式一:Shell 脚本(推荐)
-bash backups/一键备份.sh
-
-# 方式二:直接运行 Python
-python3 backups/快速备份.py
-
-# 指定输出文件
-python3 backups/快速备份.py -o my_backup.tar.gz
-
-# 指定项目目录
-python3 backups/快速备份.py -p /path/to/project
-```
-
-## 输出位置
-
-默认输出到 `backups/gz/备份_YYYYMMDD_HHMMSS.tar.gz`
-
-## 参数说明
-
-| 参数 | 说明 | 默认值 |
-|------|------|--------|
-| `-p, --project` | 项目根目录 | 当前目录 |
-| `-o, --output` | 输出文件路径 | `backups/gz/备份_时间戳.tar.gz` |
-| `-g, --gitignore` | gitignore 文件路径 | `.gitignore` |
-
-## 依赖
-
-- Python 3.x(无需额外包)
-- Bash(用于 Shell 脚本)

+ 0 - 83
backups/一键备份.sh

@@ -1,83 +0,0 @@
-#!/bin/bash
-
-# 一键备份项目脚本
-# 自动读取 .gitignore 规则并排除匹配的文件
-# bash backups/一键备份.sh
-
-set -e
-
-# 颜色输出
-GREEN='\033[0;32m'
-BLUE='\033[0;34m'
-YELLOW='\033[1;33m'
-NC='\033[0m' # No Color
-
-# 脚本所在目录
-SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
-
-# 项目根目录(脚本所在目录的父目录)
-PROJECT_ROOT="$(cd "${SCRIPT_DIR}/.." && pwd)"
-
-# 项目backups目录
-BACKUPS_DIR="${PROJECT_ROOT}/backups"
-
-# 备份脚本路径(始终在项目的backups目录中)
-BACKUP_SCRIPT="${BACKUPS_DIR}/快速备份.py"
-
-# 检查备份脚本是否存在
-if [ ! -f "${BACKUP_SCRIPT}" ]; then
-    echo -e "${YELLOW}⚠️  错误: 备份脚本不存在${NC}"
-    echo ""
-    echo "备份工具应位于项目的 backups/ 目录中:"
-    echo "  ${BACKUPS_DIR}/"
-    echo ""
-    echo "请确保:"
-    echo "  1. 复制快速备份.py到 ${BACKUPS_DIR}/"
-    echo "  2. 复制一键备份.sh到 ${BACKUPS_DIR}/"
-    echo ""
-    echo "或者使用方式:"
-    echo "  • 在项目根目录执行: bash backups/一键备份.sh"
-    echo "  • 或直接执行: python3 backups/快速备份.py"
-    exit 1
-fi
-
-echo -e "${BLUE}========================================${NC}"
-echo -e "${BLUE}     项目快速备份工具${NC}"
-echo -e "${BLUE}========================================${NC}"
-echo ""
-echo -e "${GREEN}✓${NC} 找到备份脚本: backups/快速备份.py"
-
-# 检查 Python3 是否可用
-if ! command -v python3 &> /dev/null; then
-    echo -e "${YELLOW}⚠️  错误: 未找到 python3 命令${NC}"
-    exit 1
-fi
-
-echo -e "${GREEN}✓${NC} 项目目录: ${PROJECT_ROOT}"
-echo -e "${GREEN}✓${NC} 备份脚本: ${BACKUP_SCRIPT}"
-echo -e "${GREEN}✓${NC} Python 版本: $(python3 --version)"
-echo ""
-
-# 执行备份
-echo -e "${YELLOW}▶ 正在执行备份...${NC}"
-echo ""
-
-# 切换到项目根目录
-cd "${PROJECT_ROOT}"
-
-# 运行备份脚本
-python3 "${BACKUP_SCRIPT}"
-
-# 检查执行结果
-if [ $? -eq 0 ]; then
-    echo ""
-    echo -e "${GREEN}========================================${NC}"
-    echo -e "${GREEN}     ✓ 备份完成!${NC}"
-    echo -e "${GREEN}========================================${NC}"
-else
-    echo ""
-    echo -e "${YELLOW}========================================${NC}"
-    echo -e "${YELLOW}     ✗ 备份失败${NC}"
-    echo -e "${YELLOW}========================================${NC}"
-    exit 1
-fi

+ 0 - 265
backups/快速备份.py

@@ -1,265 +0,0 @@
-#!/usr/bin/env python3
-"""
-快速备份项目工具
-读取 .gitignore 规则并打包项目文件(排除匹配的文件)
-
-bash backups/一键备份.sh
-
-文件位置:
-  backups/快速备份.py
-
-工具清单(backups/目录):
-  • 快速备份.py         - 核心备份引擎(7.3 KB)
-  • 一键备份.sh         - 一键执行脚本(2.4 KB)
-
-使用方法:
-  $ bash backups/一键备份.sh
-  或
-  $ python3 backups/快速备份.py
-
-备份输出:
-  backups/gz/备份_YYYYMMDD_HHMMSS.tar.gz
-
-适用项目:
-  任何包含 .gitignore 文件的项目(自动读取规则并排除匹配文件)
-
-依赖:
-  无需额外安装包,仅使用Python内置模块
-"""
-
-import os
-import tarfile
-import fnmatch
-from pathlib import Path
-from datetime import datetime
-import argparse
-import sys
-
-
-class GitignoreFilter:
-    """解析 .gitignore 文件并过滤文件"""
-
-    def __init__(self, gitignore_path: Path, project_root: Path):
-        self.project_root = project_root
-        # 规则按照出现顺序存储,支持取反(!)语义,后匹配覆盖前匹配
-        # 每项: {"pattern": str, "dir_only": bool, "negate": bool, "has_slash": bool}
-        self.rules = []
-        self.load_gitignore(gitignore_path)
-
-    def load_gitignore(self, gitignore_path: Path):
-        """加载并解析 .gitignore 文件"""
-        if not gitignore_path.exists():
-            print(f"⚠️  警告: {gitignore_path} 不存在,将不应用任何过滤规则")
-            return
-
-        try:
-            with open(gitignore_path, 'r', encoding='utf-8') as f:
-                for line in f:
-                    line = line.strip()
-
-                    # 跳过空行和注释
-                    if not line or line.startswith('#'):
-                        continue
-
-                    negate = line.startswith('!')
-                    if negate:
-                        line = line[1:].lstrip()
-                        if not line:
-                            continue
-
-                    dir_only = line.endswith('/')
-                    has_slash = '/' in line.rstrip('/')
-
-                    self.rules.append({
-                        "pattern": line,
-                        "dir_only": dir_only,
-                        "negate": negate,
-                        "has_slash": has_slash,
-                    })
-
-            print(f"✓ 已加载 {len(self.rules)} 条规则(含取反)")
-
-        except Exception as e:
-            print(f"❌ 读取 .gitignore 失败: {e}")
-            sys.exit(1)
-
-    def _match_rule(self, rule: dict, relative_path_str: str, is_dir: bool) -> bool:
-        """按规则匹配路径,返回是否命中"""
-        pattern = rule["pattern"]
-        dir_only = rule["dir_only"]
-        has_slash = rule["has_slash"]
-
-        # 目录规则:匹配目录自身或其子路径
-        if dir_only:
-            normalized = pattern.rstrip('/')
-            if relative_path_str == normalized or relative_path_str.startswith(normalized + '/'):
-                return True
-            return False
-
-        # 带路径分隔的规则:按相对路径匹配
-        if has_slash:
-            return fnmatch.fnmatch(relative_path_str, pattern)
-
-        # 无斜杠:匹配任意层级的基本名
-        if fnmatch.fnmatch(Path(relative_path_str).name, pattern):
-            return True
-        # 额外处理目录命中:无通配符时,若任一父级目录名等于 pattern 也视为命中
-        if pattern.isalpha() and pattern in relative_path_str.split('/'):
-            return True
-        return False
-
-    def should_exclude(self, path: Path, is_dir: bool = False) -> bool:
-        """
-        判断路径是否应该被排除(支持 ! 取反,后匹配覆盖前匹配)
-        返回 True 表示应该排除(不备份)
-        """
-        try:
-            # 统一使用 POSIX 路径风格进行匹配
-            relative_path_str = path.relative_to(self.project_root).as_posix()
-        except ValueError:
-            return False  # 不在项目根目录内,不处理
-
-        # Git 风格:从上到下最后一次匹配决定去留
-        matched = None
-        for rule in self.rules:
-            if self._match_rule(rule, relative_path_str, is_dir):
-                matched = not rule["negate"]  # negate 表示显式允许
-
-        return bool(matched)
-
-
-def create_backup(project_root: Path, output_file: Path, filter_obj: GitignoreFilter):
-    """创建备份压缩包"""
-
-    # 统计信息
-    total_files = 0
-    excluded_files = 0
-    included_files = 0
-
-    print(f"\n{'='*60}")
-    print(f"开始备份项目: {project_root}")
-    print(f"输出文件: {output_file}")
-    print(f"{'='*60}\n")
-
-    try:
-        with tarfile.open(output_file, 'w:gz') as tar:
-            # 使用 os.walk 可在目录层级提前剪枝,避免进入已忽略目录
-            for root, dirs, files in os.walk(project_root, topdown=True):
-                root_path = Path(root)
-
-                # 目录剪枝:命中忽略规则或 .git 时不再深入
-                pruned_dirs = []
-                for d in dirs:
-                    dir_path = root_path / d
-                    if d == '.git' or filter_obj.should_exclude(dir_path, is_dir=True):
-                        print(f"  排除目录: {dir_path.relative_to(project_root)}")
-                        excluded_files += 1
-                        continue
-                    pruned_dirs.append(d)
-                dirs[:] = pruned_dirs
-
-                for name in files:
-                    path = root_path / name
-                    total_files += 1
-
-                    # 文件忽略判定
-                    if '.git' in path.parts or filter_obj.should_exclude(path):
-                        excluded_files += 1
-                        print(f"  排除: {path.relative_to(project_root)}")
-                        continue
-
-                    arcname = path.relative_to(project_root)
-                    tar.add(path, arcname=arcname)
-                    included_files += 1
-                    print(f"  备份: {arcname}")
-
-        print(f"\n{'='*60}")
-        print("备份完成!")
-        print(f"{'='*60}")
-        print(f"总文件数: {total_files}")
-        print(f"已备份: {included_files} 个文件")
-        print(f"已排除: {excluded_files} 个文件/目录")
-        print(f"压缩包大小: {output_file.stat().st_size / 1024 / 1024:.2f} MB")
-        print(f"{'='*60}")
-
-        return True
-
-    except Exception as e:
-        print(f"\n❌ 备份失败: {e}")
-        import traceback
-        traceback.print_exc()
-        return False
-
-
-def main():
-    parser = argparse.ArgumentParser(
-        description='快速备份项目(根据 .gitignore 排除文件)',
-        formatter_class=argparse.RawDescriptionHelpFormatter,
-        epilog="""
-使用示例:
-  # 基本用法(备份到 backups/gz/ 目录)
-  python backups/快速备份.py
-
-  # 指定输出文件
-  python backups/快速备份.py -o my_backup.tar.gz
-
-  # 指定项目根目录
-  python backups/快速备份.py -p /path/to/project
-        """
-    )
-
-    parser.add_argument(
-        '-p', '--project',
-        type=str,
-        default='.',
-        help='项目根目录路径(默认: 当前目录)'
-    )
-
-    parser.add_argument(
-        '-o', '--output',
-        type=str,
-        help='输出文件路径(默认: backups/备份_YYYYMMDD_HHMMSS.tar.gz)'
-    )
-
-    parser.add_argument(
-        '-g', '--gitignore',
-        type=str,
-        default='.gitignore',
-        help='.gitignore 文件路径(默认: .gitignore)'
-    )
-
-    args = parser.parse_args()
-
-    # 解析路径
-    project_root = Path(args.project).resolve()
-    gitignore_path = Path(args.gitignore).resolve()
-
-    if not project_root.exists():
-        print(f"❌ 错误: 项目目录不存在: {project_root}")
-        sys.exit(1)
-
-    # 确定输出文件路径
-    if args.output:
-        output_file = Path(args.output).resolve()
-    else:
-        # 默认输出到 backups/gz/ 目录
-        backup_dir = project_root / 'backups' / 'gz'
-        backup_dir.mkdir(parents=True, exist_ok=True)
-
-        timestamp = datetime.now().strftime('%Y%m%d_%H%M%S')
-        output_file = backup_dir / f'备份_{timestamp}.tar.gz'
-
-    # 确保输出目录存在
-    output_file.parent.mkdir(parents=True, exist_ok=True)
-
-    # 创建过滤器
-    filter_obj = GitignoreFilter(gitignore_path, project_root)
-
-    # 执行备份
-    success = create_backup(project_root, output_file, filter_obj)
-
-    sys.exit(0 if success else 1)
-
-
-if __name__ == '__main__':
-    main()