Có một vấn đề mà tôi thấy rất nhiều người tìm kiếm đó là "xóa commit đã push". Tình cờ tôi cũng có một bài viết có tên là Tôi vừa lỡ commit sai, làm sao để sửa lại ngay lập tức? lại lọt vào kết quả tìm kiếm top đầu trên google cho từ khóa đấy, nhưng điều đáng nói là trong bài viết đó không có nhắc đến cách giải quyết vấn đề đang gặp phải, mà nó chỉ đơn giản là hướng dẫn bạn xóa commit "chưa" push.
Vì thế, để tránh gây hiểu nhầm đồng thời giúp cho bạn đọc có một giải pháp chính xác hơn trong vấn đề này, thì bài viết ngày hôm nay chúng ta hãy cùng nhau tìm hiểu cách làm thế nào để xóa commit đã push nhé.
Tôi có nghe nhiều người nói git khá "dễ", hoặc tự tin "khoe" kỹ năng sử dụng thành thạo git. Thành thật mà nói đối với tôi git là một thứ gì đó rất khó mà bản thân chỉ có thể sử dụng nó ở mức trung bình. Nghĩa là init, clone, pull, push, branch… và một số lệnh thông dụng hàng ngày trong làm việc nhóm. Thực ra git cung cấp rất nhiều câu lệnh khác nữa, chưa kể đến githooks, nhiều lệnh nâng cao của git phải nói là chưa bao giờ đụng đến, thậm chí không dám đụng vì nó rất khó hiểu. Mỗi người, nhóm, tổ chức lại có một quy trình làm việc bằng git riêng, cho nên điều đó cũng góp phần tạo nên sự đa dạng trong cách sử dụng git.
Quay trở lại với vấn đề, tạm quên những thứ phức tạp ở trên đi. Về bản chất, một khi bạn đã push commit lên remote rồi thì khả năng để xóa commit đó khá là rủi ro. Chưa biết đến mục đích xóa commit đó là gì. Commit vô nghĩa? Commit sai nên xóa đi cho đẹp git tree?… Suy nghĩ đơn giản là git sinh ra cho quy trình làm việc nhóm, mỗi commit push lên rồi, có người pull về, họ tiếp tục viết thêm mã vào và lại đẩy lên. Giả sử là bạn có thể xóa được commit bất kì đi thì chẳng phải sẽ gây ra một sự xáo trộn mã ghê ghớm hay sao?
Lúc này, bạn sẽ phải từ bỏ hy vọng xóa bất kì commit đã push nào đi, vì git không khuyến khích làm điều đó. Nhưng nếu muốn xóa các commit cuối cùng thì vẫn có khả năng làm được với rủi ro tối thiểu.
Có thể bạn sẽ thấy một khoảng "thời gian vàng" để có thể xóa các commit cuối mà không gây ảnh hưởng đến ai đó chính là push lên rồi nhưng chưa ai pull về. Như vậy chúng ta hoàn toàn có thể sử dụng cờ --force
để push lại toàn bộ commit ở dưới local lên remote. Tất nhiên cờ --force
luôn là một thứ gì đó ghê ghớm và không nên lạm dụng. Hầu hết các chương trình cung cấp force đều cảnh báo không nên sử dụng nó, nếu sử dụng hãy chắc chắn là bạn biết bạn đang làm gì. Nếu không, đừng bao giờ sử dụng force
. Nhưng trước khi đi sâu vào cách làm như thế nào thì có hai điều cần làm sáng tỏ.
1, Bạn muốn force push trên nhánh dùng chung (ví dụ như develop)
Nhánh dùng chung để ám chỉ nhánh được nhiều người tham gia phát triển, ví dụ điển hình là develop, nơi mọi người trong nhóm liên tục commit hoặc merge code vào.
Giả sử nhánh develop trên remote có commit cuối cùng là commit bạn muốn xóa, tuyệt vời, hãy tận dụng khoảng thời gian chưa ai pull về và chưa ai push bất kì thứ gì mới lên thì bạn có thể force.
# Trở về commit trước đó
$ git reset HEAD~1
# Force push lại toàn bộ commit trước đó
$ git push --force
Thế là xong, bây giờ git tree của bạn trở về y hệt như trước khi có commit cuối và commit đó cũng hoàn toàn biến mất.
Trường hợp hai, commit cuối cùng không phải là commit của bạn nữa, lúc này chắc chắn đã có người pull commit của bạn về rồi, nếu force push thời điểm này sẽ gây ra một sự xáo trộn mã ghê ghớm, dễ thấy nhất là khả năng mất tất cả commit từ phía sau commit bạn muốn xóa.
2, Bạn muốn force push trên nhánh một mình phát triển (ví dụ như feature/xxx)
feature chưa được merge vào develop, có một commit cuối cùng sai và bạn muốn xóa nó khỏi git thì lúc này có thể thoải mái sử dụng force push để đẩy lại code. Vì nhánh chỉ có một mình commit nên khả năng sẽ không có ai pull code về và push code lên. Cách làm thì cũng tương tự như trên.
# Trở về commit trước đó
$ git reset HEAD~1
# Force push lại toàn bộ commit trước đó
$ git push --force
Trong git, nếu sử dụng --force
để push, nó sẽ thay thế toàn bộ commit dưới local của bạn lên remote. Thế cho nên commit của người khác sau thời điểm bạn force thì sẽ "không cánh mà bay". Vì thế, một quy tắc vàng ở đây là: chỉ force push trên nhánh một mình phát triển, còn đối với nhánh nhiều người tham gia thì đừng bao giờ force. Nếu vẫn quyết định force, hãy tập hợp mọi người lại và xin chỉ giáo họ đã commit thêm gì chưa. Nếu chưa ai làm gì thì có thể "xin phép" force.
Chưa kể, nhiều nhóm có quy trình làm việc sử dụng "protected branch", tức là tạo ra những quy tắc cho từng branch một, ai có quyền pull/push, ai có quyền merge… nếu giả sử bạn có một commit merge vào branch develop đã được hạn chế quyền push trực tiếp. Rõ ràng bạn không có cách nào để force push develop về trước đó được. Lúc đó, khả năng cao là bạn cần trình bày vấn đề với PM trước khi xin được quyền force push trên develop.
Từ đầu đến giờ tôi cứ nhắc đến force…force nghe mà nặng nề. Vậy ngoài cách đó ra thì còn cách nào xóa được commit không? Theo tôi được biết thì không còn cách nào cả. Commit khi còn ở dưới local thì có thể xóa theo cách trong bài viết Tôi vừa lỡ commit sai, làm sao để sửa lại ngay lập tức?, chứ một khi đã push lên rồi thì chỉ có cách force push để xóa, mà force push thì khác nào chúng ta đang init project từ đầu với hàng tá commit có sẵn trước đó đâu, ít nhiều sẽ gây ra rủi ro conflic hoặc mất code.
Thay vào đó, hãy thử revert
lại commit trước đó. Lệnh revert
tạo ra một commit với các thay đổi là sửa lại những thay đổi đã có ở commit trước đó. Mọi thứ sẽ trở lại như trước commit vừa revert, chỉ có điều bạn không thể xóa được commit đó.
$ git revert HEAD
$ git push
Cuối cùng, đây là bài viết tham khảo chứ không khuyến khích bạn đọc áp dụng vào trong project thực tế. Nếu muốn thử hãy trải nghiệm trên một project test để từ đó rút ra kinh nghiệm cho bản thân trước khi hành động.
Git được sinh ra để giải quyết vấn đề làm việc nhóm hoặc hơn thế nữa. Mỗi commit trong git như một cam kết và rất khó để xóa được chúng nếu đã đẩy lên remote. Tuy nhiên bạn có thể thử áp dụng cách force push để xóa các commit cuối cùng hoặc một giải pháp an toàn hơn là revert lại commit.
Xin chào, tôi tên là Hoài - một anh Dev kể chuyện bằng cách viết ✍️ và làm sản phẩm 🚀. Với nhiều năm kinh nghiệm lập trình, tôi đã đóng góp một phần công sức cho nhiều sản phẩm mang lại giá trị cho người dùng tại nơi đang làm việc, cũng như cho chính bản thân. Sở thích của tôi là đọc, viết, nghiên cứu... Tôi tạo ra trang Blog này với sứ mệnh mang đến những bài viết chất lượng cho độc giả của 2coffee.dev.Hãy theo dõi tôi qua các kênh LinkedIn, Facebook, Instagram, Telegram.
Bình luận (0)