ยกเลิกการเปลี่ยนแปลงโดยไม่ลบจากประวัติ


180

มีการกระทำที่เพียงแค่ไม่ได้ทำงานดังนั้นฉันต้องการที่จะละทิ้งมันโดยไม่ต้องลบออกจากประวัติ

ฉันได้อัปเดตจากการแก้ไขก่อนหน้านี้และมุ่งมั่นจึงสร้างหัวใหม่


ฉันไม่มีสาขาฉันไม่ต้องการสาขาฉันแค่อยากจะไปกับหัวใหม่อย่างที่มันเป็นไม่มีอะไรแฟนซีไม่รวมไม่ต้องกังวลไม่ต้องลืมไปก่อนหน้านี้

ฉันไม่สามารถหาวิธีการทำเช่นนั้นได้และฉันเริ่มเชื่อว่ามันไม่สามารถทำได้ สิ่งที่ฉันพบคือสิ่งที่เกี่ยวกับสาขาหรือสิ่งที่เกี่ยวกับการรวม


1
มันอยู่ใน repo ของคุณดังนั้นจึงไม่ถูกลบออกจากประวัติ คุณได้สร้างหัวใหม่เพื่อให้คุณสามารถทำการแก้ไขได้โดยไม่ผิดพลาด อะไรทำให้คุณไม่สามารถทำสิ่งใหม่ ๆ ได้?
ataylor

ความเกลียดชังของคุณต่อสาขาคืออะไร?
Andres Jaan Tack

@Andres มันไม่ได้รังเกียจที่จะสาขา ฉันแค่ต้องการให้มันทำงานโดยไม่ต้องเพิ่มขั้นตอนโง่ ๆ ในการสร้างเพียงแค่ปิดมัน
o0 '

ใครก็ตามที่อ่าน - โปรดทราบว่าสาขาได้ถูกสร้างขึ้นแล้วในสถานการณ์นี้ สังเกตคำอธิบายที่ให้ไว้ในคำตอบนี้: stackoverflow.com/a/3692607/3195477
UuDdLrLrSs

คำตอบ:


181

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

คุณยังสามารถดูสาขาที่ปิดได้หากคุณใช้-cตัวเลือกhg headsนี้ แต่จะไม่ปรากฏขึ้นตามค่าเริ่มต้นและhg mergeจะไม่ทราบว่าจะพยายามผสานกับส่วนหัวที่ปิดอยู่

คุณจะต้องใช้hg push --forceครั้งแรกที่คุณผลักหัวปิดนี้ไปยังที่เก็บอื่นเนื่องจากคุณกำลังสร้างหัวเพิ่มเติมในที่เก็บระยะไกลจริง ๆ เมื่อคุณกด ดังนั้นบอก Mercurial ว่านี่--forceใช้ได้ คนที่ดึงหัวที่ปิดสนิทจะไม่ถูกรบกวนจากคำเตือนใด ๆ


3
@Niall C. จะไม่ทำงานเฉพาะในกรณีที่เขาทำเครื่องหมายว่าเป็นสาขาที่มีชื่อ ฉันคิดจากสิ่งที่เขาบอกว่าเขาทำมันเป็นค่าเริ่มต้น
msarchet

แต่ ... ไม่เป็นความจริงฉันยังได้รับทั้งสองหัวไว้เมื่อฉันโทรhg heads... ฉันใช้ Mercurial 1.4.3 นั่นคือฟีเจอร์ที่ใหม่กว่านี้หรือไม่?
o0 '

2
@msarchet: AFAIK ลองใช้วันนี้ - ปิดสาขาไม่ทำงานกับสาขาที่ไม่ระบุตัวตน มันควร แต่ไม่ ฉันหวังว่าการเปลี่ยนแปลงนี้ใน Mercurial รุ่นต่อไป สาขานิรนามเป็นสิ่งที่ดีมาก แต่ควรเป็นสาขาที่มีชื่อเหมือนกัน
Krazy Glew

4
@ KrazyGlew: ปัญหาคือว่าสาขา "ไม่ระบุชื่อ" เป็นเพียงสาขาที่สองที่มีชื่อเดียวกันกับสาขาที่เป็นพื้นฐาน คุณไม่ได้พยายามปิดสาขา (ชื่อ): คุณกำลังพยายามยกเลิกการเปลี่ยนแปลงที่คุณทำ กล่าวอีกนัยหนึ่งhg branchesก็ควรจะแสดงชื่อสาขาที่คุณอยู่ แทนที่จะพยายามปิดสาขาให้รวมสาขาที่ไม่ระบุชื่อของคุณกลับเข้าไปในสาขาเดิมโดยละทิ้งการเปลี่ยนแปลงทั้งหมด
StriplingWarrior

2
ในกรณีของฉันฉันมีสาขาที่เรียกว่า default (นี่คือมาตรฐาน) และอีกสาขาที่เรียกว่า default / master (ฉันคิดว่าเนื่องจากคลังเก็บระยะไกลนั้นเป็นคอมไพล์จริง ๆ ) hg update default / master; hg กระทำ - ปิดสาขา; การอัปเดต hg เริ่มต้นใช้งานได้สำหรับฉัน
MattD

68

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


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

มีส่วนดีในเอกสาร Mercurial ที่จะพาคุณผ่านจำนวนของตัวเลือกรอบเป็นสาขาการตัดแต่งกิ่งตาย

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

hg update -r 123
hg commit --close-branch -m 'Closing old branch'
hg update -C default

3
Blurgh - เพิ่งเห็นคำตอบของ @ Niall หลังจากฉันเข้ามา การลงคะแนนของ Niall และของฉันจะทำให้อ่อนลงในจุดศูนย์รวม :)
Nick Pierpoint

1
ฉันชอบคำตอบของคุณดีขึ้นมันต้องใช้คำศัพท์ของ merucrial น้อยลง (ซึ่งใกล้ที่สุดเท่าที่ฉันจะบอกได้ว่าได้รับเลือกให้สร้างความสับสนให้กับผู้ใช้ git)
tacaswell

8
ฮ่า ๆ มันตรงกันข้าม! คำศัพท์ของ mercurial ได้รับเลือกให้เป็นเสียงที่เป็นธรรมชาติสำหรับผู้ใช้ svn ในขณะที่ git นั้นสับสนเหมือนนรก! ยังไงก็ตามการถอนคำตอบนี้เพราะมันรวมถึงการอัพเดทครั้งล่าสุด -C
Tobia

2
ทำไมคุณต้อง-Cในhg update? ดูเหมือนว่าจะไม่มีไฟล์ใดถูกแก้ไขดังนั้นจึงควรใช้งานได้หากไม่มี
สูงสุด

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

21

ก่อนอื่นพิมพ์:

hg heads

ลองนึกภาพคุณมีสามหัวอยู่ในรายการ:

changeset:   223:d1c3deae6297
user:        Your name  <your@email.com>
date:        Mon Jun 09 02:24:23 2014 +0200
summary:     commit description #3

changeset:   123:91c5402959z3
user:        Your name <your@email.com>
date:        Sat Dec 23 16:05:38 2013 +0200
summary:     commit description #2

changeset:   59:81b9804156a8
user:        Your name <your@email.com>
date:        Sat Sep 14 13:14:40 2013 +0200
summary:     commit description #1

สมมติว่าคุณต้องการให้ส่วนหัวสุดท้ายยังคงทำงานอยู่ (223) และปิดส่วนที่เหลือ

จากนั้นคุณจะทำดังนี้:

ปิดหัว # 59

hg up -r 59
hg ci --close-branch -m "clean up heads; approach abandoned"

ปิดหัว # 123

hg up -r 123
hg ci --close-branch -m "clean up heads; approach abandoned"

ยอมรับการเปลี่ยนแปลง

hg push

อย่าลืมเปลี่ยนไปใช้หัวขวาในตอนท้าย

hg up -r 223

และคุณทำเสร็จแล้ว


นี่คือบทช่วยสอนที่ดี แต่ตัวอย่างการส่งข้อความเป็นบิตเมตา ฉันจะรวมตัวอย่างที่ดีกว่าเพื่อให้การเรียนรู้จากคุณอาจให้ข้อความที่ดีขึ้น --close-branch -m "Closing branch - technique #2 abandoned in favor of technique #3"สิ่งที่ชอบ
Jason R. Coombs

5
นอกจากนี้คุณก็เสร็จสิ้นการเรียงลำดับยกเว้นว่าสำเนาการทำงานของคุณยังคงอยู่ในหัวที่คุณเพิ่งปิด กระทำการเปลี่ยนแปลงอื่นจะเกิดขึ้นบนหัวที่ปิดไว้เปิดใหม่อีกครั้ง คุณจะต้องhg up -r 223ก่อนทำการเปลี่ยนแปลงใด ๆ
Jason R. Coombs

@ Jason R. Coombs: ถูกต้อง!
Artur Barseghyan

ตาม @Niall และจากประสบการณ์ของฉันตอนนี้คุณจะต้องhg push --forceไม่ใช่แค่hg pushเตือนผ่านการผลักหัวหลายครั้ง
craq

1
@Artur ฉันเห็นด้วยโดยทั่วไป ในกรณีนี้hg pushด้วยตัวเองไม่ได้ผลสำหรับฉัน คุณจะแนะนำการผลักดันการเปลี่ยนแปลงไปยัง repo ภายนอกได้อย่างไรถ้ามันปฏิเสธเพราะมีหลายหัว
craq

12

hg backoutคุณต้องการที่จะใช้ สิ่งนี้จะลบการเปลี่ยนแปลงที่ทำโดยเซ็ตการแก้ไขออกจากเซ็ตการแก้ไขย่อยใด ๆ

ลองดูคำอธิบายที่ดี Mercurial Backout


2
นี่คือคำตอบที่ถูกต้อง Backout เพิ่มค่าผกผันของเซ็ตการแก้ไขยกเลิกการทำงานและให้ข้อความยืนยันเพื่อเตือนตัวเองว่าทำไมคุณถึงไม่ชอบไอเดีย
Ry4an Brase

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

1
@ Martin Geisler ดีผมเห็นด้วยกับเรื่องนี้ในทั่วไป แต่ OP ที่ระบุว่าเขาอยากที่จะละทิ้งการเปลี่ยนแปลงโดยไม่ต้องสาขา
msarchet

2
@ มาร์ติน Geisler ใช่ฉันทั้งหมดสำหรับกิ่งเพียงบางครั้งการเปลี่ยนแปลงที่ไม่ดีเป็นสิ่งที่ดีที่สุด
msarchet

1
บางครั้งมันอาจมีประโยชน์ แต่นั่นก็ไม่ใช่สิ่งที่ฉันต้องการ ขอขอบคุณ :)
o0 '

2

ทั้งคำตอบของ Niall และ Nick นั้นตรงไปตรงมา เนื่องจากฉันพบว่าตัวเองกำลังสร้างห้อยต่องแต่งมากมายฉันจึงเขียนชื่อแทนเพื่อปิดหัวได้ง่ายขึ้น โดยเพิ่มสิ่งนี้ลงใน.hgrc:

[alias]
behead = !REV=$($HG id -i); $HG update $@ -q && $HG ci --close-branch -m "Closing dead head" && $HG update $REV -q

(หากคุณมี[alias]หัวข้ออยู่แล้วคุณสามารถต่อท้ายได้แทน)

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

$ hg behead 123

หมายเหตุ: นามแฝงใช้ประโยชน์จากข้อเท็จจริงที่ว่านามแฝง Mercurial สามารถเป็นคำสั่งเชลล์ได้ ซึ่งหมายความว่าสิ่งนี้อาจใช้ได้กับ UNIX เท่านั้นไม่ใช่บน Windows


2

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

สมมติว่าประวัติชุดการเปลี่ยนแปลงมีลักษณะดังนี้:

1-2-3-4-5-6    
       \    
        7-8-*

และมันคือ5และ6สิ่งที่ไม่ต้องการอีกต่อไป

คุณสามารถทำได้:

hg up 8
hg merge -r 6 -t :local
hg commit ...

ซึ่งจะสร้างสิ่งนี้:

1-2-3-4-5-6    
       \   \
        7-8-9-*

การปรับปรุงเพื่อ8ให้แน่ใจว่าคุณกำลังทำงานในส่วนหัวที่ต้องการในประวัติศาสตร์ซึ่งคุณต้องการเก็บไว้

-t :localสั่ง HG ใช้ผสาน "เครื่องมือ" ที่เรียกว่าท้องถิ่นที่บอกว่ามันจะไม่สนใจการเปลี่ยนแปลงจากสาขาอื่น ๆ เช่นคนที่ไม่ได้เป็นตัวแทนโดยรัฐโฟลเดอร์การทำงานปัจจุบัน ข้อมูลเพิ่มเติม

ดังนั้นการเปลี่ยนแปลงที่ไม่พึงประสงค์ใน5และ6จะถูกเก็บไว้ในประวัติศาสตร์ แต่จะไม่ส่งผลกระทบต่อสิ่งที่ผ่านมา


2

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

ด้วยส่วนขยาย Evolve คุณก็ทำได้

hg prune -r revname

และต่อกับชีวิตของคุณ cset จะยังคงอยู่ที่นั่น แต่ล้าสมัยแล้ว มันจะไม่ปรากฏให้เห็นจนกว่าคุณจะผ่าน--hiddenตัวเลือกไปยังคำสั่ง Mercurial และตามค่าเริ่มต้นจะไม่ถูกผลักไปยังที่เก็บข้อมูลระยะไกล แม้ว่าฉันคิดว่าคุณสามารถบังคับได้ถ้าคุณต้องการจริงๆ

หาก cset ที่คุณกำลังตัดมีบรรพบุรุษที่คุณต้องการเก็บไว้คุณจะต้องรันhg evolveเพื่อรีบูตเซ็ตการแก้ไขเหล่านั้น hg evolveจะทำโดยอัตโนมัติ มิฉะนั้นคุณไม่ต้องทำอะไรเลย


1

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

hg clone --rev myGoodResition myDirtyRepo myCleanRepo

1
นี่ไม่ใช่สิ่งที่ฉันขอทั้งหมดขอโทษ
o0 '

4
@ Kristof: เป็นเรื่องตลกหรือไม่? อ่านบรรทัดแรกของโพสต์ของฉันอีกครั้ง: "ปล่อยโดยไม่ลบออกจากประวัติ "
o0 '

-1

ฉันพบปัญหานี้หลายครั้งเมื่อฉันต้องการตัดหัวที่สร้างขึ้นด้วยความผิดพลาด ฉันอยากจะเห็นมันหายไปจากพื้นโลก

บนสำเนาในเครื่องของคุณรับล่าสุดแล้ว:

  1. ค้นหาจุดเริ่มต้นของศีรษะที่คุณต้องการตัด (ที่คอใหม่เริ่มแตกแขนงออก) รับหมายเลขการแก้ไข

  2. ตัดมัน


ที่มา: TipsAndTricks

ที่มา: PruningDeadBranches # Using_strip

hg --config extensions.hgext.mq= strip -n <rev>
  1. ทำการอัปเดตไฟล์เล็กน้อย (เพิ่มช่องว่างให้ไฟล์) คอมมิตและพุช

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


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