Git-特定のブランチの最初のコミットを見つける方法


91

次の例のツリーでは:

A-B-C-D-E (master branch)
    \
     F-G-H (xxx branch)

私はFを探しています-xxxブランチの最初のコミット。私はそれが可能だと思います:

git log xxx --not master

そして最後にリストされたコミットはFであるはずです。それは正しい解決策ですか、それともいくつかの欠点がありますか?

stackoverflowについても同様の質問があったことは知っていますが、そのような解決策を提案した人はいません。


回答:


109
git log master..branch --oneline | tail -1

「branch」は特定のブランチ名です。ドットドットは、マスターが持っていないブランチが持つすべてのコミットを提供します。tail -1前の出力の最後の行を返します。


3
これは「ブランチ」が存在する場合にのみ機能します。ブランチが削除されたらどうしますか?
Oz123 2016

2
@ Oz123ブランチは、HEAD、sha1、タグなどの任意の参照で置き換えることができます。しかし、明らかに何らかの参照が必要です。
Zitrax

3
私が期待していたものを私に与えません。私のブランチ(古いブランチ)はすでにマスターにマージされています。つまり、xxxのすべてのコミットはすでにマスターにあります。それでも、そのブランチの最初のコミットであるコミットを知る必要があります-または実際には、そのブランチのコミットの履歴だけを調べる必要があります-マスターにあるかどうかは関係ありません。
Motti Shneor 2017

1
@MottiShneorは、どのようにマージしたかによって、トリッキーになる可能性があります。あなたが早送りをしたなら、それはまるでブランチが存在しなかったかのようです。それ以外の場合は、分岐点を見つけるためのいくつかの方法がリストされているこの回答に興味がある可能性があります。ブランチポイントを取得すると、SHAはを置き換えることができmaster、ブランチが削除されていない限り、git log <sha>..branch --oneline | tail -1探している結果が得られます。
ND Geek 2017年

1
あなたは使用することができる--reverseなどの色、との下位ログを読むために
ドミニク・

8

merge-baseこれを正確に解決するように設計された機能を使用する必要があります。

git merge-base remotes/origin/<branch> develop 

元の分岐点に戻したい場合、これはうまくいきません。<branch>に開発をマージすると、merge-baseは元の分岐点よりも新しくなります。
Alexander Mills

5
また、これはFを指すのではなく、masterブランチでのコミットを指します(OPの図面ではわかりにくいですが、BまたはCのようです)。
RomainValeri


1

ブランチ(古いブランチ)をもう一度マスターにマージしても期待した結果が得られない場合、Pythonスクリプトを使用して初期ブランチコミットIDを検索しています。

git rev-list --first-parentチェンジセット

--first-parentは、マージコミットを確認すると、最初の親コミットのみを追跡します。

親ブランチが見つかるまで、上記のコマンドからチェンジセットを繰り返します。

def status_check(exec_command, exec_dir=None, background=False):
    if exec_dir:
        os.chdir(exec_dir)
    res = subprocess.Popen(exec_command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
    if not background:
        result = res.communicate()
    return result



def findNewBranchCommits(changeset=None):
    cmd = "git rev-list --first-parent "+ changeset
    rev_list = status_check(cmd,self.module_dir)
    rev_list = str(rev_list[0]).split('\n')
    rev_list = list(filter(None, rev_list))
    for x in rev_list:                      # Iterate until branch base point
        rev_cmd = "git branch --contains " + x
        rev_cmd = status_check(rev_cmd,self.module_dir)
        rev_cmd = str(rev_cmd[0]).split('\n')
        if(len(rev_cmd) > 2): 
            print "First Commit in xxx branch",x
            break

findNewBranchCommits(changeset)

0
git cherry master -v | tail -1   

ただし、これにより、マスターにないブランチxxxでの最初のコミットのみが得られ、ブランチxxxでの最初のコミットは得られません。ブランチxxxが1回以上削除または再作成されている場合、後者は困難です。その場合、次のことを試すことができます。

git reflog | grep checkout | grep xxx | tail -1   

3
head -n 1代わりに書くつもりtail -1ですか?tail -1最初のコミットではなく最新のコミットを返します。
Nelu

-1

git rev-list --ancestry-path $(git merge-base master xxx)..xxx | tail -1


私のリポジトリでは、これはブランチxxxの最初のコミットではなく、マスターからブランチxxxへの最後のマージ以降の最初のコミットを示しています。
jk7 2016年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.