Sửa lỗi 'git stash pop' thất bại với 'Your local changes would be overwritten by merge'

intermediate📦 Git2026-06-02| Git 2.x trên Linux, macOS, Windows (mọi hệ điều hành đã cài Git)

Error Message

error: Your local changes to the following files would be overwritten by merge: src/main.py Please commit your changes or stash them before you merge. Aborting
#git#stash#stash-pop#merge-conflict#working-tree

Điều Gì Đã Xảy Ra

Bạn đã stash công việc, làm gì đó khác, rồi chạy git stash pop — và bị ném thẳng vào mặt thông báo này:

error: Your local changes to the following files would be overwritten by merge:
        src/main.py
Please commit your changes or stash them before you merge.
Aborting

Stash không được áp dụng. Nhưng không có gì bị mất — stash của bạn vẫn đang nằm trong stack. Git từ chối tiếp tục vì bạn đã có các thay đổi chưa commit trên src/main.py, và việc áp dụng stash sẽ ghi đè lên chúng.

Tại Sao Git Hủy Bỏ

Chạy git stash pop sẽ kích hoạt một lần merge của stash diff trở lại vào working tree. Nếu một file đã có các chỉnh sửa chưa commit, Git không có cách an toàn nào để áp dụng stash lên trên — nó sẽ âm thầm xóa sạch những gì bạn đang làm dở. Vì vậy nó dừng lại sớm.

Tình huống phổ biến nhất dẫn đến đây:

  • Bạn stash các thay đổi trên src/main.py.
  • Bạn chuyển sang branch khác, sửa nhanh một cái gì đó, rồi chuyển về.
  • Hoặc — điều này xảy ra liên tục — bạn quên mất rằng stash đang tồn tại và bắt đầu chỉnh sửa src/main.py lại.
  • Bạn chạy git stash pop. Nó nổ tung.

Bắt đầu bằng cách xác định chính xác bạn đang đối mặt với điều gì:

# Xem stash chạm vào những file nào
git stash show

# Xem những gì hiện chưa được commit
git status
git diff src/main.py

Cách Sửa 1 — Commit hoặc Stash Thay Đổi Hiện Tại Trước (Khuyến Nghị)

Dọn sạch working tree trước khi pop. Có hai cách:

# Lựa chọn A: commit những gì bạn có hiện tại
git add src/main.py
git commit -m "WIP: current changes before stash pop"
git stash pop

# Lựa chọn B: stash các thay đổi hiện tại lên trên
git stash          # lưu thay đổi hiện tại thành stash@{0}
git stash pop stash@{1}  # pop stash gốc (giờ đã dịch chuyển sang index 1)
# Giải quyết các conflict nếu có, rồi:
git stash pop      # pop stash WIP bạn vừa tạo

Lựa chọn B giữ tất cả mọi thứ trong stash stack. Sau lần pop đầu tiên, bạn vẫn có thể gặp merge conflict — điều đó là bình thường. Git đánh dấu các vùng conflict bằng ký hiệu <<<<<<< để bạn có thể giải quyết thủ công.

Cách Sửa 2 — Bỏ Qua Thay Đổi Working Tree Hiện Tại

Đôi khi các thay đổi đang chặn bạn không đáng giữ lại — một thử nghiệm làm dở, vài dòng debug print, hay gì đó tương tự. Cứ bỏ đi thôi:

# Hủy thay đổi trên file cụ thể
git checkout -- src/main.py

# Rồi thử lại
git stash pop

Cần xóa sạch tất cả thay đổi chưa commit?

git restore .   # Git 2.23+
# hoặc
git checkout -- .

Cảnh báo: Thao tác này là vĩnh viễn. Các thay đổi working tree đã hủy sẽ mất hoàn toàn — Git không có thùng rác cho chúng. Kiểm tra kỹ git diff trước khi chạy bất kỳ lệnh nào ở trên.

Cách Sửa 3 — Ép 3-Way Merge Bằng git apply

Cả hai bộ thay đổi đều quan trọng, nhưng git stash pop cứ hủy bỏ? Xuất stash thành patch và để Git tự thử merge:

git stash show -p | git apply --3way

Thay vì hủy bỏ khi có conflict, --3way khiến Git cố gắng hết sức và để lại các conflict marker (<<<<<<< / >>>>>>>) trong các file không thể tự giải quyết. Bạn sẽ tự tay xử lý những chỗ đó.

# Kiểm tra những file nào cần xử lý
git status

# Chỉnh sửa src/main.py để giải quyết các conflict marker, rồi:
git add src/main.py

# Xóa stash entry — nó đã được áp dụng thủ công
git stash drop

Cách Sửa 4 — Áp Dụng Stash Mà Không Xóa Nó

Không chắc việc apply sẽ diễn ra suôn sẻ? Dùng git stash apply thay vì pop:

# Áp dụng mà không xóa (stash vẫn còn trong stack)
git stash apply

# Giải quyết conflict, rồi xóa stash thủ công
git stash drop

Điểm khác biệt duy nhất so với pop: stash entry tồn tại cho đến khi bạn chủ động xóa nó. Nếu có gì đó đi sai hướng, stash vẫn còn đó như một mạng lưới an toàn. Đây là lựa chọn mặc định tốt khi bạn chưa hoàn toàn tự tin về kết quả.

Kiểm Tra

Kiểm tra nhanh trước khi tiếp tục:

# Stash stack nên trống (hoặc ít hơn một entry)
git stash list

# Working tree chỉ nên hiển thị những thay đổi bạn mong đợi
git diff HEAD

# Không còn conflict marker nào sót lại
grep -r '<<<<<<<' src/

git stash list trống cộng với git status sạch? Bạn đã xong.

Phòng Tránh Lần Sau

Một vài thói quen giúp loại bỏ hoàn toàn vấn đề này:

  • Chạy git status trước git stash pop. Ba mươi giây kiểm tra đánh đổi với mười phút gỡ rối conflict.
  • Chỉ định rõ ràng stash bạn muốn pop. Khi có nhiều entry trong stack, git stash pop stash@{1} an toàn hơn nhiều so với để Git tự đoán.
  • Đừng dùng stash cho bất cứ thứ gì lâu hơn vài phút. Với các lần chuyển ngữ cảnh kéo dài một tiếng hay một ngày, một WIP commit trên branch tạm thời đáng tin cậy hơn nhiều.
  • Đặt tên cho stash. git stash push -m "refactor: before adding auth layer" tốn thêm năm giây nhưng khiến git stash list thực sự dễ đọc.

Related Error Notes