Git默认功能已经很强,但每个人的工作习惯不一样!就像给手机装插件、电脑换主题,Git也能“个性化定制”~
本章会教你玩转Git配置、属性、钩子,让Git完全适配你的工作流:比如自动格式化提交信息、处理跨平台换行问题、限制文件修改权限等。新手也能轻松上手,配置一次,受益终身!
⚙️ Git配置 - 给Git“调参数”
配置层级
客户端配置
服务器配置
颜色配置
1. 配置层级 - 不同范围的设置 📌
Git的配置分三个层级,优先级从高到低:本地仓库 > 全局用户 > 系统全局,高层级会覆盖低层级的设置。
# 1. 系统级配置(所有用户共享,需管理员权限)
git config --system 配置项 值
# 配置文件路径:/etc/gitconfig(Linux/Mac)、C:\Program Files\Git\etc\gitconfig(Windows)# 2. 全局级配置(当前用户所有仓库生效)
git config --global 配置项 值
# 配置文件路径:~/.gitconfig(Linux/Mac)、C:\Users\用户名\.gitconfig(Windows)
# 3. 本地仓库配置(仅当前仓库生效)
git config 配置项 值
# 配置文件路径:当前仓库/.git/config
# 查看所有配置(包含三个层级)
git config --list
# 查看某个具体配置
git config user.name
💡 实用场景:全局配置设置用户名和邮箱,本地仓库可以单独设置不同的邮箱(比如工作仓库用工作邮箱,个人仓库用私人邮箱)~
2. 常用客户端配置 - 提升日常使用体验 🚀
这些配置能解决日常使用中的小痛点,建议全局设置:
# 1. 设置默认编辑器(替换vi为你常用的编辑器)
git config --global core.editor "code --wait" # VS Code
git config --global core.editor "subl -w" # Sublime Text
git config --global core.editor "emacs" # Emacs# 2. 设置提交信息模板(强制提交信息格式规范)
# 先创建模板文件 ~/.gitmessage.txt,内容示例:
# [类型] 简短描述(50字内)
#
# 详细说明:
# 1. 功能亮点
# 2. 改动范围
# [关联工单:XXX]
git config --global commit.template ~/.gitmessage.txt
# 3. 关闭分页输出(git log、git diff不再分页,直接显示全部)
git config --global core.pager ""
# 4. 设置GPG签名密钥(提交和标签自动签名,增强安全性)
git config --global user.signingkey 你的GPG密钥ID
# 5. 全局忽略文件(所有仓库都忽略这些文件,比如编辑器缓存)
# 先创建 ~/.gitignore_global 文件,添加忽略规则:
# *.swp(Vim缓存)
# *.sublime-*(Sublime缓存)
# .DS_Store(Mac系统文件)
git config --global core.excludesfile ~/.gitignore_global
# 6. 命令自动纠错(输错命令时自动提示并执行正确命令)
git config --global help.autocorrect 1 # 1=0.1秒后自动执行
3. 颜色配置 - 让输出更易读 🎨
Git默认会给日志、差异等输出上色,也可以自定义颜色:
# 开启所有颜色(默认是auto,终端输出上色,重定向到文件不上色)
git config --global color.ui true# 自定义diff输出颜色(比如元信息蓝色粗体)
git config --global color.diff.meta "blue bold"
# 自定义分支列表颜色
git config --global color.branch.current "green bold" # 当前分支绿色粗体
git config --global color.branch.remote "red" # 远程分支红色
颜色值支持:black、red、green、yellow、blue、magenta、cyan、white;属性支持:bold(粗体)、ul(下划线)、reverse(反色)。
4. 服务器配置 - 增强仓库安全性 🛡️
如果是自己搭建的Git服务器,可以通过配置限制推送行为:
# 1. 强制校验对象完整性(防止恶意推送损坏的对象)
git config --system receive.fsckObjects true# 2. 禁止非快进推送(防止强制覆盖已推送的提交)
git config --system receive.denyNonFastForwards true
# 3. 禁止删除分支和标签
git config --system receive.denyDeletes true
⚠️ 注意:这些配置需要在服务器的裸仓库中设置(—system 对所有仓库生效,或进入仓库目录用 git config 只对该仓库生效)~
📄 Git属性 - 给文件“定规则”
.gitattributes
二进制文件处理
关键字替换
合并策略
导出忽略
1. 什么是Git属性?
Git属性通过 .gitattributes 文件设置(放在仓库根目录,需提交到仓库),可以给特定文件或目录指定规则,比如“如何处理二进制文件”“合并时用什么策略”等。
如果不想把属性文件提交到仓库,可以写在 .git/info/attributes 文件中(仅本地生效)。
2. 二进制文件处理 - 让Git正确识别 📦
有些文件看似文本(比如Xcode的 .pbxproj),但实际是二进制格式,Git默认可能误判,导致合并冲突或无用的diff输出:
# 在 .gitattributes 中添加:
# 标记 .pbxproj 文件为二进制,不尝试diff和合并
*.pbxproj binary# 让Word文档支持diff(需要安装 docx2txt 工具)
*.docx diff=word
# 配置diff工具(全局设置)
git config diff.word.textconv docx2txt
# 让图片文件diff时显示EXIF信息(需要安装 exiftool)
*.png diff=exif
git config diff.exif.textconv exiftool
💡 效果:运行 git diff 时,Word文档会显示文本内容差异,图片会显示文件大小、尺寸等变化,再也不是“Binary files differ”了~
3. 关键字替换 - 自动注入信息 🔍
类似SVN的关键字替换,Git可以在文件检出时注入提交信息(比如版本号、日期),提交时自动移除:
# 1. 简单替换:注入文件的SHA-1值
# .gitattributes 中添加:
*.txt ident
# 在文件中添加 $Id$,检出时会替换为 $Id: 文件SHA-1 $# 2. 自定义替换(比如注入最后提交日期)
# 第一步:创建替换脚本 expand_date(放在PATH目录)
# #!/usr/bin/env ruby
# data = STDIN.read
# last_date = `git log --pretty=format:"%ad" -1`
# puts data.gsub('$Date$', '$Date: ' + last_date.to_s + '$')
# chmod +x expand_date
# 第二步:配置Git过滤器
git config --global filter.dater.smudge expand_date
git config --global filter.dater.clean 'perl -pe "s/\\\$Date[^\\\$]*\\\$/\\\$Date\\\$/"'
# 第三步:.gitattributes 中指定文件
date*.txt filter=dater
# 在 date_test.txt 中添加 $Date$,检出时会自动替换为最后提交日期
⚠️ 注意:自定义过滤器脚本需要分发给团队成员,否则其他人检出文件时不会替换关键字~
4. 合并策略 - 解决特定文件冲突 🤝
有些文件(比如配置文件)在不同分支可能有不同内容,合并时不想冲突,直接保留当前分支的版本:
# .gitattributes 中添加:
database.xml merge=ours # 合并时保留当前分支的 database.xml# 配置“ours”合并策略(全局设置)
git config --global merge.ours.driver true
效果:合并其他分支时,database.xml 不会出现冲突,直接使用当前分支的版本,适合环境相关的配置文件。
5. 导出忽略 - 打包时排除文件 📤
用 git archive 打包仓库时,有些文件(比如测试用例、构建产物)不想包含,可以通过属性排除:
# .gitattributes 中添加:
test/ export-ignore # 排除 test 目录
*.log export-ignore # 排除所有 .log 文件
.gitignore export-ignore # 排除 .gitignore 文件
执行 git archive HEAD —format=zip -o 项目名.zip 时,这些文件会自动排除,适合生成部署包。
🤖 Git钩子 - 给操作“加脚本”
客户端钩子
服务器端钩子
提交相关钩子
推送相关钩子
1. 钩子基础 - 怎么启用钩子?
Git钩子是事件触发的脚本(支持Shell、Ruby、Python等),仓库初始化后会在 .git/hooks 目录生成示例脚本(后缀 .sample),启用方法:
# 1. 复制示例脚本,去掉 .sample 后缀(以提交前检查为例)
cd .git/hooks
cp pre-commit.sample pre-commit# 2. 编辑脚本,添加自定义逻辑
vim pre-commit
# 3. 给脚本添加执行权限
chmod +x pre-commit
⚠️ 注意:钩子文件不会随 git clone 复制到本地!团队共享钩子需要手动分发,或通过项目文档告知成员安装~
2. 客户端钩子 - 本地操作触发 🔧
客户端钩子在本地执行(比如提交、合并、检出),常用钩子如下:
(1)pre-commit - 提交前触发
用于检查提交前的代码(比如语法检查、空格检查),脚本退出非0会终止提交:
#!/bin/sh
# 检查代码中是否有 console.log(前端项目示例)
if git diff --cached --name-only -- '*.js' | xargs grep -q 'console.log'; then
echo "❌ 错误:提交中包含 console.log,请删除后再提交!"
exit 1
fi# 检查是否有 trailing whitespace(行尾空格)
if git diff --cached --check; then
echo "✅ 代码格式检查通过!"
exit 0
else
echo "❌ 错误:存在行尾空格等格式问题,请修复!"
exit 1
fi
(2)commit-msg - 提交信息检查
强制提交信息符合规范(比如必须包含工单编号),脚本退出非0会终止提交:
#!/bin/sh
# 获取提交信息文件路径
msg_file=$1
# 读取提交信息
msg=$(cat "$msg_file")
# 正则匹配:必须包含 [ref: 数字] 格式
if ! echo "$msg" | grep -qE '\[ref: [0-9]+\]'; then
echo "❌ 错误:提交信息格式不正确!"
echo "✅ 正确格式示例:修复登录bug [ref: 123]"
exit 1
fi
exit 0
(3)post-checkout - 检出后触发
检出分支后自动执行操作(比如安装依赖、生成文档):
#!/bin/sh
# 检出后自动安装npm依赖(前端项目)
if [ -f "package.json" ]; then
echo "📦 正在安装依赖..."
npm install
fi# 生成API文档
if [ -f "README.md" ]; then
echo "📄 正在生成文档..."
npm run docs
fi
3. 服务器端钩子 - 推送操作触发 🚀
服务器端钩子在Git服务器上执行(仅针对裸仓库),常用钩子如下:
(1)pre-receive - 接收推送前触发
对所有推送的引用(分支、标签)进行检查,脚本退出非0会拒绝整个推送:
#!/bin/sh
# 检查所有推送的提交信息是否符合规范
while read oldrev newrev refname; do
# 获取该分支新增的提交
commits=$(git rev-list $oldrev..$newrev)
for commit in $commits; do
# 读取提交信息
msg=$(git cat-file commit $commit | sed '1,/^$/d')
# 检查格式
if ! echo "$msg" | grep -qE '\[ref: [0-9]+\]'; then
echo "❌ 错误:提交 $commit 的信息格式不正确!"
echo "✅ 正确格式示例:修复登录bug [ref: 123]"
exit 1
fi
done
done
exit 0
(2)post-receive - 接收推送后触发
推送成功后执行操作(比如触发CI/CD、发送通知):
#!/bin/sh
# 推送成功后触发Jenkins构建
curl -X POST http://jenkins服务器地址/job/项目名/build?token=触发令牌# 发送邮件通知(假设存在 send-email.sh 脚本)
./send-email.sh "项目有新推送" "分支:$refname,提交范围:$oldrev..$newrev"
(3)update - 每个引用推送时触发
和 pre-receive 类似,但对每个推送的分支/标签单独触发,拒绝单个引用不会影响其他引用:
#!/bin/sh
refname=$1 # 引用名(比如 refs/heads/master)
oldrev=$2 # 推送前的版本
newrev=$3 # 推送后的版本# 禁止强制推送master分支
if [ "$refname" = "refs/heads/master" ] && ! git merge-base --is-ancestor $oldrev $newrev; then
echo "❌ 错误:禁止强制推送master分支!"
exit 1
fi
exit 0
🌍 实战场景 - 企业级Git政策 enforcement
大型团队需要统一规范,结合配置、属性、钩子可以实现强约束,以下是常见场景:
场景1:强制提交信息格式 + 分支权限控制
需求:所有提交必须包含工单编号,普通开发者只能修改指定目录,管理员无限制。
# 1. 服务器端 update 钩子(检查提交信息和目录权限)
#!/usr/bin/env ruby
refname = ARGV[0]
oldrev = ARGV[1]
newrev = ARGV[2]
user = ENV['USER'] # 假设通过SSH环境变量获取用户名# 检查提交信息格式
regex = /\[ref: (\d+)\]/
`git rev-list #{oldrev}..#{newrev}`.split("\n").each do |rev|
msg = `git cat-file commit #{rev} | sed '1,/^$/d'`
unless regex.match(msg)
puts "[POLICY] 提交 #{rev} 信息格式错误,需包含 [ref: 工单编号]"
exit 1
end
end
# 检查目录权限(ACL文件放在仓库根目录的 acl 文件中)
acl = {
'admin' => [''], # 管理员无限制
'dev1' => ['lib', 'tests'], # 只能修改lib和tests目录
'doc' => ['doc'] # 只能修改doc目录
}
`git rev-list #{oldrev}..#{newrev}`.split("\n").each do |rev|
`git log -1 --name-only --pretty=format:'' #{rev}`.split("\n").each do |path|
next if path.empty?
has_access = acl[user]&.any? { |p| p.empty? || path.start_with?(p) }
unless has_access
puts "[POLICY] 用户 #{user} 无权限修改 #{path}"
exit 1
end
end
end
exit 0
场景2:跨平台换行问题处理
Windows用CRLF换行,Linux/Mac用LF换行,导致提交时出现大量“空白修改”,通过配置和属性解决:
# 1. 全局配置(Windows用户)
git config --global core.autocrlf true # 提交时CRLF转LF,检出时LF转CRLF# 2. 全局配置(Linux/Mac用户)
git config --global core.autocrlf input # 提交时CRLF转LF,检出时不转换
# 3. .gitattributes 中强制所有文件用LF(推荐,统一仓库换行格式)
* text=auto eol=lf # 文本文件自动识别,强制LF换行
*.bat text eol=crlf # bat文件特殊处理,保留CRLF
*.png binary # 二进制文件不转换
💡 推荐用 .gitattributes 统一配置,避免每个用户本地配置不一致导致的问题~
场景3:自动格式化代码 before commit
团队统一代码风格(比如ESLint、Prettier),提交前自动格式化,避免格式冲突:
# pre-commit 钩子脚本
#!/bin/sh
# 安装依赖(如果未安装)
if ! command -v prettier &> /dev/null; then
echo "📦 正在安装 prettier..."
npm install -g prettier
fi# 格式化所有 staged 的 js、vue、css 文件
git diff --cached --name-only -- '*.js' '*.vue' '*.css' | xargs prettier --write
# 重新暂存格式化后的文件
git diff --cached --name-only -- '*.js' '*.vue' '*.css' | xargs git add
echo "✅ 代码格式化完成!"
exit 0
🎯 本章总结 - Git个性化核心要点
- 配置层级:本地 > 全局 > 系统,按需设置不同范围的参数
- 常用配置:编辑器、提交模板、颜色、全局忽略,提升日常效率
- Git属性:通过 .gitattributes 控制文件的diff、合并、导出规则
- Git钩子:客户端钩子规范本地操作,服务器端钩子强制团队政策
- 实战场景:结合三者可以解决跨平台、代码规范、权限控制等问题
要不要我帮你整理一份Git个性化配置大全?包含常用配置命令、.gitattributes 模板、实用钩子脚本,直接复制就能用,让你快速打造专属Git工作流~