553
votes

I am trying to rename a file to have different capitalization from what it had before:

git mv src/collision/b2AABB.js src/collision/B2AABB.js
fatal: destination exists, source=src/collision/b2AABB.js, destination=src/collision/B2AABB.js

As you can see, Git throws a fit over this. I tried renaming using just the plain old mv command as well, but Git doesn't pick up the rename (as a rename or as a new untracked file).

How can I change a file to have a different capitalization of the same name? I am on Mac OS X v10.7.3 (Lion) with Git 1.7.9.1 using Z shell (zsh) 4.3.15.

11
it is because the osx file system is case preserving andcase insensitive by default. You can simply proceed in two steps: git mv myfile foo; git mv foo MyFiletonio
Got it working with "git mv --force myfile MyFile".Marcello de Sales
Starting git 2.0.1 (June 2014), git mv hello.txt Hello.txt will work on case insensitive OS. See my answer belowVonC

11 Answers

680
votes

Starting Git 2.0.1 (June 25th, 2014), a git mv will just work on a case-insensitive OS.

See commit baa37bf by David Turner (dturner-tw).

mv: allow renaming to fix case on case-insensitive filesystems

"git mv hello.txt Hello.txt" on a case-insensitive filesystem always triggers "destination already exists" error, because these two names refer to the same path from the filesystem's point of view and requires the user to give "--force" when correcting the case of the path recorded in the index and in the next commit.

Detect this case and allow it without requiring "--force".

git mv hello.txt Hello.txt just works (no --force required anymore).


The other alternative is:

git config --global core.ignorecase false

And rename the file directly; git add and commit.

It does work in a CMD. It might fail in a git bash (on Windows) session (see Louis-Caron's answer)

472
votes

Considering larsks' answer, you can get it working with a single command with "--force":

 git mv --force myfile MyFile
123
votes

Sometimes you want to change the capitalization of a lot of file names on a case insensitive filesystem (e.g. on OS X or Windows). Doing git mv commands will tire quickly. To make things a bit easier this is what I do:

  1. Move all files outside of the directory to, let’s, say the desktop.
  2. Do a git add . -A to remove all files.
  3. Rename all files on the desktop to the proper capitalization.
  4. Move all the files back to the original directory.
  5. Do a git add .. Git should see that the files are renamed.

Now you can make a commit saying you have changed the file name capitalization.

67
votes

File names under OS X are not case sensitive (by default). This is more of an OS problem than a Git problem. If you remove and readd the file, you should get what you want, or rename it to something else and then rename it back.

45
votes

Set ignorecase to false in git config

As the original post is about "Changing capitalization of filenames in Git":

If you are trying to change capitalisation of a filename in your project, you do not need to force rename it from Git. IMO, I would rather change the capitalisation from my IDE/editor and make sure that I configure Git properly to pick up the renaming.

By default, a Git template is set to ignore case (Git case insensitive). To verify you have the default template, use --get to retrieve the value for a specified key. Use --local and --global to indicate to Git whether to pick up a configuration key-value from your local Git repository configuration or global one. As an example, if you want to lookup your global key core.ignorecase:

git config --global --get core.ignorecase

If this returns true, make sure to set it as:

git config --global core.ignorecase false

(Make sure you have proper permissions to change global.) And there you have it; now your Git installation would not ignore capitalisations and treat them as changes.

As a suggestion, if you are working on multi-language projects and you feel not all projects should be treated as case-sensitive by Git, just update the local core.ignorecase file.

10
votes

You can open the ".git" directory and then edit the "config" file. Under "[core]" set, set "ignorecase = true" and you are done ;)

4
votes

To bulk git mv files to lowercase on macOS and git bash on Windows:

for f in *; do git mv "$f" "`echo $f | tr "[:upper:]" "[:lower:]"`"; done

It will lowercase all files in a folder.

1
votes

This Python snippet will git mv --force all files in a directory to be lowercase. For example, foo/Bar.js will become foo/bar.js via git mv foo/Bar.js foo/bar.js --force.

Modify it to your liking. I just figured I'd share :)

import os
import re

searchDir = 'c:/someRepo'
exclude = ['.git', 'node_modules','bin']
os.chdir(searchDir)

for root, dirs, files in os.walk(searchDir):
    dirs[:] = [d for d in dirs if d not in exclude]
    for f in files:
        if re.match(r'[A-Z]', f):
            fullPath = os.path.join(root, f)
            fullPathLower = os.path.join(root, f[0].lower() + f[1:])
            command = 'git mv --force ' + fullPath + ' ' + fullPathLower
            print(command)
            os.system(command)
1
votes

Working example:

git mv ./src/images/poster_video.PNG ./src/images/poster_video.png
1
votes

Answer by Vonc is totally correct, but there is still a potential situation where your rename action would not work with git for windows:

Let's say you want to rename dir/mypath to dir/myPath:

git mv dir/mypath dir/myPath

but it fails reporting:

Rename from 'dir/mypath' to 'dir/mypath' failed. Should I try again? (y/n) 

The problem is that the bash has silently replaced your command line dir/myPath with dir/mypath because it has detected that such a path exists with a different capitalization.

The solution is to use an intermediate move operation:

git mv dir/mypath dir/mypath_temp
git mv dir/mypath_temp dir/myPath
0
votes

I got the following changes on Windows in Sourcetree:

enter image description here

I solved it by removing the file from the file system:

enter image description here

Then simply discard the file I want to keep and commit:

enter image description here

Now everything worked as expected.

enter image description here

Based on this answer:

https://stackoverflow.com/a/66121726/3850405