My .gitconfig file dissected
原文作者:Kiran Rao
译者:菜小鸟魔王
下面是我的 .gitconfig1 文件(kiranrao.ca/2024/06/21/…)。虽然很多人都有这种配置文件,但这一份独属于我。
这份配置文件并不冗长,也并不复杂难懂。但它却掌控着很多开发者工作流程中的核心工具 —— git。本文将逐步剖析这份文件,深入探讨 git 的工作机制,以助力各位读者优化已有的工作流。
[user]
name = Kiran Rao
email = hi@kiranrao.ca
signingkey = AAAAABBBBBB
[gpg]
program = gpg
[commit]
gpgsign = true
[alias]
co = checkout
ci = commit
st = status
br = branch
di = diff
fp = fetch --prune
rb = rebase
hist = log --graph --abbrev-commit --decorate --date=short \
--format=format:'%C(bold cyan)%h%C(reset) %C(bold green)(%ar)%C(reset) %C(white)%s%C(reset) %C(dim white)%an%C(reset) %C(bold yellow)%d%C(reset)' \
--branches --remotes --tags
git = !exec git
gti = !exec git
[push]
autoSetupRemote = true
01 What is git config?
.gitconfig文件用于控制git的运行方式,但并非唯一承担此任务的配置文件。
一般情况下,存在三种级别的配置文件决定git的运行方式。运行 git config --add 命令,就可以添加新的配置文件(三种配置级别均可)。这些文件按优先级从低至高排序如下:
-
系统级配置:
/etc/gitconfig。该配置文件对系统内的所有用户均生效。若想修改此文件,需使用--system参数。 -
用户级配置:
~/.gitconfig。该文件适用于当前用户的所有代码库。调整这类配置时,应使用--global参数。 -
代码库级配置:
.git/config。只影响单个代码库。直接操作此文件即可,修改该配置文件时无需附加任何参数。
本文将分析我的用户级gitconfig文件,不过文中涉及的配置信息同样适用于其他两个层级。
02 User section 用户信息部分
这部分记录了用户姓名及电子邮箱地址,用于标识用户身份。
[user]
name = Kiran Rao
email = hi@kiranrao.ca
那么,这些信息具体在哪些场景下会被调取使用呢?实际上,在每一次 commit(代码提交)或 tag(创建版本标签)时,用户的姓名和电子邮件都会自动嵌入其中。在执行git log命令查看提交历史时,便能一目了然:
commit ce97934132deb2b322c54de68ccbc1d402ca18e4 (HEAD -> git-config)
Author: Kiran Rao <hi@kiranrao.ca>
Date: Fri Jun 14 20:31:03 2024 -0400
WIP: User section
了解用户信息部分的内容我们可以发现:为每个代码库单独配置姓名和邮箱也非常便捷。比如,为了区分工作和个人用途,或是管理不同的客户项目,都是典型使用场景。
这又引发了一轮新的思考:理论上,我们可以随意地修改我们的用户名和邮箱信息。同样,别人应该也能毫无障碍地将他们的这些信息改为我们的。好在有 GPG 这种开源解决方案,理论上可以一定程度上避免这类问题的发生。
03 GPG key signing 使用 GPG 加密签名
GPG 是一种公钥加密系统(public-key cryptography system),被广泛应用于代码提交记录的签署,确保所有发布的内容确实出自持有者之手(即本人,或拥有访问我私钥及GitHub账户权限的个人)。
signingkey = AAAAABBBBBB
[gpg]
program = gpg
[commit]
gpgsign = true
配置文件可用于指示 git 进行如下操作:
- signingkey = AAAAABBBBBB:这是用于签名的密钥
- program = gpg:用于执行签名的程序
- gpgsign = true:表示自动为每次代码提交添加签名
可通过执行 git log --show-signature 命令来查看签名信息。
commit da7c2d3863581f00d489c0852a91bc15ba98eae0 (HEAD -> git-config)
gpg: Signature made Fri Jun 14 21:00:11 2024 EDT
gpg: using EDDSA key BA8B30A6D0E47B0B447FD15DC0B595B4F1573243
gpg: Good signature from "Tigger 2024-06-11 <hi@kiranrao.ca>" [ultimate]
Author: Kiran Rao <hi@kiranrao.ca>
Date: Fri Jun 14 21:00:11 2024 -0400
Start GPG
现在,Commits 在 GitHub、GitLab 以及其他 git 平台上的状态都显示为“verified(已验证)”。
GitHub 上`unverified`(未经验证)和`verified `(已验证)的 `commit` 对比截图
我无法详尽地解释 GPG signing 的具体工作机制。如若想要深入了解如何以及为何要为 Git commits 进行签名,有一篇文章提供了详细的解答[1]。为了帮助读者操作,此处有两篇指南:一是关于如何生成一个新的 GPG 密钥[2],二是关于如何将 GPG 密钥添加到我们的 GitHub 账户中[3]。
04 为常用操作设置快捷指令
通过设定 Git 的快捷指令,我们能够减少输入常规命令时的按键次数,从而提升工作效率。
[alias]
co = checkout
ci = commit
st = status
br = branch
di = diff
fp = fetch --prune
rb = rebase
虽然每次使用快捷指令(alias)仅能节省几秒时间,但这些节约的微小时间⌛️会迅速累积,长期下来效果显著。
05 优化提交记录展示
对于那些打字不便的冗长命令,我也设置了快捷指令(alias)。比如,git hist 命令利用 git log 来直观呈现项目的历史提交图。
hist = log --graph --abbrev-commit --decorate --date=short \
--branches --remotes --tags \
--format=format:'%C(bold cyan)%h%C(reset) %C(bold green)(%ar)%C(reset) %C(white)%s%C(reset) %C(dim white)%an%C(reset) %C(bold yellow)%d%C(reset)' \
标准的 git log 命令通常只显示线性的历史记录。然而,我们可以通过配置命令让其展示更丰富的信息。
--graph: 在每次commit旁边添加*--*--*,清晰展现各commit间的关联。--abbrev-commit: 缩短显示的commit信息长度。--decorate: 相当于--decorate:short。--date=short: 采用更简洁的日期格式。--branches: 不仅限于当前分支,展示所有分支。--remotes: 展现所有远程分支的本地副本。--tags: 包含标签(tags)信息。--format=format:'...': 使用一种多年前我从别处复制的精美格式。虽然与--oneline命令功能类似,但这个命令显示效果不及前者。
当这些配置选项组合在一起时,git hist 命令便能生动地呈现出项目的历史提交图,帮助我们更直观地理解项目发展脉络。
作为一名 Git 新手,我发现 git hist 命令极其实用。每当完成一次merge、rebase或cherry-pick操作后,它都能让我立刻一目了然地看到项目的历史提交图。更重要的是,在遇到操作失败需要调试时,git hist 也是不可或取的工具,它能让我们清楚掌握代码库内各个分支的具体状况。
06 巧用快捷指令节省时间
我曾经无意识地输入过太多次 git git status。有人可能会建议,应当纠正这种行为,认为“我应该纠正自己的打字习惯,防止这类错误的再次发生”。
然而,我并不赞同这一看法。避免敲入 git git 这样的误操作,并不会真正改善我的思维逻辑。相反,我选择采取一种更直接的方法来解决这一问题,通过设置快捷指令,让常用命令的输入变得更简便。
git = !exec git
gti = !exec git
利用 !exec,可以将后续的所有内容当作终端命令来执行。具体到此例中,它会重跑一遍 git 命令,并且带上原先的所有参数。这样一来,误输入的 git git status 就被修正为正常的 git status 命令。更妙的是,!exec 命令还支持递归操作!
07 自动配置远程分支
在我创建并尝试推送新分支时,时常会遇到这样一个错误:
fatal: The current branch new-branch has no upstream branch.
To push the current branch and set the remote as upstream, use
git push --set-upstream origin new-branch
这太不人性化了(TMD,蠢死了)。每当本地分支缺少对应的远程分支时,我总希望能够自动创建一个。
[push]
autoSetupRemote = true
把 autoSetupRemote 参数设置为 true 后,系统就能自动为本地分支匹配远程分支,无需额外的特殊操作。这样一来,我再也不必看到这个烦死人😡的错误了!
08 Conclusion
深入分析我们的 .gitconfig 文件,你会发现里面藏着不少秘密。希望本文能让你对 Git 的理解和应用“更上一层楼”。同时,我也希望通过这次分享,.gitconfig 文件对大家来说不再是神秘莫测的存在。勇敢地去修改你自己的 Git 配置文件吧!2
————
-
请注意,这其实不是我的
.gitignore文件。但已经很接近了,为了隐私安全和内容的清晰表达,我做了些内容调整和省略了部分内容。↩ -
需要强调一下,如果各位读者因为错误配置 Git 而遇到麻烦,我既不承担任何责任,也不承诺提供任何技术支持。但如果你在探索过程中有什么新奇的发现,不妨与我们留言分享一下!↩
文中链接
[2]docs.github.com/en/authenti…
[3]docs.github.com/en/authenti…
P.S. 原文作者没有审校过本译文,且译者在翻译本内容时带有个人对原文的理解。可能理解有误,麻烦请在评论区指出!