Git status không hiển thị thay đổi sau khi đổi tên 'file.txt' thành 'File.txt' trên Windows/macOS

beginner📦 Git2026-04-21| Git trên Windows (NTFS) và macOS (HFS+/APFS mặc định không phân biệt chữ hoa/thường), Git 2.x

Error Message

git status shows no changes after renaming 'file.txt' to 'File.txt' on Windows/macOS
#git#case-sensitive#rename#config

Vấn đề

Bạn đổi tên utils.js thành Utils.js — chỉ một chữ hoa. Chạy git status: không có gì. Git coi như chưa có chuyện gì xảy ra.

Ở máy local, mọi thứ chạy bình thường. Rồi bạn push lên server CI chạy Linux và build thất bại — các import bị lỗi vì server tìm Utils.js nhưng repo vẫn còn utils.js. Đây là lỗi kinh điển: ẩn ở local, bùng phát trên production.

Tại sao điều này xảy ra

Windows (NTFS) và macOS (HFS+/APFS ở cấu hình mặc định) sử dụng filesystem không phân biệt chữ hoa/thường. Đối với hệ điều hành, file.txtFile.txt là cùng một file. Vì Git dựa vào filesystem để phát hiện thay đổi, nó không bao giờ nhận ra sự khác biệt.

Còn một tùy chọn Git config liên quan: core.ignoreCase. Trên Windows và macOS, Git tự động đặt giá trị này thành true khi cài đặt. Điều đó là có chủ đích — nó ngăn các false positive trên filesystem không phân biệt chữ hoa/thường. Nhưng cũng có nghĩa là Git sẽ bỏ qua hoàn toàn các lần đổi tên theo chữ hoa/thường thực sự.

Linux thì khác. Filesystem của nó phân biệt chữ hoa/thường, nên file.txtFile.txt là hai file hoàn toàn khác nhau. Khi code chạy trên Linux — server, Docker container, GitHub Actions — nó tìm đúng tên file trong repo. Nếu Git chưa bao giờ theo dõi việc đổi tên, tên cũ vẫn còn đó và các tham chiếu bị hỏng.

Cách sửa 1: Dùng git mv với tên tạm thời (Khuyến nghị)

Đổi tên qua một tên trung gian tạm thời. Cách này đánh lừa Git ghi lại hai lần đổi tên riêng biệt thay vì một lần đổi tên vô hình.

# Bước 1: Đổi sang tên tạm thời
git mv utils.js utils_temp.js

# Bước 2: Đổi từ tên tạm sang tên cuối cùng
git mv utils_temp.js Utils.js

# Bước 3: Xác nhận Git đã ghi lại
git status

Staging area bây giờ sẽ hiển thị:

Changes to be committed:
  renamed:    utils.js -> Utils.js
# Bước 4: Commit
git commit -m "Rename utils.js to Utils.js"

Cách sửa 2: Đặt core.ignoreCase = false và đổi tên trực tiếp

Một tùy chọn khác — chuyển Git sang chế độ phân biệt chữ hoa/thường chỉ cho thao tác này:

# Bật phân biệt chữ hoa/thường cho repo này
git config core.ignoreCase false

# Bây giờ đổi tên trực tiếp
git mv utils.js Utils.js

git status

Sau khi commit, bạn có thể giữ nguyên core.ignoreCase false hoặc đặt lại. Lưu ý: để giá trị false trên filesystem không phân biệt chữ hoa/thường đôi khi khiến Git báo các thay đổi ảo trên file không bị chỉnh sửa. Cách sửa 1 tránh hoàn toàn vấn đề này.

# Tùy chọn: khôi phục config sau khi commit
git config core.ignoreCase true

Cách sửa 3: Đã commit với tên sai chữ hoa/thường?

Nếu file đã được commit và push với tên sai, cần cập nhật trực tiếp index:

# Xóa file cũ khỏi index của Git (không xóa khỏi ổ đĩa)
git rm --cached utils.js

# Thêm file với tên mới đúng
git add Utils.js

# Commit bản sửa
git commit -m "Fix: rename utils.js to Utils.js (case correction)"

Nếu Git báo lỗi file không tồn tại, thử cách triệt để hơn — index lại toàn bộ:

# Trên macOS/Windows khi file không hiển thị thay đổi:
git rm -r --cached .
git add .
git commit -m "Fix file casing in Git index"

Cảnh báo: git rm -r --cached . bỏ stage mọi thứ rồi thêm lại. Các file thực tế của bạn không bị ảnh hưởng — lệnh này chỉ tác động đến Git index. Dù vậy, hãy chạy git status trước khi commit để kiểm tra các file không liên quan mà bạn không muốn đưa vào.

Kiểm tra: Xác nhận đã sửa thành công

Kiểm tra xem việc đổi tên có hiển thị đúng trong commit cuối không:

# Kiểm tra commit mới nhất có ghi nhận việc đổi tên
git log --oneline --name-status -1

Kết quả mong đợi:

a3f9c12 Rename utils.js to Utils.js
R100    utils.js    Utils.js

R100 có nghĩa là Git đã ghi lại việc đổi tên với độ tương đồng 100%. Nếu thấy D (đã xóa) và A (đã thêm) thay vào đó thì không lý tưởng, nhưng vẫn hoạt động — file sẽ tồn tại với tên đúng trên Linux sau khi clone mới.

Push và xác nhận trên remote:

git push origin main

# Sau đó kiểm tra GitHub/GitLab — file bây giờ phải hiển thị đúng chữ hoa/thường

Phòng ngừa: Thêm Git alias cho việc đổi tên theo chữ hoa/thường

Thường xuyên đổi tên file theo chữ hoa/thường? Thêm alias này vào config toàn cục một lần và quên đi thao tác hai bước:

git config --global alias.mvcased '!f() { git mv "$1" "${1}_tmp" && git mv "${1}_tmp" "$2"; }; f'

Cách dùng:

git mvcased utils.js Utils.js

Tóm tắt nhanh

  • Tình huống 1 — File chưa commit: git mv file.txt temp.txt && git mv temp.txt File.txt
  • Tình huống 2 — Đã commit, chưa push: Đặt core.ignoreCase false, dùng git mv, rồi reset lại config
  • Tình huống 3 — Đã push: git rm --cached oldname + git add newname + commit + push
  • Tình huống 4 — Nhiều file bị ảnh hưởng: git rm -r --cached . && git add . để index lại toàn bộ

Related Error Notes