# lfs-script **Repository Path**: Zherphy/lfs-script ## Basic Information - **Project Name**: lfs-script - **Description**: No description available - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2025-12-29 - **Last Updated**: 2025-12-30 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # LFS迁移脚本 ## 概述 这是一个用于迁移Git LFS文件的Bash脚本。脚本的主要功能是从atomgit平台克隆指定仓库,检查每个分支是否管理了LFS文件,如果管理了LFS文件,再检查是否通过`.lfsconfig`文件使用自定义LFS数据源进行LFS文件管理。如果没有使用`.lfsconfig`文件进行LFS文件管理,需要在该分支生成`.lfsconfig`文件,然后使用`git lfs migrate import`命令对LFS文件进行迁移(包括历史中的LFS文件),最后使用`git push --force --all`将修改推送到远程仓库。 ## 功能特性 1. **自动克隆**:从atomgit平台自动克隆指定仓库 2. **认证支持**:支持用户名和token认证 3. **多分支支持**:自动检查仓库的所有分支 4. **LFS文件检测**:检查每个分支是否管理了LFS文件 5. **配置文件检查**:检查`.lfsconfig`文件是否存在且配置正确 6. **自动生成配置**:根据需要自动生成`.lfsconfig`文件 7. **LFS文件迁移**:使用`git lfs migrate import`迁移LFS文件(包括历史) 8. **强制推送**:使用`git push --force --all`推送重写的历史 9. **模式检测**:自动从`.gitattributes`文件检测LFS文件模式 10. **干运行模式**:预览将要执行的操作而不实际执行 11. **详细日志**:支持详细输出和日志文件 12. **API集成**:通过gitcode API自动禁用仓库LFS功能 13. **错误处理**:完善的错误处理和恢复机制 ## 安装要求 - Bash 4.0+ - Git - Git LFS (2.0.0+,支持`migrate import`命令) ## 使用方法 ### 基本用法 ```bash ./lfs_migration.sh -o owner -n repo_name ``` ### 参数说明 | 参数 | 简写 | 说明 | 默认值 | |------|------|------|--------| | `--owner` | `-o` | 仓库所有者(必需,用于从atomgit克隆仓库) | 无 | | `--name` | `-n` | 仓库名称(必需,用于从atomgit克隆仓库) | 无 | | `--url` | `-u` | atomgit仓库完整URL(可选,如果提供则覆盖owner/name) | 无 | | `--clone-dir` | `-c` | 克隆仓库的目标目录 | `./{repo_name}` | | `--dry-run` | `-d` | 只显示将要执行的操作,不实际执行 | false | | `--verbose` | `-v` | 显示详细输出 | false | | `--log-file` | `-l` | 指定日志文件路径 | 无 | | `--username` | | Git用户名(用于认证) | 无 | | `--token` | | Git token(用于认证) | 无 | | `--skip-push` | | 跳过推送步骤(只进行本地迁移) | false | | `--commit-message` | | 提交消息(用于LFS迁移后的提交) | "迁移LFS文件到新服务器" | | `--help` | `-h` | 显示帮助信息 | 无 | ### 示例 1. **基本迁移**: ```bash ./lfs_migration.sh -o myorg -n myrepo ``` 2. **带认证的迁移**: ```bash ./lfs_migration.sh -o myorg -n myrepo --username=myuser --token=mytoken ``` 3. **指定克隆目录**: ```bash ./lfs_migration.sh -o myorg -n myrepo -c /tmp/migration ``` 4. **使用完整URL**: ```bash ./lfs_migration.sh -u https://atomgit.com/myorg/myrepo.git ``` 5. **干运行模式(预览)**: ```bash ./lfs_migration.sh -o myorg -n myrepo -d ``` 6. **只迁移不推送**: ```bash ./lfs_migration.sh -o myorg -n myrepo --skip-push ``` 7. **详细输出并保存日志**: ```bash ./lfs_migration.sh -o myorg -n myrepo -v -l migration.log ``` 8. **自定义提交消息**: ```bash ./lfs_migration.sh -o myorg -n myrepo --commit-message="迁移LFS文件到新LFS服务器" ``` 9. **组合使用**: ```bash ./lfs_migration.sh -o myorg -n myrepo -d -v -l migration.log -c /tmp/migration --username=myuser --token=mytoken --commit-message="LFS迁移到新服务器" ``` ## 工作流程 脚本按照以下步骤执行: 1. **参数解析**:解析命令行参数并验证 2. **环境检查**:检查Git和Git LFS是否可用 3. **仓库克隆**:从atomgit平台克隆指定仓库(支持认证) 4. **认证配置**:配置git用户名和token(如果提供) 5. **分支遍历**:获取仓库的所有分支 6. **LFS检查**:对每个分支检查是否管理了LFS文件 7. **配置检查**:如果分支有LFS文件,检查`.lfsconfig`文件 8. **配置生成**:如果没有或配置不正确,生成`.lfsconfig`文件 9. **历史迁移**:使用`git lfs migrate import --everything`迁移历史中的LFS文件 10. **API调用**:通过gitcode API禁用仓库的LFS功能(需要--token参数) 11. **强制推送**:使用`git push --force --all`和`git push --force --tags`推送修改 12. **清理恢复**:切换回原始分支,完成迁移 ## LFS迁移详情 脚本使用`git lfs migrate import`命令进行迁移,该命令会: 1. **重写git历史**:将历史中的LFS文件转换为LFS指针 2. **包含所有分支和标签**:使用`--everything`参数迁移所有引用 3. **自动检测文件模式**:从`.gitattributes`文件提取LFS跟踪的文件模式 4. **保留提交信息**:保持原有的提交信息和作者信息 ### 迁移命令示例 ```bash git lfs migrate import --everything --include="*.psd,*.zip,*.exe" ``` ## 推送详情 迁移完成后,脚本会执行以下操作: 1. **API调用**:通过gitcode API禁用仓库的LFS功能(需要--token参数) 2. **强制推送所有分支**:`git push --force --all` 3. **强制推送所有标签**:`git push --force --tags` ### API调用详情 在推送之前,脚本会调用gitcode API禁用仓库的LFS功能: - API端点:`https://api.gitcode.com/api/v5/repos/:owner/:repo` - 方法:PATCH - 查询参数:`access_token`(使用--token参数提供的token) - 请求体:`{"lfs_enabled": false}` ### 为什么需要强制推送? 因为`git lfs migrate import`重写了git历史,产生了新的提交哈希。远程仓库的历史与本地不一致,必须使用`--force`参数覆盖远程历史。 ### 为什么需要禁用LFS功能? 在迁移LFS文件后,仓库中的大文件已经被转换为LFS指针,不再需要原平台的LFS服务。禁用LFS功能可以: 1. 避免后续操作使用错误的LFS端点 2. 确保仓库完全迁移到新的LFS服务器 3. 防止新旧LFS配置冲突 ## .lfsconfig文件格式 脚本生成的`.lfsconfig`文件格式如下: ```ini [lfs] url = https://artlfs.openeuler.openatom.cn/{owner}/{repo} ``` 其中`{owner}`和`{repo}`会被替换为实际的仓库所有者和仓库名称。 ## 认证配置 脚本支持多种认证方式: ### 1. Git操作认证 #### HTTPS + Token认证 ```bash ./lfs_migration.sh -o myorg -n myrepo --username=myuser --token=mytoken ``` 脚本会自动将token添加到HTTPS URL中:`https://username:token@atomgit.com/owner/repo.git` #### SSH密钥认证 如果不提供用户名和token,脚本会使用系统配置的SSH密钥。 ### 2. API调用认证 API调用需要单独的token认证,使用`--token`参数提供的token: - API端点使用查询参数`access_token`进行认证 - 同一个token可以用于Git操作和API调用 - 如果未提供token,API调用会跳过并显示警告 ### 3. 认证流程 1. **Git克隆**:使用HTTPS+token或SSH密钥 2. **Git推送**:使用配置的远程URL(可能包含token) 3. **API调用**:使用`--token`参数提供的access_token ## 错误处理 脚本包含完善的错误处理机制: 1. **参数错误**:显示帮助信息并退出 2. **环境错误**:检查Git和Git LFS是否安装 3. **克隆错误**:处理仓库克隆失败的情况 4. **认证错误**:处理认证失败的情况 5. **分支错误**:处理分支切换失败的情况 6. **LFS错误**:处理LFS操作失败的情况 7. **推送错误**:处理推送失败的情况 8. **自动恢复**:出错时尝试切换回原始分支 ## 注意事项 ### 重要警告 1. **历史重写**:`git lfs migrate import`会重写git历史,这意味着: - 所有分支和标签都会被修改 - 其他开发者需要重新克隆仓库 - 必须使用`--force`参数推送到远程仓库 2. **备份**:在执行实际迁移前,**强烈建议**: - 使用`--dry-run`模式预览操作 - 备份原始仓库 - 在测试仓库上先进行试验 3. **协作仓库**:如果仓库有多人协作,需要: - 通知所有协作者 - 协调迁移时间 - 提供迁移后的新仓库地址 - 所有协作者需要重新克隆仓库 4. **认证安全**: - Token会显示在命令行历史中,请谨慎使用 - 建议使用具有最小权限的token - 迁移完成后及时撤销或更新token ### 其他注意事项 5. **权限**:确保对目标目录有读写权限 6. **网络**:需要网络连接访问atomgit平台和LFS服务器 7. **存储空间**:确保有足够的磁盘空间存储克隆的仓库和LFS文件 8. **时间**:大型仓库的克隆和迁移可能需要较长时间 9. **Git LFS版本**:确保Git LFS版本支持`migrate import`命令 ## 支持的atomgit URL格式 脚本支持以下atomgit URL格式: 1. **HTTPS格式**:`https://atomgit.com/owner/repo.git` 2. **HTTPS格式**:`https://atomgit.com/owner/repo.git` 3. **SSH格式**:`git@atomgit.com:owner/repo.git` ## 常见问题 ### Q: 迁移会修改我的git历史吗? A: **是的**。`git lfs migrate import`会重写git历史,将历史中的大文件转换为LFS指针。这是LFS迁移的标准做法。 ### Q: 为什么需要强制推送? A: 因为历史被重写,新的提交哈希与远程仓库不一致。必须使用`--force`参数覆盖远程历史。 ### Q: 如何知道哪些文件模式会被迁移? A: 脚本会从`.gitattributes`文件中提取LFS跟踪的文件模式。如果没有找到,会使用一组默认的常见二进制文件模式。 ### Q: 迁移后其他开发者怎么办? A: 其他开发者需要: 1. 备份本地修改 2. 删除本地仓库并重新克隆 3. 重新应用本地修改 ### Q: 可以只迁移当前分支吗? A: 脚本使用`--everything`参数迁移所有分支和标签。如果需要只迁移特定分支,可以使用`--skip-push`然后手动推送。 ### Q: 迁移失败怎么办? A: 脚本有错误处理机制,会尝试恢复原始状态。如果迁移失败,可以: 1. 检查错误日志 2. 从备份恢复仓库 3. 调整参数后重试 ### Q: Token安全吗? A: Token会出现在命令行历史中。建议: 1. 使用环境变量代替命令行参数 2. 使用具有最小权限的token 3. 迁移完成后立即撤销token ### Q: 支持私有仓库吗? A: 支持,可以通过`--username`和`--token`参数提供认证信息。 ### Q: 可以迁移到其他LFS服务器吗? A: 目前脚本固定使用`https://artlfs.openeuler.openatom.cn/`作为LFS服务器,如有需要可以修改脚本中的URL。 ## 许可证 本脚本为开源软件,遵循MIT许可证。 ## 支持 如有问题或建议,请提交Issue或联系维护者。