私の〜/ .gitconfigは次のとおりです。
[alias]
commit = "!sh commit.sh"
ただし、git commitと入力すると、スクリプトは呼び出されません。
それは可能ですか、それとも別のエイリアス名を使用する必要がありますか?
それは不可能です
これは私のgit.gitのクローンからのものです:
static int run_argv(int *argcp, const char ***argv)
{
int done_alias = 0;
while (1) {
/* See if it's an internal command */
handle_internal_command(*argcp, *argv);
/* .. then try the external ones */
execv_dashed_external(*argv);
/* It could be an alias -- this works around the insanity
* of overriding "git log" with "git show" by having
* alias.log = show
*/
if (done_alias || !handle_alias(argcp, argv))
break;
done_alias = 1;
}
return done_alias;
}
したがって、それは不可能です。 (コマンドが見つかった場合、handle_internal_command
はexit
を呼び出します)。
行の順序を変更し、エイリアスが見つかった場合はhandle_alias
がexit
を呼び出すことで、ソースでこれを修正できます。
すでに述べたように、gitエイリアスを使用してgitコマンドをオーバーライドすることはできません。ただし、シェルエイリアスを使用してgitコマンドをオーバーライドすることは可能です。 POSIXyシェル(つまり、MS cmd
ではない)の場合、目的の変更された動作を実行し、シェルエイリアスを設定する単純な実行可能スクリプトを記述します。私の.bashrc
(Linux)と.bash_profile
(Mac)には
export PATH="~/bin:$PATH"
...
alias git='my-git'
私の~/bin
フォルダーには、最初の引数(つまり、gitコマンド)がclone
であるかどうかをチェックするmy-git
という実行可能なPerlスクリプトがあります。基本的には次のようになります。
#!/usr/bin/env Perl
use strict;
use warnings;
my $path_to_git = '/usr/local/bin/git';
exit(system($path_to_git, @ARGV))
if @ARGV < 2 or $ARGV[0] ne 'clone';
# Override git-clone here...
鉱山はもう少し構成可能ですが、あなたはその考えを理解します。
私はこれをbash関数で解決することを選びました。 git clone
を呼び出すと、呼び出しがgit cl
にリダイレクトされます。これは、いくつかのスイッチが追加されたエイリアスです。
function git {
if [[ "$1" == "clone" && "$@" != *"--help"* ]]; then
shift 1
command git cl "$@"
else
command git "$@"
fi
}
不可能なだけでなく、WONTFIX
浜野さんの返信 :
現在、gitはエイリアスがビルトインをオーバーライドすることを許可していません。その理由は理解できますが、保守的すぎるのではないかと思います。
そうではない。
ほとんどのシェルはエイリアスを使用したコマンドのオーバーライドをサポートしており、なぜgitをシェルよりも保守的にする必要があるのかわかりません。
正気のシェルはスクリプトで使用されたときにエイリアスを展開せず、コマンドラインからでもエイリアスを無効にする便利な方法を提供するためです。
$ alias ls='ls -aF' $ echo ls >script $ chmod +x script
比較してください:
$ ./script $ ls $ /bin/ls
FWIW、私はこれを解決しました(わかりました、 "回避しました"...)次の~/bin/git
ラッパーを記述して、例:~/bin/git-clone
、および組み込みの代わりにthatを呼び出します。
[注:「巧妙な」bash-ismについてはお詫びしますが、2つのヘルパー関数(1つはシンボリックリンクを展開するため、もう1つは$ PATHでラップされている実行可能ファイルを検索するため)を通過した後、実際のスクリプト自体は3行になります。 Code™...だから、結局申し訳ありませんね、へぇ!]
#!/usr/bin/env bash
###########################
### UTILITY FUNCTIONS ### ...from my .bashrc
###########################
#
# deref "/path/with/links/to/symlink"
# - Returns physical path for specified target
#
# __SUPER__
# - Returns next "$0" in $PATH (that isn't me, or a symlink to me...)
deref() {
( # Wrap 'cd's in a sub-Shell
local target="$1"
local counter=0
# If the argument itself is a link [to a link, to a link...]
# NOTE: readlink(1) is not defined by POSIX, but has been shown to
# work on at least MacOS X, CentOS, Ubuntu, openSUSE, and OpenBSD
while [[ -L "$target" ]]; do
[[ $((++counter)) -ge 30 ]] && return 1
cd "${target%/*}"; target="$(readlink "$target")"
done
# Expand parent directory hierarchy
cd "${target%/*}" 2>/dev/null \
&& echo "$(pwd -P)/${target##*/}" \
|| echo "$([[ $target != /* ]] && echo "$(pwd -P)/")$target"
)
}
__SUPER__() {
local cmd="${1:-${0##*/}}"
local me="$(deref "$0")"
# NOTE: We only consider symlinks... We could check for hardlinks by
# comparing device+inode, but stat(1) has portability problems
local IFS=":"
for d in $PATH; do
[[ -x "$d/$cmd" ]] && [[ "$(deref "$d/$cmd")" != "$me" ]] \
&& { echo "$d/$cmd"; return; }
done
# else...
return 1
}
########################################################################
# (1) First, figure out which '$0' we *WOULD* have run...
GIT="$(__SUPER__)" || { echo "${0##*/}: command not found" >&2; exit 1; }
# (2) If we have a "~/bin/git-${command}" wrapper, then
# prepend '.../libexec/git-core' to $PATH and run it
[[ -f "${HOME}/bin/git-$1" ]] &&
PATH="$PATH:$( "$GIT" --exec-path )" \
exec "${HOME}/bin/git-$1" "${@:2}"
# (3) Else fall back to the regular 'git'
exec "$GIT" "$@"