ฉันสามารถทำสควอชใน Mercurial ได้หรือไม่?


110

ฉันมีคู่กรรมที่ควรจะเป็นเพียงหนึ่งเดียว ถ้าฉันใช้คอมไพล์ฉันจะใช้:

git rebase -i <some-commit-before>

แล้วสควอชพวกเขา

ฉันสามารถทำใน Mercurial ได้หรือไม่? ถ้าเป็นอย่างไร

คำตอบ:


88

ได้คุณสามารถทำได้โดยใช้ Mercurial โดยไม่มีส่วนขยายใด ๆ โดยการเชื่อมต่อชุดการเปลี่ยนแปลง

อีกวิธีหนึ่งหากคุณต้องการใช้ส่วนขยายที่คุณสามารถใช้ได้:


ใช่ฉันตอบคำถามนั้นจากคำถามหลอกลวงที่ฉันชอบในความคิดเห็นของฉันเกี่ยวกับคำถามทั่วไป ฉันคิดว่ามันเป็นคำตอบของคุณในเรื่องนั้น
Ry4an Brase

4
หมายเหตุด้านข้างเล็กน้อย: ส่วนขยาย Histedit แจกจ่ายด้วย Mercurial 2.3 และใหม่กว่า คุณต้องเปิดใช้งาน
Paidhi

1
ในชุดการเปลี่ยนแปลงที่เชื่อมโยงกันใช้แนวคิดนามธรรมของ "repos" ฉันจะอ้างอิงสิ่งเหล่านั้นได้อย่างไร ตัวอย่าง: hg -R oldrepo export ... สร้าง "abort: repository oldrepo not found!
Aleksandr Levchuk

13
แค่พยายามสควอช 2 คอมมิต ฉันต้องการหน้าวิกิที่มีคำสั่งมากกว่า 10 คำสั่งหรือส่วนขยายทางเลือกหรือไม่?
Aleksandr Levchuk

3
ดูความคิดเห็น Histedit อยู่ในตัวแล้วคุณเพียงแค่ต้องเปิดใช้งาน (เนื่องจากไม่มีคำสั่งเริ่มต้นที่จะแก้ไขประวัติ)
Ry4an Brase

43

ที่ชอบคือhg strip --keepคำสั่ง จากนั้นฉันก็ทำการเปลี่ยนแปลงทั้งหมดในคอมมิตเดียว

เป็นวิธีที่เร็วและสะดวกสบายที่สุดสำหรับฉันเพราะฉันชอบทำงานเล็ก ๆ น้อย ๆ ระหว่างการทำงานประจำวันของฉัน)


หมายเหตุ 1: stripจำเป็นmqต้องเปิดใช้งานส่วนขยายในตัว
หมายเหตุ 2: ไคลเอนต์ Git / Mercurial ที่ฉันชอบ (SmartGit / Hg) ต่อท้ายด้วย--keepพารามิเตอร์เริ่มต้นในระหว่างstrip. และสิ่งที่สะดวกกว่า: มีตัวเลือกที่เรียกว่าjoin commits:]


4
คำสั่งแบบเต็มสำหรับ hg strip คือ หมายเลขการแก้ไขของการคอมมิตครั้งแรกที่คุณต้องการสควอชกับอันสุดท้ายhg strip --keep --rev [rev] อยู่ที่ไหนrev
Nicolas Forney

3
@NicolasForney ไม่แน่นอน--revเป็นทางเลือกคำสั่งเต็มคือhg strip --keep [rev]
G.Demecki

การแก้ไขมีผลบังคับใช้สำหรับฉันใน 3.3.3: hg help stripให้และถนัดการแก้ไขให้ฉันhg strip [-k] [-f] [-n] [-B bookmark] [-r] REV... abort: empty revision set
Roman Starkov

3
การใช้hg stripไม่ใช่ความคิดที่ดีที่สุด มันไม่ปลอดภัยอย่างแน่นอน ลองhg histeditบางทีลองใช้ส่วนขยายวิวัฒนาการ
Martin Thomson

ดูเหมือนเป็นวิธีที่เป็นธรรมชาติที่สุดสำหรับคนที่ชอบคอมไพล์;)
foo

32

ขยาย Rebaseทำงานเช่นเสน่ห์ ในการสควอช 2 คอมมิต:

$ hg rebase --dest .~2 --base . --collapse

Dot เป็นทางลัดสำหรับการแก้ไขปัจจุบัน

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

$ hg rebase --dest {destination branch (e.g. master)} --base . --collapse

วิธีการทำงาน:

ใส่คำอธิบายภาพที่นี่

(จากhttp://mercurial-scm.org/wiki/RebaseExtension#Collapsing )


1
คุณพบ "~ 2" สำหรับสองคอมมิตที่ใด
Mi-La

1
มีอธิบายไว้ในหัวข้อ revsets ดู hg help revsets
markand

13

ถ้าคุณกำลังอ่านคำตอบนี้คุณสามารถลืมทุกตัวเลือกอื่น ๆ ที่กล่าวถึงในคำตอบนี้และใช้foldคำสั่งจากส่วนขยายวิวัฒนาการ

evolveเป็นส่วนเสริมของ Mercurial ซึ่งช่วยให้เรามีประวัติที่ไม่แน่นอนที่ปลอดภัย แต่ก็ยังคงทดลองอยู่ คุณสามารถใช้มันได้โดยการโคลนจากrepoและเพิ่มใน. hgrc ของคุณเช่นนี้

[extensions]
evolve = ~/evolve/hgext/evolve.py

สมมติว่าคุณโคลนวิวัฒนาการ repo ในโฮมไดเร็กทอรีของคุณ ตอนนี้คุณพร้อมที่จะไป hg help foldนอกจากนี้คุณยังสามารถดูเพื่อขอความช่วยเหลือจาก

คำสั่งพับ

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

ตอนนี้สมมติว่าคุณมีประวัติดังต่อไปนี้

a -> b -> c -> d -> e -> f -> g

คุณต้องการที่จะสควอชe, และf gคุณทำได้

hg up g
hg fold -r e

ผลลัพธ์จะเป็นอย่างไร

a -> b -> c -> d -> h

ที่hเป็นเซ็ตที่มีการเปลี่ยนแปลงจากทั้งสามกระทำe, fและgและ

นอกจากนี้คุณยังสามารถพับชุดการเปลี่ยนแปลงจากตรงกลางของประวัติกล่าวคือคุณไม่จำเป็นต้องเลือกโซ่ที่มีปลาย สมมติว่าคุณต้องการที่จะพับb, และc dคุณทำได้

hg up d
hg fold -r b
hg evolve --all

ซึ่งจะส่งผลให้

a -> i -> j

ที่iเป็นเซ็พับb, c, dและเป็นเช่นเดียวกับการแก้ไข j คู่มือผู้ใช้ Evolveเป็นสิ่งที่ต้องอ่านh


ดูเหมือนว่า rebase จะครอบคลุมกรณีการใช้งานส่วนขยายนั้นส่วนใหญ่ (อาจทั้งหมด?) และแน่นอนว่าเป็นกรณีที่ถูกถามในคำถามนี้ คุณลักษณะที่ยอดเยี่ยมของส่วนขยายนั้นคือการซ่อน (แทนที่จะลบ) การแก้ไขที่คุณแทนที่ แต่--keepตัวเลือกของ rebase จะครอบคลุมสิ่งนี้ (ตามด้วยการทำเครื่องหมายการแก้ไขเป็นความลับหรือใช้แถบเมื่อคุณตรวจสอบผลลัพธ์แล้ว) แม้แต่การย้ายการแก้ไขระหว่างการแก้ไขอื่น ๆ ก็สามารถทำได้ด้วยลำดับของคำสั่ง rebase สองคำสั่ง
Arthur Tacca

... นอกจากนี้หากคุณกำลังทำสิ่งที่ซับซ้อนจริงๆคุณสามารถโคลน repo ในเครื่องก่อนเพื่อใช้เป็นข้อมูลสำรองได้เสมอ เมื่อพิจารณาว่าหายาก (หวังว่า!) นั่นคือความพยายามน้อยกว่าการเรียนรู้วิธีใช้ส่วนขยายใหม่ทั้งหมด
Arthur Tacca

"NameError: name 'execfile' ไม่ได้กำหนดไว้" - ซึ่งหมายความว่าวิวัฒนาการถูกเขียนด้วย Python 2 ซึ่งโดยพื้นฐานแล้วเป็นยุคหิน
Neil G

1
@NeilG mercurial ยังไม่รองรับ Python 3
Pulkit Goyal

2
@NeilG ใช่ชุมชน Mercurial กำลังทำงานอย่างหนักเพื่อรับการสนับสนุน py3 โดยเร็ว
Pulkit Goyal

1

ด้วย Mercurial 4.8 (พฤศจิกายน 2018, 9 ปีต่อมา) คุณสามารถพิจารณาคำสั่งใหม่ได้hg absorb(เป็นคุณลักษณะทดลองมาก่อน )

ดู "การดูดซับการกระทำที่เปลี่ยนแปลงใน Mercurial 4.8 "

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

ในระดับเทคนิคhg absorbพบการเปลี่ยนแปลงที่ไม่ได้ผูกมัดทั้งหมดและพยายามแมปแต่ละบรรทัดที่เปลี่ยนแปลงกับคอมมิตก่อนหน้าที่ไม่คลุมเครือ
สำหรับการเปลี่ยนแปลงทุกครั้งที่สามารถแมปได้อย่างหมดจดการเปลี่ยนแปลงที่ไม่ได้กำหนดไว้จะถูกดูดซับไปยังการกระทำก่อนหน้านี้ที่เหมาะสม การกระทำที่ได้รับผลกระทบจากการดำเนินการจะถูกปรับฐานใหม่โดยอัตโนมัติ
หากไม่สามารถแมปการเปลี่ยนแปลงกับคอมมิตก่อนหน้าที่ไม่คลุมเครือได้การเปลี่ยนแปลงนั้นจะไม่ถูกผูกมัดและผู้ใช้สามารถถอยกลับไปใช้เวิร์กโฟลว์ที่มีอยู่ได้ (เช่นการใช้hg histedit)

ตรรกะการเขียนซ้ำอัตโนมัติhg absorbถูกนำไปใช้โดยทำตามประวัติของบรรทัดซึ่งแตกต่างกันโดยพื้นฐานจากแนวทางที่ใช้hg histeditหรือgit rebaseซึ่งมักจะอาศัยกลยุทธ์การผสานตามการผสาน3 ทางเพื่อรับไฟล์เวอร์ชันใหม่ที่มีการป้อนข้อมูลหลายรายการ เวอร์ชัน

วิธีนี้รวมกับความจริงที่ว่า hg ดูดซับข้ามการเปลี่ยนแปลงด้วยแอพพลิเคชั่นที่คลุมเครือหมายความว่าการดูดซับ hg จะไม่พบกับความขัดแย้งในการผสาน!

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


0

ฉันคิดว่าchistedit(สร้างขึ้นตั้งแต่ Mercurial 2.3) เป็นรุ่นที่ใกล้เคียงที่สุดกับrebase -iMercurial บริสุทธิ์ ( chisteditเป็นเวอร์ชันโต้ตอบhistedit) เมื่ออยู่ใน histedit foldคำสั่งแมปไป rebase ของsquashและrollคำสั่งแมปไป fixuprebase ดูhisteditเอกสารสำหรับข้อมูลเพิ่มเติม

นี่คือตัวอย่างง่ายๆ สมมติว่าคุณมีสิ่งต่อไปนี้และต้องการย้ายการเปลี่ยนแปลงทั้งหมดของ 1e21c4b1 ไปยังการแก้ไขก่อนหน้านี้และเก็บข้อความของการแก้ไขก่อนหน้านี้ไว้

@  1e21c4b1 drees tip
|  A commit you want to squash
o  b4a738a4 drees
|  A commit
o  788aa028 drees
|  Older stuff

คุณสามารถเรียกใช้hg chistedit -r b4a738a4เพื่อแก้ไขประวัติกลับไปที่ b4a738a4 ใน chistedit ให้คุณเคอร์เซอร์ลงไปที่ 1e21c4b1 และกดrเพื่อระบุว่าคุณต้องการม้วนการแก้ไขนั้น โปรดทราบว่าลำดับในฮิสแก้ไข (เก่าที่สุดไปหาใหม่ที่สุด) จะกลับจากhg log(ใหม่สุดไปเก่าสุด)

#0  pick   160:b4a738a49916   A commit
#1  ^roll  161:1e21c4b1500c

หลังจากเลือกการเปลี่ยนแปลงของคุณแล้วคุณจึงเลือก cจะยอมรับผลลัพธ์มีดังต่อไปนี้:

@ bfa4a3be เคล็ดลับ drees | กระทำ o 788aa028 drees | สิ่งที่เก่ากว่า

หากคุณค่อนข้างใหม่สำหรับพวกเขาhisteditอาจเป็นทางเลือกที่ดีกว่าchisteditเนื่องจากมีคำอธิบายคำสั่งในไฟล์ฮิสแก้ไขสำหรับการอ้างอิง ใช้เวลาแก้ไขอีกเล็กน้อยเพื่อตั้งค่าคำสั่งโดยใช้การแก้ไขข้อความปกติ (เช่นเดียวกับ rebase ปกติ)

หมายเหตุหากต้องการใช้อย่างใดอย่างหนึ่งhisteditหรือchisteditคุณต้องเพิ่มhisteditในส่วนขยายของคุณใน ~ / .hgrc ของคุณ:

[extensions]
histedit =

ฉันแนะนำchisteditเนื่องจากใกล้เคียงที่สุดrebase -iและทำงานได้ทุกที่ในประวัติศาสตร์ หากคุณต้องการเพียงแค่สมัคร / ปรับแต่งการแก้ไขปัจจุบันในการแก้ไขก่อนหน้านี้ให้ @G stripข้อเสนอแนะของ Demecki นั้นดีเพราะสิ่งที่เกิดขึ้นนั้นชัดเจน สร้างขึ้นตั้งแต่ Mercuria 2.8 เพื่อให้ได้ผลลัพธ์เทียบเท่าข้างต้นคุณสามารถทำสิ่งต่อไปนี้:

hg strip .
hg add
hg commit --amend

หมายเหตุstripเช่น histedit ต้องเปิดใช้งานใน ~ / .hgrc ของคุณ:

[extensions]
strip =

0

สมมติว่าคุณต้องการสควอช (รวมกัน) 2 คอมมิตล่าสุด

  1. ค้นหาหมายเลขการแก้ไข

    hg log -G -l 3
    

    ผลลัพธ์ที่เป็นไปได้:

    @  changeset:   156:a922d923cf6f
    |  branch:      default
    |  tag:         tip
    |  user:        naXa!
    |  date:        Thu Dec 13 15:45:58 2018 +0300
    |  summary:     commit message 3
    |
    o  changeset:   155:5feb73422486
    |  branch:      default
    |  user:        naXa!
    |  date:        Thu Dec 13 15:22:15 2018 +0300
    |  summary:     commit message 2
    |
    o  changeset:   154:2e490482bd75
    |  branch:      default
    ~  user:        naXa!
       date:        Thu Dec 13 03:28:27 2018 +0300
       summary:     commit message 1
    
  2. สาขาซอฟต์รีเซ็ต

    hg strip --keep -r 155
    
  3. ยอมรับการเปลี่ยนแปลงอีกครั้ง

    hg commit -m "new commit message"
    

หมายเหตุ

stripต้องมีการเปิดใช้งานส่วนขยายในตัว สร้าง / แก้ไข~/.hgrcไฟล์กำหนดค่าด้วยเนื้อหาต่อไปนี้:

[extensions]
strip = 

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