DEBUG.WIKI
V.PS:让项目靠近用户,亚太、欧洲、北美 KVM VPS
IPPeak:从目标地区访问网页,住宅代理、SEO 监测、广告验证
ZgoCloud:多地区部署,按需选节点;日本、美国、香港、德国

在子目录执行 git clean 后,其他目录的文件没有清理

在 src 等子目录执行 git clean 后,其他目录的未跟踪文件可能仍阻止切换分支。确认工作区根目录,用 git -C 在正确位置预览指定路径,备份后处理冲突文件,并区分忽略文件和嵌套仓库。

切换分支时,Git 提示未跟踪文件会被覆盖:

error: The following untracked working tree files would be overwritten by checkout:
        generated/local.txt
Please move or remove them before you switch branches.
Aborting

接着在 src 目录运行 git clean -fd,没有看到目标文件被删除,再切分支仍然报同样的错误。如果报错文件位于 src 之外,就需要核对清理命令的执行目录。

git clean 从当前目录向下清理,并不会因为找到了仓库,就自动把整个工作区扫一遍。这里讨论的是普通工作区中未跟踪文件的清理范围;子模块、嵌套仓库和忽略文件还各有边界,不能只凭“文件还在”认定是这个原因。

当前目录会限制清理范围

下面是一个示例目录,假定 generated/local.txt 尚未被 Git 跟踪,也没有被忽略:

/path/to/repo/
├── .git/
├── src/                  ← 终端当前目录
└── generated/
    └── local.txt         ← 切换分支时发生路径冲突

在 src 里执行没有指定路径的 git clean -fd,不会去清理旁边的 generated。-f 表示允许删除,-d 允许在未指定路径时递归进入未跟踪目录;这两个参数都不会把清理起点提升到仓库根目录。

容易误判的是,git status 能显示工作区的其他改动,不代表当前目录下的 git clean 会处理那些路径。状态命令列出什么,与清理命令从哪里开始,是两件事。

先运行只读检查,确认当前目录与工作区顶层目录:

pwd
git rev-parse --show-toplevel

如果第二条命令返回的根目录不是你要处理的项目,先停下来确认仓库边界。处在子模块或另一个嵌套仓库里时,不能把那里得到的根目录当成外层项目的根目录。

从正确目录预览,但只处理冲突路径

以下 /path/to/repo 是占位路径,generated/local.txt 是示例冲突文件。替换为实际路径后再使用。命令中的 -C 放在 clean 或 status 前,表示让 Git 按指定目录执行。

先查看该路径的状态,再预览清理结果:

git -C /path/to/repo status --short --untracked-files=all -- generated/local.txt
git -C /path/to/repo clean -n -- generated/local.txt

在短状态输出中,?? 表示未跟踪。clean -n 只列出将要删除的内容,不实际删除。此时若能看到示例文件,而在原来的 src 目录里预览不到它,就能把问题缩小到执行目录或原命令的路径范围。

不要为方便直接把命令改成对整个仓库执行 git clean -fd。仓库根目录下可能还有尚未提交的脚本、实验数据或本地配置;它们与这次分支切换冲突无关。

如果冲突文件还要用,优先把它移到仓库之外的备份目录,确认备份可读,再切换分支。目标分支可能会在同一路径放入它自己跟踪的文件,之后应比较内容、合并需要的改动,不要用备份直接覆盖。

只有在已经确认文件可丢弃或有可恢复备份,并逐项看过预览后,才把同一条命令的 -n 改为 -f:

git -C /path/to/repo clean -f -- generated/local.txt

这条命令只指定了一个文件。若实际传入的是目录路径,匹配范围就可能包含目录中的多个文件;指定路径时,不能把“没写 -d”当作不会删除目录内容的保护。预览和执行之间也应避免构建任务继续往目标位置写文件。

未跟踪内容可能从来没有进入 Git 对象库,删除后不能指望从提交历史中恢复。备份应在删除之前完成,不能用执行后的 git status 代替备份核验。

根目录下仍没有清理候选时

如果在正确的根目录下,针对实际路径运行预览仍没有结果,就不要继续叠加强制参数。先区分文件类型:

git -C /path/to/repo status --short --untracked-files=all --ignored -- generated/local.txt

输出中的 !! 表示被忽略的路径。默认的 git clean 会遵守忽略规则,因此这类文件可能不在清理候选里。-x 会扩大范围,连忽略文件也纳入;-X 则只针对忽略文件。不要为了这次冲突直接对整个仓库使用它们,尤其是有 .env、密钥或本地数据库文件的项目。确认文件用途后,单独备份并移走冲突文件通常更容易控制影响。

如果路径已经被跟踪,git clean 就不是处理它的工具。此时需要按已跟踪改动决定提交、保留或恢复,不能继续套用未跟踪文件的删除步骤。

对于未跟踪的嵌套 Git 仓库,Git 还有额外保护;第二个 -f 可以绕过这一层保护。它不是普通的“再试一次”,可能删掉整个独立仓库。若目标是子模块、目录里有自己的 Git 元数据,或状态与预期不符,应先查清这个目录属于哪个仓库,不在这里用双重强制清理。

再次切换分支与恢复文件

移走或确认删除冲突路径后,重新执行针对该路径的 status 和 clean -n,核对不再有待处理的同名未跟踪文件,然后使用原来的普通分支切换命令。

不要用 git checkout -f 作为清理范围不明时的替代办法。强制切换会丢弃本地改动,并处理阻碍切换的未跟踪文件或目录;一次切换成功并不能证明那些内容原本无用。

如果仍然报错,比较新错误中的路径清单。可能还剩其他冲突文件,也可能已经变成已跟踪改动阻止切换,处理对象会随之改变,不应照着旧清单继续删。

需要恢复备份时,先核对当前分支是否已经跟踪该路径,再决定恢复到别处进行比较,或把所需改动合并进去。只有文件内容和项目运行所需的本地配置都检查过,才算完成这次清理。