故障处理
Codex 无法 git commit:.git/index.lock 权限被拒怎么排查
Codex 能改代码却无法 git add 或 git commit?区分 index.lock 权限拒绝、锁占用与 dubious ownership,定位真实 Git 目录、检查生效权限,并审查暂存和提交结果。
Codex 已经改好代码,git status 也能显示改动,但一到 git add 或 git commit 就失败。先保留完整错误、失败命令和报错路径:能写源文件,并不代表能写 Git 的索引、对象或引用。
如果你搜索的是 codex git index.lock permission denied 或 Operation not permitted,先用下表分流。锁文件不存在也可能报“无法创建锁”,不能一看到 index.lock 就删文件。
先分清是哪种失败
| 错误或现象 | 先判断什么 | 下一步 |
|---|---|---|
Permission denied 或 Operation not permitted |
创建或替换 Git 文件的权限被拒 | 查真实目录、系统权限与 Codex 生效策略 |
File exists |
目标锁已存在,可能有任务在使用 | 查正在运行的 Git 操作,再判断是否为遗留锁 |
detected dubious ownership |
Git 不信任当前身份访问该仓库 | 核实仓库归属与信任,不当成锁权限修复 |
Author identity unknown、签名或 hook 失败 |
已进入其他提交阶段 | 按身份、签名或 hook 的具体错误处理 |
nothing to commit |
当前目录或暂存内容不符合预期 | 查分支、worktree 与暂存区,不调整权限 |
只想找回另一目录中的改动时,先看 worktree 改动找不到。本文处理的是已经发生的 Git 写入失败。
1. 在失败的环境里定位真正的 Git 目录
适用情况: 已拿到错误,但还不能确定被拒的是哪个目录。让 Codex 在原执行环境运行以下检查;自己核对时,也要进入同一台主机、同一容器或 WSL 环境的同一仓库。
git --version
git rev-parse --show-toplevel
git rev-parse --path-format=absolute --git-dir
git rev-parse --path-format=absolute --git-common-dir
git rev-parse --path-format=absolute --git-path index
git --no-optional-locks status --short
这些命令用于读取位置与状态,最后一条避免 status 顺带进行可选的索引刷新。--git-dir 是当前工作树的 Git 元数据位置;--git-common-dir 是共享 Git 目录;--git-path index 给出索引路径。通常索引路径加上 .lock 就是对应的索引锁,仍以本次错误中的完整路径为准。
预期结果: 顶层目录是你要提交的项目;元数据目录和索引位置明确。worktree 的 .git 可以是一个指向其他位置的文件,不能只检查项目内的 .git 外观。Git 官方路径参考也支持对这些路径输出绝对位置。
如果命令提示不在仓库,先纠正工作目录。若提示不支持参数,记录 Git 版本,分别运行不带 --path-format=absolute 的命令,并按当前目录解释相对路径;不要把相对路径误当成仓库根目录下的位置。如果已出现 dubious ownership,直接进入第 4 步,先解决信任判断。
2. 权限被拒:比较系统访问与 Codex 策略
适用情况: 报错是 Permission denied 或 Operation not permitted。记录 Codex 客户端、CLI 版本,以及命令实际在本地、远程、WSL 还是容器运行;CLI 版本可在对应终端用 codex --version 查看。
先查看第 1 步得到的真实 Git 目录及其父目录。以下路径是占位示例,替换为刚刚读到的路径;不要照抄到其他项目。
macOS / Linux 可先查看目录和已有索引的基本权限:
ls -ld "/实际/Git目录" "/实际/Git目录的父目录"
ls -l "/实际/索引路径"
macOS 需要进一步查看 ACL 和文件标记时,使用 ls -ldeO 检查同一目标;Linux 若有额外 ACL、只读挂载或容器卷限制,需要继续查对应系统配置。基本权限位看起来可写,不能排除这些限制。
Windows 原生环境可只读显示目录 DACL:
whoami
icacls "C:\实际\Git目录"
icacls "C:\实际\Git目录的父目录"
这里的 icacls 没有带修改参数。查看当前身份适用的允许、拒绝与继承项;owner 相同也不代表一定可写。WSL 内失败则先查 WSL 内的路径和挂载,不能只看 Windows 终端中的同名项目。
随后检查 Codex 会话本身。当前 CLI 可在会话中使用:
/status
/debug-config
/status 用于查看当前审批策略、可写根目录等状态;/debug-config 用于定位配置层和策略来源。命令不存在时,以该版本命令菜单与帮助为准,不套用其他客户端的界面。
官方审批与安全文档说明,默认 workspace-write 模式仍把 .git 及指针解析后的 Git 目录保护为只读。因此,“仓库在可写根目录内”不足以证明可以提交。审批是否允许某次操作,与文件系统边界也需要分别看。
如果使用新版权限 profile,查当前选中的 profile 及覆盖规则。权限文档目前将该机制标为 Beta;继承 :workspace 会保留 .git 等路径的只读保护。它与旧的 sandbox_mode、sandbox_workspace_write 不是叠加配置;加载了旧 sandbox_mode 或传了 --sandbox 等情况下,可能仍在使用旧机制。不要把两套配置拼在一起,也不必为一次提交强行迁移。
如何据此操作:
- 如果系统本身就拒绝访问,由仓库维护者修复已确认的目标目录权限或挂载问题,再复查同一个路径。不要递归改整个磁盘的 owner,也不要使用
chmod 777。 - 如果证据指向 Codex 的 Git 目录保护,且这次暂存或提交已经获得授权,使用当前客户端和组织策略允许的单次审批或最小必要授权,核对完整命令与目标后再执行。
- 如果管理策略禁止该操作,保留策略诊断,交管理员确认;若团队允许人工提交,可由你在正常授权的终端审查并完成第 5 步。不要用管理员身份重开所有程序或全局关闭沙箱来试错。
验证目标: 同一环境、同一仓库中的目标操作获准,且原拒绝不再出现。若外部终端成功而 Codex 仍失败,继续核对两者的身份、路径和策略差异;这条对比证据本身不能单独证明是哪项设置导致。
3. File exists:先确认谁在使用锁
适用情况: 完整错误明确写着锁已存在。Git 锁文件机制会在更新文件时创建锁,并在完成后替换目标文件;另一个写入者遇到已有锁会失败。
先检查当前终端、IDE 源码管理、其他 Codex 任务是否正在暂存、提交、合并、变基或等待提交消息编辑器。使用系统任务管理工具核对相关进程、启动时间与项目路径;让已知操作正常完成,再重试原来的单个操作。不要批量结束所有 Git 或 Codex 进程。
如果没有活动操作,但锁仍存在,记录实际锁路径、修改时间,以及此前是否有中断的 Git 操作。仅凭锁很旧,或者一次进程查询没找到结果,还不能证明它可删除。
只有仓库维护者确认相关写入者已退出、暂停该仓库的自动 Git 操作,并备份未提交工作与当前索引后,才处理这一个确认遗留的锁;可先移到有记录的备份位置。不要删索引文件本身,不要扫描并清空所有 .lock。处理后重试一次;锁立即重现时回到进程排查,若变成权限错误则回到第 2 步。
预期结果: 活动 Git 操作正常结束,或确认遗留锁被有范围地处理;原操作可以继续,原有暂存内容没有丢失。
4. dubious ownership:核实信任,别扩大到所有仓库
适用情况: Git 明确提示仓库归属可疑。先确认路径是否为你预期的仓库,是否由不同账号、管理员、容器或共享盘创建。若是打开错了副本,回到正确目录即可。
对确实需要使用的共享仓库,由维护者确认预期身份与归属。如果团队确认该仓库可信并允许添加例外,可按 Git 提示只为这个已核实的绝对路径设置 safe.directory,然后重新运行状态检查。Git 官方配置说明解释了它允许的是仓库信任例外。
不要将 safe.directory 设为 *,也不要把信任例外当作写权限授予。信任错误消失后若出现 index.lock: Permission denied,说明还需继续第 2 步。
5. 只暂存审查过的文件,再核对提交
适用情况: 原因已处理,且你确实要提交这些改动。先在正确仓库检查当前状态、已有暂存和未暂存差异:
git --no-optional-locks status --short
git diff --cached --stat
git diff --cached
git diff
git diff 不包含未跟踪文件正文;状态中的 ?? 文件需要另外打开审查。若暂存区已有他人的改动,先协调范围,不执行一次包含所有内容的提交。参见 Git 的 状态与 差异参考。
确认暂存区只会包含本次目标后,把下面占位路径与消息换为实际值,逐条执行:
git add -- "本次要提交的文件"
git diff --cached --name-status
git diff --cached
git commit -m "说明本次改动"
git show --stat --oneline HEAD
git --no-optional-locks status --short
看到暂存差异与预期不符就停在提交之前。提交后,确认新提交包含目标文件;需要核对正文时再运行 git show HEAD。其他原有未提交改动应仍在预期状态;仓库不必完全干净。Git commit 文档说明了默认提交暂存内容的行为。
如果新的错误是身份、签名或 hook 失败,就沿新错误处理,不再反复调整锁权限。暂存成功只证明这一步可以写索引,不能代替提交成功的验证。
仍然失败时,带哪些信息求助
提供脱敏后的失败命令、完整错误、Git 与 Codex 版本、执行环境、仓库顶层/Git 目录/索引位置,以及当前策略来源。说明失败发生在 add 还是 commit,是否有其他活动 Git 操作;不要上传整个配置、环境变量、私有差异或凭据。
配置明明改了却未生效,可继续查 config.toml 排障;脚本退出状态不明确时,查 codex exec 输出与异常退出。如果连 CLI 版本都与预期不同,先核对 更新后版本没变。
本文于 2026-10-17 核对官方资料,并在 macOS 独立测试仓库验证 worktree 路径、已有锁与目录不可写两类错误,以及审查后的提交结果。该验证没有调用模型,也没有模拟所有平台的 Codex 沙箱或管理策略;Windows 检查以官方命令资料为依据。