Mẹo nhỏ để tránh làm mất code khi sử dụng Git.
TL;DR: Không sử dụng push -f hay push --force ! Thay vào đó nên sử dụng push --force-with-lease Giải thích: Git push --force rất nguy hiểm, vì theo cơ chế của mình, nó sẽ ghi đè lên remote repo bằng code ở local của mình, mà không cần quan tâm đến việc bên phía remote đang chứa thứ gì. Vì ...
TL;DR: Không sử dụng push -f hay push --force ! Thay vào đó nên sử dụng push --force-with-lease
Giải thích:
Git push --force rất nguy hiểm, vì theo cơ chế của mình, nó sẽ ghi đè lên remote repo bằng code ở local của mình, mà không cần quan tâm đến việc bên phía remote đang chứa thứ gì. Vì vậy, sẽ rất dễ để làm mất code trên phía remote repo, kể cả các code mà các thành viên khác đã push lên trước đó. Thay vào đó, ta có một công cụ tốt hơn: sử dụng option --force-with-lease khi push sẽ giúp ta trong trường hợp cần phải force push code lên remote, nhưng vẫn đảm bảo không làm mất những code đã có trước đó.
Giải thích kỹ hơn 1 chút:
Cần thiết phải nhắc lại 1 lần nữa: việc sử dụng git push -f hay git push --force là hoàn toàn không được khuyến khích, vì nó sẽ xóa bỏ hoàn toàn các commit khác đã được push lên một repository chung. (Thực ra thì vẫn có cách khôi phục, nếu như các commit kia vẫn còn ở trong máy của người push chúng).
Một trong những trường hợp dễ gặp nhất ở đây , đó là khi ta cần thực hiện việc rebase một nhánh. Để dễ hiểu, hãy xét ví dụ dưới đây:
- Giả sử ta có 1 project với một nhánh feature đang làm, tạm gọi là nhánh feature.
- 2 người A và B cùng thực hiện công việc trên nhánh này, họ cùng clone nhánh về máy mà bắt đầu code.
- A hoàn thành code của mình, push code lên remote.
- B hoàn thành code của mình, nhưng trước khi push code lên, B cũng đã kiểm tra và thấy rằng có gì đó đã được merge lên nhánh master từ trước rồi. Vì thế, trước khi push code mình lên, anh ấy thực hiện việc rebase nhánh feature của mình với master.
- Đây là lúc vấn đề xảy ra: sau khi rebase xong, B sẽ push lại nhánh feature của mình lên, và lúc này git sẽ báo reject, buộc B phải push --force. Tuy nhiên, vì không biết rằng A cũng đã push code của mình lên feature trước đó, thế nên lúc này việc B push -f lên sẽ xóa toàn bộ commit của A trước đó đã đẩy lên.
Nhìn sâu hơn, khi thực hiện push -f, B không thực sự biết trước đó vì sao code của mình lại bị reject khi push: trong trường hợp này, B đã nghĩ việc bị reject là do mình rebase, chứ không nghĩ tới việc là do A đã push lên từ trước.
Thay vào đó, hãy xét tới trường hợp sử dụng option --force-with-lease khi push - option này sẽ phần nào bảo vệ bạn khỏi việc lỡ tay làm mất code khi force update