จะคืนค่าคอมไพล์เริ่มต้นได้อย่างไร?


357

ฉันยอมรับที่เก็บ git เป็นครั้งแรก; จากนั้นฉันเสียใจที่กระทำและต้องการเปลี่ยนมัน ฉันลอง

# git reset --hard HEAD~1

ฉันได้รับข้อความนี้:

fatal: ambiguous argument 'HEAD~1': unknown revision or path not in the working tree.

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

คำตอบ:


565

คุณเพียงแค่ต้องลบสาขาที่คุณอยู่ คุณไม่สามารถใช้git branch -Dเนื่องจากมีการตรวจสอบความปลอดภัยในการทำเช่นนี้ คุณสามารถใช้update-refการทำเช่นนี้

git update-ref -d HEAD

ไม่ได้ใช้rm -rf .gitหรืออะไรอย่างนี้เป็นนี้สมบูรณ์จะเช็ดพื้นที่เก็บข้อมูลทั้งหมดของคุณรวมทั้งสาขาอื่น ๆ เช่นเดียวกับสาขาที่คุณกำลังพยายามที่จะตั้งค่า


1
ลองสิ่งนี้ในขณะที่อยู่ในการรีบูต - ต้องการแยกการกระทำแรก - จากนั้นก็ทำgit statusและทำให้ฉันประหลาดใจ git พูดfatal: Not a git repository (or any parent up to mount point ...)!
Matt Fenwick

1
สิ่งนี้ไม่ได้ผลสำหรับฉัน ไฟล์ยี่ห้อรวมทั้งบางส่วนที่ควรจะละเลย .gitignoreแต่ไม่มี git add ., git commit -m "initial commit", git update-ref -D HEADสร้าง.gitignoreแจ้งให้ทราบว่าคอมไพล์ยังจะเห็นไฟล์ที่มันเพิ่มก่อนหน้านี้ว่าควรละเว้น ในคำอื่น ๆgit update-ref -d HEADไม่ได้พาฉันกลับไปที่รัฐก่อนที่ความมุ่งมั่นเริ่มต้น
gman

1
แต่นั่นคือประเด็นของคำถามเดิม กลับไปที่รัฐก่อนที่จะเริ่มต้นกระทำ
gman

2
git reset --hard HEAD~1จะลบไฟล์ที่เพิ่มเข้ามาสำหรับการกระทำอื่น ๆ ทั้งหมด เห็นได้ชัดว่าคำถามคือวิธีการได้รับสถานะเดียวกันกับคำสั่งนั้นทำงานในกรณีอื่น ๆ ทั้งหมด ดูส่วนสำคัญนี้เพื่อพิสูจน์ว่าโซลูชันของคุณใช้งานไม่ได้ gist.github.com/greggman/522fa69a21d6cfb3ff0b
gman

11
ในกรณีที่ใครก็ตามเกิดความสับสนตามความคิดเห็นของ gman: git update-ref -d HEAD จะยกเลิกการกระทำเริ่มต้นจริง ๆ แต่จะเก็บการเปลี่ยนแปลงที่ทำไว้ก่อนหน้านี้ทั้งหมดไว้ในดัชนี git reset --hardหากคุณต้องการที่จะยังเอาการเปลี่ยนแปลงเหล่านั้นเพียงแค่ดำเนินการต่อไปนี้ แม้ว่าจะไม่สมบูรณ์คำตอบนี้เป็นคำตอบที่ดีที่สุดดังนั้นหลีกเลี่ยงการใช้rm -fr .git(เว้นแต่คุณจะรู้ว่าคุณกำลังทำอะไรอยู่)
rsenna

62

คุณสามารถลบ HEAD และกู้คืนที่เก็บของคุณเป็นสถานะใหม่ซึ่งคุณสามารถสร้างการคอมมิทเริ่มต้นใหม่:

git update-ref -d HEAD

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

git push --force origin

1
น่าสังเกตว่า ... นี่เป็นคำสั่งที่ถูกต้อง แต่จะไม่ลบ HEAD ... มันจะลบการอ้างอิง (อยู่ภายใต้. git \ refs \ heads) ที่ไฟล์. git \ HEAD ได้ตรวจสอบแล้ว หลังจากรันคำสั่งนี้คุณยังคงสามารถค้นหาไฟล์ HEAD ที่ชี้ไปยังไฟล์ refs / heads / <name> ที่คุณลบ แต่ถ้าคุณทำตามเส้นทางนั้นคุณจะเห็นว่าไม่มีการอ้างอิงหัวอีกต่อไป
DanK

15

คำถามนี้เชื่อมโยงจากบล็อกโพสต์นี้และเสนอทางเลือกอื่นสำหรับ Git รุ่นใหม่:

git branch -m master old_master
git checkout --orphan master
git branch -D old_master

วิธีแก้ปัญหานี้จะถือว่า:

  1. คุณมีความมุ่งมั่นเพียงอย่างเดียวในmasterสาขาของคุณ
  2. ไม่มีสาขาที่เรียกว่าold_masterดังนั้นฉันสามารถใช้ชื่อนั้นได้ฟรี

มันจะเปลี่ยนชื่อสาขาที่มีอยู่เป็นold_masterและสร้างใหม่, กำพร้า, สาขาmaster (เช่นที่สร้างขึ้นสำหรับที่เก็บใหม่)หลังจากที่คุณสามารถลบold_master... หรือไม่ แล้วแต่คุณ.

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


11

ภายใต้เงื่อนไขที่ระบุไว้ในคำถาม:

  • การคอมมิทเป็นการคอมมิทครั้งแรกในที่เก็บ
  • ซึ่งหมายความว่ามีการดำเนินการคำสั่งน้อยมาก:
    • git init,
    • git addการดำเนินการบางอย่างน่าจะเป็นไปได้
    • และgit commit,
    • และนั่นคือทั้งหมด!

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

rm -fr .git

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

อันตราย! สิ่งนี้จะลบไดเรกทอรีที่เก็บ Git

มันจะลบไดเรกทอรีที่เก็บข้อมูลของ Git อย่างถาวรและไม่สามารถกู้คืนได้เว้นแต่ว่าคุณได้สำรองข้อมูลไว้ที่ใดที่หนึ่ง ภายใต้เงื่อนไขเบื้องต้นคุณไม่มีอะไรที่คุณต้องการเก็บไว้ในที่เก็บดังนั้นคุณจะไม่สูญเสียอะไรเลย ไฟล์ทั้งหมดที่คุณเพิ่มยังคงมีอยู่ในไดเรกทอรีทำงานสมมติว่าคุณยังไม่ได้แก้ไขและยังไม่ได้ลบ ฯลฯ อย่างไรก็ตามการทำเช่นนี้จะปลอดภัยเฉพาะในกรณีที่คุณไม่มีสิ่งใดในที่เก็บของคุณเลย ภายใต้สถานการณ์ที่อธิบายไว้ในคำถาม 'กระทำที่เก็บข้อมูลครั้งแรก - แล้วเสียใจ' มันปลอดภัย อย่างไรก็ตามบ่อยครั้งที่มันไม่ปลอดภัย

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

ระวัง แต่มันปลอดภัยและมีประสิทธิภาพเมื่อตรงตามเงื่อนไข

หากคุณทำสิ่งอื่นด้วยที่เก็บที่คุณต้องการเก็บไว้นี่ไม่ใช่เทคนิคที่เหมาะสม - ที่เก็บของคุณไม่ตรงตามเงื่อนไขที่กำหนดไว้เพื่อให้สิ่งนี้เหมาะสม


9
นี่คือคำแนะนำที่ไม่ดี เกิดอะไรขึ้นถ้ามีสิ่งอื่น ๆ ใน repo ที่คุณไม่ต้องการเสีย?
Matt Fenwick

5
จากนั้นมันก็จะไม่เป็นการกระทำเริ่มต้นมันจะ มีความมุ่งมั่นเริ่มต้นเพียงครั้งเดียวเท่านั้น
Jonathan Leffler

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

2
มีประโยชน์ แต่ควรมีคำเตือน
Simon Bengtsson

5
มันใช้งานได้จริง คำตอบที่ยอมรับไม่ได้ ดูความคิดเห็น
gman


3

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

ตรวจสอบให้แน่ใจว่าคุณอยู่ในสาขาที่ถูกต้อง

git checkout master

git update-ref -d HEAD

git commit -m "Initial commit

git push -u origin master

สิ่งนี้สามารถแก้ไขปัญหาได้

สิ่งสำคัญ

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


1

ฉันสงสัยว่าทำไม "การแก้ไข" ไม่แนะนำและถูกขีดฆ่าโดย @kamrat เนื่องจากการแก้ไขนั้นปรากฏแก่ฉันว่าเป็นวิธีที่ถูกต้องในการแก้ไขปัญหาพื้นฐานที่มีประสิทธิภาพมากที่สุดในการแก้ไขการกระทำที่ผิดเนื่องจากไม่มีวัตถุประสงค์ที่จะไม่เริ่มต้น ผูกมัด ในขณะที่บางคนเครียดคุณควรแก้ไขสาขา "สาธารณะ" อย่างมาสเตอร์ถ้าไม่มีใครลอกเลียนแบบ repo ของคุณ ...

git add <your different stuff>
git commit --amend --author="author name <author.name@email.com>"-m "new message"

- ต้องมีการอนุญาตเฉพาะเมื่อมีคนแก้ไขการมอบสิทธิ์
Richard

0

รีเซ็ต git - ทำการเปลี่ยนแปลงแล้วทำ

git add -A
git commit --amend --no-edit 

หรือ

git add -A
git commit --amend -m "commit_message"

แล้ว

git push origin master --force

- แรงจะเขียนใหม่ที่ส่งไปแล้วในขั้นตอนแรก

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


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