【问题标题】:Git Alias - Multiple Commands and ParametersGit Alias - 多个命令和参数
【发布时间】:2011-11-23 22:52:26
【问题描述】:

我正在尝试创建一个同时使用多个 Git 命令和位置参数的别名。每个都有 Stackoverflow 页面,两者都做显然很痛苦,但我遇到了麻烦。

例如,我想切换到分支 foo 并执行一个状态。所以在我的.gitconfig 中,我有:

  [alias] 
     chs = !sh -c 'git checkout $0 && git status'

这是行不通的。而这样的事情会起作用。

chs = !sh -c 'git checkout $0'

echoes = !sh -c 'echo hi && echo bye'

任何见解将不胜感激。

【问题讨论】:

  • 我的别名:git config --global alias.go '!git commit -a && git pull --rebase && git push && git status'。注意:使用简单的引号。

标签: git sh alias git-alias


【解决方案1】:

这将起作用(用 zsh 和 bash 测试):

[alias] chs = !git checkout $1 && git status

【讨论】:

  • 不,不会的。 Git 会将git chs foo 转换为git checkout && git status foo
  • 有趣的是,git 实际上确实在 shell 别名中填充了位置变量。但它仍然被打破,因为它也将它们作为论据。 echo $1 && echo done 的别名,当使用参数 'foo' 调用时,将输出“foo”和“done foo”。
  • 哇...不幸的是,这都是版本问题。我使用的是 Git 1.7.3,但这些方法都不起作用。我更新到 1.7.6,瞧,一切正常。谢谢大家!
  • 第一次调用git时,前面的感叹号是什么意思?
  • @ElijahLynn:在 git 别名中,前导 ! 表示将整个内容传递给 shell。否则,它假定您正在尝试运行另一个 git 命令并将其作为参数传递给 git 二进制文件。
【解决方案2】:

你可以定义一个shell函数。

[alias] chs = "!f(){ git checkout \"$1\" && git status; };f"

【讨论】:

  • 我在另一个 stackoverflow 页面上看到了这个,但是我的 cygwin 终端说当我尝试运行它时无法识别该函数。
  • @Stella:我在那里留下了一个结束引号,这个配置文件语法没有用。确保你没有它。
  • 哇...不幸的是,这都是版本问题。我使用的是 Git 1.7.3,但这些方法都不起作用。我更新到 1.7.6,瞧,一切正常。谢谢大家!
  • 如果使用 Windows 我认为你必须用双引号括住 shell 函数定义 "
  • 奥利维尔的回答对我使用参数(OSX)不起作用。这非常有效。
【解决方案3】:
[alias]
chs = !git branch && git status

【讨论】:

  • ! 是干什么用的?
  • 我找不到 ! 的文档,但据我所知,git 默认会假定别名是 git 命令,所以 t = status 可以工作。但是,如果您尝试t = git status,它将无法正常工作(会说“git”命令未找到)。这样在! 出现的地方,它会告诉它像运行shell 一样运行命令,通常当每个别名有多个git 命令时你需要这个,所以你可以拥有t = !git status && git log,它会工作。
  • 这是一个 StackOverflow 问题,处理 Git 别名中的感叹号 (!):stackoverflow.com/questions/21083933/…
  • 如果别名扩展以感叹号为前缀,将被视为shell命令git-scm.com/docs/git-config
【解决方案4】:

试试这个:

[alias]
    chs = "!sh -c 'git checkout \"$0\" && git status'"

这样称呼它:git chs master

【讨论】:

    【解决方案5】:

    可以通过在每行末尾附加 \ 来获得多行 git 别名。

    [alias] 
       chs = "!git checkout $1 \ 
              ; git status     \
             "
    

    【讨论】:

    • 谢谢!实际上,我使用 "!git fetch --prune --all; git pull --rebase upstream master; git push origin master" 作为我的别名没有问题。
    【解决方案6】:

    这里的问题是位置参数似乎被发送到 shell 命令两次(从 gi​​t 1.9.2 开始)。要明白我的意思,试试这个:

    [alias]
      test = !git echo $*
    

    然后,执行git test this is my testing string。您应该观察以下输出(为清楚起见,此处编辑了最后两行):

    03:41:24 (release) ~/Projects/iOS$ git test this is my testing string
    this is my testing string this is my testing string
    ^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^
              #1                         #2
    

    解决这个问题的一种方法是

    [alias]
      chs = !git checkout $1 && git status && git echo x >/dev/null
    

    这将消耗额外的位置参数,因为它被应用于最后一个回显命令并且对结果没有影响。

    【讨论】:

    • 您的示例将扩展为: git echo 这是我的测试字符串 这是我的测试字符串 在末尾添加 # 将修复它(不要忘记命令别名周围的双引号)。
    • 在 .gitconfig 中: a0 = "!echo $*" 和 a1 = "!echo $* #" 。测试它们: git a0 hallo daar ; git a1 你好 daar
    【解决方案7】:

    这针对 Windows 批处理/msysgit bash;可能不适用于其他环境。

    正如 Olivier Verdier 和 Lily Ballard 所说

    [alias] chs = !git checkout $1 && git status

    几乎可以工作,但会提供一个虚假的额外参数插入...

    git chs demo -> git checkout demo && git status demo

    但是,如果您将&& : 添加到别名的末尾,则虚假参数将被消耗到位置标记中。

    所以

    [alias] chs = !git checkout $1 && git status && :
    

    给出正确的输出... git chs demo -> git checkout demo && git status

    【讨论】:

    • && : 是金子,使此解决方案适用于额外参数可能有问题的命令。
    • @Clay(或其他任何人) - 有人可以向 BASH 挑战者解释 && : 做了什么吗?
    • @JustinMorgan && 表示如果前面的命令变为 0(成功),则在 && 之后运行命令。 ':',冒号,是一个 shell 内置命令,除了扩展参数和执行重定向并返回状态 0 之外什么都不做。这里有一些用法: 1. a=123;$a 错误,但 a=123; : $a 没有。 2.: > hello.txt清空hello.txt。 3. if [ "$a" = "hello" ];then : ;fi 运行正常,但没有':'时出错。这就像 python 中的pass。 4.: this is a comment,冒号后跟空格在注释行中作为#
    • 这是一个 hack...git 应该接受多个命令模式
    • @kchoi 如此真实 :) 然而,它似乎是社区非常重视的黑客攻击:D
    【解决方案8】:

    我能够创建多行且相当复杂的 git 别名。它们在 Windows 上运行良好,但我认为它们也可以在其他地方运行,例如:

    safereset = "!f() { \
                    trap 'echo ERROR: Operation failed; return' ERR; \
                    echo Making sure there are no changes...; \
                    last_status=$(git status --porcelain);\
                    if [[ $last_status != \"\" ]]; then\
                        echo There are dirty files:;\
                        echo \"$last_status\";\
                        echo;\
                        echo -n \"Enter Y if you would like to DISCARD these changes or W to commit them as WIP: \";\
                        read dirty_operation;\
                        if [ \"$dirty_operation\" == \"Y\" ]; then \
                            echo Resetting...;\
                            git reset --hard;\
                        elif [ \"$dirty_operation\" == \"W\" ]; then\
                            echo Comitting WIP...;\
                            git commit -a --message='WIP' > /dev/null && echo WIP Comitted;\
                        else\
                            echo Operation cancelled;\
                            exit 1;\
                        fi;\
                    fi;\
                }; \
                f"
    

    我写了一个帖子,还有几个例子here

    【讨论】:

    • 对此的一个改进是添加 !f() { : reset 以从重置命令 github.com/git/git/blob/master/contrib/completion/… 获得完成
    • 干得好!那篇文章是根据什么许可证发表的?你介意我把它的一部分翻译成俄语的 StackOverflow 吗?
    • @NickVolynkin 抱歉回复晚了。谢谢你,当然,继续:)
    • @NickVolynkin,你最终翻译了吗?
    【解决方案9】:

    想尝试不同别名的人的示例。

    把它放在 GIT 配置文件的别名部分(例如~/.gitconfig):

    [alias]
        a0 = "!echo $*"
        a1 = "!echo $* #"
        a2 = "!f () { echo \"$*\"; }; f "
        a3 = "!f () { echo \"$*\"; }; f #"
        a4 = "!f () { echo \"$*\"; }; f \"$*\" #"
        a5 = "!f () { echo \"$*\"; }; f \"$@\" #"
        a6 = "!f () { echo \"$*\"; }; f \"$1\" #"
    

    然后执行这个命令:

    cat ~/.gitconfig | grep --extended-regexp -- '(a[0-9])|(alias)' ; \
    echo "" ; \
    export CMD ; \
    for I in {0..6} ; \
    do \
        CMD="a""${I}" ; \
        echo -n "Executing alias.${CMD} = " ; \
        git config --global alias."${CMD}" ; \
        git $CMD 'hoi daar' en nu ; \
        git $CMD hoi daar en nu ; \
        echo "" ; \
    done ; \
    unset CMD ;
    

    应该将此作为输出:

    [alias]
        a0 = "!echo $*"
        a1 = "!echo $* #"
        a2 = "!f () { echo \"$*\"; }; f "
        a3 = "!f () { echo \"$*\"; }; f #"
        a4 = "!f () { echo \"$*\"; }; f \"$*\" #"
        a5 = "!f () { echo \"$*\"; }; f \"$@\" #"
        a6 = "!f () { echo \"$*\"; }; f \"$1\" #"
    
    Executing alias.a0 = !echo $*
    hoi daar en nu hoi daar en nu
    hoi daar en nu hoi daar en nu
    
    Executing alias.a1 = !echo $* #
    hoi daar en nu
    hoi daar en nu
    
    Executing alias.a2 = !f () { echo "$*"; }; f 
    hoi daar en nu
    hoi daar en nu
    
    Executing alias.a3 = !f () { echo "$*"; }; f #
    
    
    
    Executing alias.a4 = !f () { echo "$*"; }; f "$*" #
    hoi daar en nu
    hoi daar en nu
    
    Executing alias.a5 = !f () { echo "$*"; }; f "$@" #
    hoi daar en nu
    hoi daar en nu
    
    Executing alias.a6 = !f () { echo "$*"; }; f "$1" #
    hoi daar
    hoi
    

    【讨论】:

      【解决方案10】:
      [alias]
            chs = !git checkout && git status
            ac = !git add . && git commit -m 
      

      什么是! ?

      如果别名扩展以感叹号为前缀,它将被视为 shell 命令。 What does the exclamation mark mean in git config alias?

      从 .gitconfig 文件中调用别名

      git chs
      git ac "write_your_commit_message" 
      

      alias 对 git 中的 add 和 commit 更有用,你可以做得更快

      【讨论】:

        猜你喜欢
        • 2017-05-13
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-11-30
        • 2019-08-26
        • 1970-01-01
        • 1970-01-01
        • 2023-03-11
        相关资源
        最近更新 更多