ด้วย Mercurial ฉันจะ "บีบอัด" ชุดการเปลี่ยนแปลงให้เป็นชุดเดียวก่อนที่จะผลักดันได้อย่างไร


96

สมมติว่าฉันมีที่เก็บ Mercurial ในพื้นที่และระยะไกล ตอนนี้ฉันเริ่มทำงานกับฟีเจอร์หนึ่ง ฉันทำงานกับมันและเมื่อฉันคิดว่าเสร็จแล้วฉันก็ยอมรับชุดการเปลี่ยนแปลง การทดสอบอีกเล็กน้อยฉันพบว่าฉันสามารถปรับปรุงคุณสมบัตินี้เพิ่มเติมได้โดยการปรับแต่งบางอย่างในโค้ด ฉันทำการเปลี่ยนแปลงและกระทำ 20 นาทีต่อมาฉันพบว่ามีข้อบกพร่องในฟีเจอร์ใหม่นี้ดังนั้นฉันจึงแก้ไขและยืนยันเช่นกัน

ตอนนี้ฉันมีชุดการเปลี่ยนแปลง 3 ชุดที่ฉันต้องการส่งไปยังที่เก็บระยะไกลเป็นชุดการเปลี่ยนแปลงหนึ่งชุดที่มีข้อความ "การใช้คุณลักษณะ X"

ฉันจะทำสิ่งนี้ได้อย่างไรโดยไม่ต้องยุ่งยากมากนัก ฉันเชื่อว่าฉันสามารถทำได้ด้วยแพตช์ แต่ดูเหมือนว่าจะต้องทำงานมาก


40
เห็นได้ชัดว่าไม่ใช่สถานที่ของฉันที่จะพูดถึงคุณโดยไม่พยายามบีบอัดชุดการเปลี่ยนแปลงของคุณ แต่คุณอาจต้องการพิจารณาว่าค่าครึ่งหนึ่งของการควบคุมเวอร์ชันกำลังตอบว่า "ทำไม" ไม่ใช่แค่ "อะไร" ในเดือนและปีต่อมา การแสดงที่ถูกต้องว่าคุณลักษณะเกิดขึ้นได้อย่างไรและในขั้นตอนใดอาจมีคุณค่าในอนาคต ดูเหมือนว่าการทิ้ง ...
Ry4an Brase

สิ่งนี้นำไปสู่คำถามอื่น ... อะไรคือความแตกต่างระหว่าง 'histedit' และ 'ยุบ'
sylvanaar

1
การยุบเป็นส่วนย่อยของคุณสมบัติของฮิสแก้ไขและฮิสแก้ไขมี UX ที่ใช้งานง่ายกว่ามาก
Stefan Rusek

1
นอกจากนี้ยังมีกลไกในการแก้ไขข้อความชุดการเปลี่ยนแปลงที่ผสาน
Stefan Rusek

1
@ Ry4an: อันที่จริงการบีบ / การยุบเพิ่มความเกี่ยวข้องกับการควบคุมเวอร์ชันในบางกรณี หากไม่มีการบีบฉันจะมีสองคอมมิตทุกวันที่ไม่มีส่วนเกี่ยวข้องกับคุณสมบัติหรือการแก้ไขข้อบกพร่อง แต่มีไว้สำหรับการย้ายรหัสจากแล็ปท็อปไปยังเดสก์ท็อปและในทางกลับกัน เพียงแค่เพิ่มเสียงรบกวนในประวัติเวอร์ชัน
John Reynolds

คำตอบ:


39

แล้วCollapse Extensionล่ะ?


20
ทักทายจากอนาคต! ฉันเพิ่ง googled สำหรับฟังก์ชันเดียวกันและเห็นได้ชัดว่าทุกวันนี้ hg สนับสนุนสิ่งนี้นอกกรอบด้วยhg rebase --collapse. ตรวจสอบ hg wiki บนคำสั่ง rebase เนื่องจากคำถามนี้เป็นผลการค้นหาโดยรวมครั้งที่ 3 และเป็นครั้งแรกใน stackoverflow ฉันจึงคิดว่าข้อมูลอาจมีประโยชน์
a.peganz

1
คำอวยพรจากต่อไปในอนาคต !! ดูเหมือนว่าส่วนขยาย rebase จะมีเป้าหมายที่การย้ายชุดการเปลี่ยนแปลงจากสาขาหนึ่งไปยังอีกสาขาหนึ่งเท่านั้น ใช่มีตัวเลือก - ยุบ แต่ยังคงใช้ได้เฉพาะเมื่อย้ายชุดการเปลี่ยนแปลงข้ามสาขา ดู < mercurial-scm.org/wiki/… >
Brad Oestreicher

3
คุณสามารถใช้hg rebaseกับ--collapseภายในสาขาเดียว
UuDdLrLrSs

52

histeditขยายเป็นสิ่งที่คุณกำลังมองหา

hg histedit -o

หรือ

hg histedit --outgoing

จะแสดงรายการชุดการเปลี่ยนแปลงที่ส่งออก จากรายการคุณสามารถ

  • พับชุดการเปลี่ยนแปลง 2 ชุดขึ้นไปสร้างชุดการเปลี่ยนแปลงเดียว
  • วางชุดการเปลี่ยนแปลงเพื่อลบออกจากประวัติ
  • จัดลำดับชุดการเปลี่ยนแปลงใหม่ตามที่คุณต้องการ

histedit จะแจ้งให้คุณทราบถึงข้อความคอมมิตใหม่ของชุดการเปลี่ยนแปลงที่พับไว้ซึ่งค่าเริ่มต้นจะเป็นสองข้อความโดยมี "\ n *** \ n" คั่น

คุณยังสามารถรับผลลัพธ์ที่คล้ายกันได้โดยใช้ส่วนขยาย mq แต่มันยากกว่ามาก

คุณยังสามารถใช้ส่วนขยายการยุบเพื่อทำการพับได้ แต่มันไม่ได้มี UI ที่ดีเท่าและไม่มีวิธีแก้ไขข้อความคอมมิต การแก้ไขข้อความคอมมิตที่เป็นผลลัพธ์ยังช่วยให้สามารถล้างข้อความสุดท้ายซึ่งเป็นสิ่งที่ฉันมักจะใช้


ขอบคุณนั่นคือสิ่งที่ฉันต้องการ คงจะดีถ้าคุณสามารถทำได้จากใน TortoiseHg - แต่บรรทัดคำสั่งนั้นง่ายพอ
sylvanaar

21

ใช่คุณสามารถทำได้ด้วยแพตช์: สมมติว่างานของคุณอยู่ในชุดการเปลี่ยนแปลง 100 ถึง 110 รวมอยู่ด้วย

  1. สร้างแพทช์:

    % hg export -o mypatch 100:110 --git

  2. อัปเดตเป็น 99:

    % hg update 99

  3. ใช้โปรแกรมแก้ไขด้วย --no-commit (มิฉะนั้นคุณจะได้รับชุดการเปลี่ยนแปลงทั้งหมดกลับมา):

    % hg import --no-commit mypatch

  4. ยอมรับการเปลี่ยนแปลงทั้งหมดในครั้งเดียว:

    % hg commit

  5. ตอนนี้คุณมีสองหัว (110 และ 111) ซึ่งควรจะเทียบเท่ากันในแง่ของไฟล์ที่สร้างในไดเร็กทอรีการทำงานของคุณ - อาจแตกต่างกันเพื่อความมีสติก่อนที่จะลอกไฟล์เก่าออก:

    % hg strip 100

ตกลงตอนนี้ฉันสะกดหมดแล้วดูเหมือนจะยาว แต่หลังจากทำมาหลายครั้งแล้วฉันก็ไม่คิดว่ามันจะเป็นงานที่น่าเบื่อเกินไป ...


1
คำตอบที่ดี แต่มีความจำเป็นที่: ขยาย MQ ต้องเปิดใช้งาน
Chris Kelly

หากต้องการรวมการเปลี่ยนแปลงในไฟล์ไบนารีด้วยอย่าลืมใช้ --git option: ตัวอย่างเช่น "hg export -o mypatch 100: 110 --git" สำหรับข้อมูลเพิ่มเติมโปรดดู: stackoverflow.com/a/12537738/ 367663 ฉันได้ใช้เสรีภาพในการแก้ไขคำตอบ
Kharlos Dominguez

1
ดูเหมือนจะซับซ้อนทำไมไม่hg strip --keepแล้วทำทุกอย่างในครั้งเดียว?
G.Demecki

@ G.Demecki เนื่องจากเป็นการดำเนินการที่อาจสูญเสียมาก .. ? แม้ว่า MQ จะมากเกินไป (และไม่แนะนำให้ใช้) ยกเว้นเมื่อต้องการเวิร์กโฟลว์เช่นนี้
user2864740

@ user2864740 คุณพูดถูกเพราะฉันไม่ใช่ผู้เชี่ยวชาญด้าน Mercurial แต่โดยค่าเริ่มต้นhg stripจะวางข้อมูลสำรองไว้ใน.hg/strip-backup/ไดเรกทอรี ฉันเดาว่ามันไม่ปลอดภัยเท่าgit reflogแต่ก็ยังให้การช่วยเหลืออยู่บ้าง
G. Demecki

19

หากคุณใช้ TortoiseHg การใช้สามารถเลือกการแก้ไขได้สองครั้ง (ใช้ CTRL เพื่อเลือกการแก้ไขที่ไม่ใช่ครั้งต่อ ๆ ไป) คลิกขวาและเลือก"ประวัติการบีบอัด" "ประวัติศาสตร์การบีบอัด"

หลังจากนั้นคุณจะได้รับรายการการเปลี่ยนแปลงใหม่ในส่วนหัวใหม่โดยเริ่มจากการเปลี่ยนแปลงแรกที่คุณเลือกไว้ก่อนหน้านั้นรายการการเปลี่ยนแปลงจะมีรายการการเปลี่ยนแปลงที่สืบเนื่องกันทั้งหมดระหว่างรายการที่คุณเลือก

คุณสามารถถอดรายการการเปลี่ยนแปลงเก่าออกได้หากคุณไม่ต้องการอีกต่อไป: ใช้ส่วนขยายMQ อีกครั้งใน TortoiseHg: คลิกขวาที่รายการเปลี่ยนแปลงครั้งแรกที่จะต้องถอดกับลูกหลานของมัน, "ปรับเปลี่ยนประวัติศาสตร์ -> สตริป"


18

วิธีการที่ต้องการของฉันของการใช้ MQ สำหรับพับนี้ใช้ TortoiseHg ตามที่อธิบายไว้ที่นี่ อย่างไรก็ตามสามารถทำได้อย่างง่ายดายจากบรรทัดคำสั่งดังนี้:

hg qimport -r <first>:<last> 
    -- where <first> and <last> are the first and last changesets 
    -- in the range of revisions you want to collapse

hg qpop <first>.diff
    -- remove all except for the first patch from the queue
    -- note: mq names patches <#>.diff when it imports them, so we're using that here

hg qfold <next>.diff
    -- where <next> is <first>+1, then <first>+2, until you've reached <last>

hg qfinish -a
    -- apply the folded changeset back into the repository

(อาจมีวิธีที่ดีกว่าในการทำขั้นตอน qfold แต่ฉันไม่รู้เพราะฉันมักจะใช้ TortoiseHg สำหรับการดำเนินการนั้น)

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


4

hg collapseและhg histeditเป็นวิธีที่ดีที่สุด หรือจะเป็นวิธีที่ดีที่สุดถ้าพวกเขาทำงานได้อย่างน่าเชื่อถือ ... ฉันhisteditต้องล้มเหลวด้วยกองถ่ายภายในสามนาทีCollapseก็ไม่ดีขึ้นมาก

คิดว่าฉันอาจแบ่งปัน BKM อีกสองคน:

  1. hg rebase --collapse

    ส่วนขยายนี้แจกจ่ายด้วย Mercurial ฉันยังไม่มีปัญหากับมัน คุณอาจต้องเล่นเกมบางเกมเพื่อหลีกhg rebaseเลี่ยงข้อ จำกัด - โดยพื้นฐานแล้วมันไม่ชอบการรีเบตใหม่ให้กับบรรพบุรุษในสาขาเดียวกันชื่อหรือค่าเริ่มต้นแม้ว่าจะอนุญาตให้เล่นซ้ำระหว่างสาขา (ชื่อ)

  2. ย้ายที่เก็บ ( foo/.hg) ไปยังไดเร็กทอรีการทำงาน ( bar) และไฟล์ ไม่ใช่วิธีอื่น ๆ

บางคนได้พูดคุยเกี่ยวกับการสร้างต้นไม้โคลนสองต้นและคัดลอกไฟล์ระหว่างกัน หรือปะติดระหว่างกัน. แต่มันง่ายกว่าที่จะย้าย.hgไดเรกทอรี

hg clone project work
... lots of edits
... hg pull, merge, resolve
hg clone project, clean
mv work/.hg .hg.work
mv clean/.hg work/.hg
cd work
... if necessary, pull, nerge, reconcile - but that would only happen because of a race
hg push

สิ่งนี้ใช้ได้ตราบเท่าที่ที่เก็บจริง.hgต้นไม้ไม่ขึ้นอยู่กับไดเร็กทอรีการทำงานและไฟล์

หากพวกเขาไม่เป็นอิสระ ...


ในปี 2558 histeditเป็นตัวเลือกที่ดีมากสำหรับงานนี้ ฉันยังไม่เชื่อใจเพราะฉันทำ git rebase -i แต่ก็ไม่ผิดพลาด .. อย่างน้อยเวอร์ชันที่ใหม่กว่าจะทำให้คุณอยู่ในสาขาชั่วคราวหากมีสิ่งผิดปกติเกิดขึ้นอย่างมากดังนั้นครั้งเดียวที่ชุดการเปลี่ยนแปลงจะถูกถอดออก คือหลังจากที่สาขาใหม่ได้รับการยอมรับ
user2864740

2

ฉันไม่เคยใช้ Mercurial แต่ฟังดูคล้ายกับสิ่งที่ Martin Fowler พูดถึงในบล็อกของเขาเมื่อไม่นานมานี้:

http://martinfowler.com/bliki/MercurialSquashCommit.html


มันดูซับซ้อนกว่าเล็กน้อย แต่ขอบคุณสำหรับลิงค์ จริงๆแล้วฉันหวังว่าจะมีส่วนขยายมหัศจรรย์ที่จะทำในสิ่งที่ฉันต้องการเช่นการดึงและการปลูกถ่ายด้วยการดึงและการเปลี่ยนเชอร์รี่
Lucas

0

ทำไมไม่hg strip --keepสั่งแค่?

จากนั้นคุณสามารถทำการเปลี่ยนแปลงทั้งหมดเป็นคอมมิตเดียว


@ สตรอเบอร์รี่ไม่ให้คำตอบ ?? คิดว่ามันตอบคำถามของผู้เขียนได้อย่างสมบูรณ์แบบ คุณสามารถอธิบายประเด็นของคุณอย่างละเอียดได้หรือไม่?
G. Demecki

มันเป็นประวัติศาสตร์ที่เก่าแก่ดังนั้นฉันจะถอนคำพูดออก แต่คำตอบที่ได้รับการอนุมัติดูเหมือนจะเป็นการอ้างอิงที่เชื่อถือได้มากกว่า
สตรอเบอรี่

1
@ สตรอเบอร์รี่แท้จริงมันเป็นด้ายโบราณ แต่คำตอบที่ยอมรับนั้นล้าสมัยเนื่องจาก Mercurial ไม่ต้องการส่วนขยายของบุคคลที่สามแยกต่างหากสำหรับงานนี้อีกต่อไป
G. Demecki

0

HistEdit จะทำในสิ่งที่คุณต้องการ แต่มันอาจจะมากเกินไป หากสิ่งเดียวที่คุณต้องการคือการพับชุดการเปลี่ยนแปลงบางอย่างเข้าด้วยกันCollapse Extensionจะทำงานได้


1
แม้ว่ามันจะให้การใช้งานและทำความเข้าใจ UI ได้ง่ายกว่ามากซึ่งก็มีเหตุผลเพียงพอที่จะใช้ แต่มันก็มีกลไกในการแก้ไขข้อความชุดการเปลี่ยนแปลงที่ผสานซึ่งเป็นอีกสิ่งหนึ่งที่ฉันอยากทำเสมอเมื่อฉัน รวมชุดการเปลี่ยนแปลง
Stefan Rusek

และปัญหาในการทำความเข้าใจ UI เพียงอย่างเดียวก็คือสิ่งที่ไม่เข้าใจจริงๆ .. อย่างไรก็ตามในอดีตในขณะที่ histedit อนุญาตให้เปลี่ยน 'ข้อความ' และเปลี่ยนข้อความเมื่อ 'พับ' Histedit นั้นสมบูรณ์แบบ หากมีสิ่งใดแสดงว่าส่วนขยายการยุบนั้นไม่เป็นประโยชน์
user2864740

0

สมมติว่าคุณมีสองรายการที่ไม่ได้เผยแพร่THISและยอมรับTHATใน Mercurial และต้องการให้พวกเขาเข้าร่วมในการกระทำเดียว ณTHISจุด ::

... --> THIS --> ... --> THAT --> ... --> LAST

ตรวจสอบว่าไม่ได้เผยแพร่คอมมิตของคุณ ::

$ hg glog -r "draft() & ($THIS | $THAT)"

อัปเดตเพื่อLASTกระทำ ::

$ hg up

และนำเข้าคอมมิตถึงTHISMQ ::

$ hg qimport $THIS::.

ยกเลิกการใช้แพตช์ทั้งหมดและใช้ครั้งแรกเท่านั้นTHIS::

$ hg qpop -a
$ hg qpush
$ hg qapplied
... THIS ...

เข้าร่วมกับTHAT::

$ hg qfold $THATNAME

หมายเหตุในการค้นหาชื่อTHATNAMEใช้ ::

$ hg qseries

ใช้แพตช์ทั้งหมดและย้ายไปที่ประวัติที่เก็บ ::

$ hg qpush -a
$ hg qfinish -a

โพสต์บล็อกของฉันในเรื่องจะเข้าร่วมสองกระทำใน Mercurial


0

ใช่strip --keepใช้ได้กับคำถามของผู้เขียน แต่แตกต่างจากรุ่นอื่นเล็กน้อยเช่นหากคุณมีเวอร์ชัน 1 ถึง 30 แต่ต้องการยุบเวอร์ชัน 12-15 เท่านั้น โซลูชันอื่น ๆ ใช้ได้ผล แต่ไม่ได้strip --keepผล

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.