我想创建一个
sh
脚本来配置我所有的 git 别名。一些别名带有竖线 (|
) 和双引号 ("
)。我想在 ~/.gitconfig
文件中看到的输出是:
[alias]
assume = update-index --assume-unchanged
unassume = update-index --no-assume-unchanged
assumed = "!git ls-files -v | grep ^h | cut -c 3-"
但是,运行以下三个命令会产生错误的
assumed
条目:
# setup git aliases per: http://blog.apiaxle.com/post/handy-git-tips-to-stop-you-getting-fired/
git config --global alias.assume "update-index --assume-unchanged"
git config --global alias.unassume "update-index --no-assume-unchanged"
git config --global alias.assumed '"!git ls-files -v | grep ^h | cut -c 3-"'
第三个别名 (
assumed
) 有不需要的反斜杠:
assumed = \"!git ls-files -v | grep ^h | cut -c 3-\"
通过命令行配置别名的正确语法是什么?
所以命令是:
git config --global alias.assumed '!git ls-files -v | grep ^h | cut -c 3-'
"!..."
)作为别名值时,转义可能会很奇怪。当您想要编写应该引用某些内容的安全 shell 脚本时,问题会变得更加复杂。当您想要惰性/延迟执行命令时(其中 涉及将字符串评估/扩展为字符串,然后解释这些字符串,例如
eval
、子 shell 或其他)。这是一个例子,虽然有点做作,只是为了证明它并不简单。
\\"
不起作用,因为第一个反斜杠充当第二个反斜杠的转义字符。这留下了剩余的
"
,这实际上是错误的语法,因为它以 INI 格式关闭了整个别名(这与尝试编写
"
相同。
\\\"
在子 shell 中实现单个
"
文字。
\\>
可以实现“
>
”字符,但仅当在子 shell 中被文字引号包围时才有效,否则
>
可以工作。 (> 是 shell 解释器的一个特殊字符:重定向运算符,因此取决于上下文,例如
eval echo "\>"
、
echo \>
和
eval echo \\\>
与语法错误:
eval echo \>
)
\"$cmd\"
,引号将由 git 传递到 shell,然后 shell 将吞下它们作为正常“词法分词”的一部分。
.config/git
[alias]
escaping-characters-example = "!effect() { \
local timestamp=$(date +'%Y-%m-%dT%H-%M-%S'); \
local branch=${1-feat/NOISSUE/${timestamp}}; \
local path=${2-${timestamp}}; \
local base=${3-origin/main}; \
local cmd='git worktree add -b \"${branch}\" \"${path}\" \"${base}\"'; \
echo \\\"Fully surround me quotes ==\\> $cmd\\\"; \
echo \"After arrow quoted ==> \\\"$cmd\\\"\"; \
echo \"Suitable for lazy eval ==> $cmd\"; \
printf \"Print unexpanded cmd to pass to eval: \" && echo $cmd; \
printf \"Eval (expanded value; eval already applied split words lexically; quotes have been swallowed) ==> \" && eval echo $cmd; \
}; effect"
使用方法
$ git escaping-characters-example
"Fully surround me quotes ==> git worktree add -b "${branch}" "${path}" "${base}""
After arrow quoted ==> "git worktree add -b "${branch}" "${path}" "${base}""
Suitable for lazy eval ==> git worktree add -b "${branch}" "${path}" "${base}"
Print unexpanded cmd to pass to eval: git worktree add -b "${branch}" "${path}" "${base}"
Eval (expanded value; eval already applied split words lexically; quotes have been swallowed) ==> git worktree add -b feat/NOISSUE/2024-04-03T09-30-22 2024-04-03T09-30-22 origin/main
所有这些都可以在 Git 文档中作为使用示例或其他内容。因为每个人都使用他们想要的任何 shell(并且 shell 也是可配置的),所以它很快就会变得复杂。我不是那里的贡献者,我只是玩得很开心。