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

我是否可以嵌入以下 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***

这是从我的 上一题/答案开始的,我把代码放到了。Sh 文件,然后别名为该文件:

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

但是在对简单性永无止境的追求中,必须有一种方法可以跳过文件并直接将代码插入到别名中?我不知道怎么安排。

37222 次浏览

Adding these 2 line to your .git/config file should do the trick.

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

Edit: presumably the git-config version works too, but I like to keep my aliases in the config file for ease of management.

There is a nice page on the git wiki that explains aliases very clearly: http://git.or.cz/gitwiki/Aliases In particular, read 'advanced aliases with arguments'

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

This is redundant in one way. If you are going to add 'diffall.sh' into your $PATH anyway, why not save it as 'git-diffall', and save yourself from declaring an alias. Yes, "git diffall" will run it.

I couldn't find in documentation, but if you create a script "git-<name>" in path, you can call it with "git name" in your repo.

See:

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

So, you can write any alias you like with this (rather obscure) way too.

Even more you can add autocompletion to that new command defining a function. Info here

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

(From ProGit documentation: http://progit.org/book/ch7-3.html)

Have you tried to add a script in .git/hooks?

For example, if you create a script .git/hooks/post-checkout:

#!/bin/bash


echo "This is run after a 'git checkout'"

and then run the command:

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

To run commands inside of a git alias, and in particular to pass arguments to those commands, you will likely have to create a temporary function which you then immediately invoke:

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

In this example, the function is probably what you need (and is also more flexible as to what you can do in a single "statement"); and you can probably tell that for both options, the remaining args to the git command are simply passed as args to the alias, regardless if it's "echo" or "f"; invoking the function simply consumes the args, ignoring what's not explicitly used:

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


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

Another example (lists all aliases, based on matching pattern) (note: you can keep reusing the same function name "f()" throughout the .gitconfig):

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

The first returns the alias for just "foo$", the second for "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: actual results may vary based on shell; I'm using this with bash on Linux, Unix & Cygwin (Windows).)