Dengan Git, bagaimana saya bisa tahu jika satu komit di cabang saya adalah keturunan dari komit lain?
--is-ancestorsolusinya.
Dengan Git, bagaimana saya bisa tahu jika satu komit di cabang saya adalah keturunan dari komit lain?
--is-ancestorsolusinya.
Jawaban:
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.
git checkout -b quickcheck <more-recent-commit-ID>kemudian git branch --contains <older-commit-ID>(dan kemudian git branch -D quickcheckmenyingkirkan cabang sementara).
git merge-base --is-ancestor2 tahun.
git branch --contains <commit>dan git merge-base --is-ancestor ...: 3m40s vs 0,14s
Dari Git 1.8.0, ini didukung sebagai opsi untuk merge-base:
git merge-base --is-ancestor <maybe-ancestor-commit> <descendant-commit>
Dari halaman manual:
--adalah leluhur
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.
Sebagai contoh:
git merge-base --is-ancestor origin/master master; echo $?
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
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.
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:
git rev-list --boundary 85e54e2408..0815fcf18a
0815fcf18a19441c1c26fc3495c4047cf59a06b9
8a1658147a460a0230fb1990f0bc61130ab624b2
-85e54e240836e6efb46978e4a1780f0b45516b20
(Komit batas diawali dengan -)
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.
-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 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.
--prettysaya menggunakan --oneline: git log --oneline ce2ee3d | grep ec219ccworks great
https://stackoverflow.com/a/13526591/895245 menyebutkannya, sekarang untuk membuatnya lebih ramah manusia:
git-is-ancestor() (
if git merge-base --is-ancestor "$1" "$2"; then
echo 'ancestor'
elif git merge-base --is-ancestor "$2" "$1"; then
echo 'descendant'
else
echo 'unrelated'
fi
)
alias giia='git-is-ancestor'
git show-branch branch-sha1 commit-sha1
Dimana:
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)
commit-graph: perkenalkancommit_graph_data_slabDitandatangani oleh: Abhishek Kumar
Komit struct digunakan dalam banyak konteks. Namun, anggota
generationdangraph_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 kecommit_graph_dataslab.Sementara keseluruhan test suite berjalan secepat
master, (seri: 26m48s,:master27m34s, lebih cepat 2,87%), perintah-perintah tertentu sepertigit 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.
Membangun jawaban itub, jika Anda perlu melakukan ini untuk semua tag di repositori:
for i in `git tag` ; do echo -ne $i "\t" ; git log --pretty=format:%H $i | (grep <commit to find> || echo ""); done