以下是我正在编辑的配置的摘录。这位于[alias]
的{{1}}部分:
.gitconfig
我基本上试图将ignored = !git ls-files -v | grep "^S"
status-with-ignored = "!f() { git status; ignored=$(git ignored | cut -d ' ' -f 2 | sed -e s/^/z/ -e s/$/z/); [ -n \"$ignored\" ] && echo \"git skip-worktree (ignored):\n$ignored\"; };f"
的输出着色,因为我将它粘贴到git状态的末尾。我上面显示的工作正常,但如果我的git ignored
命令里面有任何括号(对于构建正则表达式非常有用),它不起作用(fatal: bad config file line 18 in ~/.gitconfig
)。
例如,我希望能够编写具有parens的内容,例如sed
而不是sed s/^(.*)$/z\1z/
。
由于我会使用sed -e s/^/z/ -e s/$/z/
,\x1b[31m
等来实现颜色化,但您明白了这一点。
我尝试过一个,两个,三个和四个反斜杠以逃避这些问题,但没有任何效果。
答案 0 :(得分:3)
这里有一些单独的问题:一个是你的配置转义,一个是sed
中的括号,另一个是git别名中的<(date)
进程替换。
首先,bad config file
的问题不是命令替换,而是你的换行符。
[YOURS] status-with-ignored = "!f() { git status; ignored=$(git ignored | cut -d ' ' -f 2 | sed -e s/^/z/ -e s/$/z/); [ -n \"$ignored\" ] && echo \"git skip-worktree (ignored):\n$ignored\"; };f"
[MINE] status-with-ignored = "!f() { git status; ignored=$(git ignored | cut -d ' ' -f 2 | sed -e s/^/z/ -e s/$/z/); [ -n \"$ignored\" ] && echo \"git skip-worktree (ignored):\\n$ignored\"; };f"
您的\n
似乎被解释为应用于配置文件;这是需要逃避的部分,而不是任何与人有关的事情。
我通过让bash
和git config
为我处理转义,然后用cut " "
代替' '
来获得上述内容:
git config alias.status-with-ignored '!f() { git status; ignored=$(git ignored | cut -d " " -f 2 | sed -e s/^/z/ -e s/$/z/); [ -n "$ignored" ] && echo "git skip-worktree (ignored):\n$ignored"; };f'
(如果你想聪明一点escaping single quotes within bash
single quotes,你可以,但对我来说,它可以有效地防止可读性。)
其次,Bash和其他shell无法处理未加引号的括号。这不是git别名特有的,这只是解析规则。
echo I am (Batman) # Doesn't work
echo I am Batman # Does work
后者有效;蝙蝠侠没有parens。
您可以转义括号或引用字符串:
echo "I am (Batman)" # Works
echo I am \(Batman\) # Also works
将您的配置文件保留为:
status-with-ignored = "!f() { git status; ignored=$(git ignored | cut -d ' ' -f 2 | sed -e \"s/^(.*)$/z\1z/\"); [ -n \"$ignored\" ] && echo \"git skip-worktree (ignored):\\n$ignored\"; };f"
或者你的git config
语句如下:
git config alias.status-with-ignored '!f() { git status; ignored=$(git ignored | cut -d " " -f 2 | sed -e "s/^(.*)$/z\1z/"); [ -n "$ignored" ] && echo "git skip-worktree (ignored):\n$ignored"; };
最后,似乎git alias
只是不处理进程替换。来自the git config
man page:
参数按空格分隔,支持通常的shell引用和转义。引号对或反斜杠可用于引用它们。
看起来git正在使用sh
或它自己的解析,而不是调用bash
本身,因为本地不支持non-portable bash extension进程替换。你可以抨击bash:
git config alias.sample '!cat <(seq 3)'; git sample
git config alias.sample '!bash -c "cat <(seq 3)"'; git sample
...但此时您可能只是make a script named git-status-with-ignored
and add it to your path。