-
A1. 附录 A:其他环境下的 Git
- A1.1 图形界面
- A1.2 Visual Studio 中的 Git
- A1.3 Visual Studio Code 中的 Git
- A1.4 IntelliJ / PyCharm / WebStorm / PhpStorm / RubyMine 中的 Git
- A1.5 Sublime Text 中的 Git
- A1.6 Bash 中的 Git
- A1.7 Zsh 中的 Git
- A1.8 PowerShell 中的 Git
- A1.9 总结
-
A2. 附录 B:在你的应用中嵌入 Git
-
A3. 附录 C:Git 命令
10.8 Git 内部原理 - 环境变量
环境变量
Git 总是运行在 bash
shell 中,并且使用一些 shell 环境变量来决定它的行为。有时,了解这些变量以及如何使用它们来使 Git 按照您想要的方式运行会很有用。这不是 Git 关注的所有环境变量的详尽列表,但我们将介绍最有用的变量。
全局行为
Git 作为计算机程序的某些通用行为取决于环境变量。
GIT_EXEC_PATH
决定了 Git 在哪里查找其子程序(例如 git-commit
、git-diff
等)。您可以通过运行 git --exec-path
来检查当前设置。
HOME
通常不被认为是可自定义的(太多其他的东西依赖于它),但它是 Git 查找全局配置文件的位置。如果您想要一个真正可移植的 Git 安装,并具有完整的全局配置,您可以在可移植 Git 的 shell 配置文件中覆盖 HOME
。
PREFIX
类似,但用于系统范围的配置。 Git 在 $PREFIX/etc/gitconfig
中查找此文件。
GIT_CONFIG_NOSYSTEM
,如果设置,则禁用系统范围的配置文件的使用。如果您的系统配置干扰了您的命令,但您无法访问更改或删除它,这将非常有用。
GIT_PAGER
控制用于在命令行上显示多页输出的程序。如果未设置,则将使用 PAGER
作为后备。
GIT_EDITOR
是用户需要编辑一些文本时(例如提交消息)Git 将启动的编辑器。如果未设置,将使用 EDITOR
。
仓库位置
Git 使用多个环境变量来确定它如何与当前仓库交互。
GIT_DIR
是 .git
文件夹的位置。如果未指定,Git 将向上遍历目录树,直到到达 ~
或 /
,并在每一步查找 .git
目录。
GIT_CEILING_DIRECTORIES
控制搜索 .git
目录的行为。如果您访问加载速度慢的目录(例如磁带驱动器上的目录或通过慢速网络连接的目录),您可能希望 Git 比其他情况下更早地停止尝试,特别是当在构建 shell 提示符时调用 Git 时。
GIT_WORK_TREE
是非裸仓库的工作目录根目录的位置。如果指定了 --git-dir
或 GIT_DIR
,但未指定 --work-tree
、GIT_WORK_TREE
或 core.worktree
中的任何一个,则当前工作目录被视为工作树的顶层。
GIT_INDEX_FILE
是索引文件的路径(仅限非裸仓库)。
GIT_OBJECT_DIRECTORY
可以用来指定目录的位置,该目录通常位于 .git/objects
。
GIT_ALTERNATE_OBJECT_DIRECTORIES
是一个以冒号分隔的列表(格式如 /dir/one:/dir/two:…
),它告诉 Git 如果在 GIT_OBJECT_DIRECTORY
中找不到对象,应该在哪里查找。如果你有许多项目,其中包含具有完全相同内容的大文件,可以使用此变量来避免存储过多的副本。
Pathspecs(路径规范)
“pathspec”指的是你在 Git 中指定事物路径的方式,包括使用通配符。 这些用于 .gitignore
文件中,也用于命令行中(git add *.c
)。
GIT_GLOB_PATHSPECS
和 GIT_NOGLOB_PATHSPECS
控制路径规范中通配符的默认行为。 如果 GIT_GLOB_PATHSPECS
设置为 1,通配符将充当通配符(这是默认设置); 如果 GIT_NOGLOB_PATHSPECS
设置为 1,通配符仅匹配自身,这意味着像 *.c
这样的表达式只会匹配 命名为 “\*.c”的文件,而不是任何名称以 .c
结尾的文件。 你可以通过以 :(glob)
或 :(literal)
开始路径规范来覆盖单个实例中的这种行为,如 :(glob)\*.c
。
GIT_LITERAL_PATHSPECS
禁用上述两种行为; 没有通配符会起作用,并且覆盖前缀也被禁用。
GIT_ICASE_PATHSPECS
设置所有路径规范以不区分大小写的方式工作。
提交
Git 提交对象的最终创建通常由 git-commit-tree
完成,它使用这些环境变量作为其主要信息来源,只有在这些变量不存在时才回退到配置值。
GIT_AUTHOR_NAME
是 “author” 字段中可读的名称。
GIT_AUTHOR_EMAIL
是 “author” 字段的电子邮件地址。
GIT_AUTHOR_DATE
是用于 “author” 字段的时间戳。
GIT_COMMITTER_NAME
设置 “committer” 字段的人员姓名。
GIT_COMMITTER_EMAIL
是 “committer” 字段的电子邮件地址。
GIT_COMMITTER_DATE
用于 “committer” 字段中的时间戳。
EMAIL
是备用电子邮件地址,以防未设置 user.email
配置值。 如果 *这个* 没有设置,Git 将回退到系统用户和主机名。
网络
Git 使用 curl
库通过 HTTP 执行网络操作,因此 GIT_CURL_VERBOSE
告诉 Git 发出该库生成的所有消息。 这类似于在命令行上执行 curl -v
。
GIT_SSL_NO_VERIFY
告诉 Git 不要验证 SSL 证书。 如果你正在使用自签名证书通过 HTTPS 提供 Git 存储库,或者你正在设置 Git 服务器但尚未安装完整的证书,有时这是必要的。
如果 HTTP 操作的数据速率低于每秒 GIT_HTTP_LOW_SPEED_LIMIT
字节的时间超过 GIT_HTTP_LOW_SPEED_TIME
秒,Git 将中止该操作。 这些值会覆盖 http.lowSpeedLimit
和 http.lowSpeedTime
配置值。
GIT_HTTP_USER_AGENT
设置 Git 在通过 HTTP 通信时使用的用户代理字符串。 默认值类似于 git#2.0.0
。
差异和合并
GIT_DIFF_OPTS
有点用词不当。 唯一有效的值是 -u<n>
或 --unified=<n>
,它控制 git diff
命令中显示的上下文行数。
GIT_EXTERNAL_DIFF
用作 diff.external
配置值的覆盖。 如果设置了它,Git 将在调用 git diff
时调用此程序。
从 GIT_EXTERNAL_DIFF
或 diff.external
指定的程序内部,GIT_DIFF_PATH_COUNTER
和 GIT_DIFF_PATH_TOTAL
非常有用。 前者表示正在差异化的一系列文件中的哪个文件(从 1 开始),后者是批处理中文件的总数。
GIT_MERGE_VERBOSITY
控制递归合并策略的输出。 允许的值如下:
-
0 不输出任何内容,除了可能的一条错误消息。
-
1 仅显示冲突。
-
2 还显示文件更改。
-
3 显示由于文件未更改而被跳过的文件。
-
4 显示处理时的所有路径。
-
5 及以上显示详细的调试信息。
默认值为 2。
调试
想 *真正* 了解 Git 在做什么? Git 嵌入了一套相当完整的跟踪功能,你所需要做的就是打开它们。 这些变量的可能值如下:
-
“true”、“1” 或 “2” – 跟踪类别被写入 stderr。
-
以
/
开头的绝对路径 – 跟踪输出将被写入该文件。
GIT_TRACE
控制一般跟踪,这些跟踪不属于任何特定类别。 这包括别名的扩展以及委派给其他子程序。
$ GIT_TRACE=true git lga
20:12:49.877982 git.c:554 trace: exec: 'git-lga'
20:12:49.878369 run-command.c:341 trace: run_command: 'git-lga'
20:12:49.879529 git.c:282 trace: alias expansion: lga => 'log' '--graph' '--pretty=oneline' '--abbrev-commit' '--decorate' '--all'
20:12:49.879885 git.c:349 trace: built-in: git 'log' '--graph' '--pretty=oneline' '--abbrev-commit' '--decorate' '--all'
20:12:49.899217 run-command.c:341 trace: run_command: 'less'
20:12:49.899675 run-command.c:192 trace: exec: 'less'
GIT_TRACE_PACK_ACCESS
控制对 packfile 访问的跟踪。 第一个字段是被访问的 packfile,第二个字段是该文件中的偏移量。
$ GIT_TRACE_PACK_ACCESS=true git status
20:10:12.081397 sha1_file.c:2088 .git/objects/pack/pack-c3fa...291e.pack 12
20:10:12.081886 sha1_file.c:2088 .git/objects/pack/pack-c3fa...291e.pack 34662
20:10:12.082115 sha1_file.c:2088 .git/objects/pack/pack-c3fa...291e.pack 35175
# […]
20:10:12.087398 sha1_file.c:2088 .git/objects/pack/pack-e80e...e3d2.pack 56914983
20:10:12.087419 sha1_file.c:2088 .git/objects/pack/pack-e80e...e3d2.pack 14303666
On branch master
Your branch is up-to-date with 'origin/master'.
nothing to commit, working directory clean
GIT_TRACE_PACKET
为网络操作启用数据包级别的跟踪。
$ GIT_TRACE_PACKET=true git ls-remote origin
20:15:14.867043 pkt-line.c:46 packet: git< # service=git-upload-pack
20:15:14.867071 pkt-line.c:46 packet: git< 0000
20:15:14.867079 pkt-line.c:46 packet: git< 97b8860c071898d9e162678ea1035a8ced2f8b1f HEAD\0multi_ack thin-pack side-band side-band-64k ofs-delta shallow no-progress include-tag multi_ack_detailed no-done symref=HEAD:refs/heads/master agent=git#2.0.4
20:15:14.867088 pkt-line.c:46 packet: git< 0f20ae29889d61f2e93ae00fd34f1cdb53285702 refs/heads/ab/add-interactive-show-diff-func-name
20:15:14.867094 pkt-line.c:46 packet: git< 36dc827bc9d17f80ed4f326de21247a5d1341fbc refs/heads/ah/doc-gitk-config
# […]
GIT_TRACE_PERFORMANCE
控制性能数据的日志记录。 输出显示每个特定 git
调用花费的时间。
$ GIT_TRACE_PERFORMANCE=true git gc
20:18:19.499676 trace.c:414 performance: 0.374835000 s: git command: 'git' 'pack-refs' '--all' '--prune'
20:18:19.845585 trace.c:414 performance: 0.343020000 s: git command: 'git' 'reflog' 'expire' '--all'
Counting objects: 170994, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (43413/43413), done.
Writing objects: 100% (170994/170994), done.
Total 170994 (delta 126176), reused 170524 (delta 125706)
20:18:23.567927 trace.c:414 performance: 3.715349000 s: git command: 'git' 'pack-objects' '--keep-true-parents' '--honor-pack-keep' '--non-empty' '--all' '--reflog' '--unpack-unreachable=2.weeks.ago' '--local' '--delta-base-offset' '.git/objects/pack/.tmp-49190-pack'
20:18:23.584728 trace.c:414 performance: 0.000910000 s: git command: 'git' 'prune-packed'
20:18:23.605218 trace.c:414 performance: 0.017972000 s: git command: 'git' 'update-server-info'
20:18:23.606342 trace.c:414 performance: 3.756312000 s: git command: 'git' 'repack' '-d' '-l' '-A' '--unpack-unreachable=2.weeks.ago'
Checking connectivity: 170994, done.
20:18:25.225424 trace.c:414 performance: 1.616423000 s: git command: 'git' 'prune' '--expire' '2.weeks.ago'
20:18:25.232403 trace.c:414 performance: 0.001051000 s: git command: 'git' 'rerere' 'gc'
20:18:25.233159 trace.c:414 performance: 6.112217000 s: git command: 'git' 'gc'
GIT_TRACE_SETUP
显示有关 Git 正在发现的有关存储库及其交互环境的信息。
$ GIT_TRACE_SETUP=true git status
20:19:47.086765 trace.c:315 setup: git_dir: .git
20:19:47.087184 trace.c:316 setup: worktree: /Users/ben/src/git
20:19:47.087191 trace.c:317 setup: cwd: /Users/ben/src/git
20:19:47.087194 trace.c:318 setup: prefix: (null)
On branch master
Your branch is up-to-date with 'origin/master'.
nothing to commit, working directory clean
杂项
如果指定了 GIT_SSH
,则在 Git 尝试连接到 SSH 主机时,将调用该程序而不是 ssh
。 它的调用方式为 $GIT_SSH [username@]host [-p <port>] <command>
。 请注意,这并不是自定义如何调用 ssh
的最简单方法; 它不支持额外的命令行参数。 要支持额外的命令行参数,你可以使用 GIT_SSH_COMMAND
,编写一个包装脚本并将 GIT_SSH
设置为指向它,或使用 ~/.ssh/config
文件。
GIT_SSH_COMMAND
设置 Git 尝试连接到 SSH 主机时使用的 SSH 命令。 该命令由 shell 解释,并且可以将额外的命令行参数与 ssh
一起使用,例如 GIT_SSH_COMMAND="ssh -i ~/.ssh/my_key" git clone git@example.com:my/repo
。
GIT_ASKPASS
是 core.askpass
配置值的覆盖。 每当 Git 需要向用户询问凭据时,都会调用此程序,该程序可以期望文本提示作为命令行参数,并且应该在 stdout
上返回答案(有关此子系统的更多信息,请参阅凭据存储)。
GIT_NAMESPACE
控制对命名空间引用的访问,等同于 --namespace
标志。 这主要在服务器端有用,你可能希望在一个存储库中存储单个存储库的多个分支,仅保持引用分开。
GIT_FLUSH
可用于强制 Git 在以增量方式写入 stdout 时使用非缓冲 I/O。 值为 1 会导致 Git 更频繁地刷新,值为 0 会导致所有输出都被缓冲。 如果未设置此变量,则默认值是根据活动和输出模式选择合适的缓冲方案。
GIT_REFLOG_ACTION
允许你指定写入 reflog 的描述性文本。 这是一个例子:
$ GIT_REFLOG_ACTION="my action" git commit --allow-empty -m 'My message'
[master 9e3d55a] My message
$ git reflog -1
9e3d55a HEAD@{0}: my action: My message