git reset vs git revert

  sonic0002        2019-02-02 08:26:39       106,647        14          English  简体中文  繁体中文  ภาษาไทย  Tiếng Việt 

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

ในโพสต์นี้ เราจะแนะนำวิธีหลักสองวิธีที่นักพัฒนาใช้บ่อยๆ

  • git reset
  • git revert

ความแตกต่างและกรณีการใช้งานที่เกี่ยวข้องคืออะไร เราจะพูดคุยกันในรายละเอียดด้านล่าง

git reset

สมมติว่าเรามีการคอมมิตดังต่อไปนี้

Commit A และ B เป็นคอมมิตที่ใช้งานได้ แต่ commit C และ D เป็นคอมมิตที่ไม่ดี ตอนนี้เราต้องการย้อนกลับไปที่ commit B และทิ้ง commit C และ D ปัจจุบัน HEAD ชี้ไปที่ commit D 5lk4er เราเพียงแค่ต้องชี้ HEAD ไปที่ commit B a0fvf8 เพื่อให้ได้สิ่งที่เราต้องการ 

การใช้คำสั่ง git reset เป็นเรื่องง่าย

git reset --hard a0fvf8

หลังจากรันคำสั่งข้างต้น HEAD จะชี้ไปที่ commit B

แต่ตอนนี้ remote origin ยังคงมี HEAD ชี้ไปที่ commit D หากเราใช้ git push เพื่อพุชการเปลี่ยนแปลงโดยตรง จะไม่ทำการอัปเดต remote repo เราต้องเพิ่มออปชัน -f เพื่อบังคับพุชการเปลี่ยนแปลง

git push -f

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

git revert

การใช้ git revert คือการสร้างคอมมิตใหม่ซึ่งจะย้อนกลับคอมมิตก่อนหน้า HEAD จะชี้ไปที่คอมมิตที่ย้อนกลับใหม่ 

สำหรับตัวอย่างของ git reset ด้านบน สิ่งที่เราต้องทำคือการย้อนกลับ commit D แล้วจึงย้อนกลับ commit C 

git revert 5lk4er
git revert 76sdeb

ตอนนี้จะสร้างคอมมิตใหม่สองรายการคือ D' และ C'  

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

git revert OLDER_COMMIT^..NEWER_COMMIT

วิธีนี้จะไม่มีข้อเสียของ git reset โดยจะชี้ HEAD ไปที่คอมมิตที่ย้อนกลับที่สร้างขึ้นใหม่ และสามารถพุชการเปลี่ยนแปลงไปยัง remote ได้โดยตรงโดยไม่ต้องใช้ตัวเลือก -f

ตอนนี้ลองมาดูตัวอย่างที่ยากขึ้น สมมติว่าเรามีสามคอมมิต แต่คอมมิตที่ไม่ดีคือคอมมิตที่สอง 

ไม่ใช่ความคิดที่ดีที่จะใช้ git reset เพื่อย้อนกลับคอมมิต B เนื่องจากเราต้องเก็บคอมมิต C ไว้เนื่องจากเป็นคอมมิตที่ดี ตอนนี้เราสามารถย้อนกลับคอมมิต C และ B แล้วใช้ cherry-pick เพื่อคอมมิต C อีกครั้ง 

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

อ้างอิง: https://kknews.cc/news/4najez2.html

GIT  GIT RESET  GIT REVERT 

       

  RELATED


  14 COMMENTS


Anonymous [Reply]@ 2019-02-03 08:11:41

Really hard to take anything you say seriously when you use the entire aplhabet for your hexadecimal SHA1 examples.

Anonymous [Reply]@ 2019-02-04 21:52:35

No need for that

Anonymous [Reply]@ 2019-02-05 07:25:42

On the contrary, it’s a good decision, since those strings are never going to match any actual SHAs. Sort of like how it’s good practice to use “example.com” in example URLs since it’s been reserved for that purpose. Since we don’t have any reserved SHAs (at least that I’m aware of) it’s better to use illegal ones.

Alan [Reply]@ 2019-02-03 08:46:00

Given a lot of commits to cherry pick, the more efficient way to handle this is a basic interactive git rebase of the last X commits, and you delete the line(s) of the commit(s) to be deleted. Easy!

Anonymous [Reply]@ 2019-02-03 15:26:14

The drawback of force pushing is not that some commits get lost. It's that you change the history of a public repositor, breaking everyone else's local copy and forcing them to fix it on their side. It's such a bad idea that most tools and hosting services don't even allow it by default.

Anonymous [Reply]@ 2019-02-03 19:25:49
yes, good point
Anonymous [Reply]@ 2024-03-10 06:51:25

That's what --force-with-lease is for and that is perfectly okay to do, even in a production environment.

cmbuckley [Reply]@ 2019-02-04 12:02:25
There’s absolutely no reason to revert C, B and then re-apply C in your last example. You can simply revert B.
Ke Pi [Reply]@ 2019-02-04 19:41:20

yes, agreed

Anonymous [Reply]@ 2019-02-04 21:53:21

https://google.com

Anonymous [Reply]@ 2019-02-04 22:12:51

You can also use `git checkout a1b2c3d4 -- filename` to check out older revisions and then recommit those changes. It works great for shared state files that shouldn't be stored in version control but sometimes are

Anonymous [Reply]@ 2019-11-18 13:30:02

Had a hard time finding a good explanation of either revert or reset - then I found yours that not only explains each one, but compares and contrasts the two. Excellent article, thanks for the information!

Anonymous [Reply]@ 2020-03-27 18:40:17

Found this really helpful ! Thank you so much !

Ke Pi [Reply]@ 2020-03-28 05:29:48

thank you for liking it :)



  RANDOM FUN

Pray for Windows Phone

With the restructuring of Windows Mobile recently, it reveals the death of Windows Phone. Windows Phone has fallen to just 3 percent market share worldwide, it's even lower than Java Mobile. The only we can do now is praying for Windows Phone. See market share of different mobile OSes here.&nbs