TL;DR
- Bản chất: Shared Branch là nhánh dùng chung mà nhiều developer cùng clone/pull về máy (
main,develop,release). - Quy tắc an toàn: Trên Shared Branch đã
git push, BẮT BUỘC dùnggit revert(tiến về phía trước), CẤM dùnggit reset(lùi lại và viết lại lịch sử). - Điểm mấu chốt:
git resetxóa bỏ commit khỏi lịch sử nhánh, ép buộc phải dùngpush --force→ làm hỏng lịch sử của toàn bộ thành viên khác. Ngược lại,git reverttạo ra một commit MỚI có nội dung đảo ngược hoàn toàn thay đổi của commit lỗi, giữ nguyên tính tuyến tính của lịch sử.
Core Concept
1. Shared Branch là gì?
- Shared Branch (Nhánh dùng chung): Là bất kỳ nhánh nào đã được
pushlên Remote Repository (GitHub, GitLab) và có từ 2 người trở lên đang dựa vào các commit trên nhánh đó để phát triển (ví dụ:main,master,develop,staging, hoặc nhánhfeature/team-authcó nhiều người cùng code). - Private Branch (Nhánh cá nhân): Là nhánh chỉ một mình bạn làm việc trên máy local (hoặc nhánh feature cá nhân chưa có ai pull về).
2. Thảm họa khi dùng git reset trên Shared Branch
Giả sử commit C bị lỗi trên nhánh main và đã được push lên Remote:
[A] <── [B] <── [C (Lỗi)] <── (main trên Remote & mọi máy của đồng nghiệp)
Nếu bạn chạy git reset --hard HEAD~1 và git push --force:
- Remote bị ép lùi về
B(CommitCbiến mất trên Remote). - Khi đồng nghiệp chạy
git pull, Git sẽ phát hiện lịch sử bị phân nhánh (Diverged) và tự động merge commitCtừ máy của đồng nghiệp ngược trở lại Remote → Lỗi cũ tự động hồi sinh. - Nếu đồng nghiệp lỡ
rebasetheo, commit của họ có nguy cơ bị ghi đè hoặc tạo ra hàng loạt xung đột không thể giải quyết.
3. Cơ chế cứu nguy an toàn của git revert
Thay vì xóa commit C, git revert <SHA-of-C> tạo ra một Commit MỚI C':
[A] <── [B] <── [C (Lỗi)] <── [C' (Đảo ngược C)] <── (main: Tiến về phía trước)
- Nội dung của
C': Bỏ đi toàn bộ code màCđã thêm vào, và thêm lại toàn bộ code màCđã xóa. - Tính tương thích: Lịch sử commit luôn đi thẳng về phía trước (Append-only).
- Khi đồng nghiệp
git pull, máy của họ chỉ cần tải thêm commitC'một cách bình thường, không có xung đột, không cần force push.
Practical Implementation
1. Revert một commit đơn lẻ đã push
# Đảo ngược commit gần nhất
git revert HEAD
# Đảo ngược một commit cụ thể trong quá khứ
git revert a1b2c3d
2. Revert một Merge Commit (Cần chỉ định cờ -m)
Khi revert một merge commit (có 2 parent), bạn phải báo cho Git biết muốn giữ lại nhánh nào làm nhánh chính (Parent 1 thường là nhánh đích như main):
# Giữ lại parent 1 (main), đảo ngược nhánh feature vừa merge nhầm
git revert -m 1 <merge-commit-sha>
Related Notes
- Git_Four_Zones_and_Reset_Lifecycle: Chi tiết hoạt động của 3 cờ
reset(--soft,--mixed,--hard). - Git_DAG_and_Object_Storage_Model: Bản chất Append-only của đồ thị DAG trong Git.
- 000_Methods_MOC: Danh mục các quy trình và phương pháp kỹ thuật.