Git: hoàn tác commit
Cập nhật lần cuối
Cách hoàn tác một commit tùy vào đó là commit nào và nó đã được push hay chưa. Một commit cũ nằm sâu trong lịch sử, hoặc bất cứ thứ gì đã chia sẻ, thì cần git revert: lệnh này thêm một commit mới để đảo ngược nó mà không viết lại gì cả. Một loạt commit cục bộ gần đây thì chỉ cần git reset là xong. Nếu bạn chỉ cần hoàn tác commit mới nhất, trang git undo last commit trình bày mọi biến thể của cách sửa nhanh đó.
Bạn có thể thử các lệnh này trong terminal playground: một shell thật ngay trên trình duyệt, không cần cài đặt gì.
Nên dùng lệnh nào
| Tình huống | Lệnh |
|---|---|
| Hoàn tác một commit cũ, giữ mọi thứ sau nó | git revert <hash> |
| Hoàn tác commit đã push | git revert <hash> |
| Hoàn tác 3 commit cục bộ cuối, giữ phần việc | git reset --soft HEAD~3 |
| Hoàn tác 3 commit cục bộ cuối, bỏ phần việc | git reset --hard HEAD~3 |
| Hoàn tác một dải commit bằng các commit đảo ngược mới | git revert HEAD~3..HEAD |
reset và revert
| Đặc điểm | git reset | git revert |
|---|---|---|
| Viết lại lịch sử | Có | Không |
| An toàn với commit đã push | Không | Có |
| Tạo commit mới | Không | Có |
| Dùng được với commit cũ giữa lịch sử | Không | Có |
| Có thể bỏ thay đổi | Có (--hard) | Không |
Ví dụ từng bước
Hoàn tác một commit cũ cụ thể, kể cả commit đã push, mà không động tới các commit đến sau nó.
| Bước | Lệnh | Kết quả |
|---|---|---|
| 1 | git log --oneline | Tìm hash của commit lỗi (ví dụ a1b2c3d) |
| 2 | git revert a1b2c3d | Một commit mới đảo ngược nó; các commit sau giữ nguyên |
| 3 | git push | Chia sẻ bản sửa: không có lịch sử nào bị viết lại |
Câu hỏi thường gặp về hoàn tác commit trong Git
Làm sao hoàn tác một commit cũ mà không mất các commit sau nó?
git revert <hash>. Revert tạo một commit mới chỉ đảo ngược đúng commit bạn chỉ định, mọi commit sau nó giữ nguyên như cũ. Tìm hash trước bằng git log --oneline. Nếu revert xung đột với các thay đổi về sau, Git sẽ tạm dừng để bạn giải quyết rồi chạy git revert --continue.Làm sao hoàn tác nhiều commit cùng lúc?
git reset --soft HEAD~3 gỡ ba commit cuối nhưng giữ thay đổi của chúng ở trạng thái staged (dùng --hard để bỏ luôn). Với commit đã push, hãy revert cả dải: git revert --no-commit HEAD~3..HEAD đảo ngược cả ba, rồi một lệnh git commit duy nhất ghi lại việc hoàn tác.Làm sao hoàn tác commit đã push?
git revert <hash> thay vì reset. Revert tạo một commit mới hoàn tác thay đổi của commit đích, giữ nguyên lịch sử. Đây là cách an toàn để hoàn tác commit dùng chung: viết lại lịch sử đã push bằng reset sẽ buộc mọi người phải xử lý lại bản của họ.Khi nào dùng reset, khi nào dùng revert?
Dùng reset khi commit chỉ của riêng bạn và vẫn còn ở máy bạn: lệnh này đơn giản là lùi nhánh lại, như thể các commit chưa từng tồn tại. Dùng revert khi commit đã push, đã chia sẻ hoặc nằm giữa lịch sử: lệnh này hoàn tác thay đổi bằng một commit mới mà ai pull về cũng an toàn.
Có thể luyện tập lệnh này online không?
Có. Mở terminal playground để chạy các lệnh này trong một shell thật ngay trên trình duyệt, không cần cài đặt gì. Khóa học Git tương tác miễn phí của Coddy cũng hướng dẫn từng bước cách hoàn tác thay đổi.