ฉันจะบอกได้อย่างไรว่าการกระทำหนึ่งเป็นการสืบทอดของการกระทำอื่น


146

ด้วย Git ฉันจะบอกได้อย่างไรว่าคนที่ทำหน้าที่ในสาขาของฉันเป็นลูกหลานของอีกคนหนึ่งที่ทำ


2
คำถามเดียวกันถามตรงข้าม: stackoverflow.com/questions/18345157/…
Chris Cleeland

11
คุณเปลี่ยนคำตอบที่ยอมรับได้ไหม ส่วนใหญ่ชอบ--is-ancestorวิธีการแก้ปัญหา
Robert Siemer

คำตอบ:


51

หากคุณต้องการตรวจสอบโปรแกรมนี้ (เช่นในสคริปต์) คุณสามารถตรวจสอบว่าgit merge-base A Bเท่ากับgit rev-parse --verify A(จากนั้น A สามารถเข้าถึงได้จาก B) หรือถ้าเป็นgit rev-parse --verify B(จากนั้น B สามารถเข้าถึงได้จาก A) git rev-parseจำเป็นต้องมีการแปลงจากกระทำชื่อเพื่อกระทำ SHA-1 / กระทำ ID

การใช้Likegit rev-listในคำตอบของ VonCก็เป็นไปได้เช่นกัน

แก้ไข:ในปัจจุบัน Git git merge-base --is-ancestorมีการสนับสนุนอย่างชัดเจนสำหรับการค้นหานี้ในรูปแบบของ


หากหนึ่งในความมุ่งมั่นที่คุณถามเกี่ยวกับเป็นเคล็ดลับสาขาแล้วgit branch --contains <commit>หรือgit branch --merged <commit>อาจจะเป็นทางออกที่ดีไม่ใช่โปรแกรม


1
อาจเป็นไปได้ว่าวิธีที่เร็วที่สุดคือไปgit checkout -b quickcheck <more-recent-commit-ID>แล้วgit branch --contains <older-commit-ID>(และgit branch -D quickcheckเพื่อกำจัดสาขาชั่วคราว)
Clee

2
สองแนวทางที่เป็นไปได้ทั้งสองวิธีนั้นแย่กว่าแนวทางของ @ MattR มาก
jwg

6
@jwg: คำตอบของ MattR นั้นดีกว่า แต่คำตอบนี้ (และอาจเป็นที่ยอมรับได้) ถือเป็น git 1.8.0 และgit merge-base --is-ancestor2 ปี
Jakub Narębski

@ JakubNarębskiยุติธรรมพอขอโทษ
jwg

2
ในพื้นที่เก็บข้อมูลขนาดใหญ่ (2 ล้านคอมมิชชัน) ฉันเปรียบเทียบความเร็วgit branch --contains <commit>และgit merge-base --is-ancestor ...: 3 m40s เทียบกับ 0.14s
hagello

259

จาก Git 1.8.0 สิ่งนี้ได้รับการสนับสนุนเป็นตัวเลือกmerge-base:

git merge-base --is-ancestor <maybe-ancestor-commit> <descendant-commit>

จากหน้าคน:

--is-บรรพบุรุษ

ตรวจสอบว่าคนแรกเป็นบรรพบุรุษของคนที่สองและออกด้วยสถานะ 0 ถ้าเป็นจริงหรือด้วยสถานะ 1 ถ้าไม่ ข้อผิดพลาดจะถูกส่งสัญญาณโดยสถานะที่ไม่ใช่ศูนย์ที่ไม่ใช่ 1

ตัวอย่างเช่น:

git merge-base --is-ancestor origin/master master; echo $?

4
ดี! นี่คือเชลล์สคริปต์ที่รวบรวมคำตอบนี้ในบางสิ่งด้วยผลลัพธ์ที่มนุษย์สามารถนำกลับมาใช้ได้: gist.github.com/simonwhitaker/6354592
Simon Whitaker

1
กล่าวอีกนัยหนึ่ง: git merge-base THING --is-ancestor OF_THING && echo yes || echo noเช่น:git merge-base my-feature-branch --is-ancestor master && echo yes || echo no
1735594

2
@smarber git merge-base --is-ancestor -- commit commitทำงานเพื่อแฮชที่ด้านข้างของฉันด้วยgit2.1.4 (Debian / Devuan 7.10 jessie) และ 1.9.1 (Ubuntu 14.04 trusty) ซึ่งตอนนี้ค่อนข้างเก่าแล้ว มันทำงานได้แม้สำหรับ Debian ดังเสียงฮืด ๆ sudo apt-get install git/wheezy-backportsถ้าคุณทำ
Tino

15

การดำเนินการเช่นนี้ขึ้นอยู่กับแนวคิดของช่วงการแก้ไขที่มีรายละเอียดในคำถาม SO: " ความแตกต่างใน 'ต้นกำเนิดบันทึก git / ต้นแบบ' vs 'กำเนิดบันทึก git / ต้นแบบ .. ' "

git rev-list ควรจะสามารถเดินจากความมุ่งมั่นไปอีกจนกว่าจะถึงถ้าเข้าถึงได้

ดังนั้นฉันจะลอง:

git rev-list --boundary 85e54e2408..0815fcf18a
0815fcf18a19441c1c26fc3495c4047cf59a06b9
8a1658147a460a0230fb1990f0bc61130ab624b2
-85e54e240836e6efb46978e4a1780f0b45516b20

(ขอบเขตคอมมิชชันถูกขึ้นต้นด้วย - )

หากการคอมมิชชันล่าสุดแสดงเหมือนกันกับคอมมิชชันแรกใน git rev-listคำสั่ง, มันเป็นการคอมมิตที่เข้าถึงได้จากการคอมมิทที่สอง.

หากความมุ่งมั่นครั้งแรกไม่สามารถเข้าถึงได้จากครั้งที่สองgit rev-listไม่ควรส่งคืนสิ่งใด

git rev-list --boundary A..B

จะเสร็จโดยAถ้าABสามารถเข้าถึงได้จาก
มันเหมือนกับ:

git rev-list --boundary B --not A

ด้วยอ้างอิงในเชิงบวกและอ้างอิงเชิงลบ มันจะเริ่มต้นที่และเดินกลับผ่านกราฟจนกว่าจะพบการแก้ไขที่สามารถเข้าถึงได้จาก ฉันจะยืนยันว่าหากสามารถเข้าถึงได้โดยตรงจากมันจะพบ (และแสดงเพราะตัวเลือก) ตัวเองBA
BA
AB--boundaryA


ดูเหมือนว่าจะเป็นกรณีใช้งานทั่วไปที่ฉันประหลาดใจที่ git ยังไม่ได้เผยแพร่คำสั่ง "ลายคราม" ที่ทำสิ่งนี้
Lawrence I. Siden

1
@lsiden: จริง หมายเหตุด้านข้าง: อย่าลืมว่าเพื่อตรวจสอบบางอย่างโดยทางโปรแกรมคุณไม่ควรใช้คำสั่งเครื่องเคลือบ (เช่นในstackoverflow.com/questions/6976473/ … ) แต่คำสั่งการวางท่อประปา (ดังที่แสดงในstackoverflow.com/questions / 3878624 / … )
VonC

โอ้มนุษย์ดูเหมือนว่าฉันจะต้องกลับไปทำงานกับการเขียนสคริปต์เชลล์ของฉัน!
Lawrence I. Siden

1
คำถาม: ทำไม-85e54e2...ข้อมูลโค้ดในมีเครื่องหมายลบ ยังพิมพ์ผิดที่เป็นไปได้: "... เหมือนกันกว่าการกระทำครั้งแรก ... "
sdaau

1
@sdaau -หมายความว่ามันเป็นขอบเขตที่กระทำ ฉันได้แก้ไขคำตอบเพื่อให้ชัดเจนยิ่งขึ้นรวมถึงรีเฟรชลิงก์ doc และแก้ไขข้อผิดพลาดสำหรับคำตอบอายุ 5 ปีนี้
VonC

11

อีกวิธีหนึ่งที่จะใช้และgit loggrep

git log --pretty=format:%H abc123 | grep def456

สิ่งนี้จะสร้างเอาต์พุตหนึ่งบรรทัดหาก commit def456 เป็นบรรพบุรุษของ commit abc123 หรือไม่มีเอาต์พุตอื่น

โดยปกติคุณสามารถหลีกเลี่ยงการ--prettyโต้แย้ง แต่จำเป็นถ้าคุณต้องการตรวจสอบให้แน่ใจว่าคุณค้นหาแฮชการคอมมิชชันที่เกิดขึ้นจริงเท่านั้นไม่ใช่ผ่านข้อคิดเห็นการบันทึกและอื่น ๆ


ฉันคาดว่าการแก้ปัญหานี้จะช้า แต่จริงๆแล้วมันค่อนข้างเร็วแม้สำหรับโครงการที่มี 20k + ความมุ่งมั่น
Renato Zannon

2
แทนที่จะ--prettyใช้ - ออนไลน์: ใช้git log --oneline ce2ee3d | grep ec219ccงานได้ดี
วงศ์

3

https://stackoverflow.com/a/13526591/895245กล่าวถึงตอนนี้เพื่อทำให้มนุษย์เป็นมิตรมากขึ้น:

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'

นี้จะกลับมา 'ไม่เกี่ยวข้อง' ถ้าพารามิเตอร์ทั้งชี้ไปที่เดียวกันกระทำ
MIK

1

git show-branch branch-sha1 commit-sha1

ที่ไหน:

  • branch-sha1: the sha1 ในสาขาของคุณที่คุณต้องการตรวจสอบ
  • กระทำ -sha1: sha1 ของการกระทำที่คุณต้องการตรวจสอบ

0

หากคุณกำลังใช้ git merge-base --is-ancestorงานให้ใช้ Git 2.28 (ไตรมาสที่ 3 ปี 2020)

ด้วย Git 2.28 (ไตรมาสที่ 3 ปี 2020) มีการย้ายบางฟิลด์ใน " struct commit" ที่ไม่จำเป็นต้องมีอยู่เสมอมาเพื่อส่งมอบแผ่นพื้น

ดูกระทำ c752ad0 , กระทำ c49c82a , กระทำ 4844812 , กระทำ 6da43d9 (17 มิถุนายน 2020) โดยAbhishek Kumar (abhishekkumar2718 )
(รวมโดยJunio C Hamano - gitster-ในการกระทำ d80bea4 , 6 กรกฎาคม 2020)

commit-graph: แนะนำ commit_graph_data_slab

ลงชื่อออกโดย: Abhishek Kumar

คอมมิชชัน commit ถูกใช้ในหลายบริบท อย่างไรก็ตามสมาชิกgenerationและgraph_posจะใช้สำหรับการดำเนินการที่เกี่ยวข้องกับการกระทำกราฟและหน่วยความจำเสีย

การสูญเสียนี้จะเด่นชัดมากขึ้นเมื่อเราเปลี่ยนเป็นหมายเลขรุ่น v2 ซึ่งใช้หมายเลขรุ่น 64 บิตแทนรุ่นปัจจุบัน 32 บิต

ในขณะที่พวกเขามักจะเข้าถึงด้วยกันเราจะแนะนำ struct commit_graph_dataและย้ายพวกมันไปที่commit_graph_dataพื้น

ในขณะที่ชุดทดสอบโดยรวมวิ่งอย่างรวดเร็วเพียงเท่าmaster(ชุด: 26m48s, master: 27m34s เร็วขึ้นจาก 2.87%) คำสั่งบางอย่างเช่นการgit merge-base --is-ancestorได้รับการชะลอตัวลง 40% ขณะที่ค้นพบโดย Szeder Gábor
หลังจากลดการเข้าถึงการคอมมิตพื้นที่การลดลงยังคงมีอยู่ แต่ใกล้ถึง 20%

Derrick Stolee เชื่อว่าการชะลอตัวลงนั้นเกิดจากอัลกอริธึมพื้นฐานมากกว่าความเชื่องช้าของการเข้าถึงคอมมิตและเราจะติดตามผลในซีรีย์ต่อไป


-1

สร้างคำตอบของ itub ในกรณีที่คุณต้องทำสิ่งนี้กับแท็กทั้งหมดในที่เก็บ:

for i in `git tag` ; do echo -ne $i "\t" ; git log --pretty=format:%H $i | (grep <commit to find> || echo ""); done
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.