让Git忽略文件模式(chmod)更改的方法
技术背景
在使用Git进行版本控制时,文件的执行权限(文件模式)更改有时会被Git记录,这可能会干扰正常的版本管理流程。例如,在不同的操作系统或文件系统之间切换时,文件的执行权限可能会发生变化,导致Git认为文件有更改,即使文件内容并未改变。
实现步骤
临时设置
可以使用-c
标志为一次性命令设置core.fileMode
选项:
1
| git -c core.fileMode=false diff
|
全局设置
对于所有Git仓库,可以使用以下命令设置:
1
| git config --global core.fileMode false
|
不过需要注意,此设置可能会被本地配置覆盖,并且在最新版本的Git中,fileMode
值会根据当前文件系统自动选择。
单个仓库设置
对于单个Git仓库,可以在仓库目录下执行以下命令:
1
| git config core.fileMode false
|
手动修改配置文件
如果上述命令不起作用,可以手动修改配置文件:
- 进入项目的
.git
文件夹:
- 编辑
config
文件:
- 将
filemode = true
改为filemode = false
:
1 2 3
| [core] repositoryformatversion = 0 filemode = false
|
- 保存并退出,返回上一级目录:
- 重新初始化Git:
撤销工作树中的模式更改
在不同系统中可以使用以下命令:
Linux
1 2
| git diff --summary | grep --color 'mode change 100755 => 100644' | cut -d' ' -f7- | xargs -d'\n' chmod +x git diff --summary | grep --color 'mode change 100644 => 100755' | cut -d' ' -f7- | xargs -d'\n' chmod -x
|
mingw - Git
1 2
| git diff --summary | grep 'mode change 100755 => 100644' | cut -d' ' -f7- | xargs -e'\n' chmod +x git diff --summary | grep 'mode change 100644 => 100755' | cut -d' ' -f7- | xargs -e'\n' chmod -x
|
BSD/macOS
1 2
| git diff --summary | grep --color 'mode change 100644 => 100755' | cut -d' ' -f7- | tr '\n' '\0' | xargs -0 chmod -x git diff --summary | grep --color 'mode change 100755 => 100644' | cut -d' ' -f7- | tr '\n' '\0' | xargs -0 chmod -x
|
递归设置子模块
如果要递归地将配置文件中的filemode
设置为false
(包括子模块),可以使用以下命令:
1
| find -name config | xargs sed -i -e 's/filemode = true/filemode = false/'
|
核心代码
临时设置命令
1
| git -c core.fileMode=false diff
|
全局设置命令
1
| git config --global core.fileMode false
|
单个仓库设置命令
1
| git config core.fileMode false
|
撤销工作树模式更改(以Linux为例)
1 2
| git diff --summary | grep --color 'mode change 100755 => 100644' | cut -d' ' -f7- | xargs -d'\n' chmod +x git diff --summary | grep --color 'mode change 100644 => 100755' | cut -d' ' -f7- | xargs -d'\n' chmod -x
|
最佳实践
- 尽量避免使用
chmod -R 777
这样的命令,因为它会使所有文件都具有执行权限,这在大多数项目中是不必要的,并且存在安全风险。可以分别处理文件夹和文件的权限:
1 2
| find . -type d -exec chmod a+rwx {} \; find . -type f -exec chmod a+rw {} \;
|
- 不要一直将
core.fileMode
设置为false
,只在必要时使用。 - 可以通过定义别名来临时禁用文件模式检查:
1 2
| [alias] nfm = "!f(){ git -c core.fileMode=false $@; };f"
|
使用时:
常见问题
全局设置不生效
如果git config --global core.filemode false
不生效,可能是本地配置覆盖了全局配置。可以使用以下命令移除本地配置:
1
| git config --unset core.filemode
|
或者将本地配置更改为正确的值:
1
| git config core.filemode false
|
执行命令时提示找不到配置文件
如果在没有--global
选项且当前工作目录不是Git仓库时运行命令,会出现以下错误:
1
| error: could not lock config file .git/config: No such file or directory
|
请确保在Git仓库目录下执行命令。