Git 2.18 (Q2 2018) จะปรับปรุง--preserve-merge
ตัวเลือกอย่างมากโดยการเพิ่มตัวเลือกใหม่
" git rebase
" เรียนรู้ " --rebase-merges
" เพื่อปลูกโครงสร้างทั้งหมดของการกระทำอื่น ๆ กราฟ
(หมายเหตุ: Git 2.22, Q2 2019 จริงเลิกใช้แล้ว --preserve-merge
และ Git 2.25, Q1 2020 หยุดโฆษณาในgit rebase --help
เอาต์พุต "" )
ดูกระทำ 25cff9f ,กระทำ 7543f6f , กระทำ 1131ec9 , กระทำ 7ccdf65 , กระทำ 537e7d6 , กระทำ a9be29c , กระทำ 8f6aed7 , กระทำ 1644c73 , กระทำ d1e8b01 , กระทำ 4c68e7d , กระทำ 9055e40 , กระทำ cb5206e , กระทำ a01c2a5 , กระทำ 2f6b1d1 , กระทำ bf5c057 (25 เมษายน 2018) โดยโยฮันเน Schindelin (dscho
)
ดูกระทำ f431d73 (25 เมษายน 2018) โดยสเตฟานสนั่น (stefanbeller
)
ดูกระทำ 2429335 (25 เมษายน 2018) โดยฟิลลิปไม้ (phillipwood
)
(รวมโดยJunio C Hamano - gitster
-ในการกระทำ 2c18e6a , 23 พฤษภาคม 2018)
pull
: ยอมรับ--rebase-merges
เพื่อสร้างโทโพโลยีสาขาใหม่
คล้ายกับpreserve
โหมดเพียงแค่ส่ง--preserve-merges
ตัวเลือกไปยังrebase
คำสั่งmerges
โหมดก็จะส่ง
--rebase-merges
ตัวเลือก
สิ่งนี้จะช่วยให้ผู้ใช้สามารถรีบูตทอพอโลยีที่ไม่น่ารำคาญเมื่อดึงคอมมิตใหม่โดยไม่ทำให้แบนราบ
git rebase
หน้าคนตอนนี้มีส่วนเต็มทุ่มเทให้กับการ rebasing ประวัติศาสตร์ที่มีการผสาน
สารสกัดจาก:
มีเหตุผลที่ถูกต้องว่าทำไมนักพัฒนาอาจต้องการสร้างการรวมซ้ำ: เพื่อรักษาโครงสร้างของสาขา (หรือ "กระทำโทโพโลยี") เมื่อทำงานกับสาขาที่เกี่ยวข้องกันหลายสาขา
ในตัวอย่างต่อไปนี้ผู้พัฒนาทำงานบนแขนงหัวข้อที่ refactors วิธีการกำหนดปุ่มและบนอีกหัวข้อสาขาที่ใช้การปรับโครงสร้างใหม่นั้นเพื่อใช้ปุ่ม "รายงานข้อบกพร่อง"
ผลลัพธ์ของgit log --graph --format=%s -5
อาจมีลักษณะเช่นนี้:
* Merge branch 'report-a-bug'
|\
| * Add the feedback button
* | Merge branch 'refactor-button'
|\ \
| |/
| * Use the Button class for all buttons
| * Extract a generic Button class from the DownloadButton one
ผู้พัฒนาอาจต้องการรีบูตสิ่งที่ผูกมัดให้ใหม่กว่าmaster
ในขณะที่รักษาโทโพโลยีสาขาเช่นเมื่อคาดว่าสาขาหัวข้อแรกจะรวมเข้ากับmaster
เร็วกว่าอันที่สองพูดเพื่อแก้ไขความขัดแย้งผสานกับการเปลี่ยนแปลง
DownloadButton
คลาสที่สร้างขึ้น master
มันกลายเป็น
การรีบูตนี้สามารถทำได้โดยใช้--rebase-merges
ตัวเลือก
ดูคอมมิชชัน 1644c73สำหรับตัวอย่างเล็ก ๆ :
rebase-helper
--make-script
: แนะนำการตั้งค่าสถานะเพื่อลดการรวม
ซีเควนเซอร์เพิ่งเรียนรู้คำสั่งใหม่ที่มีวัตถุประสงค์เพื่อสร้างโครงสร้างสาขาใหม่ ( คล้ายกับวิญญาณ--preserve-merges
แต่มีการออกแบบที่หักน้อยกว่าอย่างมาก )
มาอนุญาตให้rebase--helper
สร้างรายการสิ่งที่ต้องทำใช้ประโยชน์จากคำสั่งเหล่านี้ที่ถูกกระตุ้นโดย--rebase-merges
ตัวเลือกใหม่
สำหรับทอพอโลยีแบบนี้ (ที่ HEAD ชี้ไปที่ C):
- A - B - C (HEAD)
\ /
D
รายการสิ่งที่สร้างขึ้นจะมีลักษณะเช่นนี้:
# branch D
pick 0123 A
label branch-point
pick 1234 D
label D
reset branch-point
pick 2345 B
merge -C 3456 D # C
ความแตกต่าง--preserve-merge
คืออะไร?
Commit 8f6aed7อธิบาย:
กาลครั้งหนึ่งนักพัฒนานี่คิดว่าจะไม่เป็นการดีถ้าพูดว่า Git สำหรับ Windows 'ติดตั้งอยู่บนแกน Git อาจแสดงเป็นกิ่งก้านหนาและถูกนำกลับมาใช้ใหม่บนแกน Git เพื่อ คงชุดของชุดแพทช์เชอร์รี่เลือก?
ความพยายามเริ่มแรกที่จะตอบคำถามนี้คือ: git rebase --preserve-merges
.
อย่างไรก็ตามการทดลองนั้นไม่ได้มีจุดประสงค์เพื่อเป็นตัวเลือกแบบโต้ตอบเท่านั้นและมีการสำรองหมูไว้เท่านั้นgit rebase --interactive
เนื่องจากการใช้งานคำสั่งนั้นดูคุ้นเคยและคุ้นเคยเป็นอย่างมาก: ถูกออกแบบโดยบุคคลเดียวกันกับผู้ออกแบบ--preserve-merges
: ของคุณอย่างแท้จริง
และโดย "ของคุณอย่างแท้จริง" ผู้เขียนอ้างถึงตัวเอง: Johannes Schindelin ( dscho
)ซึ่งเป็นเหตุผลหลัก (มีฮีโร่อีกสองสามคน - Hannes, Steffen, Sebastian, ... ) ที่เรามี Git สำหรับ Windows (แม้ว่าย้อนกลับไปในวัน - 2009 - นั่นไม่ใช่เรื่องง่าย )
เขาทำงานที่ Microsoft มาตั้งแต่เดือนกันยายน 2558ซึ่งสมเหตุสมผลเมื่อพิจารณาว่า Microsoft ใช้ Git อย่างหนักและต้องการบริการของเขา
ว่าแนวโน้มเริ่มต้นในปี 2013 จริงกับ TFS ตั้งแต่นั้นมา Microsoft จัดการพื้นที่เก็บข้อมูล Git ที่ใหญ่ที่สุดในโลก ! และตั้งแต่ตุลาคม 2018 ไมโครซอฟท์ได้รับ GitHub
คุณสามารถเห็นโยฮันเนสพูดในวิดีโอนี้สำหรับ Git Merge 2018 ในเดือนเมษายน 2018
หลังจากนั้นไม่นานนักพัฒนาคนอื่น (ฉันกำลังมองหาคุณ Andreas! ;-)) ตัดสินใจว่าจะเป็นการดีที่จะอนุญาตให้--preserve-merges
รวมกับ--interactive
(กับ caveats!) และผู้ดูแล Git (ดีผู้ดูแล Git ชั่วคราว) ในช่วงที่ไม่อยู่ของจูนิโอนั่นคือ) เห็นด้วยและนั่นคือเมื่อความเย้ายวนใจของการ--preserve-merges
ออกแบบเริ่มกระจุยค่อนข้างเร็วและไร้เสน่ห์
โยนาธานกำลังพูดถึงที่นี่ Andreas Schwabจาก Suse
คุณสามารถเห็นบางส่วนของการสนทนาของพวกเขากลับในปี 2012
เหตุผล? ใน--preserve-merges
โหมดผู้ปกครองผสานกระทำ (หรือว่าเรื่องของใด ๆ ที่กระทำ) ที่ไม่ได้ระบุไว้อย่างชัดเจน แต่
โดยนัยตามชื่อกระทำการส่งผ่านไปยังpick
คำสั่ง
นี่เองที่ทำให้มันเป็นไปไม่ได้เช่นการกระทำการสั่งซื้อ
ไม่ต้องพูดถึงที่จะย้ายกระทำระหว่างกิ่งไม้หรือเทพห้ามแยกสาขาหัวข้อออกเป็นสอง
อนิจจาข้อบกพร่องเหล่านี้ยังป้องกันโหมดนั้น (ซึ่งมีจุดประสงค์ดั้งเดิมเพื่อตอบสนองความต้องการของ Git สำหรับ Windows ด้วยความหวังเพิ่มเติมว่ามันอาจเป็นประโยชน์ต่อผู้อื่นเช่นกัน) จากการให้บริการความต้องการของ Git สำหรับ Windows
ห้าปีต่อมาเมื่อมันไม่สามารถป้องกันได้จริง ๆ ที่มีชุดแพทช์ฮ็อดจ์ - พอดจ์ขนาดใหญ่ที่เกี่ยวข้องบางส่วนแพทช์ที่ไม่เกี่ยวข้องบางส่วนใน Git สำหรับ Windows ที่ถูก rebased ลงบนแท็ก Git หลักเป็นครั้งคราว ของโชคไม่ดี
git-remote-hg
ซีรีส์ที่ที่ Git ล้าสมัยครั้งแรกสำหรับวิธีการแข่งขันของ Windows เพียงเพื่อถูกทอดทิ้งโดยไม่ต้องดูแลในภายหลัง) ไม่สามารถป้องกันได้จริง ๆ " Git garden shears " เกิดมา : สคริปต์ลูกหมูบนหลังรีบูต ที่แรกจะกำหนดสาขาโทโพโลยีของแพทช์ที่จะ rebased สร้างรายการสิ่งที่ต้องทำหลอกสำหรับการแก้ไขเพิ่มเติมเปลี่ยนผลเป็นรายการสิ่งที่ต้องทำจริง (การใช้งานหนักของexec
คำสั่งเพื่อ "ใช้" คำสั่งรายการสิ่งที่ต้องทำที่หายไป) และสร้างชุดข้อมูลแก้ไขที่ด้านบนสุดของการคอมมิทฐานใหม่
(สคริปต์ Git garden shears อ้างอิงในโปรแกรมแก้ไขนี้ในการคอมมิชชัน 9055e40 )
นั่นคือในปี 2013
และใช้เวลาประมาณสามสัปดาห์ในการออกแบบและนำมันมาใช้เป็นสคริปต์นอกกรอบ จำเป็นต้องพูดการใช้งานต้องใช้เวลาไม่กี่ปีในการทำให้มีเสถียรภาพในขณะที่การออกแบบนั้นได้รับการพิสูจน์ว่ามีเสียง
ด้วยแพทช์นี้คุณงามความดีของ Git สวนกรรไกรมาถึงgit
rebase -i
ตัวเอง
การส่งผ่าน--rebase-merges
ตัวเลือกจะสร้างรายการสิ่งที่ต้องทำซึ่งสามารถเข้าใจได้อย่างง่ายดายและในกรณีที่เห็นได้ชัดว่าจะจัดลำดับใหม่ได้อย่างไร
สาขาใหม่ที่สามารถนำมาใช้โดยการใส่คำสั่งและเรียกlabel
และเมื่อโหมดนี้มีเสถียรภาพและเป็นที่ยอมรับในระดับสากลเราสามารถคัดค้านข้อผิดพลาดในการออกแบบที่เกิดขึ้นได้merge <label>
--preserve-merges
Git 2.19 (ไตรมาสที่ 3 ปี 2018) ปรับปรุง--rebase-merges
ตัวเลือกใหม่ด้วยการทำงานกับ--exec
มัน
"การ--exec
" เลือกที่จะ " git rebase --rebase-merges
" วางคำสั่ง exec ในสถานที่ที่ไม่ถูกต้องซึ่งได้รับการแก้ไข
ดูกระทำ 1ace63b (9 สิงหาคม 2018) และกระทำ f0880f7 (6 สิงหาคม 2018) โดยโยฮันเน Schindelin (dscho
)
(รวมโดยJunio C Hamano - gitster
-ในการกระทำ 750eb11 , 20 สิงหาคม 2018)
rebase --exec
: ทำให้มันทำงานกับ --rebase-merges
ความคิดของ--exec
คือการผนวกโทรหลังจากที่แต่ละexec
pick
ตั้งแต่การแนะนำfixup!
/ s quash!
กระทำความคิดนี้ถูกขยายเพื่อนำไปใช้กับ "เลือกอาจตามด้วย fixup / สควอชโซ่" กล่าวคือผู้บริหารจะไม่ถูกแทรกระหว่าง a pick
และใด ๆ ที่เกี่ยวข้อง
fixup
หรือsquash
บรรทัด
การดำเนินงานในปัจจุบันใช้เป็นเคล็ดลับสกปรกเพื่อให้บรรลุว่าจะอนุมานว่ามีเพียงรับ / fixup / สควอชคำสั่งแล้ว
แทรกexec
สายใด ๆ ก่อนpick
แต่แรกและผนวกสุดท้าย
กับรายการสิ่งที่ต้องทำที่เกิดจากgit rebase --rebase-merges
การดำเนินงานที่เรียบง่ายนี้แสดงให้เห็นว่าปัญหาของมันก็ก่อให้เกิดสิ่งที่ผิดที่แน่นอนเมื่อมีlabel
, reset
และmerge
คำสั่ง
ลองเปลี่ยนการใช้งานเพื่อทำสิ่งที่เราต้องการอย่างแน่นอน: มองหา
pick
สายข้ามโซ่การแก้ไข / สควอชแล้วแทรกexec
เส้น
นวดแล้วล้างซ้ำ
หมายเหตุ: เราใช้ความเจ็บปวดในการแทรกก่อนบรรทัดความคิดเห็นทุกครั้งที่เป็นไปได้เนื่องจากคอมมิทที่ว่างเปล่าจะถูกแสดงโดยสายการเลือกความคิดเห็น (และเราต้องการแทรกบรรทัด exec ของการเลือกก่อนหน้าก่อนที่จะสายดังกล่าวไม่ได้หลังจากนั้น)
ในขณะที่มันยังเพิ่มexec
บรรทัดหลังจากmerge
คำสั่งเพราะพวกเขามีความคล้ายคลึงกันในจิตวิญญาณกับpick
คำสั่ง: พวกเขาเพิ่มการกระทำใหม่
Git 2.22 (Q2 2019) แก้ไขการใช้ refs / rewritten / ลำดับชั้นเพื่อเก็บสถานะกลาง rebase ซึ่งโดยเนื้อแท้ทำให้ลำดับชั้นต่อ worktree
ดูกระทำ b9317d5 , กระทำ 90d31ff , กระทำ 09e6564 (7 มีนาคม 2019) โดยNguyễnTháiNgọc Duy (pclouds
)
(ผสานโดยJunio C Hamano - gitster
- in 917f2cd , 09 Apr 2019)
ตรวจสอบให้แน่ใจ refs / rewritten / เป็นต่อ worktree
a9be29c (sequencer: สร้าง refs ที่สร้างโดยlabel
คำสั่ง worktree-local, 2018-04-25, Git 2.19) เพิ่มrefs/rewritten/
เป็นพื้นที่อ้างอิงต่อ worktree
น่าเสียดายที่ (ไม่ดีของฉัน) มีสถานที่สองแห่งที่จำเป็นต้องมีการอัปเดตเพื่อให้แน่ใจว่าเป็นจริงต่อการทำงาน
- add_per_worktree_entries_to_dir()
มีการอัปเดตเพื่อให้แน่ใจว่ารายชื่อผู้อ้างอิงจะดูที่รายการต่อการทำงานrefs/rewritten/
แทนการซื้อต่อรายการหนึ่งรายการ
common_list[]
มีการอัปเดตเพื่อให้git_path()
ส่งคืนตำแหน่งที่ถูกต้อง ซึ่งรวมถึง "rev-parse --git-path
"
ความยุ่งเหยิงนี้สร้างโดยฉัน
ฉันเริ่มพยายามแก้ไขด้วยการแนะนำrefs/worktree,
ที่อ้างอิงทั้งหมดจะเป็นต่อ worktree โดยไม่ต้องรักษาพิเศษ
โชคไม่ดีอ้างอิง / เขียนใหม่มาก่อน refs / worktree ดังนั้นนี่คือทั้งหมดที่เราสามารถทำได้
ด้วย Git 2.24 (Q4 2019) "git rebase --rebase-merges
" เรียนรู้ที่จะผลักดันกลยุทธ์การผสานที่แตกต่างกันและผ่านตัวเลือกเฉพาะของกลยุทธ์ให้กับพวกเขา
ดูกระทำ 476998d (4 กันยายน 2019) โดยเอลียาห์ Newren (newren
)
ดูกระทำ e1fac53 , กระทำ a63f990 , กระทำ 5dcdd74 , กระทำ e145d99 , กระทำ 4e6023b , กระทำ f67336d , กระทำ a9c7107 , กระทำ b8c6f24 , กระทำ d51b771 , กระทำ c248d32 , กระทำ 8c1e240 , กระทำ 5efed0e , กระทำ 68b54f6 , กระทำ 2e7bbac , กระทำ 6180b20 , กระทำ d5b581f (31 ก.ค. 2562) โดยโยฮันเน Schindelin (dscho
)
(ผสานโดยJunio C Hamano - gitster
- in 917a319 , 18 Sep 2019)
ด้วย Git 2.25 (ไตรมาสที่ 1 ปี 2020) ตรรกะที่ใช้ในการบอก worktree local และ repository ทั่วโลกของ repository ได้รับการแก้ไขเพื่อช่วยในการผสาน
ดูกระทำ f45f88b , กระทำ c72fc40 , กระทำ 8a64881 , กระทำ 7cb8c92 , กระทำ e536b1f (21 ตุลาคม 2019) โดยSzeder Gábor (szeder
)
(ผสานโดยJunio C Hamano - gitster
- in db806d7 , 10 Nov 2019)
path.c
: อย่าเรียกใช้match
ฟังก์ชันโดยไม่มีค่าtrie_find()
ลงชื่อออกโดย: SZEDER Gábor
'logs / refs' ไม่ใช่เส้นทางเฉพาะของต้นไม้ที่ทำงานได้ แต่เนื่องจากกระทำ b9317d55a3 (ตรวจสอบให้แน่ใจว่า refs / rewritten / เป็น per-worktree, 2019-03-07, v2.22.0-rc0) ' git rev-parse --git-path
' ได้คืนพา ธ ปลอม ถ้า '' ต่อท้าย/
เป็นปัจจุบัน:
$ git -C WT/ rev-parse --git-path logs/refs --git-path logs/refs/
/home/szeder/src/git/.git/logs/refs
/home/szeder/src/git/.git/worktrees/WT/logs/refs/
เราใช้trie
โครงสร้างข้อมูลเพื่อตัดสินใจได้อย่างมีประสิทธิภาพว่าเส้นทางเป็นของ dir ทั่วไปหรือทำงานเฉพาะต้นไม้
ตามที่มันเกิดขึ้นb9317d55a3เรียกจุดบกพร่องที่เก่าแก่เหมือนกับการtrie
ติดตั้งเพิ่มใน4e09cf2acf (" path
: เพิ่มประสิทธิภาพการตรวจสอบ dir ทั่วไป", 2015-08-31, Git v2.7.0-rc0 - ผสานอยู่ในชุดที่ 2 )
ตามความคิดเห็นที่อธิบายtrie_find()
มันควรจะเรียกฟังก์ชั่นการจับคู่ที่กำหนด 'fn' สำหรับคำนำหน้า
สิ่งนี้ไม่เป็นความจริง: มีสามสถานที่ซึ่ง trie_find () เรียกฟังก์ชันจับคู่ แต่หนึ่งในนั้นขาดการตรวจสอบการมีอยู่ของค่า
b9317d55a3เพิ่มสองปุ่มใหม่ในtrie
:
- '
logs/refs/rewritten
' และ
- '
logs/refs/worktree
' ถัดจากที่มีอยู่แล้ว ' logs/refs/bisect
'
สิ่งนี้ส่งผลให้trie
โหนดที่มีพา ธ ' logs/refs/
' ซึ่งไม่เคยมีมาก่อนและไม่มีค่าที่แนบมา
แบบสอบถามสำหรับ ' logs/refs/
' พบโหนดนี้แล้วพบว่าไซต์หนึ่งไซต์ของmatch
ฟังก์ชันที่ไม่ตรวจสอบการมีอยู่ของค่าและจะเรียกใช้match
ฟังก์ชันที่มีNULL
ค่า
เมื่อ match
ฟังก์ชั่นcheck_common()
ถูกเรียกใช้โดยมีNULL
ค่ามันจะคืนค่า 0 ซึ่งบ่งชี้ว่าเส้นทางที่สอบถามไม่ได้อยู่ในไดเรกทอรีทั่วไปทำให้เกิดเส้นทางปลอมในท้ายที่สุด
เพิ่มเงื่อนไขที่หายไปtrie_find()
เพื่อที่จะไม่เรียกใช้ฟังก์ชันการจับคู่ด้วยค่าที่ไม่มีอยู่
check_common()
จะไม่ต้องตรวจสอบอีกต่อไปว่าได้รับค่าที่ไม่ใช่ค่า NULL ดังนั้นให้ลบเงื่อนไขนั้น
ฉันเชื่อว่าไม่มีเส้นทางอื่นที่สามารถก่อให้เกิดการส่งออกปลอมที่คล้ายกัน
AFAICT เฉพาะคีย์อื่นที่ทำให้เกิดฟังก์ชันการจับคู่ที่ถูกเรียกด้วยNULL
ค่าคือ ' co
' (เพราะคีย์ ' common
' และ ' config
')
อย่างไรก็ตามเนื่องจากไม่ได้อยู่ในไดเรกทอรีที่เป็นของไดเรกทอรีทั่วไปจึงต้องใช้เส้นทางเฉพาะของต้นไม้ทำงาน
git --rebase-merges
git --preserve-merges
ดูคำตอบของฉันด้านล่าง