如何将 bash 脚本直接嵌入到 git 别名中
Posted
技术标签:
【中文标题】如何将 bash 脚本直接嵌入到 git 别名中【英文标题】:How to embed bash script directly inside a git alias 【发布时间】: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'
但是在对简单性的永无止境的追求中,总有一种方法可以跳过文件并将代码直接插入别名中吗?我无法弄清楚格式...
【问题讨论】:
【参考方案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-
见:
$ 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
注意:我已在此处发布了关于此答案的后续问题:***.com/questions/52123145/…。 "如何用自定义别名替换内部 git 命令,例如git status
"以上是关于如何将 bash 脚本直接嵌入到 git 别名中的主要内容,如果未能解决你的问题,请参考以下文章