Fix lỗi Git: Local Changes Would Be Overwritten by Merge

beginner📦 Git2026-03-23| Git 2.x trên Linux, macOS, Windows — khi chạy git pull hoặc git merge với thay đổi cục bộ chưa commit

Error Message

error: Your local changes to the following files would be overwritten by merge:
#git#pull#merge#stash#working-tree

TL;DR

Git đang từ chối pull vì bạn có thay đổi chưa commit trong các file mà commit đến cũng đang chỉnh sửa. Ba cách giải quyết:

# Cách A — stash thay đổi, pull, rồi khôi phục
git stash
git pull
git stash pop

# Cách B — hủy toàn bộ thay đổi của bạn
git checkout -- path/to/file
git pull

# Cách C — commit trước, rồi mới pull
git add path/to/file
git commit -m "WIP: save local changes"
git pull

Chuyện Gì Đang Xảy Ra

Chạy git pull sẽ kích hoạt một lần merge phía sau. Git so sánh những gì có trong nhánh remote với nhánh local của bạn — và nếu một file bạn đã chỉnh sửa local cũng bị thay đổi trong các commit đến, Git sẽ dừng lại ngay:

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

Đây là hành vi có chủ đích. Git sẽ không âm thầm xóa đi công việc của bạn. Các chỉnh sửa của bạn đang nằm trong working tree (hoặc index nếu bạn đã stage chúng) nhưng chưa được commit, nên không có chỗ an toàn nào để đặt chúng trong lúc merge.

Các Cách Khắc Phục

Cách A: Stash (Khuyến nghị — giữ lại thay đổi của bạn)

Lựa chọn tốt nhất khi bạn muốn lấy lại các chỉnh sửa local sau khi pull — chẳng hạn bạn có debug logging hoặc API key local chưa sẵn sàng để commit.

# 1. Stash tất cả file đã được tracked và đã chỉnh sửa
git stash

# 2. Pull các thay đổi mới nhất
git pull

# 3. Áp lại các thay đổi đã stash
git stash pop

Nếu stash pop gặp conflict, Git sẽ đánh dấu các dòng xung đột bằng ký hiệu <<<<<<<. Hãy sửa thủ công, sau đó chạy:

git add src/config.js
git stash drop    # xóa stash entry sau khi đã giải quyết xong

Cần stash chỉ một file với nhãn có ý nghĩa? Dùng:

git stash push -m "WIP: local config tweaks" src/config.js

Chạy git stash list bất cứ lúc nào để xem tất cả những gì đang được stash.

Cách B: Hủy Thay Đổi Local (Nguy hiểm — thay đổi sẽ mất vĩnh viễn)

Chỉ dùng cách này khi các chỉnh sửa local thực sự không quan trọng — ví dụ như bạn vô tình chạm vào file trong lúc xem xét.

# Hủy thay đổi trên các file cụ thể
git checkout -- src/config.js README.md

# Hoặc xóa TOÀN BỘ thay đổi chưa commit trong working tree
git restore .

# Sau đó pull bình thường
git pull

Cảnh báo: Cả git checkout -- <file> lẫn git restore đều xóa vĩnh viễn các thay đổi chưa commit. Không thể hoàn tác, không có thùng rác.

Cách C: Commit Thay Đổi Trước

Khi các chỉnh sửa của bạn là công việc thực sự cần lưu vào lịch sử, hãy commit trước rồi mới pull.

git add src/config.js README.md
git commit -m "Update config and docs"
git pull

Việc pull vẫn có thể tạo ra merge conflict nếu cả bạn và đồng nghiệp cùng chỉnh sửa những dòng giống nhau. Điều đó hoàn toàn bình thường — Git sẽ dừng lại và hướng dẫn bạn qua quy trình giải quyết conflict thông thường.

Cách D: Force Pull (Cực đoan — ghi đè tất cả)

Chỉ dùng cho các nhánh tạm thời hoặc khi bạn hoàn toàn chắc chắn muốn lấy phiên bản remote, không cần hỏi thêm.

git fetch origin
git reset --hard origin/main

Lệnh này sẽ hard-reset nhánh của bạn để khớp chính xác với remote. Các thay đổi chưa commit sẽ biến mất. Các commit bạn đã thực hiện local nhưng chưa push? Cũng mất theo. Hãy dùng cẩn thận.

Nên Chọn Cách Nào?

Chọn dựa trên những gì bạn thực sự muốn làm với các thay đổi local đó:

  • Stash — bạn muốn lấy lại chúng sau khi pull (debug log tạm thời, chỉnh sửa env local, thử nghiệm).
  • Hủy — chúng là vô tình hoặc không liên quan và bạn sẵn sàng mất đi.
  • Commit — chúng là công việc thực sự cần lưu vào lịch sử dự án.
  • Reset --hard — nhánh local của bạn đang lộn xộn và bạn chỉ muốn nó phản chiếu remote, không cần bàn thêm.

Khi Stash Pop Xảy Ra Conflict Sau Pull

Đôi khi pull mang về thay đổi trên chính xác những dòng giống như trong stash của bạn. Git sẽ thông báo ngay:

$ git stash pop
Auto-merging src/config.js
CONFLICT (content): Merge conflict in src/config.js
The stash entry is kept in case you need it again.

Mở src/config.js, tìm các ký hiệu <<<<<<<, và chọn phiên bản đúng. Sau đó dọn dẹp:

git add src/config.js
git stash drop    # xóa stash entry sau khi đã giải quyết hoàn toàn

Kiểm Tra Lại

Sau khi áp dụng cách khắc phục, hãy xác nhận mọi thứ đã đúng:

# Nên hiển thị nhánh của bạn là up to date
git status

# Kiểm tra các commit remote mới nhất đã có trong lịch sử local
git log --oneline -5

# Nếu bạn dùng stash pop, xác nhận thay đổi đã được khôi phục
git diff HEAD

Kết quả git status sạch hiển thị "Your branch is up to date with 'origin/main'" có nghĩa là bạn đã xong.

Ngăn Điều Này Xảy Ra Lần Nữa

  • Commit thường xuyên và theo từng phần nhỏ. Một nhánh với các commit nhỏ thường xuyên hầu như không bao giờ gặp lỗi này.
  • Thử git pull --rebase. Nó replay các commit của bạn lên trên remote thay vì merge — gọn hơn cho lịch sử tuyến tính. Vẫn yêu cầu working tree sạch, nhưng kết quả ngăn nắp hơn.
  • Thêm một alias sync cho thao tác stash-pull-pop: git config --global alias.sync '!git stash && git pull && git stash pop'. Sau đó git sync xử lý tất cả chỉ trong một lệnh.

Related Error Notes