search
LoginSignup
219
Help us understand the problem. What are the problem?

More than 3 years have passed since last update.

posted at

updated at

Gitで今のブランチの派生元ブランチを特定する

Gitを使ったスクリプトなどを書くときに、カレントブランチがどこから派生したかを特定したい時があります。

--+--+--+--+   master
      \
       +--+--+--+  parent branch
              \
               +--+--+  current branch

例えばこういうケースで、parent branchが何かを特定したい。

こんなとき、

$ 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

例を引用します。

$ 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

本記事は片方のブランチが分からないという前提なので、ブランチ名を与えず、すべてのローカルブランチを出しています。

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番目の値のみ出力します。
※このとき区切り文字は正規表現として扱われるので、文字]の置き場所はメタ[の直後に置きます。

以上のような流れで派生元ブランチを特定することが出来ました!

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
What you can do with signing up
219
Help us understand the problem. What are the problem?