git reset vs git revert

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

Khi duy trì code bằng các hệ thống kiểm soát phiên bản như git, việc chúng ta cần phải rollback một số commit sai do lỗi hoặc hoàn tác code tạm thời là điều không thể tránh khỏi. Trong trường hợp này, các nhà phát triển mới vào nghề sẽ rất lo lắng vì họ có thể không biết phải làm gì để rollback các thay đổi của mình mà không ảnh hưởng đến người khác, nhưng đối với các nhà phát triển kỳ cựu, đây là công việc thường ngày của họ và họ có thể chỉ cho bạn nhiều cách khác nhau để thực hiện điều đó.

Trong bài viết này, chúng ta sẽ giới thiệu hai cách chính được các nhà phát triển sử dụng thường xuyên.

  • git reset
  • git revert

Sự khác biệt và các trường hợp sử dụng tương ứng của chúng là gì? Chúng ta sẽ thảo luận chi tiết về chúng dưới đây.

git reset

Giả sử chúng ta có một vài commit bên dưới.

Commit A và B là các commit hoạt động, nhưng commit C và D là các commit xấu. Bây giờ chúng ta muốn rollback về commit B và loại bỏ commit C và D. Hiện tại HEAD đang trỏ đến commit D 5lk4er, chúng ta chỉ cần trỏ HEAD đến commit B a0fvf8 để đạt được điều chúng ta muốn. 

Rất dễ dàng để sử dụng lệnh git reset.

git reset --hard a0fvf8

Sau khi thực thi lệnh trên, HEAD sẽ trỏ đến commit B.

Nhưng bây giờ remote origin vẫn có HEAD trỏ đến commit D, nếu chúng ta trực tiếp sử dụng git push để đẩy các thay đổi, nó sẽ không cập nhật repo từ xa, chúng ta cần thêm tùy chọn -f để buộc đẩy các thay đổi.

git push -f

Nhược điểm của phương pháp này là tất cả các commit sau HEAD sẽ biến mất sau khi reset xong. Trong trường hợp một ngày nào đó chúng ta phát hiện ra rằng một số commit là tốt và muốn giữ lại chúng thì đã quá muộn. Vì điều này, nhiều công ty cấm sử dụng phương pháp này để rollback các thay đổi.

git revert

Việc sử dụng git revert là để tạo một commit mới, commit này sẽ hoàn tác một commit trước đó. HEAD sẽ trỏ đến commit hoàn tác mới. 

Đối với ví dụ về git reset ở trên, những gì chúng ta cần làm chỉ là hoàn tác commit D và sau đó hoàn tác commit C. 

git revert 5lk4er
git revert 76sdeb

Bây giờ nó tạo ra hai commit mới D' và C', 

Trong ví dụ trên, chúng ta chỉ có hai commit để hoàn tác, vì vậy chúng ta có thể hoàn tác từng commit một. Nhưng nếu có rất nhiều commit cần hoàn tác thì sao? Chúng ta có thể hoàn tác một phạm vi.

git revert OLDER_COMMIT^..NEWER_COMMIT

Phương pháp này sẽ không có nhược điểm của git reset, nó sẽ trỏ HEAD đến commit hoàn tác mới được tạo và có thể trực tiếp đẩy các thay đổi lên remote mà không cần sử dụng tùy chọn -f.

Bây giờ chúng ta hãy xem một ví dụ khó hơn. Giả sử chúng ta có ba commit nhưng commit xấu là commit thứ hai. 

Không nên sử dụng git reset để rollback commit B vì chúng ta cần giữ lại commit C vì nó là một commit tốt. Bây giờ chúng ta có thể hoàn tác commit C và B và sau đó sử dụng cherry-pick để commit lại C. 

Từ giải thích trên, chúng ta có thể thấy rằng sự khác biệt lớn nhất giữa git resetgit revert là git reset sẽ reset trạng thái của branch về trạng thái trước đó bằng cách loại bỏ tất cả các thay đổi sau commit mong muốn, trong khi git revert sẽ reset về trạng thái trước đó bằng cách tạo các commit hoàn tác mới và giữ lại các commit ban đầu. Nên sử dụng git revert thay vì git reset trong môi trường doanh nghiệp. 

Tham khảo: 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

When nearing project deadline