Git là một trong những hệ thống quản lý phiên bản được sử dụng rộng rãi nhất trong phát triển phần mềm. Khi bạn làm việc trên các dự án, bạn chắc chắn sẽ thực hiện các cam kết mà sau này bạn muốn hoàn tác, chỉnh sửa hoặc xóa hoàn toàn. Hướng dẫn này tập trung cụ thể vào cách hủy bỏ các cam kết Git bằng cách sử dụng lệnh rebase, cung cấp các tùy chọn mạnh mẽ để thao tác với lịch sử cam kết của bạn.
Dù bạn đã vô tình cam kết thông tin nhạy cảm, bao gồm mã lỗi hay chỉ đơn giản là muốn dọn dẹp lịch sử cam kết của mình, việc hiểu cách hủy bỏ các cam kết Git là một kỹ năng thiết yếu cho mọi lập trình viên.
Tối ưu hóa phát triển API của bạn với Apidog
Khi quản lý các cam kết Git một cách hiệu quả là rất quan trọng cho việc kiểm soát phiên bản, việc có những công cụ phù hợp cho phát triển và kiểm tra API cũng quan trọng không kém. Hãy xem xét chuyển sang Apidog, giải pháp thay thế Postman tốt nhất trên thị trường hiện nay.

Apidog kết hợp tài liệu API, thiết kế, mô phỏng, kiểm tra và làm việc nhóm trong một nền tảng duy nhất, eliminating the need to switch between multiple tools.

Với giao diện trực quan, khả năng tự động đồng bộ hóa và các tính năng toàn diện, Apidog nâng cao năng suất và tối ưu hóa toàn bộ chu trình phát triển API.

Khi chúng ta lặn vào các kỹ thuật Git rebase, hãy nhớ rằng việc áp dụng các công cụ hiệu quả như Apidog có thể tối ưu hóa quy trình phát triển của bạn hơn nữa.
Hiểu về cấu trúc cam kết Git
Trước khi đi vào các kỹ thuật hủy bỏ, hãy xem xét cách Git lưu trữ thông tin cam kết. Mỗi cam kết Git:
- Có một định danh hash duy nhất
- Chỉ vào cam kết cha của nó
- Chứa siêu dữ liệu (tác giả, ngày tháng, thông điệp cam kết)
- Lưu trữ một ảnh chụp nhanh của mã nguồn của bạn tại thời điểm đó
Khi bạn cần hủy bỏ một cam kết Git, bạn về cơ bản muốn thay đổi chuỗi cam kết này theo một cách nào đó. Tùy thuộc vào nhu cầu cụ thể của bạn, có một số phương pháp bạn có thể áp dụng.
Git Revert vs. Git Reset vs. Git Rebase: Chọn công cụ Git phù hợp
Có ba cách chính để hủy bỏ một cam kết Git:
1. Git Revert
git revert HEAD
Điều này tạo ra một cam kết mới hủy bỏ các thay đổi từ một cam kết trước đó. Cam kết ban đầu của bạn vẫn còn trong lịch sử, nhưng các thay đổi của nó thì đã bị đảo ngược.
Phù hợp nhất cho: Khi bạn muốn giữ một bản ghi rằng cam kết đã xảy ra nhưng hoàn tác tác động của nó. Đây là lựa chọn an toàn nhất khi làm việc với các repository chia sẻ.
2. Git Reset
git reset --soft HEAD^
Điều này di chuyển con trỏ nhánh của bạn đến một cam kết trước đó. Cờ --soft
giữ các thay đổi của bạn trong staging, trong khi --hard
sẽ loại bỏ hoàn toàn chúng.
Phù hợp nhất cho: Khi bạn muốn loại bỏ hoàn toàn các cam kết gần đây khỏi lịch sử và chưa chia sẻ công việc của mình.
3. Git Rebase
git rebase -i HEAD~n # trong đó n là số cam kết để hiển thị
Điều này cho phép bạn thao tác với lịch sử cam kết theo nhiều cách khác nhau, bao gồm cả việc xóa hoàn toàn cam kết.
Phù hợp nhất cho: Người dùng Git nâng cao muốn kiểm soát chính xác lịch sử cam kết của họ.
Lệnh Git Rebase: Một công cụ thao tác lịch sử mạnh mẽ
Lệnh rebase là một trong những tính năng mạnh mẽ nhất của Git. Khác với merge, lệnh này tạo ra một cam kết mới để tích hợp các thay đổi, rebase viết lại lịch sử cam kết bằng cách áp dụng các cam kết lên một cam kết cơ sở khác.
Lệnh rebase tương tác (-i
flag) đặc biệt hữu ích cho việc hủy bỏ cam kết, vì nó cho phép bạn:
- Xóa cam kết
- Kết hợp nhiều cam kết
- Thay đổi thứ tự cam kết
- Chỉnh sửa thông điệp cam kết
- Chia nhỏ cam kết
Dù mạnh mẽ, rebase cần được sử dụng cẩn thận vì nó viết lại lịch sử Git, điều này có thể gây ra vấn đề trong các môi trường làm việc cộng tác.
Cách hủy bỏ một cam kết Git bằng cách sử dụng Git Rebase
Hãy cùng đi qua quy trình hủy bỏ một cam kết Git bằng cách sử dụng lệnh rebase:
Bước 1: Bắt đầu một phiên rebase tương tác
Đầu tiên, xác định bạn cần quay ngược lịch sử bao xa. Nếu bạn muốn hủy bỏ ba cam kết gần đây nhất, bạn sẽ sử dụng:
git rebase -i HEAD~3
Điều này sẽ mở trình soạn thảo văn bản mặc định của bạn với danh sách các cam kết, cam kết gần nhất ở cuối:
pick f2a9770 Thêm tính năng X
pick c69a283 Sửa lỗi trong tính năng X
pick 7c6b236 Cập nhật tài liệu
Bước 2: Xóa cam kết Git
Để hủy bỏ một cam kết, hãy thay đổi từ "pick" thành "d" (hoặc "drop") cho cam kết bạn muốn xóa:
pick f2a9770 Thêm tính năng X
d c69a283 Sửa lỗi trong tính năng X
pick 7c6b236 Cập nhật tài liệu
Trong ví dụ này, chúng tôi đang xóa cam kết "Sửa lỗi trong tính năng X" trong khi giữ lại hai cam kết còn lại.
Bước 3: Lưu và thoát
Lưu tệp và đóng trình soạn thảo. Git sẽ xử lý các hướng dẫn của bạn và áp dụng các thay đổi.
Bước 4: Giải quyết bất kỳ xung đột Git nào
Nếu có xung đột giữa các cam kết sau khi xóa một cam kết, Git sẽ dừng quy trình rebase và yêu cầu bạn giải quyết chúng. Sau khi giải quyết xung đột:
git add .
git rebase --continue
Bước 5: Tại sao phải đẩy cưỡng bức nếu cần
Nếu bạn đã đẩy các cam kết mà bây giờ bạn đã hủy bỏ, bạn sẽ cần phải đẩy cưỡng bức để cập nhật nhánh từ xa:
git push --force-with-lease
CẢNH BÁO: Việc đẩy cưỡng bức sẽ viết lại lịch sử trên repository từ xa, điều này có thể gây ra vấn đề cho các lập trình viên khác đã kéo lịch sử cũ. Chỉ sử dụng đẩy cưỡng bức khi bạn chắc chắn rằng nó sẽ không ảnh hưởng đến công việc của người khác.
Các kỹ thuật Git Rebase nâng cao để quản lý cam kết
Không chỉ đơn giản là hủy bỏ các cam kết, rebase tương tác cung cấp một số tùy chọn khác:
Kết hợp các cam kết Git
Bạn có thể kết hợp nhiều cam kết thành một:
pick f2a9770 Thêm tính năng X
squash c69a283 Sửa lỗi trong tính năng X
pick 7c6b236 Cập nhật tài liệu
Điều này sẽ kết hợp cam kết "Sửa lỗi" vào cam kết "Thêm tính năng".
Thay đổi thứ tự các cam kết Git
Đơn giản chỉ cần thay đổi thứ tự các dòng trong trình soạn thảo rebase:
pick 7c6b236 Cập nhật tài liệu
pick f2a9770 Thêm tính năng X
Chỉnh sửa các cam kết Git
Sử dụng edit
thay vì pick
để dừng lại rebase tại một cam kết cụ thể:
pick f2a9770 Thêm tính năng X
edit c69a283 Sửa lỗi trong tính năng X
pick 7c6b236 Cập nhật tài liệu
Khi rebase đến cam kết này, Git sẽ dừng lại và cho phép bạn sửa đổi cam kết trước khi tiếp tục.
Rủi ro và thực hành tốt nhất của Git Rebase
Rủi ro khi sử dụng Git Rebase
- Thay đổi không thể phục hồi: Khác với merge, rebase viết lại lịch sử cam kết, làm cho việc khôi phục lại các sai lầm trở nên khó khăn.
- Cần đẩy cưỡng bức: Sau khi rebasing các cam kết đã đẩy, bạn sẽ cần phải đẩy cưỡng bức, điều này có thể ghi đè các thay đổi của người khác.
- Thay đổi cam kết: Rebase thay đổi các hàm băm cam kết, có nghĩa là các cam kết ban đầu sẽ được thay thế bằng các cam kết mới.
- Xung đột: Các rebase phức tạp có thể dẫn đến nhiều bước giải quyết xung đột.
Các thực hành tốt nhất của Git Rebase
Tạo các nhánh sao lưu: Trước khi thực hiện các thao tác rebase phức tạp, hãy tạo một nhánh sao lưu.
git branch backup-before-rebase
Chỉ rebase các cam kết chưa được đẩy: Như một quy tắc chung, hãy tránh rebasing các cam kết đã được đẩy đến repository chia sẻ.
Sử dụng -force-with-lease
thay vì -force
: Điều này cung cấp một kiểm tra an toàn để ngăn chặn việc ghi đè các thay đổi của người khác.
git push --force-with-lease
Thực hành trong một repository thử nghiệm: Nếu bạn mới làm quen với rebase, hãy thực hành trong một repository thử nghiệm trước khi sử dụng nó trên các dự án quan trọng.
Chỉ rebase các nhánh tính năng của riêng bạn: Tránh rebasing các nhánh mà nhiều lập trình viên đang làm việc.
Khi nào sử dụng mỗi phương pháp hủy bỏ Git
- Sử dụng Git Revert khi:
- Bạn cần hoàn tác các thay đổi nhưng vẫn giữ bản ghi của cam kết gốc
- Bạn đang làm việc trên một nhánh chia sẻ như main/master
- Bạn muốn lựa chọn an toàn nhất
- Sử dụng Git Reset khi:
- Bạn muốn hoàn toàn loại bỏ các cam kết gần đây
- Bạn chưa chia sẻ các cam kết của mình với người khác
- Bạn đang làm việc trên một nhánh tính năng cục bộ
- Sử dụng Git Rebase khi:
- Bạn muốn kiểm soát chi tiết lịch sử cam kết của mình
- Bạn cần dọn dẹp lịch sử cam kết trước khi chia sẻ
- Bạn thoải mái với các thao tác Git nâng cao
Git Rebase vs. Git Merge: Hiểu sự khác biệt
Trong khi không liên quan trực tiếp đến việc hủy bỏ các cam kết, việc hiểu sự khác biệt giữa rebase và merge giúp làm rõ lý do tại sao rebase mạnh mẽ cho việc thao tác lịch sử:
- Merge tạo ra một cam kết mới kết hợp các thay đổi từ các nhánh khác nhau, giữ nguyên toàn bộ lịch sử của cả hai nhánh.
- Rebase viết lại lịch sử bằng cách chuyển các cam kết từ một nhánh sang nhánh khác, tạo ra lịch sử tuyến tính thay vì phân nhánh.
Sự khác biệt này là yếu tố then chốt tại sao rebase có thể được sử dụng để hủy bỏ cam kết—nó không chỉ thêm các cam kết mới; nó viết lại lịch sử.
Kết luận
Lệnh Git rebase là một công cụ mạnh mẽ để hủy bỏ các cam kết và duy trì một lịch sử cam kết sạch sẽ và có ý nghĩa. Trong khi nó yêu cầu sự cẩn thận và chú ý để sử dụng đúng cách, việc thành thạo rebase mang lại cho bạn sự kiểm soát chính xác đối với lịch sử Git của bạn.
Hãy nhớ rằng cách tiếp cận an toàn nhất phụ thuộc vào tình huống cụ thể của bạn:
- Nếu bạn đã chia sẻ công việc của mình, hãy xem xét việc sử dụng
git revert
- Nếu bạn đang làm việc cục bộ,
git reset
hoặcgit rebase
có thể là phù hợp - Luôn tạo các nhánh sao lưu trước khi thực hiện các thao tác Git phức tạp
Bằng cách hiểu các phương pháp khác nhau để hủy bỏ các cam kết Git, bạn sẽ được trang bị tốt hơn để xử lý sai lầm và duy trì lịch sử repository sạch sẽ. Thực hành các kỹ thuật này trong một môi trường an toàn cho đến khi bạn cảm thấy thoải mái áp dụng chúng vào các dự án thực tế của mình.