ทิ้งความมุ่งมั่นของท้องถิ่นใน Git


1469

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

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

อาจจะgit revertเป็นสิ่งที่ฉันต้องการ แต่ฉันไม่ต้องการที่จะจบลง10 คอมมิตก่อนที่จะเริ่มต้น (หรือแม้แต่หก) แม้ว่ามันจะทำให้โค้ดกลับคืนสู่สถานะที่ถูกต้องก็ตาม ฉันแค่อยากจะแกล้งครึ่งชั่วโมงที่ผ่านมาไม่เคยเกิดขึ้น

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


โปรดทราบว่าคำถามนี้เป็นพิเศษเกี่ยวกับการกระทำ , ไม่เกี่ยวกับ:

  • ไฟล์ที่ไม่ได้ติดตาม
  • การเปลี่ยนแปลงแบบไม่จัด
  • staged แต่ไม่มีข้อผูกมัดการเปลี่ยนแปลง

คำตอบ:


2470

หากคอมมิชชันที่เกินของคุณจะปรากฏให้คุณเห็นเท่านั้นคุณสามารถทำได้ git reset --hard origin/<branch_name> เพื่อย้ายกลับไปยังที่ต้นทาง สิ่งนี้จะรีเซ็ตสถานะของที่เก็บเป็นการกระทำก่อนหน้าและจะยกเลิกการเปลี่ยนแปลงในเครื่องทั้งหมด

ทำgit revertทำให้ใหม่มุ่งมั่นที่จะลบเก่ากระทำในทางที่ช่วยให้มีสติประวัติของทุกคน


91
git reset --hard <commit hash, branch, or tag>หากคุณต้องการไปที่การอ้างอิงเฉพาะนอกเหนือจากสาขาระยะไกล
Sam Soffes

55
เพียงเพื่อให้ชัดเจนถ้าคุณไม่ได้ทำงานmasterแต่อยู่ในสาขาอื่นคุณควรทำงานgit reset --hard origin/<your-branch-name>
Zoltán

33
สิ่งนี้จะไม่เพียง แต่ทิ้งการกระทำในท้องถิ่น แต่ยังทิ้งทุกอย่างในแผนผังการทำงานของคุณ (เช่นไฟล์ในเครื่องของคุณ) หากสิ่งที่คุณต้องการทำนั้นไม่ธรรมดา แต่ปล่อยให้งานของคุณไม่เสียหายคุณควรทำ "git reset HEAD ^" ... ต่อstackoverflow.com/questions/2845731/…
aaronbauman

3
คุณอาจต้องการดึงข้อมูลหลังจากนี้ สิ่งนี้แก้ไขตัวนับจำนวนการคอมมิตรอเพื่อผลักดันบน SourceTree
สแตน

2
git reset --hard origin/<branch_name>มันจะรีเซ็ตการกำหนดค่าโครงการเช่นกันดังนั้นดูแลสิ่งนี้ ฉันมี.cfgไฟล์ขนาดใหญ่ซึ่งถูกรีเซ็ตเป็นค่าเริ่มต้น ฉันต้องใช้เวลาหลายชั่วโมง
MAC

271

เพียงลบสาขาหลักในพื้นที่ของคุณแล้วสร้างใหม่ตามต้องการ:

git branch -D master
git checkout origin/master -b master

2
วิธีนี้ใช้งานได้ดีเมื่อย้อนรอยการเปลี่ยนแปลงของคุณอาจใช้เวลานานเกินไปซึ่งเกิดขึ้นกับฉันหลังจากการรีบาวด์สองสามครั้ง
Aross

1
มีประโยชน์สำหรับปัญหาการดึง / ดันย่อยของสมาชิกในทีม!
Jorge Orpinel

นี่คือที่สมบูรณ์แบบเมื่อคุณต้องการที่จะคืนค่าสาขาแทนที่จะเป็นเพียงต้นแบบ
Vladimir Ralev

1
นี่ไม่ใช่วิธีที่ดีในการลบการกระทำในเครื่องเดียว ดีกว่าที่จะใช้git reset --hard origin/<branch_name>
Kirit Vaghela

1
บางทีทางออกนั้นอาจใช้ได้ แต่ก็ไม่ได้หมายความว่าเป็นวิธีที่เหมาะสม
Adly

202

ลอง:

git reset --hard <the sha1 hash>

เพื่อรีเซ็ตหัวของคุณไปทุกที่ที่คุณต้องการ ใช้ gitk เพื่อดูว่าคุณต้องการทำอะไร คุณสามารถทำการรีเซ็ตภายใน gitk ได้เช่นกัน


5
การลงทะเบียน b / c นี้เป็นข้อมูลที่เป็นประโยชน์ แต่คำตอบของ Ben Jackson ได้รับเครื่องหมายถูกสำหรับการแก้ไขสิ่งที่ฉันต้องการอย่างแท้จริงในแบบที่ไม่ต้องการให้ฉันค้นหาแฮช :)
David Moles

2
นี่คือหนึ่งเมื่อสาขาใหม่ของคุณไม่เคยได้รับการผลักดันที่มาเลย
ม.ค.

126

ลบการคอมมิทล่าสุด:

git reset --hard HEAD~1

ลบการคอมมิทล่าสุดโดยไม่ทำลายงานที่คุณทำ:

git reset --soft HEAD~1


5
คำตอบที่เป็นประโยชน์ ขอบคุณ! ฉันใช้การตั้งค่า git - ซอฟต์ดั้งเดิม / ปรมาจารย์
Tarun Kumar

2
@TarunKumar ขอขอบคุณ! ฉันกำลังใช้การรวม VS และโซลูชันของคุณเป็นวิธีเดียวที่ฉันสามารถล้างการรวมกลุ่มที่ฉันไม่ต้องการในสาขาที่ฉันไม่ได้รับอนุญาตให้เช็คอิน
DVK

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

47

หากคุณใช้แอปAtlassian SourceTreeคุณสามารถใช้ตัวเลือกการรีเซ็ตในเมนูบริบท

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


42

ในความพยายามสาขาของคุณ:

git reset --hard origin/<branch_name>

ตรวจสอบการกลับรายการ (เป็นของรัฐโดยไม่มีข้อผูกมัดในพื้นที่) โดยใช้ " git log" หรือ " git status"


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

3
คำตอบที่ได้รับการยอมรับเป็นเช่นเดียวกับของคุณลบชื่อสาขาทั่วไปและในความคิดเห็น @Zoltan พูดอย่างชัดเจนJust to be clear, if you're not working on master but on another branch, you should run git reset --hard origin/<your-branch-name>
Troyseph

1
นี่คือคำตอบที่ดีที่สุดในความคิดของฉัน
dwjohnston

21

git reset --hard @{u}* ลบการเปลี่ยนแปลงในท้องถิ่นของคุณทั้งหมดในสาขาปัจจุบันรวมถึงการกระทำ ฉันประหลาดใจที่ไม่มีใครโพสต์สิ่งนี้ แต่เมื่อพิจารณาว่าคุณไม่ต้องค้นหาสิ่งที่กระทำเพื่อแปลงกลับหรือเล่นกับสาขา

* นั่นคือการตั้งค่าไปยังสาขาในปัจจุบันที่@{upstream}-commonly origin/<branchname>แต่ไม่เสมอไป


1
เปลือกหอยบางชนิดเช่นปลาจะตีความ "@" ดังนั้นคุณอาจต้องใส่ '@ {u}' ในเครื่องหมายคำพูดเช่น `git reset - ฮาร์ด '@ {u}' อย่างไรก็ตามหาดี!
trysis

คำตอบที่ยอดเยี่ยมนั้นยอดเยี่ยมมาก
Marko

1
คุณพิมพ์ค่าของ @ {u} ได้อย่างไร
Philip Rego

12

หากต้องการดู / รับรหัส SHA-1 ของการส่งข้อมูลที่คุณต้องการกลับมาด้วย

gitk --all

เพื่อย้อนกลับไปสู่การกระทำนั้น

git reset --hard sha1_id

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


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

หากคุณอยู่ใน gitk คุณสามารถคลิกขวาที่คอมมิทและเลือก "รีเซ็ตสาขา XY เป็นที่นี่"
mkrieger1

และความมุ่งมั่นที่ใหม่กว่าจะไม่ถูกลบทันที ไม่มีสาขาใดที่ชี้ไปที่พวกเขาอีกต่อไป (โปรดจำไว้ว่าสาขาจะไม่มีอะไรนอกจาก "บุ๊กมาร์ก" สำหรับการกระทำเฉพาะ)
mkrieger1

9

ฉันมีสถานการณ์ที่ฉันต้องการลบการกระทำที่ไม่ได้ผลัก แต่การกระทำนั้นอยู่ต่อหน้าอีกคนหนึ่ง หากต้องการทำเช่นนั้นฉันได้ใช้คำสั่งต่อไปนี้

git rebase -i HEAD~2 -> มันจะทำการ rebase สองครั้งล่าสุด

และฉันใช้ 'ปล่อย' สำหรับลายเซ็นการส่งที่ฉันต้องการลบ


9

ลบไฟล์ที่ไม่ได้ติดตาม (การเปลี่ยนแปลงโลคัลที่ไม่ได้ผูกมัด)

git clean -df

การลบการกระทำในท้องถิ่นทั้งหมดอย่างถาวรและรับการกระทำระยะไกลล่าสุด

git reset --hard origin/<branch_name>

8

สำหรับคอมมิทในพื้นที่ที่ไม่ได้ทำการส่งคุณสามารถใช้git rebase -iเพื่อลบหรือสควอชการคอมมิชชัน


1
ฉันรู้ว่านี่อาจไม่ใช่วิธีแก้ปัญหาที่สั้นที่สุด แต่ฉันก็สนับสนุนคุณเพราะ IMHO git rebase -iเป็นวิธีที่ใช้กันทั่วไปในการแก้ปัญหาที่คล้ายกันหลายอย่างและสามารถเป็นประโยชน์ในสถานการณ์ที่หลากหลาย
Stefan Marinov

1
ใช้dropคำหลัก (แทนที่จะลบบรรทัด) เมื่อลบการกระทำทั้งหมดเพื่อหลีกเลี่ยงการยกเลิกการปฏิเสธ
Michal Čizmazia

6

วิธีแก้ไขปัญหาอย่างง่ายคือจับคู่หัวหน้าสาขาหลักในท้องถิ่นกับแหล่งกำเนิด / หัวหน้าสาขาหลัก

git reset --hard origin/master

PS: จุดเริ่มต้น / หลัก - เป็นตัวชี้ระยะไกลไปยังสาขาหลัก คุณสามารถแทนที่ข้อมูลหลักด้วยชื่อสาขาใดก็ได้


4

HEADก่อนที่จะตอบให้เพิ่มพื้นหลังบางอธิบายสิ่งที่เป็นแบบนี้ เนื่องจากตัวเลือกบางตัวด้านล่างจะส่งผลให้เกิดการถอดหัว

First of all what is HEAD?

HEADเป็นเพียงการอ้างอิงถึงการกระทำปัจจุบัน (ล่าสุด) ในสาขาปัจจุบัน
สามารถมีได้เพียงครั้งเดียวHEADในเวลาที่กำหนด (ไม่รวมgit worktree)

เนื้อหาของHEADถูกเก็บไว้ภายใน.git/HEADและประกอบด้วย 40 ไบต์ SHA-1 ของการกระทำปัจจุบัน


detached HEAD

หากคุณไม่ได้อยู่บนล่าสุดกระทำ - ความหมายที่จะชี้ไปก่อนกระทำในประวัติศาสตร์ที่เรียกว่าHEADdetached HEAD

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

บนบรรทัดคำสั่งจะมีลักษณะเช่นนี้ - SHA-1 แทนชื่อสาขาเนื่องจากHEADไม่ได้ชี้ไปที่ปลายของสาขาปัจจุบัน

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

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

ตัวเลือกบางอย่างเกี่ยวกับวิธีการกู้คืนจาก HEAD เดี่ยว:


git checkout

git checkout <commit_id>
git checkout -b <new branch> <commit_id>
git checkout HEAD~X // x is the number of commits t go back

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

# Checkout a given commit. 
# Doing so will result in a `detached HEAD` which mean that the `HEAD`
# is not pointing to the latest so you will need to checkout branch
# in order to be able to update the code.
git checkout <commit-id>

# create a new branch forked to the given commit
git checkout -b <branch name>

git reflog

คุณสามารถใช้reflogเช่นกัน
git reflogจะแสดงการเปลี่ยนแปลงใด ๆ ที่มีการปรับปรุงHEADและการตรวจสอบรายการ reflog ที่ต้องการจะตั้งค่าHEADกลับไปที่การกระทำนี้

ทุกครั้งที่มีการแก้ไข HEAD จะมีรายการใหม่ใน reflog

git reflog
git checkout HEAD@{...}

สิ่งนี้จะนำคุณกลับไปสู่การกระทำที่คุณต้องการ

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


git reset --hard <commit_id>

"ย้าย" HEAD ของคุณกลับไปยังการกระทำที่ต้องการ

# This will destroy any local modifications.
# Don't do it if you have uncommitted work you want to keep.
git reset --hard 0d1d7fc32

# Alternatively, if there's work to keep:
git stash
git reset --hard 0d1d7fc32
git stash pop
# This saves the modifications, then reapplies that patch after resetting.
# You could get merge conflicts if you've modified things which were
# changed since the commit you reset to.
  • หมายเหตุ: ( ตั้งแต่ Git 2.7 )
    คุณสามารถใช้งานได้git rebase --no-autostashเช่นกัน

git revert <sha-1>

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

# add new commit with the undo of the original one.
# the <sha-1> can be any commit(s) or commit range
git revert <sha-1>

คีมานี้แสดงให้เห็นว่าคำสั่งใดทำอะไร
ในขณะที่คุณสามารถดูมีการปรับเปลี่ยนreset && checkoutHEAD

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


3

สำหรับผู้ที่สนใจในโซลูชัน Visual Studio นี่คือการฝึกซ้อม:

  1. ในTeam Explorerหน้าต่างเชื่อมต่อกับ repo เป้าหมาย
  2. จากนั้นให้คลิกขวาที่สาขาที่สนใจและเลือกBranchesView history
  3. คลิกขวาที่กระทำในหน้าต่างและเลือกHistoryReset -> Delete changes (--hard)

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


2

ถ้าสาขาของคุณไปข้างหน้า ' origin/XXX' โดย 5 คอมมิท

คุณสามารถออก:

git reset --hard HEAD~5

และควรลบ 5 คอมมิทล่าสุด


0
git reset --hard <SHA-Code>

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

คุณสามารถรับรหัส SHA ได้โดยดูที่ webVersion ของแดชบอร์ดคอมไพล์ของคุณสำหรับการกระทำครั้งสุดท้ายในสาขา

วิธีนี้คุณสามารถซิงโครไนซ์กับการคอมมิทล่าสุดในสาขา

คุณสามารถทำได้git pullหลังจากเสร็จสิ้นการฮาร์ดรีเซ็ตเพื่อยืนยันว่าไม่มีอะไรใหม่ที่จะซิงค์เช่นคุณได้รับข้อความ

สาขาของคุณเป็นข้อมูลล่าสุด Origin/<Branch Name>


0

หากคุณได้รับ repo ในพื้นที่ของคุณเป็นระเบียบเรียบร้อยแล้ววิธีที่เชื่อถือได้ในการทิ้งภาระผูกพันใน Git คือการ ...

  1. ใช้ "git config --get remote.origin.url" เพื่อรับ URL ของแหล่งกำเนิดระยะไกล
  2. เปลี่ยนชื่อโฟลเดอร์ git ในเครื่องเป็น "my_broken_local_repo"
  3. ใช้ "git clone <url_from_1>" เพื่อรับสำเนาของที่เก็บรีโมต git ระยะไกล

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

ประโยชน์ด้านข้างของขั้นตอนข้างต้นคือคุณจะพบว่าโครงการของคุณอาศัยไฟล์ในเครื่องที่ไม่ได้ใส่เข้าไปในคอมไพล์หรือไม่ หากคุณพบว่าคุณไม่มีไฟล์คุณสามารถคัดลอกไฟล์เหล่านั้นจาก "my_broken_local_repo" และเพิ่มไปยัง git เมื่อคุณมั่นใจว่า repo ในพื้นที่ของคุณมีทุกสิ่งที่ต้องการแล้วคุณสามารถลบ "my_broken_local_repo"


0

หากคุณต้องการละทิ้งการคอมมิชชันท้องถิ่นและทำการแก้ไขในไฟล์ต่อไปให้ทำการ
รีเซ็ต git @ ~
คำตอบอื่น ๆ ที่ระบุฮาร์ดรีเซ็ต

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