如何将bash脚本直接嵌入git别名中


82

我可以嵌入以下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的问题/答案开始,在该问题中,我将代码放入.sh文件中,然后将其别名为该文件:

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

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

Answers:


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

这是一种冗余。如果您仍然要将“ diffall.sh”添加到$ PATH中,为什么不将其另存为“ git-diffall”,并避免声明别名。是的,“ git diffall”将运行它。


1
那。是很棒的。我最初担心我会意外运行某些东西,因为我已经写了一些shell脚本来做git的工作,并且给他们加上前缀git-,但是我的shell(zsh)不能自动完成它们,所以我会必须明确输入它们。如果我想要自动完成行为,则可以为其自己的子命令声明一个git别名,这也是我使从脚本到子命令的链接明确的要求。
乔恩·卡特

1
是的,它是一个二进制文件,您只需要一! binary

1
不适用于我,在别名内部使用会!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 filesh在开始和否时都进行了尝试。
Hi-Angel

36

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

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

在此示例中,该功能可能就是您所需要的(并且在单个“语句”中可以执行的操作也更加灵活);并且您可能会发现,对于这两个选项,git命令中其余的args都将作为args传递给别名,无论它是“ 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

(nb:实际结果可能因外壳而异;我在Linux,Unix和Cygwin(Windows)上将它与bash一起使用。)


git.wiki.kernel.org/index.php/Aliases#What.27s_new.3F隐式建议使用sh -c,这样您就不必担心用户的登录shell是什么。
clacke

我提供的函数语法有意可移植到许多shell(sh / ksh / bash / zsh)中,并且比启动子进程要快。我建议仍然使用函数语法,除非在特定平台上存在特定的可移植性问题。
迈克尔

您的评论使我回到了这个答案,我可能会用你的方式。它节省了一个报价水平,而这些水平实际上已经足够疯狂了。:-)
clacke

这看起来像是一篇不错的文章,描述了您在做什么:atlassian.com/blog/git/advanced-git-aliases
Gabriel Staples

注意:我在这里发布了有关此答案的后续问题:stackoverflow.com/questions/52123145/…。“如何git status使用自定义别名替换内部git命令,例如”
Gabriel Staples

24

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

看到:

$ 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
| 
...
$

因此,您也可以使用这种(不太明显的)方式编写您喜欢的任何别名。

您甚至可以为该定义功能的新命令添加自动补全功能。这里的信息

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

+1,认为它只能在git libexec文件夹中工作。感谢您分享这个技巧
Olivier Refalo 2012年

14

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

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

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

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


git config --global会将您的别名存储在$ HOME / .gitconfig中,在这些别名中(IMO)它们更易于管理;几乎不需要别名是特定于存储库的。(特定于Repo进入repo / .git / config)
u0b34a0f6ae

谢谢大卫,但是对我来说这是行不通的-或您所包含的出色链接中的任何变化。也许我应该提到我在Windows环境中运行?感谢Kaizer,我同意这对我来说是“全球性”。
塞巴·伊林沃思

这些天来,git.wiki.kernel.org/index.php/Aliases#Advanced是一个不错的地方。(git或cz链接重定向到那里,但本节特别提到使用参数运行复杂的东西)
clacke

-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'

3
挂钩与配置,扩展名和别名有什么关系?
史蒂夫·布佐纳斯
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.