本章旨在说明如何通过引入重要的配置设置和钩子系统,让 Git 以更加定制化的方式运行,使其能完全符合你、你的公司或团队的需求。

Git 配置 (Git Configuration)

你可以使用 git config 命令来指定 Git 的配置设置。

配置文件的三层级别

Git 使用一系列配置文件来决定非默认行为。配置值按以下级别存储和覆盖:
  1. 系统级 (System Level)
      • 文件位置:[path]/etc/gitconfig
      • 应用范围:应用于系统上的每个用户及其所有仓库。
      • 读写选项:通过 -system 选项读写。
  1. 全局级 (Global Level)
      • 文件位置:~/.gitconfig~/.config/git/config
      • 应用范围:特定于个人用户,影响用户系统上的所有仓库
      • 读写选项:通过 -global 选项读写。
  1. 本地级 (Local Level)
      • 文件位置:当前使用的仓库的 Git 目录(.git/config)中。
      • 应用范围:特定于该单个仓库
      • 读写选项:默认使用此级别,或通过 -local 选项读写。
覆盖原则: 每一层都会覆盖前一层的配置,因此本地配置会覆盖全局配置,全局配置会覆盖系统配置。

常用客户端配置

你可以通过 git config --list 命令查看所有配置设置。
配置项
描述
语法示例
core.editor
配置 Git 需要用户输入消息时使用的默认文本编辑器。
git config --global core.editor emacs
commit.template
设置系统上一个文件的路径,Git 会将其作为提交时的默认初始消息。
git config --global commit.template ~/.gitmessage.txt
core.pager
决定 Git 用于 logdiff 等输出的分页程序(默认为 less)。
git config --global core.pager '' (关闭分页)
core.excludesfile
允许设置一个全局的 .gitignore 文件。
git config --global core.excludesfile ~/.gitignore_global
color.ui
设置是否在终端输出中启用颜色。默认值为 auto
git config --global color.ui false
color.*
针对特定命令(如 color.diffcolor.status)设置更具体的颜色配置。
git config --global color.diff.meta "blue black bold"
core.autocrlf
处理跨平台行尾问题。
git config --global core.autocrlf input (推荐 Linux/macOS)

外部工具配置

  • 外部差异工具: 通过设置 diff.external 可以使用自定义命令作为 git diff 的替代工具。
  • 外部合并工具: 通过设置 merge.tool 来使用图形化工具解决合并冲突。
    • 例如,使用 KDiff3 作为合并工具:git config --global merge.tool kdiff3

核心服务器配置

服务器端(通常在裸仓库上)的配置通常存储在系统级配置或本地仓库的 .git/config 中。
  • receive.denyNonFastForwards: 设置为 true 可以拒绝任何非快进(non-fast-forward)的推送,以保护历史记录的线性。
    • 语法:git config --system receive.denyNonFastForwards true
  • receive.denyDeletes: 设置为 true 可以拒绝任何分支或标签的删除。

Git 属性 (Git Attributes)

Git 属性允许为特定的路径(文件或目录子集)指定配置,Git 只对匹配这些路径的文件应用设置。属性可以在项目目录的 .gitattributes 文件中设置,或者在本地的 .git/info/attributes 中设置。

属性应用示例

1. 处理二进制文件和差异比较

  • 声明二进制文件: 使用 binary 属性可以告诉 Git 将文件视为二进制数据,从而避免尝试进行行尾转换或差异计算。
    • 示例:.pbxproj binary
  • 差异化二进制文件: 通过配置 diff 属性,你可以指定一个转换程序 (textconv) 将二进制文件(如 Word 文档)转换为文本格式,以便 Git 可以对其进行差异比较。
    • 例如,要对 .docx 文件使用名为 word 的过滤器:.docx diff=word
    • 随后配置 word 过滤器使用的外部程序:git config diff.word.textconv docx2txt

2. 关键字替换和内容过滤

  • Clean 和 Smudge 过滤器 (Keyword Expansion): 允许在文件检出时(smudge)和文件暂存时(clean)对内容进行处理或替代。
    • 例如,你可以设置一个名为 dater 的过滤器,在检出时将 Date 字符串替换为最新的提交日期,并在暂存时移除日期,还原为 Date
  • 导入/导出控制:
    • export-ignore: 忽略在 git archive 创建的压缩包中的文件或目录。
    • export-subst: 在 git archive 运行时,对文件中标记的关键字应用 git log 的格式化和关键字扩展处理(例如注入最近一次提交的元数据)。

3. 定义合并策略

  • merge 属性: 允许为单个文件或目录指定不同的合并策略。
    • merge=ours: 在合并时使用当前分支的文件版本,忽略传入分支的修改,这在处理如 database.xml 等只需要保留本地版本的文件时很有用。
      • 示例:database.xml merge=ours

Git 钩子 (Git Hooks)

Git 钩子是一种在特定重要操作(如提交、合并、推送)发生时触发自定义脚本的方式。钩子分为客户端钩子和服务器端钩子。

钩子安装和基本规则

  • 所有钩子脚本存储在 .git/hooks 子目录中。
  • 初始化新仓库时,Git 会填充很多示例脚本(以 .sample 结尾)。
  • 要启用钩子,需要将脚本文件重命名为正确的钩子名称(不带扩展名)并使其可执行
  • 注意: 客户端钩子不会随仓库克隆,如果需要强制执行策略,必须依赖服务器端钩子。

客户端钩子 (Client-Side Hooks)

客户端钩子由提交和合并等操作触发。
钩子名称
触发时机
用途
pre-commit
在 Git 收集提交信息前运行。
检查即将提交的快照内容,例如运行测试套件或检查空白字符错误。
prepare-commit-msg
在默认提交信息生成后、编辑器启动前运行。
程序化地插入额外信息(例如,自动引用问题跟踪系统中的工单号)。
commit-msg
接收开发者写入的提交信息文本作为参数。
验证提交信息格式是否符合项目要求;非零退出会中止提交。
post-commit
在整个提交过程完成后运行。
通常用于通知或触发一些不影响 Git 仓库的操作。
pre-rebase
在执行变基操作前运行。
用于阻止对已推送到公共仓库的提交进行变基。
post-checkout
git checkout 成功后运行。
设置工作目录以匹配项目环境,例如移动大型二进制文件或自动生成文档。

服务器端钩子 (Server-Side Hooks)

服务器端钩子在网络操作(如接收推送)期间运行,是实施项目策略的关键。
  • pre-receive: 在服务器收到推送时运行,但在任何引用更新前运行。可以检查推送中包含的所有提交,非零退出会拒绝整个推送。
  • update: 每次推送一个分支时运行一次。它接收三个参数:引用的名称 (refname)、旧的 SHA-1 值 (oldrev) 和新的 SHA-1 值 (newrev)。
    • 该钩子允许基于分支名称、用户身份和具体更改内容来拒绝推送。

Git 强制策略示例 (An Example Git-Enforced Policy)

通过结合服务器端和客户端钩子,可以实现复杂的策略管理。

策略实施方法

  1. 在服务器端 (update 钩子) 实施策略: 确保推送中包含的每个提交都符合特定的提交信息格式(例如,必须包含工单引用 [ref: 1234])。
      • 通过 git rev-list 获取推送中新增的提交列表。
      • 使用 git cat-file commit <SHA> 获取原始提交对象数据,然后提取提交信息。
      • 如果发现不合规的提交,脚本以非零退出,Git 服务器将拒绝推送,并显示 [remote rejected] 消息。
  1. 在客户端 (commit-msg 钩子) 帮助用户: 虽然服务器端钩子强制执行策略,但客户端钩子可以在用户提交时就阻止不合规的提交,避免用户在推送时才发现错误并需要修改历史的麻烦。
      • 在本地的 .git/hooks/commit-msg 中配置检查脚本,如果提交信息格式不正确,则阻止提交。
通过这种方式,Git 可以在本地工作区提供指导和即时反馈,同时在服务器端强制执行最终的策略,以确保仓库历史的质量。
学习笔记——Git常用命令学习笔记——Git 分支及操作
Loading...