Git

git clone 時に秘密鍵を指定する

git の支援が弱くて変なやり方しかない。

EDIT: git 2.3 以降で GIT_SSH_COMMAND というのが生えて、

GIT_SSH_COMMAND="ssh -i ~/.ssh/id_rsa_example -F /dev/null" git clone example

のように鍵を指定できるようになりました :tada:

.ssh/config をいじる

.ssh/config を1瞬いじって元に戻す、みたいな

~/.ssh/config
Host github.com
    User git
    IdentityFile ~/.ssh/deploy_key

絶対にやりたくない

.ssh/config に別 Host として登録する

~/.ssh/config
Host deploy1
  Hostname github.com
  User git
  IdentityFile ~/.ssh/deploy1_key

Host deploy2
  Hostname github.com
  User git
  IdentityFile ~/.ssh/deploy2_key

で、git clone の時は Host 名を指定する

$ git clone deploy1:organization/repository
$ git clone deploy2:organization/repository

とはいえ deploy key ごとに .ssh/config にエントリを増やしたくない。

GIT_SSH を使う

こんなスクリプトを作って、

git-ssh.sh
#!/bin/sh
exec ssh -oIdentityFile=~/.ssh/deploy_key "$@"

GIT_SSH 環境変数に指定する。

$ GIT_SSH=git-ssh.sh git clone git@github.com:...

とはいえ deploy key ごとに git-ssh スクリプトを作りたくはない。
※ GIT_SSH に指定するスクリプトに引数を指定したかったが、ダメ

git wrapper

なのでこんな git ラッパーを作るかんじになった。

git-ssh.sh
#!/bin/bash

usage_exit() {
    echo "Usage: $0 [-i identity_file] -- [GIT ARGUMENTS]" 1>&2
    exit 1
}

while getopts i:h OPT
do
    case $OPT in
        i) IDENTITY_FILE=$OPTARG
           ;;
        h) usage_exit
           ;;
    esac
done
shift $((OPTIND - 1))

if [ -n "$IDENTITY_FILE" ]; then
    tempfile=$(mktemp --dry-run)
    cat <<EOF > $tempfile
#!/bin/sh
exec ssh -oIdentityFile=${IDENTITY_FILE} "\$@"
EOF
    chmod a+x $tempfile
    GIT_SSH=$tempfile git $@
    rm -f $tempfile
else
    git $@
fi

これを使うと

$ git-ssh.sh -i ~/.ssh/deploy_key -- clone git@github.com:....

と出来るようになる。