ลบการกระทำจากสาขาใน Git


3233

ฉันต้องการทราบวิธีลบการส่ง

โดยdeleteฉันหมายความว่ามันเหมือนกับว่าฉันไม่ได้ทำอย่างนั้นและเมื่อฉันผลักดันในอนาคตการเปลี่ยนแปลงของฉันจะไม่ผลักไปที่สาขาระยะไกล

git reset --hard HEADผมอ่านความช่วยเหลือคอมไพล์และผมคิดว่าคำสั่งฉันควรใช้คือ ถูกต้องหรือไม่


41
ฉันคิดว่านี่ไม่ใช่การซ้ำซ้อนของGit เลิกทำการคอมมิชชันล่าสุดเนื่องจากถามว่าจะลบการกระทำใด ๆจากสาขาได้อย่างไร ฉันคิดว่าไม่ใช่คำตอบจริง ๆ ตอบคำถามนี้ พวกเขาทั้งหมดย้อนกลับการกระทำครั้งสุดท้ายไม่ใช่cherry-pickและdeleteการกระทำเดียวที่อาจเกิดขึ้นในขณะที่ผ่านมา
คริส

12
@Chris คำตอบด้วยgit rebase -i HEAD~10จะจัดการกับคำถามตามที่ให้คุณเลือกยอมรับว่าจะลบ Git จะใช้การคอมมิทในช่วงที่คุณระบุทีละตัวโดยไม่สนใจคอมมิทที่คุณลบออกจากบันทึก ฉันใช้คำสั่งนี้วันนี้เพื่อกำจัดคนที่สองและสามที่ได้ทำสัญญาล่าสุดกับ repo ของฉันในขณะที่ยังคงอยู่อันดับหนึ่ง ฉันยอมรับว่าไม่มีคำตอบอื่นใดที่น่าพอใจ
MST

@MST ใช่ฉันควรจะบอกว่าไม่ใช่ตัวเลือกในคำตอบที่ได้รับการยอมรับคำถามนี้ แต่คุณมีสิทธิ์อย่างแน่นอน - คำสั่งที่ดูเหมือนว่าจะทำงาน
Chris Chris

คำตอบ:


4126

ระวัง: git reset --hard จะลบการทำงานของคุณ DIRECTORY เปลี่ยนแปลง ตรวจสอบให้แน่ใจว่าได้ซ่อนการเปลี่ยนแปลงในระบบที่คุณต้องการเก็บไว้ก่อนที่จะรันคำสั่งนี้

สมมติว่าคุณกำลังนั่งอยู่กับการกระทำนั้นคำสั่งนี้จะทำลายมัน ...

git reset --hard HEAD~1

HEAD~1หมายถึงการกระทำก่อนที่หัว

หรือคุณสามารถดูผลลัพธ์ของgit logค้นหารหัสกระทำของการส่งข้อมูลที่คุณต้องการสำรองข้อมูลจากนั้นทำสิ่งนี้:

git reset --hard <sha1-commit-id>

หากคุณผลักมันไปแล้วคุณจะต้องใช้แรงผลักเพื่อกำจัดมัน ...

git push origin HEAD --force

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

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


FYI - git reset --hard HEADยอดเยี่ยมถ้าคุณต้องการกำจัดการทำงานในความคืบหน้า มันจะรีเซ็ตคุณกลับไปสู่การกระทำล่าสุดและลบการเปลี่ยนแปลงทั้งหมดในแผนผังการทำงานและดัชนีของคุณ


สุดท้ายหากคุณต้องการค้นหาคำมั่นสัญญาที่คุณ "ลบ" มันมักจะปรากฏในgit reflogเว้นแต่ว่าคุณมีขยะเก็บรวบรวมพื้นที่เก็บข้อมูลของคุณ


59
HEAD~1HEAD^หรือเพียงแค่ ถ้าคุณผลักคุณควรใช้git revertแทน
Jakub Narębski

13
เห็นได้ชัดว่าคุณสามารถใช้HEAD~nเพื่อ "ย้อนกลับ" nมุ่งมั่นจากหัวของคุณ บางทีจากจุดนี้คุณสามารถตีความ... --hard HEADได้ว่าHEAD~0=> กำลังลบงานที่อยู่ระหว่างดำเนินการ
nuala

13
@ beamrider9 imho git rebase เกือบจะเป็นวิธีที่ดีกว่าในการลบคอมมิท (ดังที่อธิบายไว้ในคำตอบของ Greg Hewgill) - ไม่น้อยเพราะความจริงแล้ว rebase นั้นมีคำเตือนขนาดใหญ่ที่คุณจะลบสิ่ง 4realz
Noah Sussman

20
สิ่งนี้จะไม่ลบการเปลี่ยนแปลงออกจากแผนผังการส่ง OP ขอการกระทำที่ได้ทำไปแล้ว หากคุณreset --hardและตรวจสอบlog --oneline --allความมุ่งมั่นยังคงอยู่ในต้นไม้ เราจะลบการกระทำเหล่านี้ออกจากต้นไม้ได้อย่างไร ขอบคุณ
iGbanam

17
ใช้reset --softเพื่อลบการคอมมิทโดยไม่ต้องคืนค่างานที่ทำอยู่!

704

หากคุณยังไม่ได้ส่งการกระทำที่ใดก็ได้คุณสามารถใช้git rebase -iเพื่อลบการกระทำที่ ก่อนอื่นให้ดูว่าการย้อนกลับนั้นกระทำได้ประมาณ (โดยประมาณ) จากนั้นทำ:

git rebase -i HEAD~N

~Nวิธี rebase ที่ผ่านมาNกระทำ ( Nต้องเป็นตัวเลขเช่นHEAD~10) จากนั้นคุณสามารถแก้ไขไฟล์ที่ Git นำเสนอให้คุณเพื่อลบการกระทำผิด ในการบันทึกไฟล์นั้น Git จะทำการเขียนสิ่งต่อไปนี้ทั้งหมดใหม่หากไม่มีไฟล์ที่คุณลบ

Git Book มีส่วนที่ดีในการรีบูตด้วยรูปภาพและตัวอย่าง

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


2
หมายเหตุ: หากคุณมี --no-ff รวมอยู่ในชุดคำสั่งสุดท้าย rebase จะสังหารพวกเขา :( นี่ถูกกล่าวถึงภายใต้ -p ในหน้านี้ปัญหาคือถ้าคุณแทนที่ -i ด้วย -p, คุณไม่ได้รับที่ปรากฏขึ้นกับตัวเลือกสำหรับการ "แก้ไขนี้กระทำ sqush ที่หนึ่ง" ฯลฯ เป็นต้นใครรู้วิธีการแก้ปัญหาหรือไม่
Bukov

4
ถ้าคุณผลักมันไปล่ะ? (เพียงฉันใช้ repo ระยะไกล)
คอสตา

6
@Costa คุณสามารถใช้push -fเพื่อบังคับผลักดันและแทนที่สาขาระยะไกลด้วยเครื่องของคุณ หากเป็นเพียง repo ระยะไกลของคุณเองก็ไม่มีปัญหา ปัญหาจะเริ่มขึ้นหากมีคนดึงข้อมูลออกมาระหว่างนั้น
Greg Hewgill

3
ฉันเพิ่มและส่งไฟล์ข้อมูลที่มีขนาดใหญ่เกินไปสำหรับ GitHub (ใช่มันอาจไม่ควรอยู่ใน repo ของแหล่งข้อมูลอยู่ดี; เมื่อฉันพยายามที่จะผลักดัน GitHub ปฏิเสธเพราะไฟล์ที่มีขนาดใหญ่เกินไป สิ่งที่ฉันต้องการทำคือยกเลิกการกระทำนี้ในขณะที่บันทึกการกระทำที่ไม่เกี่ยวข้องอื่น ๆ ที่ตามมา git rebase -i HEAD~5คำสั่งเป็นว่าสิ่งที่ฉันต้องการที่จะสมบูรณ์ลบนี้กระทำจาก repo ท้องถิ่นของฉัน! ขอบคุณ!
aldo

4
@dumbledad: ด้วยrebase -iการเปลี่ยนแปลงที่สอดคล้องกับการคอมมิทที่ถูกลบจะไม่ถูกรักษาไว้
Greg Hewgill

517

ความเป็นไปได้อีกอย่างหนึ่งคือหนึ่งในคำสั่งที่ฉันโปรดปราน:

git rebase -i <commit>~1

สิ่งนี้จะเริ่มการ rebase ในโหมดโต้ตอบ-iณ จุดก่อนที่จะส่งค่าคอมมิชชันที่คุณต้องการตี บรรณาธิการจะเริ่มทำรายการทั้งหมดที่ทำไว้ตั้งแต่นั้นมา ลบบรรทัดที่มีคอมมิตที่คุณต้องการกำจัดและบันทึกไฟล์ การ Rebase จะทำงานที่เหลือโดยลบเฉพาะการกระทำและการเล่นซ้ำทั้งหมดลงในบันทึก


3
ขอบคุณ, btw หากคุณพบปัญหาใด ๆ (เช่นคอมมิทที่ว่างเปล่า) คุณสามารถใช้git rebase --continue
realgt

8
ง่ายยิ่งขึ้น: git rebase -i HEAD~1
mmell

2
Wowzers git rebase -i HEAD~1ทำความสะอาด repo ขึ้นมากจริงๆ! มันยากที่จะบอกว่ามันทำอะไร แต่สิ่งทั้งหมดดูดีมาก ที่น่าตกใจจริง ๆ
Charles Wood

7
ฉันคิดว่ามันคุ้มค่าที่จะทราบว่าการกระทำนั้นไม่ได้ลบล้างไปเพียงแค่ลบออกจากรายการ หากคุณเลอะคุณจะได้รับกลับมากระทำโดยใช้reflog
Zaz

6
การลบบรรทัดเหมือนกับ d / drop หรือไม่
Leo

344

ฉันต่อท้ายคำตอบนี้เพราะฉันไม่เห็นว่าทำไมใครก็ตามที่พยายามจะทำงานที่ต้องการลบงานทั้งหมดเพราะมีข้อผิดพลาดในการใช้ Git!

หากคุณต้องการทำงานต่อไปและเพียง 'เลิกทำ' คำสั่งคอมมิท (คุณถูกจับได้ก่อนที่จะกดเพื่อ repo):

git reset --soft HEAD~1

อย่าใช้แฟล็ก - ฮาร์ดยกเว้นว่าคุณต้องการทำลายงานที่ทำอยู่ตั้งแต่ดำเนินการครั้งสุดท้าย


5
นี่คือตัวอย่างของสาเหตุ: คุณทำงานชิ้นเล็ก ๆ บนเซิร์ฟเวอร์การพัฒนาที่คุณส่งมอบ จากนั้นปรากฎว่าเซิร์ฟเวอร์นั้นไม่มีการเข้าถึง HTTPS ดังนั้นคุณจึงไม่สามารถส่งการกระทำใด ๆ ง่ายที่สุดที่จะแกล้งทำเป็นว่ามันไม่เคยเกิดขึ้นและทำซ้ำแพทช์จากเครื่องท้องถิ่นของคุณ
Steve Bennett

1
@Karthik เนื่องจากมีการอ้างอิงเสมอ แม้ว่าหลังจากการคอมมิชชันgit reset --hard HEAD~1ล่าสุดของคุณจะพร้อมใช้งานผ่าน reflog (จนกว่าคุณจะหมดอายุ) ดูเพิ่มเติมได้ที่นี่: gitready.com/intermediate/2009/02/09/…
codeling

4
ขอบคุณ คำตอบนี้ควรอยู่ในอันดับที่สูงขึ้นหรือรวมอยู่ในคำตอบที่ยอมรับแล้ว การลบการกระทำ! = การคืนการกระทำ
Alsciende

2
@RandolphCarter: คุณจะยังคงสูญเสียการเปลี่ยนแปลงที่ไม่มีข้อผูกมัด
naught101

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

141

การลบการคอมมิททั้งหมด

git rebase -p --onto SHA^ SHA

เห็นได้ชัดว่าแทนที่ "SHA" ด้วยข้อมูลอ้างอิงที่คุณต้องการกำจัด เครื่องหมาย "^" ในคำสั่งนั้นเป็นตัวอักษร

http://sethrobertson.github.io/GitFixUm/fixup.html#change_deep


26
ฉันจะตอบคำถามนี้ได้อย่างไร โซลูชันอื่น ๆ กำลังแสดงวิธีการโต้ตอบหรือลบการกระทำที่สำคัญที่สุด
ribamar

5
-p, --preserve-merges สร้างการรวมใหม่แทนที่จะทำประวัติย่อโดยการเล่นซ้ำกระทำการรวมการกระทำที่แนะนำ การรวมการแก้ไขข้อขัดแย้งหรือการแก้ไขด้วยตนเองเพื่อรวมการกระทำจะไม่ถูกรักษาไว้
raittes

5
นี่คือคำตอบที่ถูกต้องจริง
Hamman Samuel

9
มันบอกว่า "แทนที่ SHA ด้วยการอ้างอิงที่คุณต้องการกำจัด" แต่บรรทัดนั้นมี SHA อยู่สองครั้ง นี่คือสิ่งที่ฉันทำ git rebase -p --onto 5ca8832c120 ^ 5ca8832c120 แต่ไม่มีอะไรเปลี่ยนแปลง ฉันควรจะใช้ SHA เดียวกันสองครั้งหรือไม่? ถ้าไม่เป็นเช่นนั้น SHA สำหรับการกระทำที่จะถูกลบและ SHA อื่นควรจะเป็นอย่างไร
Rubicksman

3
ว้าวมันทำงานได้ไร้ที่ติ! นี่ควรเป็นคำตอบที่ยอมรับได้!
Liran H

51

หากคุณไม่ได้เผยแพร่การเปลี่ยนแปลงเพื่อลบการกระทำล่าสุดคุณสามารถทำได้

$ git reset --hard HEAD^

(โปรดทราบว่าการดำเนินการนี้จะลบการเปลี่ยนแปลงที่ยังไม่ได้ใช้ทั้งหมดใช้ด้วยความระมัดระวัง)

หากคุณเผยแพร่การกระทำที่จะถูกลบไปแล้วให้ใช้git revert

$ git revert HEAD

นั่นไม่ได้ผล เมื่อฉันคอมไพล์บันทึกทุกอย่างยังคงมีอยู่ไม่ว่าทำไมฉันถึงทำแค่เพิ่มความมุ่งมั่นมากขึ้น ฉันต้องการล้างประวัติ
Costa

@Costa: อะไรที่ใช้ไม่ได้ (เช่นคุณใช้เวอร์ชันใด) และคุณบันทึก git อย่างไร?
Jakub Narębski

ฉันได้ลองเกือบทุกอย่างในคำถาม & คำตอบนี้แล้ว (ฉันพยายามกลับหัว git ล่าสุด) บันทึก git ของฉัน:tree = log --all --graph --format=format:'%C(bold blue)%h%C(reset) %C(dim black)%s%C(reset)%C(bold red)%d%C(reset) %C(green)by %an, %ar%C(reset)'
คอสตา

1
ฉันแค่ต้องการลบการกระทำ (เช่นราวกับว่าพวกเขาไม่เคยมีอยู่) ฉันออกไปผจญภัยการเขียนโค้ดแปลก ๆ ด้วยความมุ่งมั่นใหม่ ๆ และมันก็กลายเป็นถังขยะ ฉันจะลบไฟล์เหล่านั้นออกจากบันทึกการคอมไพล์ได้อย่างไร?
Costa

2
อึศักดิ์สิทธิ์ทำบางสิ่งที่น่าอัศจรรย์อย่างที่ฉันต้องการ .... ซึ่งหนึ่งในคำสั่งเหล่านั้นทำมัน?
Costa

44

สมมติว่าเราต้องการลบคอมมิชชันที่ 2 และ 4 จาก repo

commit 0 : b3d92c5
commit 1 : 2c6a45b
commit 2 : <any_hash>
commit 3 : 77b9b82
commit 4 : <any_hash>

หมายเหตุ: คุณจำเป็นต้องมีสิทธิผู้ดูแลระบบมากกว่าซื้อคืนตั้งแต่ที่คุณกำลังใช้และ--hard-f

  • git checkout b3d92c5 ชำระเงินการกระทำสุดท้ายที่ใช้งานได้
  • git checkout -b repair สร้างสาขาใหม่เพื่อทำงาน
  • git cherry-pick 77b9b82 วิ่งผ่านกระทำ 3
  • git cherry-pick 2c6a45b วิ่งผ่านกระทำ 1
  • git checkout master ชำระเงินหลัก
  • git reset --hard b3d92c5 รีเซ็ตโทเป็นคอมมิชชันที่ใช้งานได้ล่าสุด
  • git merge repair ผสานสาขาใหม่ของเราเข้ากับนาย
  • git push -f origin master ผลักดันต้นแบบไปยัง repo ระยะไกล

1
ขั้นตอนสุดท้ายควรจะgit push -f origin masterไม่มีตัวเลือก--hard
Vivex

2
ฉันเดาเก่ากว่าcommit 0 commit 1คุณช่วยบอกฉันหน่อยได้ไหมว่าทำไมก่อนถึงผ่านcommit 3(โดยเลือกจากเชอร์รี่) แล้วตามด้วยcommit 1? หลังจากเช็คเอาต์ของb3d92cd( commit 0) ผมจะคาดหวังเชอร์รี่เลือกแล้วcommit 1 commit 3ขอบคุณ
Jarek C

@JarekC ผมคิดว่าบนสุดกระทำเป็นรุ่นใหม่ล่าสุดที่นี่กระทำเว้นแต่ฉันเห็นสิ่งผิดปกติ ...
เจฟฟ์ Huijsmans

41
git reset --hard commitId

git push <origin> <branch> --force

PS: CommitId หมายถึงสิ่งที่คุณต้องการเปลี่ยนกลับเป็น


git push - บังคับให้ <origin> <branchName> เนื่องจากไม่ได้กล่าวถึงชื่อสาขามันอาจเปลี่ยนไฟล์ทั้งหมดในรีโมต
sheelpriy

39

เปลี่ยนประวัติศาสตร์อย่างตั้งใจ

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

git rebase -i HEAD~<number of commits to go back>ดังนั้นgit rebase -i HEAD~5หากคุณต้องการดูการกระทำห้าครั้งล่าสุด

จากนั้นในโปรแกรมแก้ไขข้อความเปลี่ยนคำถัดจากคำpickสั่งdropที่คุณต้องการลบ บันทึกและออกจากโปรแกรมแก้ไข Voila!

เพิ่มประวัติการเปลี่ยนแปลง

ลองgit revert <commit hash>ดู ย้อนกลับจะสร้างการกระทำใหม่ที่ยกเลิกการกระทำที่ระบุ


dropไม่ได้กำหนดคำหลัก หากต้องการลบการคอมมิตเพียงแค่ลบทั้งบรรทัด
Shayan Salehian

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

นี่คือสิ่งที่ฉันต้องการ ใช้งานได้ดี; ขอบคุณ!
diekunstderfuge

30

หากคุณต้องการแก้ไขการคอมมิชชันล่าสุดของคุณคุณสามารถยกเลิกการคอมมิชชันและ unstage ไฟล์ในนั้นโดยทำ:

git reset HEAD~1

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

หากคุณต้องการเลิกคอมมิชชัน N แต่ให้ทำการเปลี่ยนแปลงรหัสในไดเรกทอรีการทำงานของคุณ:

git reset HEAD~N

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

git reset --hard HEAD~1

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

git reset --hard HEAD~N

22
git rebase -i HEAD~2

นี่คือ '2' คือจำนวนการกระทำที่คุณต้องการรีบูต

'git rebase -i HEAD`

หากคุณต้องการที่จะรีบูตเครื่องทั้งหมด

จากนั้นคุณจะสามารถเลือกหนึ่งในตัวเลือกเหล่านี้

p, pick = use commit

r, reword = use commit, but edit the commit message

e, edit = use commit, but stop for amending

s, squash = use commit, but meld into previous commit

f, fixup = like "squash", but discard this commit's log message

x, exec = run command (the rest of the line) using shell

d, drop = remove commit

บรรทัดเหล่านี้สามารถสั่งซื้อใหม่ได้ พวกเขาจะดำเนินการจากบนลงล่าง หากคุณลบบรรทัดที่นี่ COMMIT จะหายไป อย่างไรก็ตามหากคุณลบทุกอย่างการปฏิเสธจะถูกยกเลิก โปรดทราบว่าความมุ่งมั่นที่ว่างเปล่าจะถูกใส่ความคิดเห็น

คุณสามารถลบการกระทำโดยใช้ตัวเลือก "d" หรือการลบบรรทัดที่มีการส่งของคุณ


ในรุ่นคอมไพล์ล่าสุดไม่มีตัวเลือกมากขึ้นd คุณต้องการเพียงแค่ลบบรรทัดที่มีคอมมิชชันจาก rebase เพื่อลบออก
Oleg Abrazhaev

17

หากต้องการลบในสาขาท้องถิ่นให้ใช้

git reset --hard HEAD~1

หากต้องการลบในสาขาระยะไกลให้ใช้

git push origin HEAD --force

12

[คำตอบที่รวดเร็ว]

คุณมีทางเลือกมากมายเช่น:

  • ทางเลือก 1:

    git rebase -i <YourCommitId>~1
    

    เปลี่ยน YourCommitId สำหรับจำนวนการกระทำที่คุณต้องการเปลี่ยนกลับเป็น

  • ทางเลือก 2:

    git reset --hard YourCommitId
    git push <origin> <branch> --force
    

    เปลี่ยน YourCommitId สำหรับจำนวนการกระทำที่คุณต้องการเปลี่ยนกลับเป็น

    ฉันไม่แนะนำตัวเลือกนี้เพราะคุณอาจสูญเสียงานระหว่างทำ

  • ทางเลือก 3:

    git reset --soft HEAD~1
    

    คุณสามารถรักษางานของคุณและยกเลิกการกระทำ


ขอบคุณคุณขอบคุณขอบคุณ (Y)
Habib Rehman

11

ที่มา: https://gist.github.com/sagarjethi/c07723b2f4fa74ad8bdf229166cf79d8

ลบการส่งครั้งล่าสุด

ตัวอย่างเช่นการกระทำครั้งสุดท้ายของคุณ

git push กำเนิด + aa61ab32 ^: หลัก

ตอนนี้คุณต้องการลบการกระทำนี้แล้ววิธีง่ายๆในการทำสิ่งต่อไปนี้

ขั้นตอน

  1. ก่อนอื่นให้รีเซ็ตสาขาเป็นพาเรนต์ของการส่งในปัจจุบัน

  2. บังคับให้กดไปที่รีโมต

git reset HEAD^ --hard

git push origin -f

สำหรับการคอมมิทโดยเฉพาะคุณต้องการรีเซ็ตกำลังติดตาม

git reset bb676878^ --hard

git push origin -f

9

นี่เป็นอีกวิธีในการทำสิ่งนี้:

ชำระเงินที่สาขาที่คุณต้องการเปลี่ยนกลับจากนั้นรีเซ็ตสำเนาการทำงานในเครื่องของคุณกลับไปเป็นการยืนยันว่าคุณต้องการเป็นสาขาล่าสุดบนเซิร์ฟเวอร์ระยะไกล ในการทำเช่นนี้ใน SourceTree I คลิกขวาที่และเลือก "รีเซ็ต BRANCHNAME เป็นการกระทำนี้" ฉันคิดว่าบรรทัดคำสั่งคือ:

git reset --hard COMMIT_ID

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

จากนั้นไปที่ไดเร็กทอรีโลคัลของที่เก็บของคุณและรันคำสั่งนี้:

git -c diff.mnemonicprefix=false -c core.quotepath=false \
push -v -f --tags REPOSITORY_NAME BRANCHNAME:BRANCHNAME

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


9

ความผิดพลาด:

ฉันgit rebase -i --rootสาขาของฉันโดยไม่รู้ตัวคิดว่าฉันสามารถ reword ครั้งแรกที่กระทำแตกต่างจากต้นแบบ ( GitHub สำหรับมุมมองเริ่มต้นของWindowsคือการเปรียบเทียบกับต้นแบบซ่อนไว้อย่างครบถ้วน)

ฉันเติบโตเครา Silicon Valley ในขณะที่ 900+ คอมมิชชันโหลดตัวเองลงใน Sublime เมื่อออกจากที่ไม่มีการเปลี่ยนแปลงฉันได้ชาร์จแบตเตอรี่ของฉันจากนั้นก็ทำการโกนต่อเนื่องจากบุคคลทั้งหมดกว่า 900+ รายมุ่งมั่นที่จะทำการรีบูตโดยไม่ได้ตั้งใจ

มุ่งมั่นที่จะเอาชนะ Git และรักษาเวลาเดิมฉันลบที่เก็บในเครื่องนี้และโคลนซ้ำจากระยะไกล

ตอนนี้มันได้เพิ่มการคอมมิทที่ไม่จำเป็นล่าสุดให้กับมาสเตอร์ที่ฉันต้องการลบดังนั้นดำเนินการต่อเช่นนี้

หลบหนีตัวเลือก:

ฉันไม่ต้องการgit revert- มันจะสร้างความมุ่งมั่นเพิ่มเติมโดยมอบให้ Git

git reset --hard HEADไม่ได้ทำอะไรเลยหลังจากตรวจสอบสิ่งreflogสุดท้ายและเพียงอย่างเดียวHEADคือการโคลน - Git ชนะ

เพื่อรับ SHA ล่าสุดฉันตรวจสอบที่เก็บระยะไกลบน github.com - ผู้ชนะเล็กน้อย

หลังจากคิดแล้ว git reset --hard <SHA>ทำงานฉันได้ปรับปรุงสาขาอื่นเป็นหลักและ 1 ... 2 ... กะเทย! ความมุ่งมั่นกลับมาแล้ว - Git ชนะ

ตรวจสอบกลับไปที่อาจารย์เวลาที่จะลองgit rebase -i <SHA>แล้วลบบรรทัด ... เพื่อประโยชน์ไม่น่าเศร้าที่จะพูด " ถ้าคุณลบบรรทัดที่นี่คอมมิทจะสูญเสีย " อ่า ... คัดสรรคุณลักษณะใหม่ ๆ ที่หมุนรอบ n00bในบันทึกประจำรุ่น 2.8.3บันทึกประจำรุ่น

การแก้ไขปัญหา:

git rebase -i <SHA> แล้วก็ d, drop = remove commitแล้วก็

ในการตรวจสอบฉันได้เช็คเอาท์ที่สาขาอื่นและ voila - ไม่มีการปิดบังเพื่อดึง / ดึงจากต้นแบบ

https://twitter.com/holman/status/706006896273063936

วันที่ดีกับคุณ.


8

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

ผมคิดว่ามีวิธีที่จะเอากระทำโดยไม่มีคำสั่งพอร์ซเลน วิธีเดียวคือการลบออกจากบันทึกและ reflog git prune --expire -nowแล้วในการดำเนินการ


1
ลำดับที่คำตอบจะปรากฏบน StackOverflow ไม่ได้รับการแก้ไข กรุณาอย่าอ้างอิง“ คำสั่งทั้งหมดข้างต้น” ทำให้คำตอบของคุณอยู่ในตัวเอง
Pascal Cuoq

คำตอบนี้ไม่ถูกต้องทั้งหมด git prune เป็นจริงหนึ่งของ "พอร์ซเลน" คำสั่ง นอกจากนี้ยังเป็นเรื่องยากที่คุณต้องการล้าง reflog ของคุณอย่างสมบูรณ์ (กรณีการใช้งานหนึ่งกรณีคือการลบข้อมูลที่ละเอียดอ่อนจาก repo ของคุณ บ่อยครั้งที่คุณไม่ต้องการเก็บข้อมูลเก่าไว้ใน reflog ในกรณีที่คุณต้องการกู้คืนข้อมูล ดูโปร Git: 9.7 Git Internals - การบำรุงรักษาและการกู้คืนข้อมูล

8

หากคุณต้องการเก็บประวัติแสดงการกระทำและการย้อนกลับคุณควรใช้:

git revert GIT_COMMIT_HASH

ป้อนข้อความที่อธิบายว่าเพราะเหตุใดคุณจึงเปลี่ยนกลับ:

git push  

เมื่อคุณออกgit logคุณจะเห็นทั้ง "ผิด" กระทำและย้อนกลับข้อความบันทึก


ใช่ แต่ OP ชัดเจนว่านั่นไม่ใช่สิ่งที่พวกเขาต้องการ
Steve Bennett

7

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

git commit --amend -m "New message here"

หากคุณมีการเปลี่ยนแปลงที่จัดฉากใหม่พวกเขาจะถูกรวมเข้ากับการคอมมิทครั้งล่าสุด (ซึ่งคุณกำลังพยายามกำจัด) และจะแทนที่การคอมมิทนั้น

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

นอกจากนี้คุณยังสามารถส่งต่อตัวเลือก '- ไม่แก้ไข' แทน '-m' หากคุณต้องการใช้ข้อความการส่งก่อนหน้านี้

เอกสาร: http://git-scm.com/docs/git-commit.html


2
นั่นไม่ใช่สิ่งที่ OP ขอมา
Steve Bennett

5

หากคุณได้ผลักแล้วขั้นแรกให้ค้นหาความมุ่งมั่นที่คุณต้องการให้อยู่ที่ HEAD ($ GIT_COMMIT_HASH_HERE)จากนั้นเรียกใช้สิ่งต่อไปนี้:

git reset --hard $GIT_COMMIT_HASH_HERE
git push origin HEAD --force

จากนั้นแต่ละที่ repo ถูกโคลนให้รัน:

git reset --hard origin/master

5

สิ่งที่ฉันมักจะทำเมื่อฉันกระทำและผลักดัน (ถ้าใครผลักเขากระทำนี้แก้ปัญหา):

git reset --hard HEAD~1

git push -f origin

หวังว่าความช่วยเหลือนี้


5

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

git reset --hard $GIT_COMMIT_HASH_HERE
git push origin HEAD --force

4

รีเซ็ตสาขาท้องถิ่น

git reset --hard HEAD~<Number of commit> So git reset --hard HEAD~3

บังคับให้กดไปที่จุดเริ่มต้น

git push -f origin

3

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

git reset --hard HEAD
git clean -f
git pull

หากคุณต้องการเก็บการเปลี่ยนแปลงของคุณและลบการกระทำล่าสุด

git reset --soft HEAD^
git pull


2

ลบการกระทำในเครื่อง

อย่างที่คุณเห็นในภาพด้านบนฉันต้องการลบการเปลี่ยนกลับ "test change 2" commit (SHA1 ID: 015b5220c50e3dfbb1063f23789d92ae1d3481a2 (คุณสามารถรับ SHA1 ID โดยใช้gitkคำสั่งใน git bash))

เพื่อที่ฉันสามารถใช้ (คำสั่งด้านล่างทั้งหมดทำงานในท้องถิ่นเท่านั้นคุณต้องผลักดันหลังจากลบ):

  1. git reset --hard 515b5220c50e3dfbb1063f23789d92ae1d3481a2// สำรองข้อมูลคุณไปที่การกระทำ (รหัส SHA1 ของการทดสอบการเปลี่ยนแปลง 4 การกระทำคือ515b5220c50e3dfbb1063f23789d92ae1d3481a2 )
  2. git reset --hard HEAD~1 // สำรองข้อมูลคุณไว้ก่อนที่จะส่งมอบ
  3. git reset --hard HEAD^ // เพื่อลบการคอมมิทล่าสุดออกจากคอมไพล์

หลังจากลบ:

หลังจากลบการกระทำ


2

git reset --hard HEAD~1
คุณจะอยู่ที่หัวก่อนหน้านี้ ดึงกิ่งไม้ กดรหัสใหม่ คอมมิทจะถูกลบออกจากคอมไพล์


หากคุณไม่ได้ผลักดันการเปลี่ยนแปลง ในกรณีนั้นฮาร์ดรีเซ็ตจะไม่ล้างข้อมูลรีโมตของคุณ ในกรณีที่การ
รีบูต

1

รีเซ็ต git - ฮาร์ด

git push ต้นกำเนิด HEAD --force

หากมีการผูกมัดอย่างน้อยหนึ่งรายการให้แท็กลบแท็กก่อน มิฉะนั้นการคอมมิตที่แท็กจะไม่ถูกลบ


0

ใช้ git revert https://git-scm.com/docs/git-revertมันจะเปลี่ยนรหัสทั้งหมดจากนั้นคุณสามารถทำคอมมิทต่อไปจากนั้นหัวหน้าจะชี้ไปที่คอมมิทสุดท้าย กระทำการย้อนกลับไม่เคยลบ แต่จะไม่ส่งผลกระทบต่อการกระทำครั้งล่าสุดของคุณ


0

ในกรณีของฉันรหัสเวทย์มนตร์สำหรับดักแด้นี้คือรหัสนี้:

git reset --hard @{u}

ทดสอบและบอกฉัน ฉันได้ลองใช้ตัวอื่นแล้ว แต่อันนี้เป็นตัวเดียวที่ช่วยฉันได้

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