gitで前に使っていたブランチのエイリアス (-)

gitで直前にいたブランチに移動したりマージしたりする時に、ブランチ名を入力しなくて良い手軽なエイリアス `-`

```sh:
git checkout -
git merge -
```

長い名前のブランチ名などをいちいちコピーしなくて良い

## ユースケース

#### checkout - 直前にいたブランチに移動

※ alias `co` -> `checkout`

```sh:
# 現在のブランチ develop
git co feature/123456_long_branch_name
#=> Switched to branch 'feature/123456_long_branch_name'
git co -
#=> Switched to branch 'develop'
```

#### merge - 直前にいたブランチをマージ

※ alias `ml` -> `merge --no-ff --log`

```sh:
# 現在のブランチ feature/123456_long_branch_name
git co develop
#=> Switched to branch 'develop'
git ml -
#=> Merge branch 'feature/123456_long_branch_name' into develop
```

## 余談

#### cd -

`cd -` は直前にいたディレクトリに戻るコマンドとして比較的有名

#### 検索であまり見つからない

git長く使ってる割に1ヶ月くらい前からやっと使い始めた
手軽な割にGooglabilityの悪さからあまり情報が見つからなかった
頑張って見つけた情報

http://kozyty.com/blog/2013/03/git_lifechanging_git-checkout-_git-merge/
https://coderwall.com/p/quirkw
http://qiita.com/yaotti/items/d7196870dee5ba738b90
http://qiita.com/yaotti/items/bb81fe699b833ae20d4a
新しい http://qiita.com/sasaplus1/items/e1a5dd0dc52061915273

Qiitaにすでにいくつかあったし

ついで

[git-fuzzy-checkout](https://gist.github.com/minrk/6126342)

#### 過去にいたブランチに移動

直前にいたブランチだけでなく、過去にいたブランチに移動できる
N番目の前にいたブランチ `@{-N}`

[git checkout PREV (StackOverflow)](http://stackoverflow.com/questions/16042823/git-checkout-prev)

```sh:
git checkout -b test1
#=> Switched to a new branch 'test1'
git checkout -b test2
#=> Switched to a new branch 'test2'
git checkout -b test3
#=> Switched to a new branch 'test3'
git checkout -b test4
#=> Switched to a new branch 'test4'

git checkout @{-2}
#=> Switched to branch 'test2'
```

多分使わない

`git stash` でも似た書き方する

```sh:
git stash list
git stash show -p stash@{4}
#=> stashのdiffを表示
```

#### どういう仕組みで動いているのか

過去にいたブランチの情報はどのくらいまでさかのぼれるかの限界が気になったので、
どの情報をもとにしてるかいろいろ探してみた

grepで探してみたらどうやら `.git/logs/HEAD` が怪しい

```sh:
$ tail .git/logs/HEAD
141dbfc... 1385124886 +0900 checkout: moving from develop to test1
141dbfc... 1385124888 +0900 checkout: moving from test1 to test2
141dbfc... 1385124889 +0900 checkout: moving from test2 to test3
141dbfc... 1385124891 +0900 checkout: moving from test3 to test4
141dbfc... 1385124901 +0900 checkout: moving from test4 to test2
```

※ 以下は実際のプロジェクトでまねしない方が良い

つじつまが合うように上のlogから最後の3行を削除してみた

```sh:
$ vi .git/logs/HEAD
$ tail .git/logs/HEAD
141dbfc... 1385124886 +0900 checkout: moving from develop to test1
141dbfc... 1385124888 +0900 checkout: moving from test1 to test2
```

`.git/logs/HEAD` を見ていないならば `test2` -> `test4` に戻るはず

```sh:
git co -
#=> Switched to branch 'test1'
```

`test4` ではなく、編集後の最後のログの `test1` に移動した

多分 `.git/logs/HEAD` をもとに動いている

#### 他のコマンドで使えるか

不明

```sh:
git branch -d -
#=> error: branch '-' not found.
```

```sh:
git rebase -i -
#=> fatal: Needed a single revision
#=> invalid upstream -
```

```sh:
git co -b one_commit_back HEAD^
#=> Switched to a new branch 'one_commit_back'
git co develop
#=> Switched to branch 'develop'
git reset --hard -
#=> fatal: bad flag '-' used after filename
```

```sh:
git show -
#=> fatal: unrecognized argument: -
```

`branch`, `rebase`, `reset`, `show` 失敗

`-` でなく `@{-1}` だと動いた

```sh:
git show @{-1}
git reset --hard @{-1}
#=> OKだった

git rebase -i @{-1}
#=> OKだが、rebaseは一連の流れの中にcheckoutを含んでいる
# .git/logs/HEAD -> checkout: moving from develop to 667fe15
```

多分`@{-N}`使わない