読者です 読者をやめる 読者になる 読者になる

コマンドラインで git を使う人に一度試して欲しい SCM Breeze

https://github.com/ndbroadbent/scm_breeze

頭おかしいほど作りこまれた SCM (今は git だけ)用 CLI サポートシェルスクリプトruby スクリプト群です。ぜひ一度体験してみてください。久々に作り手の生の情熱を感じます。

必要

ruby は 1.8 で試しました。 2.0 だと gs コマンドで文字コードに関するエラーが出ました。自分 ruby に明るくないので詳しく追いかけていません。

インストール

$ git clone git://github.com/ndbroadbent/scm_breeze.git ~/.scm_breeze
$ ~/.scm_breeze/install.sh
$ source ~/.bashrc   # or source ~/.zshrc

個人用設定

.git.scmbrc で、各機能へのエイリアスや、環境の設定ができます。必ず弄る必要があるのは、後で出てくる一箇所です。

.git.scmbrc
#
# Git File Shortcuts Config
# ----------------------------------------------
# - Set your preferred prefix for env variable file shortcuts.
#   (I chose 'e' because it is easy to slide your finger to it from '$'.)
export git_env_char="e"
# - Max changes before reverting to 'git status'. git_status_shortcuts() may slow down for lots of changes.
export gs_max_changes="99"
# - When using the git_add_shorcuts() command, automatically invoke 'git rm' to remove deleted files?
export ga_auto_remove="yes"
 
 
# Git Index Config
# ----------------------------------------------
# Repos will be automatically added from this directory.
# export GIT_REPO_DIR="$HOME/code"
export GIT_REPO_DIR="/home/oogatta/git"
# Add the full paths of any extra repos to GIT_REPOS, separated with ':'
# e.g. "/opt/rails/project:/opt/rails/another project:$HOME/other/repo"
export GIT_REPOS=""
export git_status_command="git_status_shortcuts"
# Alias
git_index_alias="c"    # Switch to a repo in the (c)ode directory
 
 
# Git Aliases
# ----------------------------------------------
git_alias="g"
 
# 1. 'SCM Breeze' functions
git_status_shortcuts_alias="gs"
git_add_shortcuts_alias="ga"
git_add_patch_shortcuts_alias="gap"
git_show_files_alias="gsf"
exec_git_expand_args_alias="ge"
# 2. Commands that handle paths (with shortcut args expanded)
git_checkout_alias="gco"
git_checkout_branch_alias="gcob"
git_commit_alias="gc"
git_reset_alias="grs"
git_reset_del_alias="grs-"
git_reset_hard_alias="grsh"
git_rm_alias="grm"
git_blame_alias="gbl"
git_diff_alias="gd"
git_diff_cached_alias="gdc"
# 3. Standard commands
git_clone_alias="gcl"
git_fetch_alias="gf"
git_fetch_all_alias="gfa"
git_fetch_and_rebase_alias="gfr"
git_pull_alias="gpl"
git_push_alias="gps"
git_pull_then_push_alias="gpls"
git_status_original_alias="gst"
git_status_short_alias="gss"
git_clean_alias="gce"
git_clean_force_alias="gcef"
git_add_all_alias="gaa"
git_commit_all_alias="gca"
git_commit_amend_alias="gcm"
git_commit_amend_no_msg_alias="gcmh"
git_commit_no_msg_alias="gch"
git_remote_alias="gr"
git_branch_alias="gb"
git_branch_all_alias="gba"
git_rebase_alias="grb"
git_rebase_alias_continue="grbc"
git_rebase_alias_abort="grba"
git_merge_alias="gm"
git_cherry_pick_alias="gcp"
git_log_alias="gl"
git_log_stat_alias="gls"
git_log_graph_alias="glg"
git_show_alias="gsh"
 
 
# Git Keyboard Shortcuts
# ----------------------------------------------
# Keyboard shortcuts are on by default. Set this to 'false' to disable them.
git_keyboard_shortcuts_enabled="true"
git_commit_all_keys="\C-x "        # CTRL+x, SPACE
git_add_and_commit_keys="\C-xc"    # CTRL+x, c
 
 
# Bash Command Wrapping
# ----------------------------------------------
# Expand numbered args for common bash commands
bash_command_wrapping_enabled="true"

リポジトリインデックス機能

リポジトリの間を縦横無尽に飛び回る機能。

まず、いつの間にか作られている ~/.git.scmbrc を自分の環境に合わせて編集します。とはいえ一行だけ。

~/.git.scmbrc
export GIT_REPO_DIR="/home/oogatta/git"

次にリポジトリのインデックスを作成します。これはリポジトリ構成が変わらない限り一度だけ。

$ c --rebuild

これで $GIT_REPO_DIR 以下のリポジトリがインデックスされます。結果として、

$ c ame[TAB]

で ame から始まるリポジトリが補完され( americanbeauty とする)、補完させた後に ENTER すると、

$ c americanbeauty
# On branch: master  |  [*] => $e*
#
➤ Untracked files
#
#      untracked: [1] test.txt 
#
$ pwd
/home/oogatta/git/americanbeauty

americanbeauty リポジトリに cd された上、ワーキングツリーが dirty の場合、現在 HEAD が向いているブランチが表示され、 git status の結果がなぜかちょっと美しく実行されます。

$ c americanbeauty/[TAB]

とすると、 americanbeauty リポジトリのワーキングツリーからディレクトリが補完候補に出てきて、どんなところからも直接任意のリポジトリの任意のサブディレクトリに移動できます。

また、リポジトリ名は一意にさえなればどんな省略名称でもよく、 americanbeauty というレポジトリには、

$ c merica
$ c nbeau
$ c beauty

などで移動できます。

ファイルショートカット機能

add や commit 、 rebase など、ファイルを対象にした操作をファイル名の入力無しに行える機能です。

まず、対象のリポジトリで gs ( git_status_shortcuts_alias 関数)を実行します。

$ c americanbeauty
$ gs
# On branch: oogatta-dev  |  +1  |  [*] => $e*
#
➤ Untracked files
#
#      untracked:  [1] bertha 
#      untracked:  [2] bill 
#      untracked:  [3] boby 
#      untracked:  [4] chinacat 
#      untracked:  [5] jerry 
#      untracked:  [6] magnolia 
#      untracked:  [7] phil 
#      untracked:  [8] playing 
#      untracked:  [9] sugaree 
#      untracked: [10] terrapin 
#

これで、環境変数 $e1 から $e10 にファイル名が積み込まれます。恐るべき所業です。従って、ここから bill 、 jerry 、 phill だけを add する場合。

$ ga $e2 $e5 $e7

と打つと add できますが、この環境変数の指定も省略でき、

$ ga 2 5 7
# add '/home/oogatta/git/americanbeauty/bill'
# add '/home/oogatta/git/americanbeauty/jerry'
# add '/home/oogatta/git/americanbeauty/phil'
#
# On branch: oogatta-dev  |  +1  |  [*] => $e*
#
➤ Changes to be committed
#
#       new file:  [1] bill 
#       new file:  [2] jerry 
#       new file:  [3] phil 
#
➤ Untracked files
#
#      untracked:  [4] bertha 
#      untracked:  [5] boby 
#      untracked:  [6] chinacat 
#      untracked:  [7] magnolia 
#      untracked:  [8] playing 
#      untracked:  [9] sugaree 
#      untracked: [10] terrapin 
#

と出来ます。これでまた環境変数が書き換わりました。

数字の指定は範囲指定もできるので、今 add した3ファイルを reset してみます。

$ grs 1-3

何も出ませんが、

$ gs
# On branch: oogatta-dev  |  +1  |  [*] => $e*
#
➤ Untracked files
#
#      untracked:  [1] bertha 
#      untracked:  [2] bill 
#      untracked:  [3] boby 
#      untracked:  [4] chinacat 
#      untracked:  [5] jerry 
#      untracked:  [6] magnolia 
#      untracked:  [7] phil 
#      untracked:  [8] playing 
#      untracked:  [9] sugaree 
#      untracked: [10] terrapin 
#

gs で reset されたことを確認できました。
その他ファイルを扱うコマンドは全てこのファイルショートカットが使えます。

diff
$ gd 5
gco
$ gco 10

など。

ちなみに、このファイルショートカットが使えるのはもちろん SCM Breeze が提供する関数だけですが、一般のコマンドにもショートカットのまま渡したい場合のために、 ge ( exec_git_expand_args 関数)があります。

$ echo $e1
/home/oogatta/git/americanbeauty/bertha
$ ge echo 1
/home/oogatta/git/americanbeauty/bertha
$ ge cat 1-3
(省略)

キーボードショートカット機能

今のところ使えるショートカットは2つ。

  • Ctrl+x c ( git_add_and_commit 関数) : add して commit する
  • Ctrl+x SPACE ( git_commit_all 関数) : 全部 commit する

今後増える予定で、 vi スタイルもサポートしていきたい、とソースには書いてありました。

後者は見ての通りやっての通りですが、前者で対象ファイルを指定する場合は、

$ 1-3 <Ctrl+x c>

とします。すると結果として git_add_and_commit 1-3 が入力され、

$&#160; git_add_and_commit 1-3 
# add '/home/oogatta/git/americanbeauty/bertha'
# add '/home/oogatta/git/americanbeauty/bill'
# add '/home/oogatta/git/americanbeauty/boby'
#
# On branch: oogatta-dev&#160; |&#160; +1&#160; |&#160; [*] => $e*
#
&#10148; Changes to be committed
#
#&#160;&#160;&#160;&#160;&#160;&#160; new file:&#160; [1] bertha 
#&#160;&#160;&#160;&#160;&#160;&#160; new file:&#160; [2] bill 
#&#160;&#160;&#160;&#160;&#160;&#160; new file:&#160; [3] boby 
#
Commit Message:

とコミットメッセージ入力待ちとなりますので。入力してコミットします。メッセージを空にするとコミットを abort できます。

$ gl
commit 755fafadbd6106077c92a20007a68e5b31b4dee1
Author: oogatta <oogatta@gmail.com>
Date:&#160;&#160; Wed May 2 13:05:49 2012 +0900
&#160;
&#160;&#160;&#160;&#160;日本語コミットメッセージ

コミットされました。

コマンド一覧

キー 内部関数 概要
c git_index リポジトリインデックス機能の大元
g git "git" コマンドのショートカット
gs git_status_shortcuts git status 兼ファイルショートカット機能のスタート
ga git_add_shortcuts 強化版 git add (無くなってるファイルは git rm してくれたりする) && gs
gap git_add_patch_shortcuts git add -p && gs
gsf git_show_affected_files git show 兼ファイルショートカット環境変数出力
ge exec_git_expand_args ファイルショートカットを展開して一般コマンドに渡し実行
gco ge git checkout
gcob git checkout -b
gc ge git commit
grs ge git reset
grs- ge git reset -- (ステージしてしまったファイル削除の、対象を指定した取り消しに使う)
grsh ge git reset --hard
grm ge git rm
gbl ge git blame
gd ge git diff
gdc ge git diff --cached
gcl git clone
gf git fetch
gfa git fetch --all
gfr git fetch && git rebase
gpl git pull
gps git push
gpls git pull && git push
gst git status (何もしない標準の git status )
gss git status -s
gce git clean
gcef git clean -fd
gaa git add -A
gca git_commit_all 全てコミット
gcm git commit --amend
gcmh git commit --amend -C HEAD
gch git commit -C HEAD
gr git remote -v
gb git branch
gba git branch -a
grb git rebase
grbc git rebase --continue
grba git rebase --abort
gm git merge
gcp git cherry-pick
gl git log
gls git log --stat --max-count=5
glg git log --graph --max-count=5
gsh git show

リソースファイル連携

psd などのファイルを Dropbox で共有し、そのディレクトリを上記のリポジトリインデックスと結びつける機能(別に Dropbox とは限らない、結果としてはディレクトリにシンボリックリンクを張るだけ)。

つまり americanbeauty/design_assets から ~/Dropbox/Design/projects/americanbeauty にシンボリックリンクが張られ、 c で補完されて直接移動できるようになるものです。

とはいえ、これ、自分自身あまり使わないと思うのでこれくらいで。

Bash Command Wrapping ?

設定ファイルにあるけど、ソース中ではコメントアウトされていた。今はまだ使えないらしい。

結論

これからますます色々出てくるであろう git (これは mercurial 実装もしたいみたいだけど)の CLI サポートスクリプトの中ではほとばしる情熱による作り込みがすごい SCM Breeze でした。ほとばしる情熱は認めるが、別に俺のユースケースには合わねえ…。とかはあると思うのですが、とにかくほとばしる情熱がすごいのでぜひ一度入れてその変態感を楽しんでいただければと思います。ソース読むと git の勉強にもなります。