Chào các bạn, lại là mình - Hữu Ngọc Tiên Sinh đây. Chắc hẳn Git đã trở thành một công cụ rất rất quen thuộc đối với các bạn rồi phải không, vậy có thể trong quá trình làm việc với Git, bạn đã từng gặp những tình huống dở khóc dở cười nhỉ. Hôm nay mình xin chia sẻ lại 1 câu lệnh mà bạn có thể sử dụng để sửa chữa một số lỗi lầm đã gây ra. Let's gooo
1. Git reflog là gì ?
git reflog là một câu lệnh trong Git để xem lại lịch sử hoạt động của HEAD và các tham chiếu trên đó, bao gồm các thao tác commit, merge, rebase, reset, stash, cherry-pick, vv..vv
Cụ thể, git reflog cho phép bạn xem lại lịch sử các commit và thao tác trên các nhánh và HEAD trên local repository của bạn, bất kể có bị xoá hay không, giúp bạn tìm lại các commit hoặc nhánh bị mất hoặc bị thay đổi.
Cách sử dụng cơ bản của reflog để trả về một danh sách tất cả các thay đổi gần đây sẽ có cú pháp như sau:
$ git reflog
8028059 (HEAD -> main) HEAD@{0}: commit (initial): the first commit.
Trông nó có vẻ khá giống với một git log --oneline
, tuy nhiên nó sẽ hiển thị nhiều thứ hơn khi có nhiều sự thay đổi. Các thành phần chính từ output của nó sẽ bao gồm:
- ID của thao tác => 8028059, đây sẽ là chìa khóa để các bạn khôi phục lại thao tác này
- (HEAD -> main): Biểu thị rằng git HEAD hiện đang trỏ đến nhánh main
- HEAD@{0}: đặc biệt lưu ý, thông số này đang biểu thị rằng thay đổi này nằm ở vị trí của HEAD đã từng ở trước đây. Các thay đổi đối với Git HEAD được thực hiện thêm trong quá khứ sẽ được biểu thị bằng reflog là HEAD@{1}, HEAD@{2}, ...
Bên cạnh đó, bạn có thể xem nhật ký của một branch khác, chẳng hạn như develop, bằng cách chỉ định nó như sau:
$ git reflog develop
231DE23 (HEAD -> master) develop@{0}: commit (initial): Initial commit.
2. Sử dụng git reflog để khôi phục dữ liệu
Sau đây là một số cách sử dụng git reflog
mà mình biết được:
2.1 Khôi phục branch đã bị xóa
Giả sử bạn lỡ tay xóa 1 branch chứa code quan trọng, mà bạn lại chưa push nó lên github. Vậy thì lúc này chúng ta làm như sau:
-
Thực hiện lệnh
git reflog
ở ví dụ trên, sau khi xóa nhánhbranch_1
, mình đã gọi lệnh git reflog, nó sẽ hiển thị lịch sử trước đây bao gồm: tạo nhánh branch1, thêm commit "first commit", "second commit", checkout về lại main -
Chúng ta sẽ xác định hành động gần nhất ở nhánh đã bị xóa, ở ví dụ này sẽ là hành động ở HEAD@{1} - thêm second commit
-
Sau đó, để khôi phục lại nhánh cũ, chúng ta thực hiện lệnh:
git checkout -b branch_1 HEAD@{1}
trong đó, branch_1 là tên cũ của branch đã bị xóa, HEAD@{1} là trạng thái mới nhất của branch trước khi bị xóa
- Vậy là chúng ta đã khôi phục được branch_1, và nó có chứa đủ tất cả commit trước đó
2.2 Khôi phục code khi lỡ dùng Git reset --hard
git reset
là một lệnh hữu ích để chúng ta thay đổi nội dung commit trước đó, hoặc loại bỏ commit. Giả sử 1 ngày đẹp trời bạn muốn dùng git reset --soft HEAD~1
để chỉnh lại commit trước đó, nhưng bạn lại nhớ nhầm là git reset --hard HEAD~1
, và thế là commit chứa cả đống code của bạn đã bay màu.
-
Chúng ta dùng lệnh
git reflog
để xem lại lịch sử của HEAD -
Trường hợp 1: Sau khi xóa commit, bạn chưa thêm bất kì commit nào mới Ta thấy HEAD@{1} là hành động thêm commit đã bị xóa, Lúc này chúng ta có thể dùng
git reset --hard HEAD@{1}
để khôi phục nó -
Trường hợp 2: Sau khi xóa commit, bạn đã có thêm những commit mới, nhưng vẫn muốn khôi phục lại commit kia. Lúc nào chúng ta sử dụng lệnh
git cherry-pick 5796d1c
, trong đó5796d1c
chính là ID của hành động tại thời điểm HEAD@{1}
2.3 Hoàn tác hành động git rebase
Giả sử bạn đang muốn rebase code mới từ branch develop vào nhánh feature của mình, nhưng bạn lại rebase nhầm nhánh master, lúc này bạn cần hoàn tác hành động này, bạn có thể thực hiện tương tự việc khôi phục commit
- Dùng
git reflog
để hiển thị lịch sử - Dùng
git reset --hard HEAD@{3}
, trong đó HEAD@{3} là ví dụ thời điểm gần nhất mà nhánh của bạn chưa được rebase
Kết luận
Trên đây là một số công dụng mà bạn có thể làm với git reflog
, ngoài ra sẽ còn nhiều cách nữa, hẹn các bạn dịp khác nhé, cảm ơn các bạn đã đọc. Nếu thấy hữu ích thì cho mình xin 1 upvote, hoặc nếu có vấn đề gì thì hãy comment cho mình biết nhé.