Mercurial: จะแก้ไขการกระทำครั้งสุดท้ายได้อย่างไร


211

ฉันกำลังมองหาส่วนต่อต้านgit commit --amendใน Mercurial นั่นคือวิธีแก้ไขความมุ่งมั่นที่สำเนาการทำงานของฉันเชื่อมโยงอยู่ ฉันสนใจเฉพาะการกระทำครั้งสุดท้ายไม่ใช่การกระทำก่อนหน้านี้โดยพลการ

ข้อกำหนดสำหรับขั้นตอนการแก้ไขนี้คือ:

  • หากเป็นไปได้ไม่ควรมีส่วนขยายใด ๆ ต้องไม่ต้องใช้ส่วนขยายที่ไม่ใช่ค่าเริ่มต้นเช่นส่วนขยายที่ไม่ได้มาพร้อมกับการติดตั้ง Mercurial อย่างเป็นทางการ

  • หากมุ่งมั่นที่จะแก้ไขเป็นหนึ่งหัวของสาขาปัจจุบันของฉันไม่ควรสร้างหัวใหม่ หากความมุ่งมั่นไม่ใช่หัวหน้าอาจจะสร้างหัวใหม่

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

อัปเดต (1):

  • ขั้นตอนจะต้องเป็นไปโดยอัตโนมัติดังนั้นจึงสามารถดำเนินการได้โดยไคลเอนต์ GUI โดยไม่ต้องมีการโต้ตอบกับผู้ใช้

อัปเดต (2):

  • ไฟล์ในไดเร็กทอรีการทำงานต้องไม่ถูกแตะต้อง (อาจมีการล็อคระบบไฟล์ในไฟล์ที่แก้ไขบางไฟล์) โดยเฉพาะอย่างยิ่งหมายความว่าวิธีที่เป็นไปได้อาจไม่จำเป็นต้องมีไดเรกทอรีการทำงานที่สะอาด

คำตอบ:


289

ด้วยการเปิดตัวMercurial 2.2คุณสามารถใช้--amendตัวเลือกกับhg commitเพื่ออัพเดทคอมมิทล่าสุดด้วยไดเรกทอรีการทำงานปัจจุบัน

จากการอ้างอิงบรรทัดคำสั่ง :

แฟล็ก --amend สามารถใช้เพื่อแก้ไขพาเรนต์ของไดเร็กทอรีการทำงานด้วยคอมมิตใหม่ที่มีการเปลี่ยนแปลงในพาเรนต์นอกเหนือจากที่รายงานในปัจจุบันโดยสถานะ hg หากมี การคอมมิชชันเก่าจะถูกเก็บไว้ในบันเดิลสำรองใน. hg / สตริป - แบ็กอัพ (ดู hg บันเดิลช่วยเหลือและ hg ช่วยคลายการคืนค่า)

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

สิ่งที่ดีคือกลไกนี้ "ปลอดภัย" เพราะอาศัยฟีเจอร์ "เฟส" ที่ค่อนข้างใหม่เพื่อป้องกันการอัปเดตที่จะเปลี่ยนประวัติที่มีอยู่นอกพื้นที่เก็บข้อมูลในเครื่องแล้ว


2
คำตอบที่ดี! ส่วนขยายการทดลองพัฒนาช่วยให้คุณสามารถแก้ไขการกระทำที่ไม่ใช่หัวอย่างปลอดภัย การกระทำเก่าจะถูกทำเครื่องหมายว่าล้าสมัยและซ่อนอยู่ ด้วยเซิร์ฟเวอร์ที่ไม่เผยแพร่คุณสามารถทำได้อย่างปลอดภัยหลังจากที่คุณผลักชุดการเปลี่ยนแปลง
Martin Geisler

5
เพียงแค่ปรับปรุงข้อความในการส่งครั้งล่าสุด: hg กระทำ - แก้ไข -m "นี่คือข้อความใหม่ของฉัน"
Jay Sheth

52

คุณมี 3 ตัวเลือกในการแก้ไขการกระทำใน Mercurial:

  1. hg strip --keep --rev -1ยกเลิกการกระทำครั้งสุดท้าย (1) ครั้งเพื่อให้คุณสามารถทำได้อีกครั้ง (ดูคำตอบนี้สำหรับข้อมูลเพิ่มเติม)

  2. ใช้ส่วนขยาย MQซึ่งจัดส่งมาพร้อมกับ Mercurial

  3. แม้ว่าจะไม่ได้จัดส่งมาพร้อมกับ Mercurial ส่วนขยายHisteditนั้นควรค่าแก่การกล่าวถึง

คุณสามารถดูได้ที่หน้าประวัติการแก้ไขของ Mercurial wiki

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

ฉันไม่คุ้นเคยกับgit commit --amendคำสั่งจริงๆแต่ AFAIK, Histedit คือสิ่งที่ดูเหมือนว่าจะเป็นวิธีที่ใกล้เคียงที่สุด แต่น่าเศร้าที่มันไม่ได้ส่งมาพร้อม Mercurial MQ นั้นซับซ้อนมากที่จะใช้ แต่คุณสามารถทำอะไรได้เกือบทุกอย่าง


1
ฉันไม่แน่ใจว่าทำไมฉันถึงพลาดการย้อนกลับ แต่ดูเหมือนว่าจะทำ (เกือบ) สิ่งที่ฉันต้องการ ปัญหาเดียวคือเมื่อไฟล์ถูกลบสำหรับการส่งต้นฉบับของฉันและได้รับการคืนชีพสำหรับการแก้ไขที่ฉันแก้ไข: ก่อนที่จะทำการย้อนกลับไฟล์จะไม่ถูกยกเลิกหลังจากการย้อนกลับจะมีการกำหนดเวลาการลบ (แต่ไฟล์ยังคงอยู่ใน ไดเรกทอรีทำงาน)
mstrap

@ Marc ฉันไม่แน่ใจว่าฉันเข้าใจปัญหาของคุณ แต่ลองดูคำสั่ง forget ฉันคิดว่ามันเป็นสิ่งที่คุณมองหา
krtek

ฉันไม่คิดว่า "ลืม" จะมีประโยชน์ที่นี่ นี่คือปัญหาของรายละเอียดเพิ่มเติม: (1) ฉันอยู่ในการแก้ไข 2 (2) ลบ "ไฟล์" และมีการเปลี่ยนแปลงอื่น ๆ (3) ยอมรับการเปลี่ยนแปลงส่งผลให้มีการแก้ไข 3 (4) ตอนนี้ฉันจะเปลี่ยนใจและตัดสินใจ "file" ไม่ควรลบออกจากการคอมมิทดังนั้นฉันต้องการแก้ไขการแก้ไข 3 ดังนั้นฉันจะเพิ่ม "file" อีกครั้งซึ่งตอนนี้ไม่ถูกยกเลิก (5) ตอนนี้ฉันทำการย้อนกลับ: มันจะรีเซ็ตความกระหายและทำเครื่องหมาย " ไฟล์ "ที่ถูกลบ (6) เมื่อดำเนินการ "hg กระทำ" อีกครั้งตอนนี้ "ไฟล์" จะยังคงถูกลบออกแม้ว่าจะไม่ควรจะเป็นอีกต่อไป การแก้ไขอัตโนมัติสำหรับลักษณะนั้นเป็นอย่างไร
mstrap

1
สำหรับชิ้นส่วนอัตโนมัติที่ฉันไม่รู้ แต่คุณสามารถทำได้hg revert myfileเพื่อเลิกทำการลบ อาจเพิ่มhg addไฟล์อีกครั้งหลังจากใช้rollbackงานได้
krtek

3
ฉันยอมรับว่าควรหลีกเลี่ยงประวัติการแก้ไขการเปลี่ยนแปลงที่เผยแพร่ แต่การแก้ไขประวัติท้องถิ่นของฉันเป็นหนึ่งในไฮไลท์ของ DVCS MQ ที่มี qimport นั้นเป็น AFAICT ที่สามารถแก้ไขประวัติได้อย่างแท้จริง
mstrap

38

GUI ที่เทียบเท่ากับhg commit --amend:

สิ่งนี้ยังใช้งานได้จาก GUI ของ TortoiseHG (ฉันใช้ v2.5):

เลื่อนไปที่มุมมอง 'Commit' หรือในมุมมอง workbench ให้เลือกรายการ 'ไดเร็กทอรีการทำงาน' ปุ่ม 'ยอมรับ' มีตัวเลือก 'แก้ไขการแก้ไขปัจจุบัน' (คลิกที่ลูกศรแบบหล่นลงของปุ่มเพื่อค้นหา)

ป้อนคำอธิบายรูปภาพที่นี่

          ||
          ||
          \/

ป้อนคำอธิบายรูปภาพที่นี่

Caveat emptor :

ตัวเลือกพิเศษนี้จะเปิดใช้งานเฉพาะในกรณีที่เวอร์ชั่น Mercurial เป็นอย่างน้อย 2.2.0 และหากการแก้ไขปัจจุบันไม่ได้เป็นแบบสาธารณะไม่ใช่ patch และไม่มีลูก [ ... ]

การคลิกปุ่มจะเรียกว่า 'ส่งมอบ - แก้ไข' เพื่อ 'แก้ไข' การแก้ไข

ข้อมูลเพิ่มเติมเกี่ยวกับสิ่งนี้ในช่องทาง THG dev


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

7

ฉันกำลังปรับแต่งสิ่งที่ krtek เขียน โซลูชันที่เฉพาะเจาะจงมากขึ้น 1:

สมมติฐาน:

  • คุณได้ยอมรับเซ็ตการแก้ไขหนึ่งรายการ (!) แต่ยังไม่ได้ส่ง
  • คุณต้องการแก้ไขชุดการเปลี่ยนแปลงนี้ (เช่นเพิ่มลบหรือเปลี่ยนแปลงไฟล์และ / หรือส่งข้อความ)

สารละลาย:

  • ใช้hg rollbackเพื่อเลิกทำคอมมิทล่าสุด
  • กระทำอีกครั้งด้วยการเปลี่ยนแปลงใหม่ในสถานที่

การย้อนกลับเป็นการยกเลิกการทำงานล่าสุด วิธีการทำงานค่อนข้างง่าย: การทำงานปกติใน HG จะต่อท้ายไฟล์เท่านั้น รวมถึงการกระทำ Mercurial คอยติดตามความยาวของไฟล์ของการทำธุรกรรมครั้งล่าสุดและสามารถเลิกทำขั้นตอนเดียวได้อย่างสมบูรณ์โดยการตัดทอนไฟล์กลับเป็นความยาวเดิม


1
ขอบคุณสำหรับการปรับจูน (1); มีปัญหาเล็กน้อยเหลืออยู่ในการย้อนกลับโปรดดูความคิดเห็นของฉันที่โซลูชันของ krtek
mstrap

8
สิ่งหนึ่งที่ให้ความสำคัญกับการย้อนกลับเพราะดึงดูดผู้คนออกมาคือการทำธุรกรรมครั้งสุดท้ายของธุรกรรมซื้อคืนซึ่งไม่ได้กระทำครั้งสุดท้าย ดังนั้นหากมีสิ่งอื่นที่ทำให้เกิดการเขียนไปยัง repo การย้อนกลับจะไม่ช่วย มันเป็นสิ่งที่สำคัญ แต่สำคัญที่ต้องจดจำ MQ และ histedit สามารถช่วยได้เมื่อหน้าต่างการย้อนกลับถูกปิด แต่ยังคงอยู่จนถึงจุดหนึ่งเท่านั้น
พอล S

7

สมมติว่าคุณยังไม่ได้เผยแพร่การเปลี่ยนแปลงของคุณนี่คือสิ่งที่คุณสามารถทำได้

  • เพิ่ม. hgrc ของคุณ:

    [extensions]
    mq =
    
  • ในพื้นที่เก็บข้อมูลของคุณ:

    hg qimport -r0:tip
    hg qpop -a
    

    แน่นอนว่าคุณไม่จำเป็นต้องเริ่มต้นด้วยการแก้ไขศูนย์หรือป๊อปอัพแพตช์ทั้งหมดสำหรับป๊อปอัพเพียงอันเดียว ( hg qpop) พอเพียง (ดูด้านล่าง)

  • ลบรายการสุดท้ายใน.hg/patches/seriesไฟล์หรือแพทช์ที่คุณไม่ชอบ การจัดลำดับใหม่ก็เป็นไปได้เช่นกัน

  • hg qpush -a; hg qfinish -a
  • ลบ.diffไฟล์ (ยังไม่ได้ใช้แพตช์) ยังอยู่ใน. hg / patches (ควรเป็นไฟล์เดียวในกรณีของคุณ)

หากคุณไม่ต้องการที่จะคืนค่าโปรแกรมแก้ไขทั้งหมดของคุณคุณสามารถแก้ไขได้โดยใช้hg qimport -r0:tip(หรือคล้ายกัน) จากนั้นแก้ไขเนื้อหาและใช้hg qrefreshเพื่อรวมการเปลี่ยนแปลงลงในโปรแกรมปรับปรุงสูงสุดบนสแต็กของคุณ hg help qrefreshอ่าน

ด้วยการแก้ไข.hg/patches/seriesคุณสามารถลบแพทช์หลาย ๆ อันหรือเรียงลำดับใหม่ได้ หากการปรับประมาณการครั้งสุดท้ายของคุณคือ 99 hg qimport -r98:tip; hg qpop; [edit series file]; hg qpush -a; hg qfinish -aคุณก็อาจจะใช้

แน่นอนว่ากระบวนการนี้เป็นสิ่งที่ท้อแท้และมีความเสี่ยงสูง สำรองข้อมูลทุกอย่างก่อนที่จะทำ!

ในฐานะที่เป็นไซเดอร์ฉันได้ทำหลายครั้งแล้วบนที่เก็บส่วนตัวเท่านั้น


ฉันได้พิจารณาด้วยการใช้ mq-extension แต่มันต้องมีการดำเนินการค่อนข้างมากซึ่งบางส่วนอาจล้มเหลว (เช่นถ้าเกี่ยวข้องกับไฟล์ไบนารี) นอกจากนี้มีการแก้ไข .hg / แพทช์ / ซีรีส์จะไม่เป็นที่ยอมรับเป็นขั้นตอนนี้ควรจะใช้ภายในลูกค้าแบบ GUI (ผมได้ปรับปรุงข้อกำหนดข้างต้น)
mstrap

อืมเสียใจด้วยที่นี่ไม่เหมาะกับคุณในที่เก็บส่วนตัวที่นี่ทำให้คุณรู้สึกแย่จริงๆ (ด้วยการสำรองข้อมูล - ฉันได้กำจัด fatfinger แล้วทำลายตัวแทนด้วย ^^) มันค่อนข้างเจ๋งที่จะรวมปะเป็นหนึ่งก่อนผลักดันการเปลี่ยนแปลงในท้องถิ่นโดยใช้hg qfoldbtw
hochl

+1 สำหรับการใช้ MQ แต่ฉันคิดว่าคุณลงน้ำไปแล้ว เขาเพียงแค่ถามเกี่ยวกับการแก้ไขความมุ่งมั่นล่าสุด นอกจากนี้การนำเข้านั้นก็จะหายไปทันทีที่มีการรวมเข้าด้วยกัน 'qimport -r tip; <แก้ไขเนื้อหา>; qrefresh -e; qfin -a 'จะทำงาน (-e เพื่อแก้ไขข้อความคอมมิชชัน)
Paul S

hg import -r<prev>:tipจริงผสานมีปัญหาผมมักจะปรากฏเพียงหนึ่งแพทช์และการใช้งาน น่ากลัวไม่มีทางลัดสำหรับรุ่นก่อนหน้าเช่นในการโค่นล้ม
hochl

2

Mercurial เวอร์ชันล่าสุดมีevolveส่วนขยายที่ให้hg amendคำสั่ง วิธีนี้ช่วยให้คุณสามารถแก้ไขการกระทำโดยไม่เสียประวัติก่อนการแก้ไขในการควบคุมเวอร์ชันของคุณ

hg แก้ไข [ตัวเลือก] ... [ไฟล์] ...

นามแฝง: รีเฟรช

รวมชุดการแก้ไขกับการปรับปรุงและแทนที่ด้วยชุดใหม่

Commits a new changeset incorporating both the changes to the given files
and all the changes from the current parent changeset into the repository.

See 'hg commit' for details about committing changes.

If you don't specify -m, the parent's message will be reused.

Behind the scenes, Mercurial first commits the update as a regular child
of the current parent. Then it creates a new commit on the parent's
parents with the updated contents. Then it changes the working copy parent
to this new combined changeset. Finally, the old changeset and its update
are hidden from 'hg log' (unless you use --hidden with log).

ดูhttps://www.mercurial-scm.org/doc/evolution/user-guide.html#example-3-amend-a-changeset-with-evolveสำหรับคำอธิบายที่สมบูรณ์ของevolveส่วนขยาย


การใช้ข้อความยืนยันซ้ำอีกครั้งเป็นคุณสมบัติที่ดี!
mpen

1

อาจไม่แก้ปัญหาทั้งหมดในคำถามเดิม แต่เนื่องจากนี่เป็นโพสต์จริง ๆ ว่า Mercurial สามารถแก้ไขข้อผูกพันก่อนหน้านี้ได้อย่างไรฉันจะเพิ่มข้อมูล 2 เซ็นต์ของฉัน

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

hg commit -X 'glob:**' --amend

หากไม่มีรูปแบบการรวมหรือไม่รวมhg commitจะรวมไฟล์ทั้งหมดในไดเรกทอรีการทำงาน รูปแบบการใช้-X 'glob:**'จะไม่รวมไฟล์ที่เป็นไปได้ทั้งหมดซึ่งอนุญาตให้แก้ไขข้อความคอมมิชชันเท่านั้น

ฟังก์ชั่นจะเหมือนกับgit commit --amendเมื่อไม่มีไฟล์ในดัชนี / สเตจ


0

โซลูชันอื่นอาจใช้uncommitคำสั่งเพื่อแยกไฟล์เฉพาะออกจากการคอมมิทปัจจุบัน

hg uncommit [file/directory]

สิ่งนี้มีประโยชน์มากเมื่อคุณต้องการรักษาคอมมิชชันปัจจุบันและยกเลิกการเลือกไฟล์บางไฟล์ (โดยเฉพาะประโยชน์สำหรับfiles/directoriesการถูกลบ)

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