如何在另一个配置值中引用一个.gitconfig
配置值?
.gitconfig
[filter "myFilter"]
foo = Hello world
bar = echo $(git config filter.myFilter.foo)
重击
$(git config filter.myFilter.bar)
# should print "Hello world"
我正在尝试编写一些smudge
/ clean
过滤器(例如latest commit),以便在签出时将tabsize设置为4个空格,并在提交时将其还原到仓库中已有的内容。
SO答案表明:
git config --global filter.tabspace.smudge 'unexpand --tabs=4' git config --global filter.tabspace.clean 'expand --tabs=4'
或等效的.gitconfig
文件:
[filter "tabspace"] smudge = 'unexpand --tabs=4' clean = 'expand --tabs=4'
如果您知道所有远程回购都使用选项卡,则此方法很好。我想对此进行概括(并在此过程中,进一步了解git config
),以便我可以设置一个值,而~/.gitconfig
中的值将完成其余工作。
我的~/.gitconfig
看起来像
#...
[filter "tabspace"]
repoTabs = false
repoTabSize = 4
smudge = # TODO
clean = # TODO
#...
当我克隆一个使用制表符或非4个空格的仓库时,我会运行
# for repos that use tabs
git config filter.tabspace.repoTabs true
# for repos that use 2 spaces
git config filter.tabspace.repoTabSize 2
,然后在.git/info/attributes
创建一个看起来像
*.js filter=tabspace
*.jsx filter=tabspace
*.ts filter=tabspace
*.tsx filter=tabspace
*.json filter=tabspace
我要用于smudge
和clean
的脚本应该相对简单一些(我在~/.gitconfig
文件中将它们分别写成一行,代替了两者) # TODO
s)
# smudge
if [ `#filter.tabspace.repoTabs` == true ]; then
expand --tabs=4
else
unexpand --tabs=`#filter.tabspace.repoTabSize` | expand --tabs=4
fi
# clean
if [ `#filter.tabspace.repoTabs` == true ]; then
unexpand --tabs=4
else
unexpand --tabs=4 | expand --tabs=`#filter.tabspace.repoTabSize`
fi
我一生无法弄清的是如何在脚本中使用filter.tabspace.repoTabs
和filter.tabspace.repoTabSize
的值。
我的测试方法是设置smudge = #my-script-here
,然后运行
$(git config filter.tabspace.smudge)
其中#my-script-here
就像echo $(git config filter.tabspace.repoTabSize)
一样,尝试了多次以单引号,双引号,转义双引号和反引号代替$()
来包围值的各个部分。我尝试过的所有操作都会对$(git config filter.tabspace.repoTabSize)
进行字面评估,或者会完全失败。
我也尝试过简单地使用repoTabSize
,希望它只是插入作用域变量,但是没有这种运气。
作为健全性检查:
git config filter.tabspace.repoTabSize 2
echo $(git config filter.tabspace.repoTabSize)
# prints
2
我还检查了将值传递到if
语句中是否满足我的需要,假设git checkout
和git commit
通过filter.tabspace.smudge
的值通过管道传递文件和filter.tabspace.clean
。
echo -e '\t'foo | if [ true ]; then expand --tabs=4; fi
# prints (with 4 spaces):
foo
答案 0 :(得分:0)
这是非常冗长的,所以我仍然想要一个更好的答案,但是使用eval
和一些转义的双引号可以实现我想要的。
在我的部分解决方案脚本中,我需要替换:
`#filter.tabspace.repoTabs` -> $(eval "git config filter.tabspace.repoTabs")
`#filter.tabspace.repoTabSize` -> $(eval "git config filter.tabspace.repoTabSize")
然后,我需要将值包装在双引号中-这也意味着在eval
表达式中转义双引号。
最终结果:
[filter "tabspace"]
repoTabs = false
repoTabSize = 4
smudge = "if [ $(eval \"git config filter.tabspace.repoTabs\") == true ]; then expand --tabs=4; else unexpand --tabs=$(eval \"git config filter.tabspace.repoTabSize\") | expand --tabs=4; fi"
clean = "if [ $(eval \"git config filter.tabspace.repoTabs\") == true ]; then unexpand --tabs=4; else unexpand --tabs=4 | expand --tabs=$(eval \"git config filter.tabspace.repoTabSize\"); fi"
顺便说一句,所引用的SO问题的答案并没有提供强制运行污迹的好方法。 This answer更好。
警告:如果您有未提交的文件,请不要这样做。
rm .git/index
git checkout HEAD -- "$(git rev-parse --show-toplevel)"
答案 1 :(得分:0)
这是比其他任何事情都更重要的shell编程问题。
请注意,git config --get
会给您返回退出代码以告诉您是否设置了某些内容:
$ git config --get branch.master.merge; echo $?
refs/heads/master
0
$ git config --get branch.master.marge; echo $?
1
您可以添加--default <value>
,但这会使退出代码无效:
$ git config --get --default simpson branch.master.marge; echo $?
simpson
0
还有git config --get -t <type> <name>
,它根据提供的类型将实际设置转换为适当的值并产生该值,或产生错误(至stderr)并以失败退出并退出:
$ git config --get -t bool core.bare; echo $?
false
0
$ git config --get -t bool branch.master.merge; echo $?
fatal: bad numeric config value 'refs/heads/master' for 'branch.master.merge' in file .git/config: invalid unit
128
因此,在shell脚本中,您可以简单地测试是否根据您的决定来设置值,或者在尝试时使用单独的布尔值:
#! /bin/sh
do_tabs=$(git config --get -t bool --default false filter.tabspace.repotabs) || exit
if $do_tabs; then
tabsize=$(git config --get -t int --default 8 filter.tabspace.repotabsize) || exit
fi
或:
#! /bin/sh
tabsize=$(git config --get -t int filter.tabspace.size)
case $? in
0) do_tabs=true;;
1) do_tabs=false;;
*) exit;;
esac
现在,无论哪种方式,您都有两个变量可以捕获期望值(“我们应该做这个制表符吗?”)和(如果是$ do_tabs)实际大小,因此现在您可以编写:
case "#1" in)
--smudge) is_smudge=true;;
--clean) is_smudge=false;;
*) echo "run with --smudge or --clean"; exit 1;;
esac
if $is_smudge; then
if $do_tabs; then
expand --$tabsize
fi
else
...
fi
(以明显的方式填写其余部分)。生成的脚本可以通过以下方式调用:
[filter "tabspace"]
smudge = script_name --smudge
clean = script_name --clean
参数($1
)确定操作模式,这两个设置来自配置文件,脚本根据需要读取stdin并写入stdout。
不过,我没有尝试再现您的完整代码,因为这里有些奇怪的事情:
unexpand --tabs = 4 |展开--tabs = [此处为任何数字]
unexpand
程序将适当地用制表符替换前导空格,四个空格变成一个制表符,8变成2,依此类推; expand
随后将替换为一定数量的空格。如果--tabs=
的数字也为4,那么整个事情就不算大了。但是,如果--tabs=
不同,则会使用仅空间文件(这似乎是您在所有工作树文件中所期望的文件),并在它们出现时更改个数是领先的空间。这似乎很奇怪。以系统其余部分通常期望的方式在每8个位置将硬标签放入文件中是否更有意义?如果是这样,则所有--unexpand
调用都应该没有参数,并且--expand
也不能带有参数,因为工作树中的文件始终只包含空格。