When you rename a file by changing its casing on Windows (ex: movie.cs -> Movie.cs), git will ignore the change. To change the casing, use the git mv command:
git mv movie.cs Movie.csCode language: Bash (bash)
This will rename the movie.cs file to Movie.cs on the file system and in the git repository, resulting in a rename change, which you can then commit:
Changes to be committed: (use "git reset HEAD <file>..." to unstage) renamed: movie.cs -> Movie.csCode language: plaintext (plaintext)
This will work even if you manually changed the filename (like through Visual Studio). The important thing is it changes the filename in the git repository.
This behavior is controlled by the git core.ignorecase setting, which is true by default (at least on Windows). This is why it ignores filename casing changes.
Changing a directory’s casing
To change a directory’s casing (ex: /data/ -> /Data/), you have to do it in two steps:
git mv data tmp git mv tmp DataCode language: Bash (bash)
This will result in all of the files in the directory having rename changes, which you can then commit:
Changes to be committed: (use "git reset HEAD <file>..." to unstage) renamed: data/MovieRepository.cs -> Data/MovieRepository.csCode language: plaintext (plaintext)
The history is retained for all of the renamed files, as you can see below:
Setting core.ignorecase to false can lead to duplicate files
I wouldn’t suggest changing git to ignore filename casing by setting core.ignorecase=false. This can lead to problems, such as duplicate files.
Here’s an example of a mess this can cause.
Let’s say you want to rename Movie.cs to movie.cs and you notice that git isn’t seeing the file change. So you execute the following to have git pay attention to filename casing:
git config core.ignorecase falseCode language: Bash (bash)
The problem is git thinks this is a new file (notice it’s “Untracked”):
Untracked files: (use "git add <file>..." to include in what will be committed) movie.csCode language: plaintext (plaintext)
If you commit this, you’ll now have movie.cs and Movie.cs in the repository. Here’s what it’ll look like in GitHub:
It will seem fine locally, because you’ll only see one file on the file system (Windows is case insensitive, so it’s impossible to have movie.cs and Movie.cs in the same directory). This can lead to big messes.
Delete duplicate file
Here’s one way to clean up the mess by deleting the duplicate file.
- First, keep core.ignorecase=false for now. It caused the problem, but you’ll need to keep this setting as is while you clean up the mess.
- Manually delete movie.cs from the file system.
- Execute git status and make sure you see two deleted changes:
Changes not staged for commit: (use "git add/rm <file>..." to update what will be committed) (use "git checkout -- <file>..." to discard changes in working directory) deleted: Movie.cs deleted: movie.csCode language: plaintext (plaintext)
- Commit and push the deleted change for the duplicate file (in this case, we want to delete Movie.cs):
git add Movie.cs git commit -m "Deleted duplicate" git pushCode language: Bash (bash)
- Undo the deleted change for the remaining file:
git checkout -- movie.csCode language: Bash (bash)
- Look at the repository in GitHub and notice the duplicate file (Movie.cs) was removed.
- Now reset the core.ignorecase setting so git is case insensitive again (to prevent this mess from happening again):
git config core.ignorecase trueCode language: Bash (bash)