core.filemode设为true,Git仍不追踪文件可执行位变更如何解决?
问题背景
Git版本2.47.1,文件系统为XFS,已将core.filemode在系统、全局、本地层面都设为true,但修改文件可执行位后Git完全不追踪变更;用git update-index --chmod标记权限变更后,暂存区显示修改,但执行git commit -am却提示无内容可提交,且拉取代码到生产环境时文件执行权限会被重置为0。
操作过程输出如下:
[me@host]$ sudo git config --get --system core.filemode true [me@host]$ git config --get --global core.filemode true [me@host]$ git config --get --local core.filemode true [me@host]$ ls -l file.py -rwxr--r-- 1 me mygrp 4530 Jul 9 12:29 file.py [me@host]$ chmod 755 file.py [me@host]$ ls -l file.py -rwxr-xr-x 1 me mygrp 4530 Jul 9 12:29 file.py [me@host]$ git diff [me@host]$ git status On branch main Your branch is up to date with 'origin/main'. nothing to commit, working tree clean
使用git-update-index后的异常情况:
[me@host]$ git reset --hard HEAD HEAD is now at 9fdf824 last change blah blah [me@host]$ ls -l file.py -rwxr-xr-x 1 me mygrp 4530 Jul 9 13:36 file.py [me@host]$ git update-index --chmod=-x file.py [me@host]$ git diff diff --git a/dir/file.py b/dir/file.py old mode 100644 new mode 100755 [me@host]$ git status On branch main Your branch is up to date with 'origin/main'. Changes to be committed: (use "git restore --staged <file>..." to unstage) modified: file.py Changes not staged for commit: (use "git add <file>..." to update what will be committed) (use "git restore <file>..." to discard changes in working directory) modified: file.py [me@host]$ git commit -am "new file permissions" On branch main Your branch is up to date with 'origin/main'. nothing to commit, working tree clean
解决步骤
1. 检查索引中的权限模式
先确认Git索引里记录的文件权限,执行:
git ls-files --stage file.py
输出格式类似100644 9fdf824... 0 file.py,其中100644是索引中的权限模式,100755代表可执行。如果索引里的模式和当前文件系统的权限不一致,就会出现Git不追踪的情况。
2. 重置索引并重新追踪权限
如果索引和工作区权限不一致,执行以下命令强制重新将文件加入索引,带上当前工作区的权限:
git rm --cached file.py git add file.py
此时执行git diff应该能看到权限变更,再执行git commit -m "fix file executable permission"即可提交变更。
3. 修复git update-index后的提交问题
当执行git update-index --chmod后出现暂存区和工作区双重修改时,先同步工作区和索引的权限:
git restore file.py
此时工作区权限会和暂存区一致,再执行:
git commit -m "update file executable permission"
就能正常提交权限变更了。
4. 检查.gitattributes配置
查看仓库根目录下的.gitattributes文件,如果存在类似以下内容:
file.py -executable
这会强制Git忽略该文件的可执行位变更,删除这一行或修改为file.py +executable即可恢复追踪。
5. 强制Git重新扫描权限
如果以上步骤无效,执行以下命令让Git重新检测所有文件的权限:
git update-index --refresh
内容的提问来源于stack exchange,提问作者mttpgn

