1. upinetree

    No comment

    upinetree
Changes in body
Source | HTML | Preview
@@ -1,97 +1,98 @@
Gitを使ったスクリプトなどを書くときに、カレントブランチがどこから派生したかを特定したい時があります。
```
--+--+--+--+ master
\
+--+--+--+ parent branch
\
+--+--+ current branch
```
例えばこういうケースで、parent branchが何かを特定したい。
こんなとき、
```bash
$ git show-branch | grep '*' | grep -v "$(git rev-parse --abbrev-ref HEAD)" | head -1 | awk -F'[]~^[]' '{print $2}'
```
と実行するとなんとか取れます。
## 何をしているのか
> `git show-branch`
`show-branch`は、各ブランチとコミットを一覧して見ることができる便利なコマンドです。
[Git - git-show-branch Documentation](http://git-scm.com/docs/git-show-branch)
例を引用します。
```bash
$ git show-branch master fixes mhf
* [master] Add 'git show-branch'.
! [fixes] Introduce "reset type" flag to "git reset"
! [mhf] Allow "+remote:local" refspec to cause --force when fetching.
---
+ [mhf] Allow "+remote:local" refspec to cause --force when fetching.
+ [mhf~1] Use git-octopus when pulling more than one heads.
+ [fixes] Introduce "reset type" flag to "git reset"
+ [mhf~2] "git fetch --force".
+ [mhf~3] Use .git/remote/origin, not .git/branches/origin.
+ [mhf~4] Make "git pull" and "git fetch" default to origin
+ [mhf~5] Infamous 'octopus merge'
+ [mhf~6] Retire git-parse-remote.
+ [mhf~7] Multi-head fetch.
+ [mhf~8] Start adding the $GIT_DIR/remotes/ support.
*++ [master] Add 'git show-branch'.
```
`---`の上にあるのがブランチの一覧です。
左側の記号のうち、`*`が現在のブランチ、`!`がその他のブランチを表し、ブランチごとの最新コミットが右側に表示されます。
`---`の下にあるのがコミットの一覧です。
こちらも左側に記号がありますが、この記号が上部ブランチ一覧の記号の位置と対応しています。
`*`が現在のブランチに属するコミット、`+`がその他のブランチに属するコミットを表します。
なお、`git show-branch branch_A branch_B`といったようにブランチ名を与えると、与えたブランチが交わる根本まで表示します。
`git show-branch --sha1-name branch_A branch_B | tail -1`として、ブランチの分岐点のコミットハッシュを取得することもできます。
参考: [gitで2つのブランチの分岐点を表示 - QA@IT](http://qa.atmarkit.co.jp/q/2148)
本記事は片方のブランチが分からないという前提なので、ブランチ名を与えず、すべてのローカルブランチを出しています。
> `grep '*'`
`show-branch`で出力した一覧から、現在のブランチに属するコミットの行で絞っています。
ここでもう一度上の例で表すと、`*`が付くコミットはこんな感じになるはずです。
```
--*--*--+--+ master
\
*--*--*--+ parent branch
\
*--*--* current branch
```
+※ `'*'` がカレントディレクトリの展開になる環境では、`"*"`に置き換えて実行してみてください
> `grep -v "$(git rev-parse --abbrev-ref HEAD)" | head -1`
`git rev-parse --abbrev-ref HEAD`でカレントブランチを特定しています。
カレントブランチを含まない行をgrepし、その一番上の行を取り出します。
> awk -F'[]~^[]' '{print $2}'
```
+ [mhf~3] Use .git/remote/origin, not .git/branches/origin.
```
例えば、これまでの操作によってこんな行が取り出されたとします。欲しいのは、`mhf`というブランチ名のみです。
なのでawkの`-F`オプションで区切り文字を指定し、切り分けられた2番目の値のみ出力します。
※このとき区切り文字は正規表現として扱われるので、文字`]`の置き場所はメタ`[`の直後に置きます。
以上のような流れで派生元ブランチを特定することが出来ました!