外壳变量在 git 配置中的扩展

我有一个 shell 变量,它指向所有配置文件所在的目录。让我们假设变量是用 export RC=$HOME/rc创建的。在配置目录中有一个全局忽略文件: ~/rc/globalgitignore

我的问题是,如何在 .gitconfig文件中展开 RC变量?

我已经试过以下方法了:

  • excludesfile = $RC/globalgitignore

  • excludesfile = !$RC/globalgitignore

  • excludesfile = !echo $RC/globalgitignore

  • excludesfile = !$(echo $RC/globalgitignore)

这些解决方案都不管用。

如果输入完整路径: excludesfile = ~/rc/globalgitignore,那么唯一的方法是,如果将 rc目录移动到另一个位置,则必须更改路径。

20542 次浏览

Git-config (1)不支持环境变量扩展,但只支持有限的类型转换和路径扩展:

类型说明符可以是—— int 或—— bool,以确保 git 配置中的变量是给定的类型,并将值转换为规范形式(对于 int 来说是简单的十进制数,对于 bool 来说是“ true”或“ false”字符串) ,或者是—— path,执行一些 路径扩展操作(参见下面的—— path)。如果传递了 没有类型说明符,则对值执行 没有检查或转换

--path的文件规定:

路径

Git-config 将 将 ~ 展开为 $HOME 的值,并将 ~ user 展开为指定用户的主目录。这个选项在设置值时没有任何效果(但是您可以从命令行使用 git config bla ~/来让 shell 执行展开)。

术语“扩展”在 git-config(1)中没有出现在任何不同的上下文中。那么,既然没有任何地方记录过这样的特性,您是如何得出这样的想法的呢?

为了展开环境变量,您必须自己对 Git 配置文件进行预处理,即创建一个模板文件,并在将文件复制到 $HOME目录之前用脚本展开变量。

如果是关于 dotfile 管理的,那么就像所有人一样: 将它们放在一个目录中,并从 $HOME向该目录添加符号链接。

我在配置中使用 bash 脚本来启用变量扩展。只需导出所需的变量即可。Bashrc 并在脚本中使用它:

在我的 ~/. bashrc:

export TESTVARIABLE="hello"

在我的 ~/. gitconfig 中:

[alias]
test = !bash -c '"echo \"Value: $TESTVARIABLE\";"'

在我的狂欢提示里:

bash> git test
Value: hello

另一种方法是在 shell 的 rc 中添加一个 git 配置命令。例如,我在我的。巴希尔:

git config --global user.name "$USER@$HOSTNAME"

我在所有机器上都有相同的配置,通过添加这个配置,我可以区分来自不同机器的提交。您也可以这样做,并向 shell rc 添加:

export RC="$HOME/rc"
git config --global core.excludesfile "$RC/globalgitignore"

使用 Git 2.31(Q12021) ,您可以考虑通过环境变量使用配置变量-值对(它调整了 GIT_CONFIG_PARAMETERS编码变量/值对的方式,使其更加健壮)。

提交 d8d7715提交 b9d147f承认吧提交 b342ae6犯罪(2021年1月12日)和 提交 b0812b6(2021年1月7日) by 帕特里克 · 斯坦哈特(pks-t)
提交 f9dbb64提交13c4495(2021年1月12日) by 杰夫 · 金(peff)
(由 朱尼奥 · C · 哈马诺 gitster第294季,第949集合并,2021年1月25日)

config : 添加通过 --config-env传递配置的新方法

合著者: Jeff King
签名: Patrick Steinhardt

虽然已经可以通过 git -c <key>=<value>(< a href = “ https://git-scm.com/docs/git # Document/git.txt-cltnamegtltvaluegt”rel = “ noReferrer”> man )传递运行时配置,但是当值包含敏感信息时可能不需要使用它。
例如。
如果希望将 http.extraHeader设置为包含身份验证令牌,那么通过 -c这样做将通过例如 ps(1)泄露这些凭据,ps(1)通常也显示命令参数。

为了在不泄漏凭据的情况下启用此用例,此提交引入了一个新的交换机 --config-env=<key>=<envvar>

它不是直接传递给定键的值,而是允许用户指定环境变量的名称。
然后,该变量的值将用作键的值。

git现在在其 手册中包括:

[--super-prefix=<path>] [--config-env <name>=<envvar>]

git现在在其 手册中包括:

--config-env=<name>=<envvar>

-c <name>=<value>一样,给配置变量 ‘ <name>’一个值,其中 <envvar>是 从中检索值的环境变量。

不像 -c没有直接将值设置为 空字符串,而环境变量本身必须是 设置为空字符串。

如果 <envvar>不存在,则为错误 <envvar>可能不包含等号 避免与包含一个。

这对于希望传递临时信息的情况非常有用 配置选项的 git,但这样做的操作系统的地方 其他进程可能能够读取您的 cmdline (例如 /proc/self/cmdline) ,但不包括你所在的环境 (例如 /proc/self/environ)。
该行为是 Linux,但可能不在您的系统上。

注意,这可能会增加变量的安全性,例如 其中敏感信息是 http.extraHeader的一部分 值,但不是例如 url.<base>.insteadOf,其中 敏感信息可能是关键的一部分。

对于您的情况,可以使用以下方法进行测试:

git --config-env=core.excludesfile=RC config core.excludesfile
# or (Git 2.32+ only)
git --config-env core.excludesfile=RC config core.excludesfile

core.excludesfile的值应该是 $RC(它应该引用完整的文件路径,而不仅仅是它的父文件夹)


注意: 在 Git 2.32之前(2021年第二季度) ,“ git --config-env var=val cmd(< a href = “ https://git-scm.com/docs/git # Document/git.txt--config-envltnamegtltenvvargt”rel = “ noReferrer”> man )没有接受(只有 --config-env=var=val被接受)。

提交 c331551提交9152904(2021年4月29日) by 帕特里克 · 斯坦哈特(pks-t)
(由 朱尼奥 · C · 哈马诺 gitster于2021年5月7日在 犯下5f586f5合并)

git : 为 --config-env的值支持单独的 arg

签名: Patrick Steinhardt
审核人: Jeff King

虽然没有这样的文档说明,但是许多顶级选项,如 --git-dir--work-tree,支持两种语法: 它们接受 option 和它的值之间的等号,并且它们支持 option 和 value 作为两个单独的参数。
最近添加的 --config-env选项只支持等号语法。

通过接受两种语法并添加验证两种工作的测试来减轻这种不一致性。


但 Git 2.31还有更多内容:

config : 允许通过 envvar 对指定配置条目

签名: Patrick Steinhardt

虽然我们目前有 GIT_CONFIG_PARAMETERS环境变量,可以用来将运行时配置数据传递给 git 进程,但它是一个内部实现细节,最终用户不应该使用它。

除了仅供内部使用外,这种传递配置条目的方式还有一个主要缺点: 需要解析配置键,因为它们在单个变量中同时包含键和值。
因此,由用户来转义值中任何潜在的有害字符,如果值由第三方控制,这是很难做到的。

因此,这个提交添加了一种通过环境添加配置条目的新方法,从而消除了这个缺点。
如果用户通过了 GIT_CONFIG_COUNT=$n环境变量,Git 将解析 [0,n)中每个 i的环境变量对 GIT_CONFIG_KEY_$iGIT_CONFIG_VALUE_$i

虽然同样可以实现与 git -c <name>=<value>(< a href = “ https://git-scm.com/docs/git # Document/git.txt-cltnamegtltvaluegt”rel = “ noReferrer”> man ),人们可能希望不这样做,为潜在的敏感信息。
例如。
如果希望将 http.extraHeader设置为包含身份验证令牌,那么通过 -c这样做将通过例如 ps(1)泄露这些凭据,ps(1)通常也显示命令参数。

git config现在在其 手册中包括:

GIT_CONFIG_COUNT

GIT_CONFIG_KEY_<n>

GIT_CONFIG_VALUE_<n>

如果将 GIT_CONFIG_COUNT设置为正数,则所有环境对 GIT_CONFIG_KEY_<n>GIT_CONFIG_VALUE_<n>到这个数字为 添加到进程的运行时配置中。

配置对是零索引的。
任何丢失的键或值都被视为错误。 空的 GIT_CONFIG_COUNTGIT_CONFIG_COUNT=0的处理方式相同,即 no 成对处理。
这些环境变量将重写值 但是将被任何显式选项覆盖 通过 git -c

这对于希望产生多个 git 命令的情况非常有用 但不能依赖于配置文件, 例如在写脚本的时候。

例如:

    GIT_CONFIG_COUNT=2 \
GIT_CONFIG_KEY_0="pair.one" GIT_CONFIG_VALUE_0="foo" \
GIT_CONFIG_KEY_1="pair.two" GIT_CONFIG_VALUE_1="bar" \
git config --get-regexp "pair.*"

将刊登:

pair.one foo
pair.two bar