Linuxvn Technical Notes
259 subscribers
34 links
Source: https://github.com/linuxvn/about , managed by @linuxvn. PRs are welcome. Synchronization runs once a hour.
Download Telegram
git-revert-to-a-good-commit

https://github.com/linuxvn/about/blob/master/Notes-2019.md#git-revert-to-a-good-commit


tags: #git #devops #trick #diff

Hôm nay trên @linuxvn (https://t.me/linuxvn/55674) có bạn hỏi làm thế nào để quay lại một commit cũ/tốt trên master, sau khi lỡ nhầm merge nhánh dev vào nhánh master. Sau câu hỏi này là một màn tranh luận sôi nổi, dài lê thê mà mình chưa kịp coi. Người hỏi muốn reset, bỏ đi các commit lỗi để quay lại cái cũ, một kiểu Undo giống khi soạn thảo văn bản.

Vấn đề này hay gặp, bạn có thể xem trao đổi trên SO: https://stackoverflow.com/questions/4114095/how-do-i-revert-a-git-repository-to-a-previous-commit tất nhiên là trên đó cũng miên man đủ thứ giải pháp, mà thật ra mình coi nhiều lần vẫn không hiểu thế nào là tốt, hoặc là cũng chả cần hiểu nhắm mắt làm theo.

Sau đây, mình giới thiệu cho bạn cách truyền thống, cực kỳ chính xác.

Thứ nhất, sau khi commit, đã merge, thì bạn không nên Undo, xóa bỏ commit bằng git reset, một khi thay đổi đã được push lên kho hay chỗ nào đó. Lời nói gió bay, chỉ có thể sửa chữa chứ không rút lại được. Trong DevOps cũng có vài nguyên tắc sống hay vậy.

Tiếp theo, về cơ bản, giữa hai commit bất kỳ trong kho git của bạn là một khoảng cách khác biệt, mà bạn luôn thấy được bằng lệnh git diff. Phục hồi commit cũ, tức là xóa đi các khác biệt này, hay là áp dụng khác biệt đó theo chiều ngược (bạn sẽ rõ hơn ở phần sau).

Giả sử, bạn đang ở master và cần quay lại commit 3323e5b tốt. Hãy chuẩn bị bước đầu tiên là clone/checkout nhánh master ra một thư mục sạch sẽ, là thư mục mà khi bạn gõ git status -u thì không thấy gì ở đó.

$ git status -u           # đảm bảo không thấy gì
$ git checkout master # chắc chắn bạn đang ở master
$ git diff HEAD..3323e5b > patch.diff


Trong lệnh cuối cùng, thứ tự rất quan trọng. Commit tốt của bạn phải nằm sau cùng (đi ngược về quá khứ). Sau đó, bạn áp dụng bản diff này

$ patch -p1 < patch.diff
$ git status -u


Kiểm tra lại xem các file nào mới chưa được commit trong kết quả của lệnh git status -u ở trên. Nếu có, bạn thêm vào: đó là các tập tin có trong commit cũ (3323e5b):

$ git add some/new/files.txt
$ git commit -a "Revert to 3323e5b, thanks to @linuxvn"


Để chắc chắn, bạn kiểm tra lại kết quả

$ git diff 3323e5b..


lần này cần phải hiện ra ... không gì cả, tức là bạn đã hoàn toàn phục hồi lại commit cũ của bạn.

Cách này lúc nào cũng thành công, đơn giản, thậm chí bạn có thể tranh thủ điều chỉnh vài thứ. Và hơn hết, thay vì phải đi hiểu một đống lệnh như là git revert, git reset, ...bạn chỉ việc tập trung hiểu bản chất của vấn đề là, diff, diff, và diff ;)



-- 03607e98 (aiyo8aiK 2019-08-08 17:46:01 +0200 45) at https://github.com/linuxvn/about/blob/master/Notes-2019.md#git-revert-to-a-good-commit
🐞🐞🐞🐞🐞🐞🐞🐞🐞🐞🐞🐞🐞🐞🐞🐞🐞🐞