Bisakah Anda mengubah jawaban yang Anda terima? Mayoritas menyukai --is-ancestorsolusinya.
Robert Siemer
Jawaban:
51
Jika Anda ingin memeriksa ini secara programatik (misalnya dalam skrip), Anda dapat memeriksa apakah git merge-base A Bsama dengan git rev-parse --verify A(maka A dapat dijangkau dari B), atau jika itu git rev-parse --verify B(maka B dapat dijangkau dari A). git rev-parsedi sini diperlukan untuk mengkonversi dari nama komit ke komit SHA-1 / commit id.
Menggunakan git rev-listlike dalam jawaban VonC juga dimungkinkan.
Sunting: di Git modern ada dukungan eksplisit untuk kueri ini dalam bentuk git merge-base --is-ancestor.
Jika salah satu dari komitmen yang Anda tanyakan adalah tip cabang , maka git branch --contains <commit>atau git branch --merged <commit>mungkin solusi non-programatik yang lebih baik.
Mungkin cara tercepat adalah dengan git checkout -b quickcheck <more-recent-commit-ID>kemudian git branch --contains <older-commit-ID>(dan kemudian git branch -D quickcheckmenyingkirkan cabang sementara).
clee
2
Dua pendekatan yang mungkin, keduanya jauh lebih buruk daripada yang ada di jawaban @ MattR.
jwg
6
@ jwg: Jawaban MattR lebih baik, tetapi jawaban ini (dan mungkin diterima) mendahului git 1.8.0 dan git merge-base --is-ancestor2 tahun.
Jakub Narębski
@ JakubNarębski Cukup adil, maaf.
jwg
2
Dalam repositori besar (2 juta komit), saya membandingkan kecepatan git branch --contains <commit>dan git merge-base --is-ancestor ...: 3m40s vs 0,14s
hagello
259
Dari Git 1.8.0, ini didukung sebagai opsi untuk merge-base:
Periksa apakah yang pertama adalah leluhur dari yang kedua, dan keluar dengan status 0 jika benar, atau dengan status 1 jika tidak. Kesalahan ditandai oleh status bukan nol yang bukan 1.
Bagus! Berikut ini adalah skrip shell yang membungkus jawaban ini dalam sesuatu dengan keluaran yang dapat diterima manusia: gist.github.com/simonwhitaker/6354592
Simon Whitaker
1
Dengan kata lain: git merge-base THING --is-ancestor OF_THING && echo yes || echo nomisalnya:git merge-base my-feature-branch --is-ancestor master && echo yes || echo no
user1735594
2
@smarber git merge-base --is-ancestor -- commit commitbekerja untuk hash di sisi saya dengan git2.1.4 (Debian / Devuan 7.10 jessie) dan 1.9.1 (Ubuntu 14.04 terpercaya) yang agak kuno sekarang. Ini bekerja bahkan untuk Wheezy Debian, jika Anda melakukannya sudo apt-get install git/wheezy-backports.
Jika komit terakhir yang ditampilkan adalah sama dengan komit pertama dalam git rev-listperintah, maka komit tersebut dapat dicapai dari komit kedua.
Jika komit pertama tidak dapat dijangkau dari komit kedua, git rev-listseharusnya tidak menghasilkan apa-apa.
git rev-list --boundary A..B
akan selesai A, jika Adapat dijangkau dari B.
Itu sama dengan:
git rev-list --boundary B --not A
, dengan Bsebuah referensi positif , dan Asebuah referensi negatif .
Ini akan dimulai pada Bdan berjalan kembali melalui grafik sampai bertemu dengan revisi yang dapat dicapai A.
Saya berpendapat bahwa jika Alangsung dapat dijangkau dari B, itu akan menemui (dan menampilkan, karena --boundaryopsi) Aitu sendiri.
Ini kedengarannya seperti kasus penggunaan yang cukup umum sehingga saya terkejut bahwa git belum menerbitkan perintah "porselen" yang melakukan hal ini.
Oh, kawan, sepertinya aku harus kembali dan mengerjakan skrip skrip Shellku!
Lawrence I. Siden
1
pertanyaan: mengapa -85e54e2...dalam cuplikan memiliki minus? juga kemungkinan salah ketik: "... sama dengan komit pertama ..."
sdaau
1
@ Sdaau -berarti komit batas. Saya telah mengedit jawaban untuk membuatnya lebih jelas, juga untuk menyegarkan tautan doc dan memperbaiki kesalahan ketik untuk jawaban berusia 5 tahun ini.
VonC
11
Cara lain adalah menggunakan git logdan grep.
git log --pretty=format:%H abc123 | grep def456
Ini akan menghasilkan satu baris output jika komit def456 adalah leluhur komit abc123, atau tidak ada output sebaliknya.
Anda biasanya bisa lolos dengan menghilangkan --prettyargumen, tetapi diperlukan jika Anda ingin memastikan bahwa Anda hanya mencari melalui hash yang sebenarnya dan tidak melalui komentar log dan sebagainya.
Komit struct digunakan dalam banyak konteks. Namun, anggota generationdan graph_poshanya digunakan untuk operasi terkait grafik-komitmen dan sebaliknya membuang memori.
Pemborosan ini akan lebih jelas ketika kita beralih ke nomor generasi v2, yang menggunakan nomor generasi 64-bit sebagai ganti 32-bit saat ini.
Karena mereka sering diakses bersama, mari kita perkenalkan struct commit_graph_datadan pindahkan ke commit_graph_dataslab.
Sementara keseluruhan test suite berjalan secepat master, (seri: 26m48s,: master27m34s, lebih cepat 2,87%), perintah-perintah tertentu seperti git merge-base --is-ancestordiperlambat oleh 40% seperti yang ditemukan oleh Szeder Gábor .
Setelah meminimalkan akses commit-slab, perlambatan tetap ada tetapi mendekati 20%.
Derrick Stolee percaya perlambatan ini disebabkan oleh algoritma yang mendasari daripada lambatnya akses commit-slab dan kami akan menindaklanjuti dalam seri selanjutnya.
--is-ancestor
solusinya.Jawaban:
Jika Anda ingin memeriksa ini secara programatik (misalnya dalam skrip), Anda dapat memeriksa apakah
git merge-base A B
sama dengangit rev-parse --verify A
(maka A dapat dijangkau dari B), atau jika itugit rev-parse --verify B
(maka B dapat dijangkau dari A).git rev-parse
di sini diperlukan untuk mengkonversi dari nama komit ke komit SHA-1 / commit id.Menggunakan
git rev-list
like dalam jawaban VonC juga dimungkinkan.Sunting: di Git modern ada dukungan eksplisit untuk kueri ini dalam bentuk
git merge-base --is-ancestor
.Jika salah satu dari komitmen yang Anda tanyakan adalah tip cabang , maka
git branch --contains <commit>
ataugit branch --merged <commit>
mungkin solusi non-programatik yang lebih baik.sumber
git checkout -b quickcheck <more-recent-commit-ID>
kemudiangit branch --contains <older-commit-ID>
(dan kemudiangit branch -D quickcheck
menyingkirkan cabang sementara).git merge-base --is-ancestor
2 tahun.git branch --contains <commit>
dangit merge-base --is-ancestor ...
: 3m40s vs 0,14sDari Git 1.8.0, ini didukung sebagai opsi untuk
merge-base
:Dari halaman manual:
Sebagai contoh:
sumber
git merge-base THING --is-ancestor OF_THING && echo yes || echo no
misalnya:git merge-base my-feature-branch --is-ancestor master && echo yes || echo no
git merge-base --is-ancestor -- commit commit
bekerja untuk hash di sisi saya dengangit
2.1.4 (Debian / Devuan 7.10 jessie) dan 1.9.1 (Ubuntu 14.04 terpercaya) yang agak kuno sekarang. Ini bekerja bahkan untuk Wheezy Debian, jika Anda melakukannyasudo apt-get install git/wheezy-backports
.Operasi semacam ini bergantung pada gagasan tentang berbagai revisi yang dirinci dalam pertanyaan SO: " Perbedaan dalam 'asal git log / master' vs 'asal git log / master ..' ".
git rev-list
harus dapat berjalan kembali dari komit, hingga yang lain jika dapat dijangkau.Jadi saya akan mencoba:
(Komit batas diawali dengan
-
)Jika komit terakhir yang ditampilkan adalah sama dengan komit pertama dalam
git rev-list
perintah, maka komit tersebut dapat dicapai dari komit kedua.Jika komit pertama tidak dapat dijangkau dari komit kedua,
git rev-list
seharusnya tidak menghasilkan apa-apa.akan selesai
A
, jikaA
dapat dijangkau dariB
.Itu sama dengan:
, dengan
B
sebuah referensi positif , danA
sebuah referensi negatif .Ini akan dimulai pada
B
dan berjalan kembali melalui grafik sampai bertemu dengan revisi yang dapat dicapaiA
.Saya berpendapat bahwa jika
A
langsung dapat dijangkau dariB
, itu akan menemui (dan menampilkan, karena--boundary
opsi)A
itu sendiri.sumber
-85e54e2...
dalam cuplikan memiliki minus? juga kemungkinan salah ketik: "... sama dengan komit pertama ..."-
berarti komit batas. Saya telah mengedit jawaban untuk membuatnya lebih jelas, juga untuk menyegarkan tautan doc dan memperbaiki kesalahan ketik untuk jawaban berusia 5 tahun ini.Cara lain adalah menggunakan
git log
dangrep
.Ini akan menghasilkan satu baris output jika komit def456 adalah leluhur komit abc123, atau tidak ada output sebaliknya.
Anda biasanya bisa lolos dengan menghilangkan
--pretty
argumen, tetapi diperlukan jika Anda ingin memastikan bahwa Anda hanya mencari melalui hash yang sebenarnya dan tidak melalui komentar log dan sebagainya.sumber
--pretty
saya menggunakan --oneline:git log --oneline ce2ee3d | grep ec219cc
works greathttps://stackoverflow.com/a/13526591/895245 menyebutkannya, sekarang untuk membuatnya lebih ramah manusia:
sumber
git show-branch branch-sha1 commit-sha1
Dimana:
sumber
Jika Anda menggunakan
git merge-base --is-ancestor
, pastikan untuk menggunakan Git 2.28 (Q3 2020)Dengan Git 2.28 (Q3 2020), beberapa bidang "
struct commit
" yang tidak harus selalu ada telah dipindahkan untuk melakukan slab.Lihat komit c752ad0 , komit c49c82a , komit 4844812 , komit 6da43d9 (17 Jun 2020) oleh Abhishek Kumar (
abhishekkumar2718
) .(Digabung oleh Junio C Hamano -
gitster
- di commit d80bea4 , 06 Jul 2020)sumber
Membangun jawaban itub, jika Anda perlu melakukan ini untuk semua tag di repositori:
sumber