为接受 N 个任意“-m”参数的“git commit”创建别名

AF7*_*AF7 3 alias eval fish

使用 Fish shell,我想创建一个函数 ( gcom) 用作命令的别名git commit,接受任意数量的字符串参数并将它们作为-m选项传递,以便
git commit -m "a" -m "b" -m "c"可以写成,简而言之,gcom "a" "b" "c".

gcom函数应接受 N 个参数,并git command使用相应的 N 个-m选项运行。

这可以通过数组上的循环来完成$argv,使用 手动构建命令string join并使用 执行此类命令eval

然而,这看起来很笨重,我很想找到一个更时尚的替代品。

如果附加gcom -?选项不加修改地通过就更好了!

fah*_*aho 5

git commit -mfoo使用“foo”作为消息,因此您可以简单地为每个参数添加前缀-m

function gcom
    git commit -m$argv
end
Run Code Online (Sandbox Code Playgroud)

由于 $argv 是一个列表,这将为其中的每个参数添加“-m”。

与其他 shell 不同,这里没有分词。$argv 不按空格分割,$argv 是给出的所有参数的列表。所以它适用于空格、换行符等。参数只需要在你给它们的地方加引号即可gcom

gcom "first argument with spaces" "second"\n"argument"\n"with"\n"newlines"
Run Code Online (Sandbox Code Playgroud)

将运行相当于

git commit -m"first argument with spaces" -m "second
argument
with
newlines"
Run Code Online (Sandbox Code Playgroud)

尝试一下printf

set -l mylist "first argument with spaces" "second"\n"argument"\n"with"\n"newlines"
printf '<%s>\n' -m$mylist
Run Code Online (Sandbox Code Playgroud)

将打印

<-mfirst argument with spaces>
<-msecond
argument
with
newlines>
Run Code Online (Sandbox Code Playgroud)

如果额外的 gcom - 就更好了?选项未经修改地通过!

如果您想这样做,您可以将所有以 $args 开头的参数保留-在附加的 $args 列表中,而不添加-m. 如果任何选项本身带有参数,例如 ,这就会被破坏--author

想一想:

gcom --author "mycoolemail@example.com" these are my message words
Run Code Online (Sandbox Code Playgroud)

这应该像这样执行

git commit --author mycoolemail@example.com -m these -m are -m my -m message -m words
Run Code Online (Sandbox Code Playgroud)

但要弄清楚“mycoolemail@example.com”属于--author并因此不应该有对应的唯一方法-m是知道--author需要选项。

为此,您可以使用 Fish 的argparse内置函数,并且您必须告诉它所有 git-commit 的选项。这就像

function gcom
    # The part before the `--` are descriptions for the options that git-commit takes
    # A "=" means that the option takes a mandatory argument and so it can be written like "--author foo",
    # A "=?" means it takes an optional argument and needs to be written like "-ufoo".
    argparse author= a interactive patch s v 'u=?' -- $argv

    # Argparse leaves all the non-option arguments in $argv.
    # For each option it gives you a $_flag_option variable,
    # but that only includes the *value* for the options that take arguments
    #
    # If we wanted to pass all --author= options we could use the `string split -m1` trick from above,
    # but here we assume that only the last --author is of use.
    #
    # This needs to be done for all the options that take arguments,
    # simple boolean flags are just stored as the flags
    # - `$_flag_patch` will contain "--patch"
    set -l flags $_flag_a $_flag_interactive $_flag_patch
    if set -q _flag_author
        set -a flags --author $_flag_author[-1]
    end
    if set -q _flag_u
        set -a flags -u$_flag_u[-1]
    end

    # [ now do the -m trick with the leftover $argv ]
    # ...
    git commit $flags -m$argv
end
Run Code Online (Sandbox Code Playgroud)

不幸的是,没有办法列出所有带参数的选项,因为否则选项的参数会与普通的消息参数混淆。鱼在这里根本无法做任何事情,这就是参数解析的工作原理。

可以运行argparse --ignore-unknown,这会告诉 argparse 在 $argv 中留下未知选项,然后仍然跳过以-. 如果您曾经传递过一个选项组(想想ls -lah,它有三个短选项)并且最后一个选项带有一个参数,但您之前没有列出其中一个选项,那么这将会中断。

因为如果你没有告诉它“-s”存在的话,鱼就无法弄清楚eg的-sFfile意思-s -F=file——因为它不知道不-s带任何选项。如果是的话,这将与 相同-s=Ffile。所以只能让整个集团完好无损。