Help us understand the problem. What is going on with this article?

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

More than 1 year has passed since last update.

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

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

Why do not you register as a user and use Qiita more conveniently?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away