Diberi id komit, bagaimana cara menentukan jika cabang saat ini berisi komit?
156
Apa yang saya coba lakukan adalah pemeriksaan versi. Saya ingin memastikan kode tetap di atas versi minimum. Jadi saya perlu cara untuk mengetahui apakah cabang saat ini berisi komit yang ditentukan.
Lihat duplikat yang diajukan untuk cara menemukan semua cabang yang berisi komit yang ditentukan. Untuk mengetahui apakah cabang saat ini berisi komit C , gunakan perintah "plumbing" git merge-base --is-ancestor. Cabang saat ini berisi C jika C adalah leluhur HEAD, jadi:if git merge-base --is-ancestor $hash HEAD; then echo I contain commit $hash; else echo I do not contain commit $hash; fi
torek
1
Hai, tolong kirimkan ini sebagai jawaban sehingga dapat dipilih sebagai jawaban yang benar =)
Ben
1
@ Ben - Saya menambahkannya sebagai jawaban wiki komunitas.
Zitrax
1
@Remover: dalam skrip shell, nol benar, bukan nol salah: kebalikan dari konvensi C. /bin/trueawalnya diimplementasikan sebagai exit 0dan /bin/falsesebagai exit 1. (Kerang modern kemudian dibangun di.)
torek
Jawaban:
220
Ada beberapa cara untuk mencapai hasil ini. Opsi naif pertama adalah menggunakan git logdan mencari komit tertentu menggunakan grep, tetapi itu tidak selalu tepat
git log | grep <commit_id>
Anda lebih baik menggunakan git branchsecara langsung untuk menemukan semua cabang yang mengandung diberikan COMMIT_IDmenggunakan
git branch --contains $COMMIT_ID
Langkah selanjutnya adalah mencari cabang saat ini yang dapat dilakukan sejak git 1.8.1menggunakan
Tetapi perintah di atas tidak mengembalikan benar atau salah dan ada versi yang lebih pendek yang mengembalikan kode keluar 0 jika komit di cabang saat ini ATAU kode keluar 1 jika tidak
git merge-base --is-ancestor $COMMIT_ID HEAD
Kode keluar memang bagus, tetapi seperti yang Anda inginkan string trueatau falsesebagai jawaban, Anda perlu menambahkan sedikit lebih banyak dan kemudian dikombinasikan dengan ifdari bash Anda dapatkan
if [ 0 -eq $(git merge-base --is-ancestor $COMMIT_ID HEAD) ]; then echo "true"; else echo "false"; fi
Itu tidak benar; hal ini grepdapat menghasilkan false positive jika git logmenyebutkan commit SHA karena alasan lain, misalnya disebutkan dalam pesan commit sebagai hasil dari port dari cabang lain.
Adam Spires
1
Dikoreksi (atau lebih tepatnya menambahkan opsi lain).
Di grepsini juga bisa menghasilkan false positive jika ada cabang lain yang mengandung komit yang namanya juga mengandung <branch-name>sebagai substring.
Adam Spires
1
Ya @AdamSpiers, Memperbarui jawabannya dengan persis sama dengan nama cabang olehgrep -E '(^|\s)branchname$'
Sajib Khan
1
Per komentar ini pada pertanyaan terkait , akan bermanfaat untuk menambahkan opsi -r("jarak jauh") atau -a("semua") git branchuntuk mencari cabang yang mungkin tidak direplikasi dalam klon repo lokal.
sxc731
Ini tidak bekerja untuk saya, saya butuhkan git branch --all --contains <commit-id>
Arthur Tacca
7
Diekstraksi komentar oleh @torek sebagai jawaban:
Lihat duplikat yang diajukan untuk cara menemukan semua cabang yang berisi komit yang ditentukan.
Untuk mengetahui apakah cabang saat ini berisi komit C, gunakan perintah "plumbing" git merge-base --is-ancestor. Cabang saat ini berisi C jika C adalah leluhur HEAD, jadi:
if git merge-base --is-ancestor $hash HEAD; then
echo I contain commit $hash
else
echo I do not contain commit $hash
fi
(Catatan: dalam skrip shell, perintah yang keluar nol adalah "benar" sedangkan yang keluar bukan nol adalah "salah".)
Ini bekerja paling baik untuk saya karena itu juga akan bekerja pada cabang-cabang terpencil yang di-cache secara lokal seperti remotes/origin/master, yang git branch --containstidak akan bekerja.
Ini mencakup lebih dari pertanyaan OP tentang hanya "cabang saat ini" tetapi saya merasa bodoh untuk menanyakan versi "cabang apa pun" dari pertanyaan ini jadi saya memutuskan untuk tetap mengirim di sini.
tidak ...error: malformed object name 'branch-name'
bbodenmiller
1
Anda mungkin mendapatkan kesalahan itu dalam 2 kasus 1. Ketika <branch name> yang diberikan tidak mengandung <commit id> yang diberikan 2. 2. checkout <branch name> bukan <branch name> yang diberikan
DreamUth
0
Karena pertanyaan ini memiliki beberapa jawaban skrip yang bagus, saya menambahkan favorit saya.
Yang ini akan menunjukkan kepada Anda, untuk $nkomit terakhir di $brmana cabang-cabang berisi masing-masing:
git merge-base --is-ancestor
. Cabang saat ini berisi C jika C adalah leluhurHEAD
, jadi:if git merge-base --is-ancestor $hash HEAD; then echo I contain commit $hash; else echo I do not contain commit $hash; fi
/bin/true
awalnya diimplementasikan sebagaiexit 0
dan/bin/false
sebagaiexit 1
. (Kerang modern kemudian dibangun di.)Jawaban:
Ada beberapa cara untuk mencapai hasil ini. Opsi naif pertama adalah menggunakan
git log
dan mencari komit tertentu menggunakangrep
, tetapi itu tidak selalu tepatAnda lebih baik menggunakan
git branch
secara langsung untuk menemukan semua cabang yang mengandung diberikanCOMMIT_ID
menggunakanLangkah selanjutnya adalah mencari cabang saat ini yang dapat dilakukan sejak
git 1.8.1
menggunakanDan digabungkan bersama sebagai
Tetapi perintah di atas tidak mengembalikan benar atau salah dan ada versi yang lebih pendek yang mengembalikan kode keluar 0 jika komit di cabang saat ini ATAU kode keluar 1 jika tidak
Kode keluar memang bagus, tetapi seperti yang Anda inginkan string
true
ataufalse
sebagai jawaban, Anda perlu menambahkan sedikit lebih banyak dan kemudian dikombinasikan denganif
dari bash Anda dapatkansumber
grep
dapat menghasilkan false positive jikagit log
menyebutkan commit SHA karena alasan lain, misalnya disebutkan dalam pesan commit sebagai hasil dari port dari cabang lain.--format=format:%H
untukgit log
.Dapatkan daftar cabang yang berisi komit spesifik.
Periksa apakah cabang memiliki komit tertentu.
Cari cabang (katakanlah,
feature
) dengan pencocokan tepat .misalnya Jika Anda memiliki 3 cabang lokal disebut
feature
,feature1
,feature2
makaAnda juga dapat mencari di kedua
local
danremote
cabang (gunakan-a
) atau hanya diremote
cabang (gunakan-r
).sumber
grep
sini juga bisa menghasilkan false positive jika ada cabang lain yang mengandung komit yang namanya juga mengandung<branch-name>
sebagai substring.grep -E '(^|\s)branchname$'
-r
("jarak jauh") atau-a
("semua")git branch
untuk mencari cabang yang mungkin tidak direplikasi dalam klon repo lokal.git branch --all --contains <commit-id>
Diekstraksi komentar oleh @torek sebagai jawaban:
Lihat duplikat yang diajukan untuk cara menemukan semua cabang yang berisi komit yang ditentukan.
Untuk mengetahui apakah cabang saat ini berisi komit C, gunakan perintah "plumbing"
git merge-base --is-ancestor
. Cabang saat ini berisi C jika C adalah leluhur HEAD, jadi:(Catatan: dalam skrip shell, perintah yang keluar nol adalah "benar" sedangkan yang keluar bukan nol adalah "salah".)
sumber
Untuk membuat daftar cabang lokal yang mengandung komit:
git branch --contains <commit-id>
dan untuk mencantumkan semua cabang, termasuk hanya jarak jauh, yang mengandung komit:
git branch -a --contains <commit-id>
Demikian pula untuk memeriksa apakah komit ada di cabang tertentu:
git log <branch> | grep <commit_id>
dan jika cabang tidak ada, awali nama cabang dengan
origin/
sumber
-a
. Terima kasih atas sarannya!Ya alternatif lain:
Ini bekerja paling baik untuk saya karena itu juga akan bekerja pada cabang-cabang terpencil yang di-cache secara lokal seperti
remotes/origin/master
, yanggit branch --contains
tidak akan bekerja.Ini mencakup lebih dari pertanyaan OP tentang hanya "cabang saat ini" tetapi saya merasa bodoh untuk menanyakan versi "cabang apa pun" dari pertanyaan ini jadi saya memutuskan untuk tetap mengirim di sini.
sumber
Ini akan mengembalikan nama cabang target jika ada komit di cabang itu. Kalau tidak, perintah akan gagal.
sumber
error: malformed object name 'branch-name'
Karena pertanyaan ini memiliki beberapa jawaban skrip yang bagus, saya menambahkan favorit saya.
Yang ini akan menunjukkan kepada Anda, untuk
$n
komit terakhir di$br
mana cabang-cabang berisi masing-masing:Yang ini mirip tetapi melakukan hal yang sama untuk daftar cabang:
sumber