Git rebase bị conflict: cách sửa hoặc abort an toàn

Nội dung

Hướng dẫn xử lý git rebase bị conflict: cách kiểm tra file lỗi, sửa conflict marker, tiếp tục rebase, abort an toàn và khi nào không nên dùng skip.

Bạn đang chạy git rebase main thì terminal báo conflict và dừng lại giữa chừng? Đừng vội đóng terminal hoặc xóa branch. Khi git rebase bị conflict, Git đang tạm dừng để bạn quyết định phiên bản code nào nên được giữ.

Bài này hướng dẫn cách đọc lỗi, sửa file conflict, chạy git rebase --continue, dừng bằng git rebase --abort và hiểu vì sao git rebase --skip cần dùng rất cẩn thận.

Git rebase bị conflict với ba lựa chọn continue abort skip
Khi rebase dừng vì conflict, bạn luôn có ba hướng: sửa tiếp, abort hoặc skip.

Tóm tắt nhanh

  • Git rebase bị conflict nghĩa là Git đang replay từng commit của bạn lên base mới và có commit không áp dụng sạch được.
  • Quy trình an toàn: xem git status, mở file conflict, sửa marker, git add, rồi git rebase --continue.
  • Dùng git rebase --abort nếu muốn quay về trạng thái trước khi rebase.
  • git rebase --skip sẽ bỏ commit đang gây conflict, nên chỉ dùng khi bạn chắc chắn commit đó không cần nữa.
  • Nếu branch đã push và bạn rebase lại lịch sử, hãy trao đổi với team trước khi force push.

Git rebase bị conflict là gì?

Git rebase bị conflict là tình huống Git không thể tự áp dụng một commit của bạn lên base mới. Rebase không merge một lần duy nhất; nó lấy từng commit trên branch hiện tại và replay lên commit nền mới [1].

Vì vậy, conflict trong rebase thường xuất hiện theo từng commit. GitHub Docs mô tả thông báo rebase conflict thường cho bạn ba lựa chọn: sửa conflict rồi chạy git rebase --continue, bỏ commit bằng git rebase --skip, hoặc dừng rebase bằng git rebase --abort [2].

Điểm dễ nhầm là conflict khi rebase không giống cảm giác merge conflict thông thường. Sau khi bạn sửa xong một conflict, Git có thể tiếp tục replay commit kế tiếp và lại gặp conflict khác. Đừng lo nếu phải lặp vài vòng; đó là hành vi bình thường.

Nếu bạn chưa chắc nên merge hay rebase, đọc thêm bài Git pull bị conflictGit reset, revert, restore để chọn hướng an toàn hơn trước khi xử lý.

Sơ đồ git rebase replay commit và dừng tại conflict
Rebase replay từng commit, nên conflict có thể xuất hiện từng vòng.

Kiểm tra trạng thái trước khi sửa

Trước khi sửa, hãy chạy git status để biết Git đang chờ bạn làm gì. Đây là bước nhỏ nhưng giúp tránh sửa nhầm file hoặc chạy nhầm lệnh.

git status

Thông thường bạn sẽ thấy danh sách file trong trạng thái both modified hoặc thông báo đang trong quá trình rebase. Git status được thiết kế để hiển thị trạng thái working tree và staging area [3].

Nếu đang lo mất code, tạo một backup branch trước khi làm tiếp:

git branch backup-before-rebase-conflict

Branch này không sửa conflict thay bạn, nhưng cho bạn điểm quay lại nếu xử lý sai. Mình khuyên bạn dùng bước này khi branch có nhiều thay đổi hoặc bạn chưa quen rebase.

Cách sửa conflict và continue

Quy trình chuẩn là mở file conflict, chọn nội dung đúng, xóa conflict markers, stage file rồi chạy git rebase --continue. Đừng chạy continue khi file vẫn còn marker.

Trong file conflict, bạn thường thấy dạng:

<<<<<<< HEAD
code từ base mới
=======
code từ commit đang rebase
>>>>>>> ten-commit

Hãy chỉnh file thành phiên bản cuối cùng bạn muốn giữ, không để lại <<<<<<<, ======= hoặc >>>>>>>. Sau đó stage file bằng git add, lệnh Git dùng để thêm nội dung vào index [4].

git add path/to/file
git rebase --continue

Nếu còn conflict ở commit tiếp theo, Git sẽ dừng tiếp. Bạn lặp lại: git status, sửa file, git add, git rebase --continue.

Các bước sửa git rebase bị conflict rồi chạy git rebase continue
Sửa conflict xong phải stage file trước khi chạy rebase continue.

Khi nào dùng abort hoặc skip?

Dùng git rebase --abort khi bạn muốn hủy toàn bộ rebase và quay lại trạng thái trước đó. Đây là lựa chọn an toàn nếu conflict quá phức tạp hoặc bạn nhận ra đang rebase nhầm branch.

git rebase --abort

--abort không phải thất bại. Nó là cách dừng có kiểm soát để bạn hỏi team, update branch, chia nhỏ commit hoặc chọn merge thay vì rebase.

git rebase --skip thì khác: nó bỏ qua commit đang gây conflict. GitHub Docs cũng cảnh báo lựa chọn này nghĩa là thay đổi từ commit đó sẽ không được đưa vào kết quả rebase [2]. Chỉ dùng skip khi bạn chắc chắn commit đó không còn cần nữa, ví dụ commit chỉ đổi file đã bị xóa có chủ đích.

git rebase --skip

Nếu đã lỡ skip hoặc abort sai, bài Git reflog khôi phục commit sẽ giúp bạn tìm lại trạng thái trước đó.

So sánh git rebase abort và git rebase skip khi xử lý conflict
Abort quay lại trước rebase; skip bỏ commit đang gây conflict.

Git pull –rebase bị conflict thì sao?

Khi git pull --rebase bị conflict, cách xử lý giống rebase thường: sửa file, git add, rồi git rebase --continue. Khác biệt chỉ là rebase được khởi động từ pull.

Quy trình an toàn:

git status
# sửa file conflict
git add path/to/file
git rebase --continue

Nếu muốn dừng:

git rebase --abort

Sau khi rebase xong, hãy chạy test hoặc ít nhất build/lint phần vừa chạm. Conflict được “giải quyết” về mặt Git chưa chắc đã đúng về mặt nghiệp vụ.

Cách giảm conflict khi rebase

Bạn không thể loại bỏ mọi conflict, nhưng có thể giảm tần suất và giảm rủi ro khi rebase. Cách thực tế nhất là rebase thường xuyên, commit nhỏ và không sửa cùng một file quá rộng.

  • Rebase branch ngắn ngày: branch để quá lâu dễ lệch xa khỏi main.
  • Commit nhỏ: conflict dễ hiểu hơn khi mỗi commit chỉ mang một ý.
  • Không rebase public branch tùy tiện: rebase viết lại lịch sử; team cần thống nhất trước.
  • Bật rerere nếu thường gặp lại conflict: Git rerere có thể ghi nhớ cách bạn đã resolve conflict và áp dụng lại khi gặp conflict tương tự [5].
  • Push cẩn thận sau rebase: nếu đã push branch trước đó, thường cần force push có bảo vệ như --force-with-lease, không dùng bừa trên branch shared.

Atlassian cũng nhấn mạnh rebase có lợi trong workflow feature branch nhưng cần hiểu rủi ro viết lại lịch sử, đặc biệt với branch đã được người khác dùng [6]. Thú vị nhỉ: rebase không nguy hiểm vì lệnh khó, mà vì nó thay đổi cách lịch sử commit được nhìn thấy.

Trong team nhỏ, một quy ước đơn giản rất hiệu quả là báo trước khi rebase branch đã mở pull request. Nếu conflict nằm ở file cấu hình, migration hoặc auth, đừng chỉ chọn phiên bản nhìn có vẻ mới hơn; hãy kiểm tra lại lý do thay đổi của cả hai phía. Với dự án có CI, nên đẩy branch sau rebase lên remote riêng hoặc cập nhật pull request rồi chờ test xanh trước khi merge. Cách này chậm hơn vài phút, nhưng giảm rất nhiều lỗi kiểu build pass local mà fail trên môi trường chung.

Checklist giảm conflict khi dùng git rebase trong team
Commit nhỏ, rebase thường xuyên và test sau conflict giúp giảm rủi ro.

Kết luận

Khi git rebase bị conflict, đừng xử lý theo cảm tính. Hãy xem trạng thái, sửa marker, stage file, continue; nếu rối thì abort; chỉ skip khi thật sự muốn bỏ commit đó.

Nguyên tắc mình dùng là: trước khi chạy lệnh mạnh, phải biết mình muốn giữ thay đổi nào. Git có nhiều đường lui, nhưng đường lui dễ dùng hơn nhiều nếu bạn bình tĩnh tạo backup branch và đọc kỹ trạng thái hiện tại.

Nguồn tham khảo

  1. Git Documentation: git-rebase
  2. GitHub Docs: Resolving merge conflicts after a Git rebase
  3. Git Documentation: git-status
  4. Git Documentation: git-add
  5. Git Documentation: git-rerere
  6. Atlassian: Git rebase

Các câu hỏi thường gặp

Git rebase bị conflict thì làm gì trước?

Chạy git status để xem file nào conflict và Git đang yêu cầu bước nào. Nếu chưa chắc, tạo backup branch trước khi sửa.

Sau khi sửa conflict rebase cần chạy lệnh gì?

Sau khi sửa file và xóa conflict markers, chạy git add path/to/file rồi git rebase –continue.

Git rebase –abort có mất code không?

Thông thường git rebase –abort đưa branch về trạng thái trước khi rebase bắt đầu. Nếu đang có thay đổi ngoài rebase, hãy kiểm tra git status và backup trước.

Có nên dùng git rebase –skip không?

Chỉ nên dùng khi bạn chắc chắn commit đang gây conflict không cần nữa. Skip sẽ bỏ thay đổi của commit đó khỏi kết quả rebase.

Rebase xong có cần force push không?

Nếu branch đã push trước khi rebase, có thể cần force push. Hãy trao đổi với team và ưu tiên git push –force-with-lease thay vì force push mù.

Tú Anh

Cây bút chính tại VietnamTutor

Bài viết cùng chuyên mục

Bảo mật vibe coding: đừng để AI sinh lỗ hổng website

Bảo mật vibe coding không chỉ là quét lỗi sau khi AI viết code. Bài viết đưa ra checklist kiểm soát secret, prompt injection, dependency, auth

Kiểm thử code do AI tạo: danh sách kiểm tra trước khi deploy

Code do AI tạo cần được kiểm thử theo nhiều lớp trước khi lên website thật. Checklist này giúp bạn kiểm tra chức năng, bảo mật,

Lỡ push .env lên Git: cách xử lý secret bị lộ

Lỡ push .env lên Git không chỉ là lỗi xóa file. Hãy revoke hoặc rotate secret trước, rồi dọn Git history và ngăn sự cố lặp

Quy trình vibe coding 7 bước: từ ý tưởng đến prototype

Quy trình vibe coding hiệu quả bắt đầu từ giả thuyết kinh doanh, không phải prompt dài. Bài viết hướng dẫn 7 bước từ brief, dữ

Vibe coding cho doanh nghiệp: việc nào nên làm bằng AI?

Vibe coding cho doanh nghiệp hữu ích khi cần thử prototype, dashboard hoặc automation nhỏ. Bài viết giúp bạn phân loại use case theo mức rủi

AI viết code nhanh hơn review: kiểm soát thế nào?

Khi AI viết code nhanh hơn khả năng review của team, doanh nghiệp cần đổi cách kiểm soát chất lượng. Bài viết đưa ra framework thực

Git detached HEAD là gì? Cách thoát an toàn

Bài viết này giải thích detached HEAD trong Git, cách nhận biết trạng thái này và các bước thoát ra an toàn mà không mất code.

Rủi ro vibe coding: 9 lỗi khiến prototype khó vận hành

Bài viết này chỉ ra 9 rủi ro phổ biến khi vibe coding và cách kiểm soát để prototype không biến thành gánh nặng vận hành.

Vibe coding là gì? Cách thử ý tưởng phần mềm bằng AI

Vibe coding giúp chủ doanh nghiệp biến ý tưởng phần mềm thành prototype nhanh hơn bằng AI. Bài viết này chỉ ra khi nào nên thử,

GitHub Actions CI/CD: quy trình deploy website an toàn

Hướng dẫn xây pipeline GitHub Actions CI/CD cho website: build, test, cache dependency, đóng artifact, deploy staging/production và quản lý secret an toàn.

.gitignore không hoạt động: nguyên nhân và cách sửa

Bài viết giúp bạn kiểm tra vì sao .gitignore không hoạt động, sửa lỗi file đã tracked và dùng git check-ignore để debug pattern.

Git push bị rejected: cách sửa non-fast-forward

Bài viết giải thích vì sao git push bị rejected, cách đọc lỗi non-fast-forward và quy trình xử lý an toàn trước khi push lại.