(สิ่งนี้เริ่มเป็นคำตอบสำหรับคำถามที่ซ้ำกันฉันได้ทำการแก้ไขเล็กน้อยเพื่อทำความสะอาดแล้ว)
ลูกศรภายในของ Git ทั้งหมดเป็นทางเดียวชี้ไปทางด้านหลัง ดังนั้นจึงไม่มีไวยากรณ์ที่สะดวกสั้น ๆ สำหรับการย้ายไปข้างหน้า: เป็นไปไม่ได้
มีความเป็นไปได้ที่จะ "เคลื่อนตัวเข้าหาลูกศร" แต่วิธีที่จะทำนั้นน่าประหลาดใจหากคุณไม่เคยเห็นมาก่อนและจากนั้นก็เห็นได้ชัดในภายหลัง สมมติว่าเรามี:
A <-B <-C <-D <-E <-- last
^
|
\--------- middle
ใช้middle~2ต่อไปนี้ลูกศรสองครั้งจากการกลับไปC Aแล้วเราจะย้ายจากCไปยังDอย่างไร คำตอบคือเราเริ่มต้นที่Eใช้ชื่อlastและถอยหลังทำงานจนกว่าเราจะได้รับการmiddle, การบันทึกจุดที่เราแวะไปพร้อมกัน จากนั้นเราก็ย้ายไปเท่าที่เราต้องการในทิศทางของlast: ย้ายขั้นตอนหนึ่งไปหรือสองDE
สิ่งนี้สำคัญอย่างยิ่งเมื่อเรามีสาขา:
D--E <-- feature1
/
...--B--C <-- master
\
F--G <-- feature2
ซึ่งกระทำการเป็นหนึ่งในขั้นตอนหลังจากที่C? ไม่มีคำตอบที่ถูกต้องจนกว่าคุณจะเพิ่มคำถาม: ในทิศทางของ feature___ (เติมในช่องว่าง)
ในการระบุการกระทำระหว่างC(ไม่รวมC) ตัวเองและ, พูดG, เราใช้:
git rev-list --topo-order --ancestry-path master..feature2
--topo-orderทำให้แน่ใจว่าแม้ในที่ที่มีความซับซ้อนแตกแขนงและผสานการกระทำออกมาเพื่อทอพอโลยีเรียง สิ่งนี้จำเป็นเฉพาะในกรณีที่โซ่ไม่เป็นเชิงเส้น --ancestry-pathจำกัด หมายความว่าเมื่อเราทำงานย้อนกลับจากfeature2เราเท่านั้นที่กระทำรายการที่มีการกระทำCเป็นหนึ่งในบรรพบุรุษของตัวเอง นั่นคือถ้ากราฟ - หรืออันที่เกี่ยวข้องของมัน - จริง ๆ แล้วมีลักษณะเช่นนี้:
A--B--C <-- master
\ \
\ F--G--J <-- feature2
\ /
H-------I <-- feature3
คำขอที่เรียบง่ายของแบบฟอร์มfeature2..masterระบุกระทำJ, GและIและFและHในการสั่งซื้อบางส่วน ด้วย--ancestry-pathเราเคาะออกHและIพวกเขาไม่ได้เป็นลูกหลานของเพียงของC Aด้วย--topo-orderเราให้แน่ใจว่าการสั่งการแจงนับจริงJแล้วนั้นGF
git rev-listคำสั่งรั่วไหลรหัสกัญชาเหล่านี้ออกจากการส่งออกมาตรฐานของตนต่อหนึ่งบรรทัด หากต้องการเลื่อนไปหนึ่งก้าวไปข้างหน้าตามทิศทางของfeature2เราก็แค่ต้องการบรรทัดสุดท้าย
เป็นไปได้ (และดึงดูดและมีประโยชน์) ในการเพิ่ม--reverseเพื่อให้git rev-listพิมพ์คำสั่งในลำดับที่กลับรายการหลังจากสร้างพวกเขา มันใช้งานได้ แต่ถ้าคุณใช้มันในไปป์ไลน์แบบนี้:
git rev-list --topo-order --ancestry-path --reverse <id1>...<id2> | head -1
เพื่อให้ได้รับ "ส่งมอบครั้งต่อไปในทิศทางของ id2" และมีรายการที่ยาวมากของgit rev-listคำสั่งคำสั่งสามารถรับไปป์ที่ขาดเมื่อพยายามเขียนheadซึ่งหยุดอ่านอินพุตและออก เนื่องจากโดยปกติแล้วเชลล์จะละเว้นข้อผิดพลาดที่ขาดไปจึงมักใช้งานได้ เพียงตรวจสอบให้แน่ใจว่ามันถูกละเว้นในการใช้งานของคุณ
นอกจากนี้ยังดึงดูดให้เพิ่ม-n 1ไปที่คำสั่งพร้อมกับgit rev-list --reverseอย่าทำมัน! ที่ทำให้git rev-listหยุดชะงักหลังจากที่เดินหนึ่งก้าวกลับมาแล้วกลับรายการ (ขาเข้า) ของกระทำเยี่ยมชม ดังนั้นนี่ผลิตออกมา<id2>ทุกครั้ง
ข้อความด้านที่สำคัญ
โปรดทราบว่าด้วยส่วนของกราฟ "diamond" หรือ "benzene ring":
I--J
/ \
...--H M--... <-- last
\ /
K--L
ย้ายหนึ่งกระทำ "ไปข้างหน้า" จากHที่มีต่อlastคุณจะได้รับอย่างใดอย่างหนึ่ง หรือI Kไม่มีอะไรที่คุณสามารถทำได้เกี่ยวกับสิ่งนั้น: การกระทำทั้งสองเป็นขั้นตอนเดียว ถ้าคุณเริ่มจากการกระทำที่เกิดขึ้นและไปอีกขั้นตอนหนึ่งตอนนี้คุณต้องยอมรับว่าคุณเริ่มต้นเส้นทางไหน
การรักษานี้คือการหลีกเลี่ยงการย้ายทีละขั้นตอนและล็อคเข้ากับโซ่ขึ้นอยู่กับเส้นทาง แต่ถ้าคุณวางแผนที่จะเยี่ยมชมโซ่ของเส้นทางบรรพบุรุษทั้งหมดก่อนที่จะทำอะไรให้ทำรายการทั้งหมดของพันธะสัญญาทั้งหมด:
git rev-list --topo-order --reverse --ancestry-path A..B > /tmp/list-of-commits
จากนั้นไปที่แต่ละการกระทำในรายการนี้ทีละครั้งและคุณจะได้รับห่วงโซ่ทั้งหมด --topo-orderจะให้แน่ใจว่าคุณจะตีIโทโพโลยีJในการสั่งซื้อนั้นและKโทโพโลยีLในลำดับที่ (แม้ว่าจะไม่มีวิธีที่ง่ายต่อการคาดการณ์ว่าคุณจะทำคู่ IJ ก่อนหรือหลังคู่ KL)