【问题标题】:How to embed bash script directly inside a git alias如何将 bash 脚本直接嵌入到 git 别名中
【发布时间】:2010-11-21 12:28:21
【问题描述】:

我可以嵌入以下 bash shell 代码吗:

for name in $(git diff --name-only $1); do git difftool $1 $name & done

直接进入创建一个git别名:

git config --global alias.diffall ***my-bash-code-here***

这从我在 SO 上的 previous question/answer 引出,我将代码放入 .sh 文件,然后为该文件添加别名:

git config --global alias.diffall '!sh diffall.sh'

但是在对简单性的永无止境的追求中,总有一种方法可以跳过文件并将代码直接插入别名中吗?我无法弄清楚格式...

【问题讨论】:

    标签: git bash shell alias


    【解决方案1】:

    将这两行添加到您的 .git/config 文件中应该可以解决问题。

    [alias]
        diffall = '!for name in $(git diff --name-only $1); do git difftool $1 $name & done'
    

    编辑:大概 git-config 版本也可以,但我喜欢将我的别名保留在配置文件中以便于管理。

    git wiki 上有一个很好的页面,它非常清楚地解释了别名:http://git.or.cz/gitwiki/Aliases 特别是,请阅读“带参数的高级别名”

    【讨论】:

    • git config --global 会将您的别名存储在 $HOME/.gitconfig 上,其中(IMO)它们更易于管理;几乎没有别名需要特定于存储库。 (回购具体进入 repo/.git/config)
    • 谢谢大卫,但它对我不起作用 - 或者您包含的伟大链接中的任何变体。也许我应该提到我在 Windows 环境中运行?谢谢凯泽,同意,这对我来说是“全球性的”。
    • 如今,git.wiki.kernel.org/index.php/Aliases#Advanced 是一个值得一看的好地方。 (git 或 cz 链接重定向到那里,但本节特别提到了使用参数运行复杂的东西)
    【解决方案2】:
    git config --global alias.diffall '!sh diffall.sh'
    

    这在某种程度上是多余的。如果你无论如何都要把 'diffall.sh' 添加到你的 $PATH 中,为什么不把它保存为 'git-diffall',这样你就不用声明别名了。是的,“git diffall”会运行它。

    【讨论】:

    • 那个。是很棒的。我最初担心我会不小心运行某些东西,因为我已经编写了一些 shell 脚本来做 git 的东西,并给它们加上前缀 'git-',但是我的 shell (zsh) 不会自动完成它们,所以我会必须明确键入它们。如果我想要自动完成行为,我可以为其自己的子命令声明一个 git 别名,这也是我明确从脚本到子命令的链接的要求。
    • 是的,它是一个二进制文件,你只需要 bang:! binary
    • 对我不起作用,在别名 !sh git checkout $(git log --branches -1 --pretty=format:'%D' | sed 's/.*, //g') 中使用会导致 /usr/lib/git-core/git: /usr/lib/git-core/git: cannot execute binary file。在开始时尝试使用和不使用sh
    【解决方案3】:

    我在文档中找不到,但是如果您在路径中创建脚本“git-”,则可以在您的存储库中使用“git name”调用它。

    见:

    $ cd ~/bin
    $ echo "echo I love this log:
    >pwd
    >git log --graph  --summary --decorate --all" > git-logg
    $ chmod +x git-logg
    $ cd /path/to/your/repo
    $ git logg
    I love this log:
    /path/to/your/repo
    * commit 3c94be44e4119228cc681fc7e11e553c4e77ad04 (whatever-branch)
    | Author: myself <my@Laptop.(none)>
    | Date:   Fri Apr 1 16:47:20 2011 +0200
    | 
    |     would have been better not to do it at all
    | 
    ...
    $
    

    所以,你也可以用这种(相当晦涩的)方式编写任何你喜欢的别名。

    您还可以为定义函数的新命令添加自动完成功能。信息here

    $ _git_logg ()
    {
      # you can return anything here for the autocompletion for example all the branches
      __gitcomp_nl "$(__git_refs)" 
    }
    

    【讨论】:

    • +1,以为它只能在 git libexec 文件夹中工作。感谢分享这个技巧
    【解决方案4】:

    (来自 ProGit 文档:http://progit.org/book/ch7-3.html

    您是否尝试在 .git/hooks 中添加脚本?

    例如,如果你创建一个脚本 .git/hooks/post-checkout:

    #!/bin/bash
    
    echo "This is run after a 'git checkout'"
    

    然后运行命令:

    $ git checkout master
    Switched to branch 'master'
    This is run after a 'git checkout'
    

    【讨论】:

    • 钩子与配置、扩展和别名有什么关系?
    【解决方案5】:

    要在 git 别名中运行命令,尤其是向这些命令传递参数,您可能必须创建一个临时函数,然后立即调用:

    $ vim ~/.gitconfig
    ...
    [alias]
        # compare:
        foo = "! echo begin arg=$1/$2/end"
        foo2 = "!f() { echo "begin arg=$1/$2/end"; }; f"
    

    在这个例子中,这个函数可能是你所需要的(并且对于你可以在单个“语句”中做什么也更加灵活);您可能会说,对于这两个选项,git 命令的剩余参数只是作为参数传递给别名,无论它是“echo”还是“f”;调用该函数只会消耗 args,而忽略未明确使用的内容:

    $ git foo a b c
    begin arg=a/b/end a b c
    
    $ git foo2 a b c
    begin arg=a/b/end
    

    另一个示例(根据匹配模式列出所有别名)(注意:您可以在整个 .gitconfig 中继续重复使用相同的函数名称“f()”):

    [alias]
        alias = "!f() { git config --get-regexp "^alias.${1}$" ; }; f"
    

    第一个返回“foo$”的别名,第二个返回“foo.*”的别名:

    $ git alias foo
    alias.foo ! echo begin arg=$1/$2/end
    
    $ git alias 'foo.*'
    alias.foo ! echo begin arg=$1/$2/end
    alias.foo2 !f() { echo begin arg=$1/$2/end; }; f
    

    (注意:实际结果可能因 shell 而异;我在 Linux、Unix 和 Cygwin (Windows) 上将其与 bash 一起使用。)

    【讨论】:

    • git.wiki.kernel.org/index.php/Aliases#What.27s_new.3F 隐式推荐使用sh -c,这样你就不用担心用户的登录shell是什么了。
    • 我提供的函数语法有意可跨多个 shell (sh/ksh/bash/zsh) 移植,并且比启动子进程更快。我建议仍然使用函数语法,除非在特定平台上存在特定的可移植性问题。
    • 你的评论让我回到了这个答案,我可能会用你的方式。它节省了一级报价,而这些级别已经足够疯狂了。 :-)
    • 这篇文章看起来不错,描述了你在做什么:atlassian.com/blog/git/advanced-git-aliases
    • 注意:我已在此处发布了关于此答案的后续问题:stackoverflow.com/questions/52123145/…。 "如何用自定义别名替换内部 git 命令,例如git status"
    猜你喜欢
    • 2019-05-01
    • 2011-06-01
    • 2023-02-26
    • 1970-01-01
    • 2017-02-09
    • 2019-08-05
    • 1970-01-01
    • 1970-01-01
    • 2022-01-20
    相关资源
    最近更新 更多