Git: Temukan leluhur bersama terbaru dari dua cabang

844

Bagaimana menemukan leluhur bersama terbaru dari dua cabang Git?

Ted
sumber
3
Tetapkan terbaru: waktu dunia nyata, jumlah komitmen, metrik lainnya?
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功
2
Relevan (penggabungan silang): stackoverflow.com/questions/26370185/…
jub0bs
1
@CiroSantilli 新疆 改造 中心 996ICU 六四 事件 sama dalam semua metrik, bukan?
YakovL
@YakovL Saya percaya tidak karena percabangan dan karena Anda dapat menetapkan tanggal komit sembarang pada objek komit Anda: tanggal itu sendiri kemungkinan bukan yang Anda inginkan.
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功
1
@CiroSantilli 新疆 改造 中心 996ICU 六四 事件 menurut saya itu hanya bisa berbeda jika sebelum komit umum terakhir di pohon ada komit yang memiliki stempel waktu lebih lama. Bisakah Anda memberikan contoh yang kurang sepele?
YakovL

Jawaban:

1019

Anda sedang mencari git merge-base. Pemakaian:

$ git merge-base branch2 branch3
050dc022f3a65bdc78d97e2b1ac9b595a924c3f2
CB Bailey
sumber
85
Perhatikan bahwa ini menemukan leluhur bersama yang paling baru ... yang saya percaya adalah yang diinginkan si penanya, jadi +1. Hanya mencatatnya, kalau-kalau ada orang datang ke sini mencoba menemukan leluhur bersama tertua (seperti yang saya lakukan) - untuk itu, lihat juga: stackoverflow.com/questions/1527234/…
lindes
16
@funroll: Atau singkatan untuk itu:git log master...HEAD
CB Bailey
17
@lindes akankah leluhur umum tertua tidak menjadi komit awal?
Thorbjørn Ravn Andersen
8
@ ThorbjørnRavnAndersen, ya, saya kira begitu ... Kesulitan dalam deskripsi datang dengan fakta bahwa git menggunakan Directed Acyclic Graph, namun sering dianggap sebagai pohon, yang secara teknis tidak. Untuk lebih berhati-hati dalam kata-kata saya, saya sedang berbicara tentang kasus di mana Anda ingin orang tua contoh pertama dari "cabang" menyimpang ... karena mereka mungkin memiliki beberapa titik di mana mereka digabungkan dan dipecah, ini adalah "tertua" dari semua ini, tetapi tidak benar-benar leluhur tertua, yang (menurut saya) selalu merupakan komitmen awal.
lindes
5
Meskipun pertanyaan ini semata-mata tentang menemukan leluhur yang sama dari dua cabang, siapa pun yang ingin leluhur yang sama dari tiga cabang atau lebih harus mencatat bahwa mereka harus melewati --octopusbendera untuk mendapatkan hasil yang tepat. Yang jelas-tetapi-salah git merge-base branch1 branch2 branch3akan memberi Anda komitmen, tetapi, seperti yang dijelaskan dalam bagian Diskusi dalam dokumen, itu tidak selalu merupakan leluhur bersama dari ketiga cabang.
Mark Amery
46

git diff master...feature

menunjukkan semua komit baru dari cabang fitur Anda saat ini (mungkin multi-komit).

man git-diff dokumen yang:

git diff A...B

sama dengan:

git diff $(git merge-base A B) B

tetapi ...lebih mudah untuk mengetik dan mengingat.

Seperti yang disebutkan oleh Dave , kasus khusus HEADdapat dihilangkan. Begitu:

git diff master...HEAD

sama dengan:

git diff master...

yang cukup jika cabang saat ini feature.

Akhirnya, ingatlah bahwa ketertiban penting! Melakukan git diff feature...masterakan menampilkan perubahan yang mastertidak aktif feature.

Saya berharap lebih banyak perintah git akan mendukung sintaks itu, tetapi saya tidak berpikir mereka melakukannya. Dan beberapa bahkan memiliki semantik berbeda untuk ...: Apa perbedaan antara double-dot ".." dan triple-dot "..." dalam rentang Git commit?

Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功
sumber
8
Atau hanya git diff master...dalam kasus khusus diffing toHEAD
Dave
"..." tidak bekerja untuk saya di PowerShell, lucu itu bekerja di git console mungkin repo tidak lengkap, git diff $ (git merge-base AB) B lakukan dan karena saya agak baru untuk git Saya agak skeptis bahwa ini mungkin menggabungkan cabang :)
Moiz Ahmed
1
Wow. cukup mengagumkan. dan jika cabang yang Anda inginkan tidak ada di repo lokal Anda karena Anda tidak pernah memeriksanya, Anda dapat melakukannyagit diff origin/branchname...
Mark Ch
25

Seperti disebutkan dalam jawaban sebelumnya, git merge-baseberfungsi:

$ git merge-base myfeature develop
050dc022f3a65bdc78d97e2b1ac9b595a924c3f2

tetapi jika myfeaturecabang saat ini, seperti yang umum, Anda dapat menggunakan gunakan --fork-point:

$ git merge-base --fork-point develop
050dc022f3a65bdc78d97e2b1ac9b595a924c3f2

Argumen ini hanya berfungsi di versi git yang cukup baru. Sayangnya itu tidak selalu berhasil, dan tidak jelas mengapa. Silakan merujuk pada batasan yang dicatat pada akhir jawaban ini .


Untuk info komit penuh, pertimbangkan:

$ git log -1 $(git merge-base --fork-point develop) 
Acumenus
sumber
Saya punya git version 2.14.1.windows.1. Menjalankan git merge-base --fork-point branch2dengan cabang (dengan komit sendiri) yang saya tahu telah bercabang dari cabang saat ini tidak menghasilkan hasil apa pun, sedangkan git merge-base branch1 branch2dengan benar menunjukkan titik garpu. Apa yang bisa menjadi masalah?
ADTC
@ADTC Checkout branch2lalu jalankan git merge-base --fork-point branch1.
Acumenus
@ADTC Gunakan penampil komit grafis, misalnya gitk, dll. Untuk melihat seperti apa pohon itu. Mungkin Anda akan mendapatkan jawaban Anda.
Acumenus
Saya tidak melihat ada yang aneh dengan pohon itu ketika saya melihatnya secara grafis. Saya dapat menelusuri jalan setapak dan menemukan leluhur bersama yang cocok dengan hasilnya git merge-base branch1 branch2. Tapi yang aneh adalah itu --fork-pointtidak memberikan apa-apa. Sudahkah Anda mengonfirmasi bahwa itu berfungsi untuk Anda seperti yang dimaksudkan?
ADTC
1
Saya mendapatkan @ADTC yang sama. Perintah 'git log -1 $ (git merge-base --fork-point anotherBranch)' tidak menunjukkan hasil apa pun menggunakan git versi 2.16.2.windows.1.
masinger
10

Dengan gitkAnda dapat melihat dua cabang secara grafis:

gitk branch1 branch2

Dan kemudian mudah untuk menemukan nenek moyang yang sama dalam sejarah dua cabang.

Martin G
sumber
6
Tidak semuanya dapat dilakukan secara visual dalam setiap kasus. Ada alasan mengapa hal-hal mungkin perlu diotomatisasi secara terprogram.
ADTC