Git 提交时神秘的 create mode 100644 到底是什么?一文告诉你答案!

简介

上下文:它出现在哪里?

常见于以下命令输出中:

shell 复制代码
$ git show

输出示例:

diff 复制代码
diff --git a/src/test.txt b/src/test.txt
new file mode 100644
index 0000000..7f3e5a4
--- /dev/null
+++ b/src/test.txt
@@ -0,0 +1,2 @@
hello
world
shell 复制代码
$ git commit -m "Add new files"
[main 1a2b3c4] Add new files
 2 files changed, 15 insertions(+)
 create mode 100644 README.md
 create mode 100755 script.sh
 create mode 120000 symlink.txt

这些都表示此提交中新增了一个文件,且该文件的"mode(模式)"为 100644。

Git 的文件模式(mode)是什么?

Git 在内部保存每个文件的三类信息(在 indextree 对象中):

信息 含义
mode 文件类型 + 权限
SHA-1/Hash 文件内容对应的 blob 对象
文件名 文件路径名

所以,Git 实际上并不直接保存整个文件,而是保存 "文件内容(blob)+ mode + 文件名" 三元组。

100644 的含义分解

100644 是一个 文件模式(mode),用八进制表示。

文件类型部分(前两位)

模式前缀 文件类型
100 普通文件(regular file)
120 符号链接(symbolic link)
160 Git 子模块(gitlink)

权限部分(后三位)

模式 含义
644 普通文件(可读写、不可执行)
755 可执行文件(脚本、二进制等)

实际权限解析(Linux 风格):

ini 复制代码
6 = rw- (所有者可读写)
4 = r-- (组可读)
4 = r-- (其他用户可读)

rw-r--r--

常见几种模式对照表

Git 模式(八进制) 类型 含义 示例
100644 普通文件 普通非执行文件(rw-r--r--) 源代码、配置文件
100755 普通文件 可执行文件(rwxr-xr-x) 脚本、二进制文件
120000 符号链接 保存符号链接路径 Linux 下的 symlink
160000 gitlink 子模块 .gitmodules 指向的 repo
040000 目录(tree 对象) 存储 tree 引用 非实际文件

查看文件在 Git 中的 mode

可以用以下命令查看工作区、索引和历史中对应文件的 mode

查看 index(暂存区):

shell 复制代码
git ls-files -s

示例输出:

复制代码
100644 4d1f48a5e9e6b032d212d24ec8594f98639b6f08 0       README.md
100755 05a43e2a77fdab64d45c601944bcdbba05cf8cb1 0       build.sh

第一列即是文件模式。

查看 tree(提交快照):

shell 复制代码
git ls-tree HEAD

输出:

sql 复制代码
100644 blob 4d1f48a5e9e6b032d212d24ec8594f98639b6f08    README.md
100755 blob 05a43e2a77fdab64d45c601944bcdbba05cf8cb1    build.sh

Git 为什么只保存两种权限(644 与 755)

  • Git 主要在 跨平台 环境使用。

  • Windows 文件系统不支持 POSIX 权限位(如执行权限)。

  • 为了避免混乱,Git 简化为两种状态:

    • 普通文件(非执行)

    • 可执行文件(执行位)

也就是说,Git 只关心文件是否"可执行",其余权限位不影响版本内容。

如何修改可执行标志

修改本地文件执行权限:

shell 复制代码
chmod +x script.sh

再次提交:

shell 复制代码
git add script.sh
git commit -m "make script executable"

提交后再次查看

ini 复制代码
mode change 100644 => 100755 script.sh

子模块(160000)与符号链接(120000)

模式 类型 存储内容 备注
160000 子模块 存储子仓库的 commit ID 不保存实际文件
120000 符号链接 存储符号链接目标路径 不保存实际文件内容

示例(符号链接):

shell 复制代码
ln -s ../config.yml link.yml
git add link.yml
git commit -m "add symlink"
# 显示 create mode 120000 link.yml

Git 是如何在内部保存这些信息的?

Git 提交由多个对象组成:

sql 复制代码
Commit → Tree → Blob

举例:

sql 复制代码
commit对象
  ↓
tree对象(保存 mode + 文件名 + blob 引用)
  ├── 100644 README.md → blob(内容)
  ├── 100755 build.sh  → blob(内容)
  └── 040000 src/ → tree(子目录)

也就是说,100644 这一信息实际上存在 tree 对象 中,是提交快照(snapshot)的一部分。

实际操作示例

场景 1:添加普通文件

shell 复制代码
# 创建普通文本文件
echo "Hello World" > hello.txt

# 查看权限
ls -l hello.txt
# -rw-r--r-- 1 user group 12 Jan 1 10:00 hello.txt

# 添加到 Git 并提交
git add hello.txt
git commit -m "Add hello"
# create mode 100644 hello.txt

场景 2:创建可执行脚本

shell 复制代码
# 创建脚本并设为可执行
echo '#!/bin/bash\necho "Hello"' > run.sh
chmod +x run.sh

# 查看权限
ls -l run.sh
# -rwxr-xr-x 1 user group 22 Jan 1 10:00 run.sh

# 添加到 Git 并提交
git add run.sh
git commit -m "Add script"
# create mode 100755 run.sh

场景 3:创建符号链接

shell 复制代码
# 创建符号链接
ln -s target.txt link.txt

# 查看文件类型
ls -l link.txt
# lrwxrwxrwx 1 user group 10 Jan 1 10:00 link.txt -> target.txt

# 添加到 Git 并提交
git add link.txt
git commit -m "Add symlink"
# create mode 120000 link.txt

文件模式的管理

查看 Git 中的文件模式

shell 复制代码
# 查看 Git 数据库中文件的模式
git ls-tree HEAD
# 100644 blob 89abcde    README.md
# 100755 blob 2345678    script.sh
# 120000 blob 3456789    link.txt
# 040000 tree 4567890    src

# 查看特定提交的文件模式
git ls-tree 1a2b3c4

修改文件模式

shell 复制代码
# 如果文件模式不正确,可以修改文件权限后重新添加
chmod +x my-script.py
git add my-script.py
git commit -m "Fix file permissions"

# 或者使用 Git 命令更新索引中的文件模式
git update-index --chmod=+x my-script.py

忽略文件权限变化

shell 复制代码
# 告诉 Git 忽略文件权限变化(在跨平台协作时有用)
git config core.filemode false

# 检查当前配置
git config core.filemode

跨平台注意:

  • Linux/MacGit 尊重文件权限。

  • Windows:权限支持有限,默认 core.fileMode = false,模式变化不会被跟踪。

相关推荐
春生野草7 小时前
Git-git stash与分支管理
git
ljh5746491197 小时前
Git合并冲突解决方法
git
悟能不能悟7 小时前
git revert commit和undo commit的区别
git
222you19 小时前
Git的diff命令
git
补三补四20 小时前
Git 基础操作指南
大数据·git·elasticsearch
222you1 天前
git的命令
git
Coolbike1 天前
Git工作流
git
~央千澈~1 天前
实战针对本地项目git如何移除旧仓库关联并且添加关联新仓库-优雅草卓伊凡
git
JH30732 天前
git常用命令大全
git