625

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.

Peter Mortensen
  • 30,030
  • 21
  • 100
  • 124
knpwrs
  • 14,665
  • 11
  • 59
  • 99
  • 58
    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 MyFile` – tonio May 09 '12 at 20:51
  • 24
    Got it working with "git mv --force myfile MyFile". – Marcello de Sales Apr 17 '13 at 22:29
  • 3
    dupe of http://stackoverflow.com/questions/6899582/i-change-the-capitalization-of-a-directory-and-git-doesnt-seem-to-pick-up-on-it – jackocnr Jul 24 '13 at 10:52
  • 8
    Starting git 2.0.1 (June 2014), `git mv hello.txt Hello.txt` will work on case insensitive OS. See [my answer below](http://stackoverflow.com/a/24979063/6309) – VonC Jul 27 '14 at 08:02
  • 1
    Linking http://stackoverflow.com/questions/1793735/change-case-of-a-file-on-windows – Oleg Estekhin Apr 07 '15 at 11:17
  • Possible duplicate of [How do I commit case-sensitive only filename changes in Git?](https://stackoverflow.com/questions/17683458/how-do-i-commit-case-sensitive-only-filename-changes-in-git) – Stevoisiak Aug 28 '17 at 20:51

11 Answers11

782

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)

As noted by jaquinocode in the comments, if your local repository itself has that setting:

git config --local core.ignorecase false
VonC
  • 1,129,465
  • 480
  • 4,036
  • 4,755
  • 6
    FWIW this regressed or never worked on Windows. Am on 2.15.1.windows.2 and still need to use --force – TTimo Dec 26 '17 at 19:09
  • 1
    @Adowrath Great news! – VonC Jul 09 '18 at 09:15
  • **Will this work for the extensions capitalization also For example, if have file name image.TXT and I want to rename it like image.txt** – siluveru kiran kumar Jun 21 '19 at 05:14
  • @siluverukirankumar Yes. Did you have any issue with that usecase? – VonC Jun 21 '19 at 05:18
  • Yes, @VonC I have a use case like where I have image name extension with capital letters like **image.PNG**, but in my code I have **image.png**, I want to change to the **image.png** (assume I don't want to change in my code) when I am changing the file name in folder but it is not showing in the modified files. – siluveru kiran kumar Jun 21 '19 at 06:31
  • @siluverukirankumar OK. Can you ask a separate question illustrating the issue, with your OS, Git and shell version? – VonC Jun 21 '19 at 06:35
  • A `git mv hello.txt Hello.txt` followed by a `git reset` would leave a `Hello.txt` in file system, not the original `hello.txt`. – Evi Song Dec 11 '19 at 06:21
  • how do i do this renaming from caps to lowercase for bulk of images? – Mohak Londhe Dec 28 '19 at 13:47
  • @MohakLondhe Pending `--pathspec-from-file` (which is slowly added to some commands with Git 2.25, but not `git mv` yet: https://stackoverflow.com/a/59505896/6309), you would need to script it, as in here: https://stackoverflow.com/a/15747640/6309 – VonC Dec 28 '19 at 21:36
  • 10
    Got this to work on windows by running this command and `git config core.ignorecase false` – John Targaryen May 05 '20 at 11:13
  • @DeepakGautam Strange. You could ask a separate question with some details illustrating your use case. – VonC Jan 17 '21 at 22:28
  • In my case, my repo's local git config had core.ignorecase set to true (I don't know why). So changing the setting to true for the global git config (by running `git config --global core.ignorecase false`) wasn't enough for me, since my repo's local setting overrode the global setting. So then I changed the local setting as well (by running `git config --local core.ignorecase false`) and that worked. – jaquinocode Dec 30 '21 at 18:28
  • 1
    @jaquinocode Good point. I have included your comment in the answer for more visibility. – VonC Dec 30 '21 at 19:36
498

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

 git mv --force myfile MyFile
Peter Mortensen
  • 30,030
  • 21
  • 100
  • 124
Marcello de Sales
  • 19,543
  • 14
  • 70
  • 75
  • 3
    If you are on a case insensitive file system and you get a fatal error "Invalid Argument" try these steps instead: http://stackoverflow.com/questions/3011625/git-mv-and-only-change-case-of-directory – Levi Dec 01 '13 at 19:10
  • 4
    While this is the correct answer for the first step, how to you then proceed to switch to another branch under Mac OS X when the other branch has the old capitalization. I get **** error: The following untracked working tree files would be overwritten by checkout: **** – TJChambers Jan 17 '14 at 02:06
  • 2
    This failed on commit for me on Windows: `Error: Will not add file alias 'MyFile' ('myfile' already exists in index)` – OrangeDog Feb 02 '16 at 11:57
142

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

  1. Move all affected files outside of the directory to, let’s say, the desktop.
  2. Do a git add . -A to stage the removal of those 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.

waldyrious
  • 3,353
  • 4
  • 32
  • 38
MrHus
  • 31,680
  • 6
  • 30
  • 31
  • 3
    This comes at the expense of all history in the files you move in and out, right? I'm guessing the git mv --force doesn't have this shortcoming. – LOAS Jan 04 '18 at 09:21
  • 20
    No, this would not remove all of the history. Notice that there is no commit between the two adds. – Michael L Perry Jan 24 '19 at 22:15
  • this is really what I needed. well done. it should be an answer as well. thank you! – Mehmet Kurtipek Jun 22 '20 at 21:35
  • See also @softarn's [answer](https://stackoverflow.com/a/40990382/266309), which offers a convenient one-liner to do this all at once :) – waldyrious Sep 27 '21 at 10:00
71

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.

Peter Mortensen
  • 30,030
  • 21
  • 100
  • 124
larsks
  • 228,688
  • 37
  • 348
  • 338
  • 2
    You can also `git clone` the repo on a Linux system, rename the files and commit them just for this situation (if you have a Linux system at hand). – gitaarik Feb 07 '14 at 12:48
  • 4
    Actually, filesystems on OS X can be case-sensitive, you can configure it on installation. [How to check if an OS X partition is case-sensitive](http://apple.stackexchange.com/q/71357/122223) – Flimm May 05 '15 at 17:19
  • 2
    ...hence the "(by default)" in the answer. – larsks Aug 18 '17 at 16:45
  • 8
    To confirm, you can use `git rm --cached fileorfolder` to remove the file or folder from git without removing the file or folder from the file system. Then you can simply add the file or folder again with `git add fileorfolder`. – kas May 01 '18 at 18:32
46

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.

Dave Everitt
  • 16,100
  • 6
  • 64
  • 93
Segmented
  • 1,814
  • 2
  • 21
  • 39
  • 7
    And if `git config --global --get core.ignorecase` doesn't return anything. Is it `true`?? because after I set it to `false` it returns false (Windows 10) – fralbo Jan 07 '17 at 10:47
  • 1
    And it seems not working as expected. I mean the desktop client see the change but after commit/sync, the filename remains unchanged online ! – fralbo Jan 07 '17 at 12:33
  • Worked for me (and better for multiple files than using `git mv`). I'm also assuming that by default it is considered true (i.e. it is ignoring case). Either that, or it matches the OS's policy to file name casing. – Jerry Dec 02 '19 at 10:10
  • THAT is THE answer. Just used it. – Dave Everitt Apr 17 '20 at 15:52
  • 1
    This should be the selected answer – Dave Everitt Apr 17 '20 at 16:00
  • 2
    Changing the global setting may not work because the local setting is overriding it. If it is not working for you check both. – Xcalibur Nov 06 '20 at 03:04
10

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

Peter Mortensen
  • 30,030
  • 21
  • 100
  • 124
  • 4
    seems that it should be changed to false such that git would be case-sensitive? – Jonathan Jun 09 '20 at 08:02
  • Yep, exactly. I personally have when git invokes a `smart` behavior and attempt to convert line endings of my files. A shitty `smart` feature that I currently detest very much, as I mainly code under Windows for Linux machines so I say `checkout as is, commit as is`. – Деян Добромиров Apr 03 '21 at 11:51
6

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.

softarn
  • 4,943
  • 3
  • 36
  • 53
5

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
Louis Caron
  • 661
  • 7
  • 15
1

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)
Peter Mortensen
  • 30,030
  • 21
  • 100
  • 124
blented
  • 2,433
  • 2
  • 21
  • 17
1

Working example:

git mv ./src/images/poster_video.PNG ./src/images/poster_video.png
Peter Mortensen
  • 30,030
  • 21
  • 100
  • 124
lucho20pt
  • 47
  • 5
  • 2
    Your answer does not solve the original question. You are lowcasing the extension – Tavo Nov 26 '19 at 10:38
  • 1
    I am looking exactly this, but for 500 images. i want to rename ./src/images/TESTIMAGE.png to ./src/images/testimage.png on git – Mohak Londhe Dec 28 '19 at 13:43
0

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

Ogglas
  • 50,115
  • 30
  • 272
  • 333