ฉันเพิ่งระบุแหล่งที่มาที่ไม่ถูกต้องในโครงการของฉันโดยใช้--force
ตัวเลือก
สามารถเปลี่ยนกลับได้หรือไม่? ฉันเข้าใจว่าสาขาก่อนหน้านี้ทั้งหมดถูกเขียนทับโดยใช้-f
ตัวเลือกดังนั้นฉันอาจทำให้การแก้ไขครั้งก่อนของฉันเสียหาย
ฉันเพิ่งระบุแหล่งที่มาที่ไม่ถูกต้องในโครงการของฉันโดยใช้--force
ตัวเลือก
สามารถเปลี่ยนกลับได้หรือไม่? ฉันเข้าใจว่าสาขาก่อนหน้านี้ทั้งหมดถูกเขียนทับโดยใช้-f
ตัวเลือกดังนั้นฉันอาจทำให้การแก้ไขครั้งก่อนของฉันเสียหาย
คำตอบ:
โดยทั่วไป Git ไม่ได้ทิ้งอะไรไป แต่การกู้คืนจากสิ่งนี้อาจเป็นเรื่องยุ่งยาก
หากคุณมีแหล่งที่มาที่ถูกต้องคุณก็สามารถกดลงในรีโมทด้วย--force
ตัวเลือก Git จะไม่ลบสาขาใด ๆ เว้นแต่คุณจะแจ้งให้ทราบ ถ้าคุณมีกระทำที่หายไปจริงแล้วจะดูที่คู่มือที่มีประโยชน์นี้เพื่อกระทำการกู้คืน หากคุณรู้จัก SHA-1 ของการคอมมิตที่คุณต้องการคุณก็น่าจะโอเค
สิ่งที่ดีที่สุดที่ต้องทำ: สำรองข้อมูลทุกอย่างและดูว่ามีอะไรอยู่ในพื้นที่เก็บข้อมูลในเครื่องของคุณ ทำเช่นเดียวกันบนรีโมทถ้าเป็นไปได้ การใช้งานgit fsck
เพื่อดูว่าคุณสามารถกู้คืนสิ่งและเหนือสิ่งอื่นใดไม่ได้ทำงานgit gc
เหนือสิ่งอื่นใดอย่าใช้--force
ตัวเลือกนี้เว้นแต่คุณจะตั้งใจจริง
git reflog show remotes/origin/master
. คุณควรจะเห็นการผลักดันของคุณที่นั่น การกระทำในบรรทัดก่อนหน้าคือจุดที่อยู่ก่อนที่คุณจะทำให้มันยุ่งเหยิง จากนั้นคุณสามารถผลักดันการแก้ไขนั้น (พร้อม--force
) ไปยังจุดเริ่มต้นและกลับมาที่เดิม!
git fetch
ed มานานแล้ว) คุณสามารถแสดง reflog ด้านข้างของ GitHub และกู้คืนได้!
หากคุณรู้จักคอมมิตแฮชก็ทำได้ง่ายๆเพียงสร้างสาขาของคุณขึ้นมาใหม่
5794458...b459f069 master -> master (forced update)
ลบสาขาระยะไกล:
git push origin :master
จากนั้นสร้างสาขาของคุณใหม่ด้วยคำสั่งต่อไปนี้:
git checkout 5794458
git branch master
git push origin master
วิธีแก้ปัญหาได้กล่าวไว้แล้วที่นี่
# work on local master
git checkout master
# reset to the previous state of origin/master, as recorded by reflog
git reset --hard origin/master@{1}
# at this point verify that this is indeed the desired commit.
# (if necessary, use git reflog to find the right one, and
# git reset --hard to that one)
# finally, push the master branch (and only the master branch) to the server
git push -f origin master
git reflog show remotes/origin/master
ถ้าจำเป็นต้องมีการอ้างอิงคอมไพล์ (ตามที่กล่าวไว้โดย @Cascabel ด้านบน)
หากคุณไม่ได้อยู่ใน repo ท้องถิ่นที่ซึ่งการผลักดันบังคับมาจากระดับต้นทาง / ระดับมาสเตอร์จะไม่มีทางกู้คืนได้ แต่ถ้าคุณโชคดีพอที่จะใช้GitHubหรือGitHub for EnterpriseคุณสามารถดูREST API และเรียกข้อมูลการกระทำที่สูญหายไปเป็นโปรแกรมแก้ไขได้เช่น
https://api.github.com/repos/apache/logging-log4j2/commits/889232e28f3863d2a17392c06c1dd8cac68485de
git ใช้ patch.patch && git คอมมิต -m "restore comm" && git push origin master
อีกวิธีหนึ่งในการกู้คืนคอมมิตที่หายไปหรือแม้กระทั่งการค้นหาว่าการกระทำใดสูญหายไปหากการผลักดันครั้งก่อนไม่ได้มาจาก repo ในพื้นที่ของคุณคือการดูที่เครื่อง CI ของคุณ
หากคุณมีงานที่ทดสอบสาขาหลักหลังจากทุกครั้งที่มีการคอมมิต (หรือชุดของการคอมมิตต่อเนื่องกัน) ซึ่งคุณควรจะมีคุณสามารถดูได้ว่ามีการทดสอบอะไรล่าสุดบ้าง นั่นคือการกระทำที่คุณต้องกู้คืน
เครื่อง CI อาจเก็บโคลนในเครื่องของ repo ซึ่งคุณอาจสามารถทำการกู้คืนนี้ได้
ใช่คุณสามารถกู้คืนคอมมิตได้หลังจากนั้น git push -f your_branch
ข้อความจาก Doc :
รายการพรุนที่เก่ากว่าเวลาที่กำหนด หากไม่ได้ระบุตัวเลือกนี้เวลาหมดอายุจะถูกนำมาจากการตั้งค่าคอนฟิกูเรชัน gc.reflogExpire ซึ่งจะมีค่าเริ่มต้นเป็น 90 วัน --expire = รายการพรุนทั้งหมดโดยไม่คำนึงถึงอายุ --expire = ไม่เคยปิดการตัดรายการที่เข้าถึงได้ (แต่ดู --expire-ไม่สามารถเข้าถึงได้)
คุณสามารถทำได้:
1- git reflog
2- คุณเลือก Head_Number ที่คุณต้องการกู้คืนด้วย git reset –hard HEAD@{HEAD-NUMBER}
3- คุณสามารถเห็นการกระทำทั้งหมดบนหัวนี้โดย git cherry -v branch_name
4- ในที่สุดคุณควรบังคับผลักดัน git push -f branch_name
หรือ
1- รับจำนวน SHA จากไคลเอนต์ GIT ของคุณ (อินเทอร์เฟซ)
git reset --hard commit_SHA
2- แรงผลัก
git push -f your_branch
หวังว่านี่จะช่วยได้
ฉันทำสิ่งเดียวกันในขณะที่ยกเลิกการกดครั้งสุดท้ายสำหรับไฟล์เดียว สิ้นสุดลงด้วยการกลับสู่สถานะเดิมของที่เก็บ ฉันใช้คำสั่ง git จาก Linus เนื่องจากฉันมีสำเนาโลคัลบน Linux โชคดีที่สำเนานั้นยังไม่บุบสลาย
สิ่งที่ฉันทำคือ (หลังจากทำสำเนา repo ในพื้นที่อีกสองสามชุดอย่างเมามัน):
git add .
git status
(มันบอกว่าต้นกำเนิด / มาสเตอร์อยู่ข้างหน้า 68 คอมมิตดี ... นั่นคือคอมมิตทั้งหมดที่ฉันลบไป)
git remote set-url origin <GIT_SSH_URL>
git push
และทุกอย่างก็กลับคืนมาเหมือนเดิมก่อนที่ฉันจะผลักดันอย่างจริงจัง สิ่งที่สำคัญที่สุดที่ต้องจำไว้คืออย่าทำการชำระเงินด้วยคอมไพล์ หลังจากที่คุณผลักแรง ๆ แต่แนวทางปฏิบัติที่ดีที่สุดคือปิดใช้งานตัวเลือกการกด ฉันไม่เคยใช้มันอีกเลย ได้เรียนรู้บทเรียนของฉัน !!
สำหรับคนที่อยู่ในสถานการณ์เลวร้ายอย่างฉัน (ตัวอย่างเช่นหากคุณได้รับbad object
ข้อผิดพลาดขณะทำงานgit reset --hard
):
ฉันเขียนสคริปต์ชื่อ treesaverที่ดึงไฟล์ทั้งหมดของคุณจาก GitHub API เป็นทางเลือกสุดท้าย วิธีการใช้งานมีดังนี้
treesaver
สคริปต์และcd
ไปที่มันSHA
สตริงของต้นไม้ที่คุณต้องการกู้คืนโดยการเข้าถึง
https://api.github.com/repos/<your_username_or_org>/<repo>/events
สตริงของต้นไม้ที่คุณต้องการที่จะเรียกคืนโดยการเข้าถึงpayload
ร็อพเพอร์ตี้ที่ตรงกับเหตุการณ์พุชของคุณค้นหาสิ่งที่commit
คุณต้องการเปลี่ยนกลับและคลิกที่เหตุการณ์นั้นurl
เหตุการณ์นั้นcommit.tree
คัดลอกtree
'surl
'spython3 main.py <tree_url> <path_to_save_to>
วิ่งตัวอย่างเช่นในกรณีของฉันฉันจะเรียกใช้:
python3 main.py https://api.github.com/repos/anthonykrivonos/my-repo/git/trees/1234567 .
แน่นอน PRs ยินดีต้อนรับ
คุณสามารถอ่านการตัดสินใจได้ที่นี่ https://evilmartians.com/chronicles/git-push---force-and-how-to-deal-with-it
คนที่สองช่วยฉันด้วย ฉันทำผิดคำสั่งเหล่านี้
1) (some-branch) git pull -> correct command was git pull origin some-branch
2) (some-branch) git push -f origin some-branch
หลังจากคำสั่งเหล่านี้ฉันสูญเสียการกระทำสามครั้ง ในการกู้คืนพวกเขาฉันมองไปที่เทอร์มินัลที่ฉันทำ 'git pull' ผิดและได้เห็นผลลัพธ์เช่น
60223bf ... 0b258eb บางสาขา -> ต้นทาง / บางสาขา
แฮชที่สอง 0b258eb คือสิ่งที่ฉันต้องการ ดังนั้นฉันจึงใช้แฮชนี้และสร้างคำสั่ง
git push --force origin 0b258eb:some-branch