git alias でチョット便利な git life

訂正:
`--get-regexp`オプションを `--get-regex`と間違えて書いてました...
git が自動的にオプションを補完してくれているようで動作自体は問題無いです．(さっき試したら `--get-r` でも動作しました．)
ただ，設定ファイルなどでは正式な名称を書いたほうがいいと思うので，このページを見て設定した方には修正をオススメします．


# git alias

何かと便利な git の alias 機能。

自分のを晒しがてら他の人のオススメの alias とかを聞いてみたい。

ちなみに自分の好みとして、オプション付きのコマンドを短く、分かりやすく設定するような alias が大半です。
複数のコマンドを組み合わせたものとかは逆に融通がきかなくなるイメージがあるので基本設定していません。 (add と commit を一括で〜 みたいなのとか)

## って事で晒してみる

```ini
[alias]
      aliass     = !git config --get-regexp alias
      amend      = commit --amend
      cancel     = reset --mixed HEAD^
      fdiff      = diff --ignore-all-space --no-index
      files      = !cd ${GIT_PREFIX:-.} && git ls-tree -z --name-only HEAD | xargs -0 -n1 -I@ -- git log -1 --pretty=format:'%C(green)%ai%Cr  eset %C(yellow)%h%Creset @ %C(blue)(%ar)%Creset %C(red)<%an>%Creset' -- @
      forcepush  = push --force
      fwdiff     = diff --ignore-all-space --word-diff --no-index
      ibase      = !sh -c 'git rebase -i --autosquash $(git merge-base ${1:-master} HEAD)' -
      l          = log --oneline
      ld         = log --decorate --oneline
      lg         = log --decorate --oneline --graph
      life       = !echo "No Git, No Life"
      lm         = log --oneline origin/master..
      lp         = log --abbrev-commit --color --pretty=format:'%C(yellow)%h%Creset -%C(yellow reverse)%d%Creset %s %C(blue)(%cr)%C(red)<%an  >%Creset'
      ls         = log --decorate --oneline --stat
      me         = !git config --get-regexp user
      nerge      = merge --no-ff
      noskip     = update-index --no-skip-worktree
      plune      = !git branch --merged | grep -vE '(master|develop|release|gh-pages|\\*)' | xargs git branch -d
      purr       = pull --rebase
      pwd        = rev-parse --show-prefix
      skip       = update-index --skip-worktree
      stat       = !cd -- ${GIT_PREFIX:-.} && git stash list && git status --short --branch
      up         = !git branch -u origin/$(git branch --show-current)
      unstage    = reset HEAD --
      wdiff      = diff --ignore-all-space --word-diff
```

## 解説

#### aliass
自分の設定している alias 一覧を表示する alias。
本当は複数形は aliases だけど e を打つのがめんどうなので aliass。
`git config` の `--get-regexp` オプションは特定の設定を確認したい時に便利なのでこれ以外でも設定の確認に使えそう．

#### amend

ちょくちょく歴史改変する時に `git commit --amend` とするのが面倒になって `git amend` で追加できるように

#### cancel

社内で `git reset` について話してた時に
「`git reset --soft HEAD^` を間違えてコミットした直後に使えばコミット直前の状態に戻してもう一度コミットし直せるよ．違うブランチでコミットしちゃった時とかに有効だよ．」
って話があって，確かに結構使いそうなコマンドだったので alias に設定しました．

cancel ってのが色々な場面で使えそうなのでここで使っていいのか若干迷いましたが，分かりやすいのでとりあえずこれで使ってみようと思います．

#### fdiff, fwdiff

昔の `git diff` は git 管理下にないファイルに対して実行しても見れたけど、最近は `--no-index` を付けないとできないようになったので、`file diff` の意味で `fdiff` と命名。

#### files

めちゃくちゃ長い。pretty format を除いてもなかなか長い。

出力は下のとおり、GitHub で見かける「それぞれのファイル / ディレクトリの最終更新日」を含めたファイル一覧を出力する。なんでか欲しいと思って作ったけど、作ってる最中になんで欲しかったかを忘れた。まぁあとで思い出すでしょう。

```bash
$ git files
2017-02-10 03:13:36 +0900 30036d3 .eslintrc.json (10 weeks ago) <takayukioda>
2017-02-07 02:03:14 +0900 b13d52e .gitignore (2 months ago) <takayukioda>
2017-02-02 23:48:04 +0900 dc2cfcc README.md (2 months ago) <takayukioda>
2017-02-06 00:33:41 +0900 a700ee2 index.js (2 months ago) <takayukioda>
2017-02-22 01:55:32 +0900 70afed6 lib (8 weeks ago) <takayukioda>
2017-02-05 11:49:32 +0900 4f3aba6 package.json (2 months ago) <takayukioda>
2017-02-05 11:18:57 +0900 229d8ce yarn.lock (2 months ago) <takayukioda>
```

実際には pretty format を使ってるのでもうちょい見え方は良い。
しかしコマンドが長い。

*追記*:
git alias は [git リポジトリの **top-level directory** で動作する](http://stackoverflow.com/questions/26243145/git-aliases-operate-in-the-wrong-directory)との事で、`GIT_PREFIX` をもとに cd しないと思ったように動作してくれない。
あと top-level directory にいると `GIT_PREFIX` が空になってホームディレクトリに飛んでしまうのでデフォルト値 `.` を入れて対応した。

#### forcepush

ブランチの歴史改変をする時 `-f` だと簡単だし、すぐ付け忘れるので。
ちょっと長いけど、「俺、強制してる！」ってわかるようにそのままの名前を付けてる。

#### ibase (@uasi さんのコメントより)

最近 GitHub を活用するようになって， rebase を多用するようになっている所だったのでありがたいです．
タイプ数を減らすことより，元のコマンドがある程度分かる状態を保ちたい気持ちが強いので interactive な rebase って事で ibase．

後で git merge-base の内容を調べる．[ToDo]

#### l, ld, lg, lm, lp, ls
ログ関連の alias 達。 decorate 万歳。
基本的に oneline でコンパクトにしつつ、graph や stat で状態を確認。

個人的には l と ~lg~ ls をよく使う。

若干 ls コマンドを意識しているのは言わずもがな（゜ω、゜）

最近追加したコマンドで `lm` が地味に便利。
`git l` だと全部のログが pager を使って表示されるが、たまに一番上のが見えなかったりと何かと不便だった。
`lm` は `orign/master` からの log を表示するので、適度な量のログになって作業状況を把握しやすい。

#### life
ジョークです。

#### me
会社の時のアカウントと個人のアカウントを分けたりしてる時にふと自分が今どんな設定してるか気になる時があるのでそんな時のalias。
これだと `github.user` の設定とかも出てくるので、 `user.xxx` の設定だけが見たければ

```ini
me = !git config --get-regexp user\.
```

とかにすると良い。
あとグローバルとローカルのが両方でるけどそれは勘弁←
unique コマンド とかにパイプ通せばできるかな？

#### nerge
merge なんだけど no fast forward でやりたい。 そんな思いが滲み出るような alias
でもGitHubを活用してると rebase と pull request が多いからあんまり活躍してない。

#### plune

今いるブランチにマージ済みのブランチを消すコマンド。
ブランチの補完が多くなりすぎた時とかに定期的に実行して綺麗にしてる。

#### purr
pull なんだけど rebase でやりたい。 そんな思いがry
rr は ll より押し辛いけど、「これは rebase」 って事を意識しやすくなるかな〜 と思って設定中。
GitHub使ってると基本 pull --rebase なので活用中

#### stat (@uasi さんのコメントより)

~~コメントでは stash も表示するようにしているみたいですが，自分は特に stash で困った経験が無いのでとりあえず外してます．
stash 忘れててアレレ〜とかが頻発するようなら入れてみるのもありかも．~~
stash 使うようになってきたので入れた←

status の短いバージョンって事も分かりやすくて良さそう．

#### unstage (@hage@github さんのコメントより)

reset コマンドは複数の用途があるので，機能を絞ってあげる事でミスが減らせるのはなかなか嬉しいですね．
名前も unstage と一発で分かるのも良い感じ．

#### skip, noskip

「管理はするけど，ローカルの変更は push したくない(.htaccess 自体は使うけど，ローカルの開発環境では RewriteBase しなくちゃいけない みたいな感じ)」なんて時に使う `update-index --skip-worktree`．長いから skip / unskip で入れ替えができるように設定．
似たようなオプションで `--assume-unchanged`/`--no-assume-unchanged` ってのもあるからちょくちょく使う場合は assume って名前で設定するのもありかも？

#### wdiff

word diff 用。
git diff は実は普通の diff としても活用できるから重宝する。

SQL をいじって、変えたい所以外が変わってないかの確認とかに word diff は重宝する。

## オススメ git alias があれば教えてくださいな

Qiitarian のオススメ待ってるよ！←