使用Ansible在Windows虚拟机执行git clone时出现内存不足错误
问题根源
手动执行Git克隆正常,但Ansible执行失败,核心原因是Ansible的win_command会实时捕获命令的stdout/stderr输出,当Git LFS处理大体积对象输出大量内容时,Ansible的管道缓冲区被填满,Windows系统会强制关闭管道,进而引发Git的"内存不足"、"Smudge error"等连锁报错——并非真的虚拟机内存不够,而是管道中断导致的异常。
解决方案
1. 重定向输出,绕过Ansible管道捕获
用win_shell替代win_command,并将Git的输出重定向到本地文件,不让Ansible处理实时输出:
- name: Clone repository with output redirected ansible.windows.win_shell: | <path/to/git.exe> clone <git-repo> > C:\git_clone_log.txt 2>&1 args: creates: <path/to/target/repo> # 目标目录存在则跳过,避免重复克隆
这样Git的输出直接写入本地日志文件,不会触发Ansible的管道缓冲区溢出问题。
2. 拆分克隆与LFS拉取步骤
先克隆仓库但不拉取LFS对象,再单独拉取LFS,分阶段降低内存压力:
- name: Clone repository without LFS objects ansible.windows.win_shell: | <path/to/git.exe> clone --no-lfs <git-repo> > C:\git_clone_nolfs_log.txt 2>&1 args: creates: <path/to/target/repo> - name: Pull LFS objects separately ansible.windows.win_shell: | cd <path/to/target/repo> && <path/to/git.exe> lfs pull > C:\git_lfs_pull_log.txt 2>&1
--no-lfs参数让Git只克隆仓库元数据,跳过LFS对象的拉取,后续单独执行git lfs pull分批次处理大文件,进一步降低单次操作的内存占用。
3. 调整Git LFS的内存优化配置
在克隆前添加Git LFS的优化配置,减少单次处理的对象数量:
- name: Configure Git LFS batch size ansible.windows.win_command: > <path/to/git.exe> config --global lfs.batch 100 - name: Enable Git LFS recent fetch optimization ansible.windows.win_command: > <path/to/git.exe> config --global lfs.fetchrecentalways true
lfs.batch设置每次拉取的LFS对象数量为100(可根据实际情况调整),避免一次性加载过多对象导致内存压力;lfs.fetchrecentalways确保只拉取必要的近期对象(适用于不需要完整历史的场景)。
4. 调整Ansible WinRM超时设置(可选)
如果克隆过程因超时中断,修改ansible.cfg中的WinRM配置:
[winrm] ansible_winrm_read_timeout_sec = 300 ansible_winrm_operation_timeout_sec = 300 ansible_winrm_output_encoding = utf-8
延长超时时间至5分钟,确保大仓库拉取过程不会被WinRM中断,同时设置正确的编码避免输出处理异常。
验证方法
执行修改后的Ansible任务后,查看生成的git_clone_log.txt或git_lfs_pull_log.txt确认进度,进入目标仓库执行git lfs ls-files检查LFS对象是否拉取完整。
内容的提问来源于stack exchange,提问作者iAmoric

