LoginSignup
43

More than 5 years have passed since last update.

もっと怠惰に Git を使うシェルの設定でもっとラクをする、あるいは賢い st の話。そしておまけ。

Last updated at Posted at 2012-06-25

Git Advent Calendar / Jun. 22日目の記事です。21日目はgit最強のオプション filter-branchでした。

gst には怠惰さが足りない

さて、12日目に怠惰にgitを使うためのシェル活用術、またはgst一族という記事がありました。これ、僕に言わせればまだ怠惰さが足りません。 alias gst='git status' などを設定すると便利という内容なのですが、 gst は長い。3文字です。g を取って st でいいじゃん。 gb も g を取って b でいいじゃん。

こう反論する向きもあるかもしれません。「自分は Mercurial や Subversion も使っていて alias hst='hg status'; alias sst='svn status' と設定している。区別と統一性のために g が必要なのだ。てゆーか短いエイリアスってヤじゃね」

でもやっぱり gst は長い。3文字です。カレントリディレクトリが Git リポジトリなのか Mercurial リポジトリなのかは明らかですから、人間様がプレフィクスをつけて gst やら hst やら使い分けなくても、コマンドの側が空気を読んでくれないものでしょうか。

たとえば、こんな st コマンドを想像してみてください。Git リポジトリの中で st と叩けば git status になり、 Mercurial リポジトリの中で st すれば hg status になる。 Subversion リポジトリの中での st は当然 svn status を実行する。コンピュータと言えどそれくらいの融通は利いてくれてもいいと思いませんか。

思いませんか、と自分の MacBook に語り掛けてみてもヨシきたお前さんの言うとおりにしてやらあと袖まくりしてくれるわけではないので、てやんでいべらぼうめとか言いながら自分で Zsh スクリプトを書きました。

この csa.zsh を使うと上述の賢い st が実現できます。

賢い st の使い方

賢い st はこんな具合に賢いです。


# Git リポジトリに cd すると st == git status になる
$ cd ~/git-repo
$ st
## master
?? hoge

# 引数も普通に渡せる
$ st --ignored
## master
!! .DS_Store
?? hoge

# Mercurial リポジトリに cd すると st == hg status になる
$ cd ~/hg-repo
$ st
? fuga

# リポジトリでないディレクトリでは st は未定義
$ cd ~/not-a-repo
$ st
zsh: command not found: st

.zshrc の設定はだいたいこんな感じです。

.zshrc

# csa.zsh を読み込む
source csa.zsh

# 初期化する
# (csa_init 以降 alias コマンドが正しく動かなくなるので、
# これ以下の設定は .zshrc の終わりあたりに書くとよい)
csa_init

# エイリアスを定義する
# csalias <ctx> <alias> <cmd>
#     ctx  : コンテキストを表す任意の文字列
#     alias: エイリアス名
#     cmd  : エイリアスに割り当てるコマンド
csalias ctx_git st 'git status -sb'
csalias ctx_hg  st 'hg  status'
csalias ctx_svn st 'svn status'

# ディレクトリを移動したときコンテキストが設定されるようにする
# (chpwd という名前の関数は、 cd したとき必ず呼ばれる)
function chpwd() {
    # カレントディレクトリがどの種類のリポジトリか判別し、
    # それに合わせてコンテキストを選ぶ
    local -a ctx
    if [[ -n `git rev-parse --is-inside-work-tree 2> /dev/null` ]]; then
        ctx+=ctx_git
    elif [[ -n `hg root 2> /dev/null` ]]; then
        ctx+=ctx_hg
    elif [[ -d .svn ]]; then
        ctx+=ctx_svn
    fi

    # コンテキストを設定する
    # csa_set_context [<ctx> [<ctx> …]]
    #     ctx: コンテキストを表す任意の文字列
    csa_set_context $ctx
}

これで st の2文字さえ覚えればどのリポジトリでもステータスを表示できるようになりました。 gsthstsst の計9文字を使い分けていたのに比べると、覚えるべき文字数を78%も削減できたことになります。

僕は他にも以下のような設定をしています。1文字エイリアスこそ怠惰の極みです。

.zshrc

csalias ctx_git b 'git branch'
csalias ctx_git c 'git commit'
csalias ctx_git d 'git diff'
csalias ctx_git l 'git log --decorate'
csalias ctx_git m 'git merge --no-ff'
# hg と svn の設定は略

まだまだ怠惰さが足りない?

と、作るには作ってみましたが、他に活用できる場面を思いつきません。怠惰さが足りないのかもしれません。以前書いた記事を焼き直してこの記事を仕立てる程度の怠惰さでは不足なのでしょうか。

僕よりも怠惰な皆さんはこのスクリプトのうまい活用法をきっと見つけてくれるものと信じています。あるいは怠惰道を極め、念じるだけで st できる手段を編み出してください。以上です。

追伸

ほとんど宣伝だし使い回しだし Git の話もしてないと書き上げてから気づいたので、適当に便利そうな小ネタをおまけしてお茶を濁すことにします。

insteadOf

.gitconfig に

.gitconfig

[url "git@github.com:USERNAME/"]
    insteadof = gh:

こう書いておくと gh:repo で GitHub にある自分の repo リポジトリにアクセスできます。 git clone gh:repo とか git push gh:repo master とか。便利ですね。

pushInsteadOf

GitHub にあるリポジトリには様々なプロトコルでアクセスできます:

  • https://github.com/USERNAME/repo.git
  • git://github.com/USERNAME/repo.git
  • git@github.com:USERNAME/repo.git

上の2つはリードオンリーなため、 push するとエラーが表示されます。


$ git push origin master  # (origin == git://github.com/USERNAME/repo.git)
fatal: remote error: 
  You can't push to git://github.com/USERNAME/repo.git
  Use git@github.com:USERNAME/repo.git

コミット権限のないリポジトリをリードオンリーな URL から clone したけれど、後からやっぱりコミッタになった、というときは origin の URL を設定し直さなければならず不便ですね。

ところが pushInsteadOf を使うと push 先の URL を書き換えることができます。

.gitconfig

[url "git@github.com:"]
    pushinsteadof = "https://github.com/"
    pushinsteadof = "git://github.com/"

こう設定しておくだけで、 git://github.com/... への push が git@github.com:... への push に置き換わります。


$ git push origin master  # (origin == git://github.com/USERNAME/repo.git)
Everything up-to-date

便利ですね。

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
43