
1. 为什么 Windows 上装个 repo 这么折腾如果你在 Windows 上拉过 AOSP 或者某些大型多仓库项目大概率被repo这个工具卡过一次。repo本质上是 Google 为管理大量 Git 仓库而写的一个 Python 脚本集合它本身不是 Git 的一部分也不是一个独立的二进制程序而是一层“仓库清单管理器”——用一个 manifest 文件描述几十上百个 Git 仓库的地址、分支、路径然后批量执行同步、切换分支、批量提交等操作。问题在于这套工具从设计之初就是跑在 Linux 和 macOS 上的官方文档里 Windows 基本属于“不保证能用”的状态。那为什么还有人在 Windows 上折腾它原因很现实很多做嵌入式、车载系统、智能硬件、跨平台应用开发的团队主力开发机就是 Windows但项目代码库又是用 repo 组织的。你不可能为了同步一份代码就专门开一台 Linux 机器所以把 repo 在 Windows 上跑起来成了一个绕不开的刚需。这篇文章要解决的就是这件事在 Windows 环境下把 repo 工具装好、配好、跑通并且能稳定地日常使用。适合谁看如果你是完全没接触过 repo 的新手文章会从 Python 环境、Git 配置一路讲到第一个repo init成功执行你能照着抄如果你已经试过但卡在某个报错上第 4 节的排查表大概率能对上你的症状。我踩过的坑包括 Python 版本不匹配、repo脚本没有执行权限、符号链接在 Windows 上失效、Git 的换行符配置把整个工作区搞乱等等这些都会在下面展开。需要先说明一个前提Windows 上跑 repo主流有两条路——一是直接在 Windows 原生环境里用 Python 跑 repo 脚本配合 Git for Windows二是借助 WSL 在 Linux 子系统里跑。两条路各有取舍第 2 节会详细对比。本文以原生方案为主线因为它的目录结构对 Windows 用户最友好IDE 和资源管理器都能直接访问WSL 方案作为备选在 2.3 节说明。2. 方案选型原生跑还是进子系统2.1 先搞清楚 repo 到底依赖什么在动手之前得先明白 repo 的运行链条不然装到一半报错你都不知道是哪一环断了。repo 的启动入口是一个叫repo的引导脚本launcher这个脚本本身是一段 Python 代码它做几件事检查 Python 版本、从远端拉取真正的 repo 工具本体存放在~/.repo/repo/目录下、然后把后续命令转交给本体执行。本体是一堆 Python 模块负责解析 manifest、调度 Git 命令。所以整条依赖链是一个可用的 Python 解释器 → 引导脚本能被执行 → Git 命令可用 → 网络能访问 manifest 仓库。四个环节缺一不可。Windows 上出问题九成集中在前两个环节Python 版本太老或者太新、引导脚本被当成普通文本没法执行。理解了这一点后面的选型和排错就有了主线。2.2 原生方案与子系统方案的取舍我把两条路的实际体验整理成了一张表你可以对照自己的情况选对比维度Windows 原生方案WSL 子系统方案目录访问资源管理器、IDE 直接打开路径是D:\code\xxx需通过\\wsl$\访问部分 IDE 索引变慢文件性能本地磁盘满速跨文件系统访问Windows 侧读写 Linux 文件明显变慢符号链接需要开发者模式或管理员权限原生支持无额外配置换行符问题需要显式配置core.autocrlf基本无感脚本执行权限需要手动处理执行方式天然可执行工具链兼容与 Windows 版编译工具链一致部分交叉编译工具需另装上手成本中等坑集中在配置较低但环境隔离带来新问题选原生方案的理由很直接代码目录就在 Windows 磁盘上Visual Studio、各类 IDE、文件搜索工具都能无缝使用编译产物也直接落在本地。代价是要手动处理执行权限和换行符。选 WSL 的理由是省心repo 在 Linux 环境下就是“本来该有的样子”但如果你要在 Windows 侧用 IDE 打开同一份代码跨文件系统的读写性能会让你抓狂尤其是仓库数量上百的时候IDE 索引能卡到怀疑人生。我的建议是如果你的日常开发、编译、调试都在 Windows 侧完成走原生方案如果你只是用 Windows 做代码浏览和编辑实际编译在 Linux 环境走 WSL。下面主线讲原生WSL 的关键差异在 2.3 单独说。2.3 WSL 方案的关键差异点WSL 方案本身不复杂装好子系统后基本就是 Linux 那套流程装 Python、装 Git、下载引导脚本、加执行权限、跑repo init。真正需要注意的是文件存放位置——代码一定要放在 Linux 文件系统内比如/home/xxx/code不要放在/mnt/d/这类挂载的 Windows 盘上。原因在于跨文件系统的元数据操作开销极大repo 同步时要对上万个文件做状态检查放在挂载盘上同步时间可能翻好几倍。如果你确实需要 Windows 侧访问用\\wsl$\路径去读但别在里面做 Git 操作。另一个差异是 Git 的身份配置。WSL 里的 Git 和 Windows 侧的 Git 是两套独立配置用户名、邮箱、换行符设置都要在子系统里重新配一遍别以为在 Windows 上配过就万事大吉。这个坑我在第一次用 WSL 时踩过提交记录里作者信息是空的回头改起来很麻烦。3. 原生方案实操从零到第一个 repo init3.1 Python 环境版本选对少走一半弯路repo 对 Python 版本是有要求的。早期版本只支持 Python 2现在的版本已经全面转向 Python 3但并不是“随便一个 Python 3 都行”。实测下来Python 3.6 到 3.9 是最稳的区间3.10 及以上在部分旧版 repo 上会遇到语法或依赖问题3.5 及以下则直接不支持。这个区间的选择逻辑是repo 本体里用到了一些较新的语法特性太老的解释器跑不动而太新的解释器又可能因为标准库变动导致兼容性问题。安装时有两个细节必须注意。第一安装向导里一定要勾选“Add Python to PATH”否则后面在命令行里敲python会提示找不到命令还得手动配环境变量。第二如果你机器上已经装了多个 Python 版本比如 Anaconda 自带一个、系统又装了一个要确认命令行里python --version输出的是你想要的那个。多版本共存时PATH 的顺序决定了默认调用哪个必要时用where python看清楚实际指向。装完后验证一下python --version pip --version两条命令都能正常输出版本号Python 这一环就算过了。如果pip报错多半是安装时没勾选 pip 组件重新跑一遍安装程序选“Modify”补上即可。注意不要用 Microsoft Store 里那个 Python 版本。它的安装路径被重定向到系统保留目录权限和路径行为都和标准安装包不一样repo 引导脚本在这种环境下容易出现路径解析异常。老老实实用官方安装包。3.2 Git 配置换行符是最大的雷Git for Windows 的安装本身没什么难度一路下一步即可但装完之后的配置决定了你后面会不会被“整个工作区所有文件都显示被修改”这种诡异现象折磨。核心就是core.autocrlf这个参数。Windows 用 CRLF 作为换行符Linux 用 LF。Git 默认行为可能在你 checkout 时把 LF 转成 CRLF提交时再转回去。对于普通项目这没问题但 repo 管理的多仓库项目里很多仓库对换行符敏感比如 shell 脚本、配置文件一旦被转换脚本在 Linux 侧执行就会报“bad interpreter”之类的错误。我的做法是在 Windows 侧统一关闭自动转换git config --global core.autocrlf false git config --global core.filemode false第一条关闭换行符自动转换让文件保持仓库里的原始状态第二条关闭文件权限位跟踪因为 Windows 的文件系统权限模型和 Linux 不同不关掉的话 Git 会误报大量权限变更。这两条配置是 Windows 上跑 repo 的“保命设置”建议装完 Git 第一件事就配上。另外把身份信息也一并配好避免提交时作者信息为空git config --global user.name 你的名字 git config --global user.email 你的邮箱3.3 获取引导脚本并让它能跑起来repo 的引导脚本需要单独下载。官方提供的获取方式是通过 curl 拉取Windows 10 以后的系统自带 curl可以直接用curl -o repo https://storage.googleapis.com/git-repo-downloads/repo如果网络访问这个地址不稳定也可以从 Git 仓库里直接拿脚本文件效果一样。下载下来的是一个没有扩展名的文本文件内容是一段 Python 脚本。这里就是 Windows 原生方案最别扭的地方这个脚本没有.py后缀Windows 不知道用什么程序去执行它。在 Linux 上它靠 shebang文件第一行的#!/usr/bin/env python指定解释器Windows 不认这套。解决办法有几种我推荐最省事的一种——用 Python 显式调用它python repo init -u manifest仓库地址 -b 分支名也就是每次执行时前面带上python。这样不需要改文件关联也不需要处理执行权限最直接。缺点是每次命令都要多敲几个字符可以写个简单的批处理包装一下把python D:\tools\repo\repo %*存成repo.bat放到 PATH 里之后就能直接敲repo了。还有一种做法是把脚本重命名为repo.py然后通过文件关联让.py默认用 Python 打开。这个方案能用但要注意别把.py关联到了编辑器而不是解释器否则双击是打开文件而不是执行。我个人更倾向批处理包装行为可控出问题好排查。提示引导脚本建议放在一个固定目录比如D:\tools\repo\不要放在代码工作区里。它是工具不是项目文件混在一起容易在清理工作区时误删。3.4 目录规划与首次 init 的完整流程在跑repo init之前先把目录结构想清楚。repo 的工作模式是你选定一个工作目录作为“工作区根”repo init会在里面创建.repo隐藏目录存放 manifest 和工具本体然后repo sync把各个子仓库拉到工作区里。所以工作区根目录要选一个空目录或者专门新建的目录不要在一个已经有其他文件的目录里 init否则同步下来的仓库和已有文件混在一起后面很难理清。我的习惯是按项目分目录比如D:\code\项目名\每个项目一个独立根目录。路径里尽量避免中文和空格虽然现在工具链对中文路径的支持好了很多但 Python 脚本、Git 钩子、构建脚本里偶尔还是会有编码问题用纯英文路径能省掉一类莫名其妙的故障。完整流程走一遍mkdir D:\code\myproject cd D:\code\myproject python D:\tools\repo\repo init -u https://example.com/manifest.git -b main-u指定 manifest 仓库地址-b指定分支。执行后脚本会先自检 Python 版本然后拉取 repo 本体到.repo/repo/再拉取 manifest 仓库到.repo/manifests/。第一次执行会看到它下载一堆东西耐心等它跑完。成功的话最后会提示 manifest 已经同步到某个提交此时工作区里只有.repo目录还没有实际代码。接着执行同步python D:\tools\repo\repo sync -j4-j4表示 4 个并发任务这个参数要根据你的网络和磁盘情况调。并发太高会把带宽打满导致部分仓库超时重试并发太低又慢。一般 4 到 8 之间比较合适机械硬盘取小值固态硬盘可以取大值。同步过程中会看到每个仓库的下载进度全部完成后工作区里就出现了各个子仓库的目录。3.5 参数背后的逻辑为什么这么配把几个关键参数的选择理由说透方便你根据自己环境调整。-b main里的分支名不是随便填的它必须和 manifest 仓库里实际存在的分支对应。如果你不确定分支名可以先不加-b默认会用 manifest 仓库的默认分支init 成功后再用repo branches查看可用分支。填错分支的典型症状是 init 阶段报“找不到指定分支”这时候别怀疑网络先确认分支名拼写。-j并发数的选择有个经验公式并发数 ≈ 可用带宽Mbps÷ 单个仓库平均大小MB的粗略比值再结合磁盘 IO 能力取整。实际操作用不着精确计算从 4 开始试观察同步时是否有大量超时重试有就降到 2没有且速度慢就往上加。我见过有人直接上-j16结果路由器扛不住一半仓库超时反而比-j4还慢。还有一个常被忽略的参数是--depth它做浅克隆只拉最近若干次提交能显著减少下载量。但它有副作用后续做repo sync增量更新或者切分支时可能出问题因为历史不完整。只在纯粹为了看代码、不打算提交的场景下用浅克隆正常开发别加这个参数。4. 常见问题与排查技巧实录4.1 高频报错速查表下面这张表是我和周围同事在 Windows 上跑 repo 时实际遇到过的报错按症状归类附上原因和处置方式报错/症状根本原因处置方式python: command not foundPython 未加入 PATH重装勾选 Add to PATH或手动配环境变量SyntaxError指向 repo 脚本某行Python 版本过新或过旧换到 3.6~3.9 区间repo: 无法将repo项识别为...直接敲了repo但没包装脚本用python repo调用或建 bat 包装init 卡在下载 repo 本体网络访问存储地址不稳定换网络环境或手动放置本体sync 后所有文件显示被修改core.autocrlf未关闭设为 false 后重新 checkout脚本类文件执行报 bad interpreter换行符被转成 CRLF同上关闭自动转换Permission denied类错误文件权限位被 Git 跟踪设core.filemode false符号链接变成普通文本文件Windows 未开启符号链接支持开启开发者模式或以管理员运行sync 中途大量超时并发过高或网络抖动降-j值重试.repo目录占用异常大历史对象累积定期repo prune清理4.2 符号链接失效的深层原因与处理符号链接这个问题值得单独说因为它在 Windows 上表现得特别隐蔽。Linux 项目里经常用符号链接来共享文件比如把某个公共头文件链接到多个模块目录repo 同步时这些链接会被创建。Windows 原生对符号链接的支持需要权限普通用户默认没有创建符号链接的权利只有管理员或者开启了“开发者模式”的账户才有。症状是同步完成后本该是链接的文件变成了一个普通文本文件内容就是链接目标的路径字符串。编译时就会报找不到头文件或者内容错误。处理方式有两条一是在系统设置里开启开发者模式这样普通权限也能创建符号链接二是以管理员身份运行命令行再执行 sync。前者一劳永逸后者每次都要提权比较麻烦。开启开发者模式后还要确认 Git 的符号链接支持是打开的git config --global core.symlinks true这个配置默认在 Windows 上可能是 false导致 Git 不把符号链接当链接处理。设成 true 之后重新 checkout 相关文件链接才会正确创建。已经同步坏的仓库删掉对应目录重新 sync 一次即可。4.3 同步中断后的恢复策略大项目 sync 动辄几十分钟中途网络断了、电脑休眠了、手滑 CtrlC 了都是常事。repo 的好处是它支持断点续传式的恢复直接重新执行repo sync即可它会对每个仓库检查本地状态已经完整的跳过不完整的继续拉。不需要删掉整个工作区重来那样反而浪费时间。但有一种情况要注意如果中断发生在某个仓库的 checkout 阶段而不是下载阶段可能留下一个“半成品”工作区表现为该仓库git status显示大量变更。这时候进到那个仓库目录执行git checkout -- .丢弃本地改动再回工作区根目录重新 sync。如果连 checkout 都报错说明仓库元数据损坏把该仓库目录整个删掉再 syncrepo 会重新拉取它。还有一个实用技巧sync 之前先跑一次repo status看看有没有未提交的本地改动。有的话先处理掉提交或 stash否则 sync 过程中如果涉及这些文件可能产生冲突处理起来更麻烦。这个习惯能帮你避免很多“同步完代码变了”的困惑。4.4 性能调优的几个实测经验同步速度慢是 Windows 用户抱怨最多的问题除了并发数还有几个因素影响很大。磁盘类型的影响远超想象。同样的项目和网络机械硬盘上 sync 可能要一小时固态硬盘二十分钟搞定因为 repo 同步过程中有大量小文件的读写和状态检查随机 IO 性能是瓶颈。如果条件允许把工作区放在固态硬盘上。杀毒软件的实时扫描会拖慢一切。repo 同步时创建和修改海量文件杀毒软件逐个扫描开销巨大。把工作区目录加入杀毒软件的排除列表速度提升立竿见影。这个操作在团队里推广后普遍反馈同步时间缩短三成以上。Git 的索引刷新也可以调。对于超大仓库可以开启文件系统监控来加速状态检查git config --global core.fscache true git config --global core.preloadindex true第一条启用文件系统缓存第二条启用索引预加载都是 Git for Windows 特有的优化项对多仓库场景有帮助。实测下来repo status这类需要遍历所有仓库的命令响应速度有明显改善。5. 日常使用中的习惯与心得5.1 把常用命令包装成顺手的工具原生方案下每次敲python D:\tools\repo\repo xxx确实烦包装成 bat 是基本操作。更进一步可以把几个高频组合也包进去比如“同步并清理”这种一条命令搞定的事echo off python D:\tools\repo\repo sync -j4 --prune python D:\tools\repo\repo prune存成rs.bat放 PATH 里以后敲rs就完成同步加清理。--prune会删除远端已经不存在的分支对应的本地引用repo prune清理已经合并的旧分支两个配合能防止.repo目录无限膨胀。这种小工具看着不起眼日积月累省下的时间很可观。5.2 多项目并存时的环境隔离如果你同时维护几个用 repo 管理的项目每个项目的 manifest 可能指向不同版本的 repo 工具本体。repo 的设计是每个工作区的.repo/repo/下存一份本体互不干扰这点很好。但引导脚本如果全局只有一份升级时会影响所有项目。我的做法是每个项目目录下放一份引导脚本的副本项目之间完全隔离某个项目需要特定版本的 repo 时不会波及其他项目。代价是磁盘上多几份几十 KB 的脚本可以忽略不计。5.3 版本升级与回退的稳妥做法repo 本体是可以独立升级的在工作区里执行repo selfupdate即可。但这个操作要谨慎新版本可能引入行为变化导致现有工作区的 manifest 解析异常。稳妥的做法是升级前先记录当前版本repo --version会输出本体所在的提交出问题时有据可查。如果升级后确实出问题进到.repo/repo/目录用 Git 切回之前的提交就能回退到旧版本。这个目录本身就是一个 Git 仓库版本管理是现成的。我在实际使用中的体会是Windows 上跑 repo 的难点不在“装”而在“配”——Python 版本、换行符、符号链接这三项配置到位后面基本就是一马平川。真正会反复折磨人的往往是那些看起来无关紧要的默认设置。所以每次在新机器上搭环境我都会把第 3 节的配置清单从头到尾过一遍宁可多花十分钟也别在同步到一半时才发现换行符把整个工作区搞乱了。