Tuyệt chiêu dùng Git Reflog để ‘hồi sinh’ Commit và Branch đã xóa

Git tutorial - IT technology blog
Git tutorial - IT technology blog

Cảm giác khi nhận ra mình vừa “xóa sạch” công sức

Tim đập nhanh, mồ hôi vã ra khi nhận ra lệnh git reset --hard vừa quét sạch 5 tiếng code liên tục. Đây là tình huống mà hầu như lập trình viên nào cũng từng gặp ít nhất một lần. Hoặc đôi khi, bạn tự tin xóa một branch vì nghĩ nó đã được merge, để rồi nhận ra mình đã nhầm to.

Lúc này, lệnh git log thường dùng trở nên vô dụng. Những commit đó đã biến mất khỏi lịch sử hiển thị của branch. Đừng vội ngồi gõ lại code từ đầu. Git có một cơ chế “ghi nhật ký” ngầm cực kỳ lợi hại: Git reflog.

Tại sao git log bó tay, nhưng git reflog thì không?

Để dùng hiệu quả, bạn cần phân biệt rõ hai công cụ này:

  • git log: Hiển thị lịch sử commit của một branch. Nếu bạn reset hoặc xóa branch, các commit liên quan sẽ bị ẩn đi.
  • git reflog: Viết tắt của “reference logs”. Nó ghi lại mọi lần con trỏ HEAD thay đổi vị trí. Dù bạn commit, checkout, reset hay merge, Git đều âm thầm lưu lại dấu vết tại local.

Về bản chất, Git không xóa dữ liệu ngay lập tức khi bạn reset. Nó chỉ gỡ bỏ các tham chiếu (reference). Dữ liệu vẫn nằm trong database cho đến khi trình dọn rác (Garbage Collector) quét qua. Mặc định, Git sẽ giữ các dữ liệu “mồ côi” này trong khoảng 30 đến 90 ngày.

Giải mã các dòng nhật ký của Reflog

Mỗi khi bạn thực hiện một thao tác làm thay đổi HEAD, một dòng mới sẽ xuất hiện trong reflog. Hãy nhìn vào ví dụ dưới đây:

e1a2b3c HEAD@{0}: commit: Fix bug logic giỏ hàng
d4e5f6g HEAD@{1}: checkout: moving from feature-abc to main
7h8i9j0 HEAD@{2}: reset: moving to HEAD~1

Cấu trúc này gồm ba phần chính. Đầu tiên là mã hash ngắn của commit. Tiếp theo là HEAD@{n}, cho biết trạng thái này cách hiện tại bao nhiêu bước. Cuối cùng là mô tả hành động bạn đã thực hiện.

Hai kịch bản cứu nguy thực tế

Dưới đây là cách mình thường xử lý khi anh em trong team lỡ tay “ấn nhầm”.

1. Khôi phục sau khi git reset –hard

Giả sử bạn đang ở commit C, nhưng lỡ tay reset nhầm về commit A. Toàn bộ code tại B và C sẽ biến mất khỏi git log.

Bước 1: Kiểm tra nhật ký bằng lệnh git reflog. Bạn hãy tìm dòng mô tả commit cuối cùng trước khi thực hiện lệnh reset.

Bước 2: Đưa dự án quay lại trạng thái đó. Nếu muốn lấy lại toàn bộ code, hãy dùng lệnh:

git reset --hard e1a2b3c # Thay e1a2b3c bằng mã hash bạn tìm thấy

Nếu chỉ muốn lấy lại code nhưng giữ nguyên các file đang sửa dở, hãy chọn --soft thay vì --hard.

2. Tìm lại branch đã xóa nhầm

Mình từng gặp trường hợp một bạn dev xóa branch feature-payment vì tưởng đã push lên server. Thực tế, code mới nhất vẫn chỉ nằm ở máy local. Lúc này, git branch sẽ không thấy tên branch đó nữa.

Cách xử lý rất đơn giản. Bạn gõ git reflog và tìm commit cuối cùng của branch đó trước khi bị xóa. Sau đó, hãy tạo lại branch từ chính mã hash đó:

git branch feature-payment 7h8i9j0

Chỉ với một dòng lệnh, toàn bộ lịch sử commit của branch sẽ xuất hiện trở lại như chưa từng có cuộc chia ly.

Ba lưu ý sống còn khi sử dụng

Dù mạnh mẽ, git reflog không phải là phép màu vạn năng. Bạn cần ghi nhớ ba quy tắc sau:

  1. Chỉ có tác dụng tại máy cá nhân: Reflog là nhật ký local, không được đẩy lên GitHub hay GitLab. Bạn không thể sang máy đồng nghiệp để khôi phục code mình đã xóa trên máy mình.
  2. Chỉ cứu được những gì đã commit: Nếu bạn chưa git add hoặc chưa commit mà lỡ tay git checkout ., reflog sẽ không có dữ liệu. Hãy tập thói quen commit thường xuyên, kể cả là commit nháp.
  3. Thời gian lưu trữ có hạn: Git sẽ dọn dẹp reflog sau 90 ngày (với commit có thể truy cập) hoặc 30 ngày (với commit mồ côi). Đừng để quá lâu mới đi tìm lại code cũ.

Lời kết

Hãy coi git reflog như một chiếc hộp đen máy bay cho mã nguồn của bạn. Hiểu cách nó vận hành giúp bạn tự tin hơn khi thực hiện các thao tác Git phức tạp. Lần tới nếu lỡ tay xóa nhầm, hãy bình tĩnh gõ git reflog trước khi bắt đầu hoảng loạn nhé!

Share: