Momo's Blog

Talk is cheap. Show me the code.

git reset --soft, --hard, --mixed khác nhau thế nào

Chào các bạn, bài lần này mình viết về một chủ đề rất cơ bản: git reset

Ai cũng từng mắc lỗi, tuy nhiên cách mỗi người xử lý khi gặp lỗi là khác nhau. Khi code cũng vậy, đôi khi ta commit nhầm, và git reset sinh ra để ta sửa chữa những lỗi lầm đó.

git reset rất mạnh, nó có thể cứu rỗi những lỗi lầm, nhưng nếu bị dùng sai cách, nó có thể trở thành thảm họa. Nên hãy nắm thật chắc nó nhé.

Cấu trúc của một câu lệnh git reset:

git reset [--soft | --mixed | --hard | --merge | --keep] <commit>

Về cơ bản ta hay sử dụng 3 lệnh sau là chủ yếu:

git reset <commit>
git reset --soft <commit>
git reset --hard <commit>

trong đó git reset <commit> thực chất chính là sử dụng tham số mặc định –mixed

2 lệnh với tham số còn lại ta không bàn tại đây.

Git quản lý các file như thế nào ?

Trước hết ta cần nắm được điều này. Trong git, có 3 nơi ta cần nhớ:

  • Working directory: Chính là project bạn đang code
  • Staging area: Chính là nơi lưu trữ các thay đổi trước khi commit. Khi bạn gõ git add thì các thay đổi sẽ được lưu tại đây.
  • Repository: chính là project khi đã commit. Khi bạn gõ git commit thì các thay đổi sẽ được lưu tại đây.

Git reset

Vậy là ta đã hiểu là sau khi đã commit thì project của bạn sẽ nằm ở Repository, khi đó giả sử repository của chúng ta có các commit như sau:

A - B - C (HEAD -> master)

Khi đó:

  • git reset --soft B: Sẽ đưa HEAD về vị trí commit B, giữ nguyên các thay đổi đã được git add tại B trong Staging Area. Tương ứng với tại B ta vừa git add xong, khi này chỉ việc git commit là ta lại có commit như C bên trên.
  • git reset B: Sẽ đưa HEAD về vị trí commit B, đồng thời đưa các thay đổi về Working directory. Tương ứng với tại B ta vừa cột xong, chưa git add.
  • git reset --hard B: Sẽ đưa HEAD về vị trí commit B, đồng thời loại bỏ tất cả các thay đổi tại B. Tương ứng với tại B ta chưa cột gì cả, xong phim.

Đấy, chuyện chỉ có vậy.

Vài điều về HEAD

Đôi khi bạn thấy lệnh git reset HEAD~1 thì nó cũng tương đương với lệnh git reset B như trên, vì HEAD~1 chính là lùi HEAD lại 1 commit.

  • HEAD chính là commit hiện tại ta đang đứng.
  • HEAD~1 là commit ngay trước HEAD trên cùng nhánh
  • HEAD~n là commit trước HEAD n commit trên cùng nhánh
  • Có thể dùng @ thay cho HEAD: git log @
  • HEAD~ != HEAD^ (trông có vẻ giống nhưng khác ý nghĩa)

Conclusion

Git tuyệt vời, git mềm dẻo, nhưng hãy cẩn thận khi sử dụng kẻo cả ngày code đi tong.

Enjoy coding!