ต้องการเปลี่ยนนายเป็นคนที่มีอายุมากกว่าฉันจะทำสิ่งนี้ได้อย่างไร?


92

ฉันต้องการย้อนกลับไปยังคอมมิตก่อนหน้าจากนั้นเผยแพร่โค้ดนั้นจากนั้นกลับไปที่คอมมิตล่าสุด

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

ฉันจะทำเช่นนี้ได้อย่างไร?

คำตอบ:


100

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

git checkout master~1            # Checkout previous commit on master
git checkout -b new_master       # Create branch for new master
git branch -D master             # Delete old master
git branch -mv new_master master # Make new_master master

อีกทางหนึ่ง:

git reset --hard master~1        # Reset current branch to one commit ago on master

1
หนึ่งปีต่อมาฉันกำลังดูสิ่งนี้และคิดว่านี่เป็นวิธีที่แย่มากที่จะทำ อย่างน้อยก็เข้าใจง่ายดี
Tyler Brock

1
ใช่นี่คือเหตุผลที่ฉันโหวตขึ้นเข้าใจง่ายบางทีคุณควรนำเสนอลิงก์ไปยังวิธีที่ดีกว่านี้
Andrew Atkinson

1
ฉันต้องทำเช่นเดียวกันโดยใช้ SourceTree กระบวนการจะคล้ายกัน 1) สร้างสาขาใหม่สำหรับสถานะหลักปัจจุบันดังนั้นคุณจะไม่สูญเสียอะไรเลย 2) ลบต้นแบบ 3) สร้างสาขาหลักใหม่เลือกคอมมิตที่ต้องการ
Danilo Gomes

จะเกิดอะไรขึ้นกับการกระทำที่เรา "ลบ" ออกจากมาสเตอร์หลังจากนี้
Arthur Colombini Gusmão

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

60

คำถามของคุณไม่ชัดเจน ฉันคิดว่าสิ่งที่คุณขอคือสิ่งนี้:

git push -f origin $old_commit_id:master

สิ่งนี้จะทำอย่างไร? มันจะผลักดัน$old_commit_idมุ่งมั่นที่จะoriginเป็นหัวใหม่ของorigin's masterสาขา

หากนั่นคือสิ่งที่คุณต้องการคุณไม่จำเป็นต้องสัมผัสmasterสาขาในพื้นที่ของคุณเลย


สิ่งนี้ทำให้เกิดmaster (non-fast-forward)ความล้มเหลวสำหรับฉัน โซลูชัน @jtdubs ใช้งานได้
Bobby Norton

3
เพียงแค่ส่ง-fไปบังคับ - แม้ว่า repo ระยะไกลอาจได้รับการกำหนดค่าให้ห้ามสิ่งนั้น ฉันได้อัปเดตคำตอบแล้ว
Aristotle Pagaltzis

ไม่ได้ผลสำหรับฉัน แต่คำตอบที่ยอมรับก็คือ
MobileMon

คุณไม่ได้บอกว่าต้องการอะไรหรือทำไมถึงใช้ไม่ได้ฉันจึงไม่สามารถบอกคุณได้ว่าทำไมถึงไม่ได้และจะทำอย่างไร (ถ้ามี)
Aristotle Pagaltzis

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

43

ใช้ git reset --hard <old commit number>

มันจะรีเซ็ต HEAD เป็นคอมมิตเก่านี้

นอกจากนี้คุณต้องใช้git push -f originเพื่อปรับเปลี่ยน repo ระยะไกลด้วย


34

หากคุณต้องการหลีกเลี่ยงการบังคับผลักดันต่อไปนี้เป็นวิธีเปลี่ยน repo ของคุณเป็นคอมมิตเก่าและรักษางานที่แทรกแซงทั้งหมด:

git checkout 307a5cd        # check out the commit that you want to reset to 
git checkout -b fixy        # create a branch named fixy to do the work
git merge -s ours master    # merge master's history without changing any files
git checkout master         # switch back to master
git merge fixy              # and merge in the fixed branch
git push                    # done, no need to force push!

เสร็จแล้ว! แทนที่ 307a5cd ด้วยสิ่งที่คุณต้องการใน repo ของคุณ

(ฉันรู้ว่าสองบรรทัดแรกรวมกันได้ แต่ฉันคิดว่ามันไม่ค่อยชัดเจนว่าเกิดอะไรขึ้น)

นี่คือกราฟิก:

c1 -- c2 -- c3 -- c4 -- c2' -- c5 ...
        \              /
         '------------'

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


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

ฉันไม่สามารถหาคำที่จะอธิบายได้ว่าฉันรักคุณมากแค่ไหนฉันยอดเยี่ยมเกินกว่าคำบรรยายสำหรับการแก้ไขบางสิ่งที่ทำให้ฉันติดขัดเป็นเวลา 6 ชั่วโมงและทำให้ฉันปวดหัวมาก ขอบคุณครับ !!!!!!!
Kostas Tsakalidis

9

สมมติว่ากราฟการกระทำเป็นดังนี้:

| (A) ---------> (B) ----------> (C)
|                                 ^
|                              (master)

คุณต้องชำระเงินก่อนmasterและสร้างสาขาที่ชี้ไปที่ที่masterปัจจุบันคือ:

git checkout master
git branch pointer master

ควรมีลักษณะดังนี้:

| (A) ---------> (B) ----------> (C)
|                                 ^
|                       (HEAD, master, pointer)

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

git reset master~1

ตอนนี้masterควรย้ายกลับหนึ่งช่องว่าง แต่pointerสาขายังคงอยู่ในคอมมิตล่าสุด:

| (A) ---------> (B) ----------> (C)
|                 ^               ^
|           (HEAD, master)    (pointer)

ณ จุดนี้คุณสามารถกดmasterไปที่รีโมตหรือที่ใดก็ได้จากนั้นกรอไปข้างหน้ารวมกลับไปที่pointerสาขา คุณสามารถฆ่าpointerสาขาได้ ณ จุดนั้น:

git push origin master
git merge --ff-only pointer
git branch -D pointer

รอบชิงชนะเลิศ:

| (A) ---------> (B) ----------> (C)
|                 ^               ^
|         [ origin/master ]    (HEAD, master)

1
หากแหล่งกำเนิด / ต้นแบบที่ซีgit push origin masterจะล้มเหลวด้วยปลายของสาขาในปัจจุบันของคุณเป็นผู้อยู่เบื้องหลังคู่ระยะไกล คุณควรส่งแฟล็ก -f ด้วย
sassospicco

8

คุณสามารถgit checkout <commit-id>ทำทุกอย่างที่ต้องการแล้วgit checkout masterกลับไปที่รหัสใหม่

หากคุณจำเป็นต้องแก้ไขโค้ดเก่าเพื่อปลดล็อกคุณควร:

git checkout -b my_release <commit-id>
... prepare code for release ...
... release code ...
git checkout master
git merge my_release

นอกจากนี้ฉันไม่สามารถแนะนำgit flow ได้เพียงพอ มันทำให้ทั้งหมดนี้ค่อนข้างง่าย


1

หากต้องการย้ายไปยังเวอร์ชันก่อนหน้า:

git checkout <version hash>

ทำงานของคุณที่นี่และลงมือทำด้วย

git commit --amend

ในการกลับไปสู่ระดับปริญญาโท :

git checkout master


1
ไม่ได้ผล git reset --hardชี้สาขาหลักของเขากลับไปที่การกระทำเดิมดังนั้นgit checkout masterจะไม่ทำอะไร
jtdubs

ขอบคุณสำหรับการแก้ไข +1 ให้คุณจะลบคำตอบของฉันด้วย แต่ฉันคิดว่าcommit --amendขั้นตอนนี้มีประโยชน์เพียงพอ
Pablo Fernandez

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