269

There are a couple of files in our git-controlled codebase that I'd like to rename. Specifically, I just want to change the case of the file, so that sourceCode.java becomes SourceCode.java, for example. The catch: I'm on a Windows box, and the filesystem thinks those are the same file name.

How can I get Windows and Git to recognize that change and check it in? The change of the file name should not be ignored, but committed to git.

Martin Nyolt
  • 4,463
  • 3
  • 28
  • 36
Electrons_Ahoy
  • 36,743
  • 36
  • 104
  • 127
  • 6
    Since Git 2.0.1+ (June 2014), a simple `git mv` should work (http://stackoverflow.com/a/24979063/6309). Even on Windows. – VonC Apr 19 '15 at 09:58
  • They're really two different questions, so I'm not sure why someone put the link to the other question. That question is about how to ignore case changes, it happens to have an answer that is the same as the one here. In any case VonC's comment is probably the latest and best answer to this, though I haven't tried it. And this probably should be linked to that question and not the one it currently is. – David Bradley Apr 30 '23 at 20:39

6 Answers6

425

To rename the file you can use the standard git mv command. Since Windows treats files with only changes in case as identical, you have to pass the -f option to force a rename:

git mv -f name.java Name.java

If instead you want to ignore case changes, have a look at the question How to make git ignore changes in case?.

Martin Nyolt
  • 4,463
  • 3
  • 28
  • 36
Igor Zevaka
  • 74,528
  • 26
  • 112
  • 128
  • 9
    As an aside this doesn't work on a FAT filesystem. I carry some project code around on a thumb drive and case changes are a real pain. – asm Nov 26 '09 at 17:53
  • 2
    This did not work for me on NTFS system and Windows 10 – Roboblob Mar 07 '18 at 08:23
  • 5
    This is surely the correct way to do it but, if you need to rename a lot of files, it may be tedious. If you've already got them renamed in the filesystem somehow and you just want to commit those changes, you can rename some parent folder, do a `git add` of that newly renamed folder, DO NOT COMMIT, change the folder name back to what it should be, `git add` it again and then commit. – Okonomiyaki3000 May 01 '18 at 01:53
  • 1
    Works on NTFS and Windows 7. – Hans Goldman May 23 '18 at 06:00
  • Is it possible to do this in bulk? e.g. with powershell, `Get-ChildItem '.' | Rename-Item {$_.Name.ToLowerCase()}` – killjoy Nov 04 '18 at 01:23
  • If you have to do bulk renaming, just use the solution with git rm cached and git add, which I describe in my answer. – Nils-o-mat Mar 24 '23 at 16:12
59

If you are on a FAT file system your only choice is to do a two stage rename:

  1. Rename sourceCode.java to anything.you.like
  2. Rename anything.you.like to SourceCode.java

Back in the days when we used Perforce we had exactly this problem and this was the only solution we could come up with.

ChrisF
  • 134,786
  • 31
  • 255
  • 325
  • 21
    Just a note for others: It is not necessary to commit in-between, but it is necessary to add to index for git to notice change – arberg Apr 04 '16 at 12:34
36

The following steps allowed me to change the case on Windows:

  • Add ignorecase = false to [core] in .git/config;
  • Move the files you are going to rename out of your project directory;
  • Add the deletes to the index;
  • Move all files back to their original location and change the case of the files and/or directories;
  • Add all "new" files to the index;
  • Remove ignorecase = false added at the first step.

This way you have a single commit that contains the rename and it makes it easy to change e.g. an entire directory.

Pieter van Ginkel
  • 29,160
  • 8
  • 71
  • 111
  • 5
    Do it for bath global and local settings: $ gti config --global core.ignorecase false $ gti config core.ignorecase false – Roman Ivanov Oct 24 '12 at 21:58
  • To make it work for required repo if any specific value already set previously ( could be skipped if you know that no special settings were done), and globally to make it as rule for new repositories. – Roman Ivanov Oct 08 '20 at 02:53
25

In my opinion one simple way is missing. You can do this for a single file, a specific directory or even the whole repository. Just rename your files in any way you like before and than execute these commands:

git rm --cached <file name or directory>
git add <file name or directory>

If you want to affect also the sub-directories, you have to use the -r flag:

git rm -r --cached <directory>
git add <directory>
Nils-o-mat
  • 1,132
  • 17
  • 31
  • 3
    Truly the simplest one. – ranu Jun 02 '20 at 05:08
  • This loses the entire history of the file, as it's set by git as a completely new one. – Alejandro Jun 03 '20 at 16:12
  • 4
    @Alejandro What you say is wrong. I just tested it and git recognized the renaming without any problems. As in other cases the file is shown as removed / new in the index, but while committing, git notices, that it has just been renamed. – Nils-o-mat Jun 04 '20 at 10:02
  • In my scenario, the case of the filename was changed on a Linux machine and my Windows git could not handle it. A "git add" of the windows directory caused both filename variants to appear in the git index. After that, I had to remove both variants from my windows git cache and then add the one I wanted to keep. E.g. "git rm --cached abc.js Abc.js; git add Abc.js". – Matt Muggeridge Jul 22 '21 at 01:23
7

Be careful. Doing this can lead to changes that are impossible to merge. Git gets confused when merging on Windows because it can't decide whether the old Uppercase name and the new lowercase name are the same file or not (for Git they are not, but for the filesystem they are). To merge you have to do some manual workaround like deleting the files before merging.

See Git rebase issue with files of same name but different case

I'm not sure if this issue is worse than having an unconventionally-named file in your project for ever and ever, but it is worth knowing about if there are lots of users with lots of branches which will all need to be merged eventually.

Community
  • 1
  • 1
jwg
  • 5,547
  • 3
  • 43
  • 57
  • Unconventionally named files in medium to large projects should always be avoided if possible due to causing problems when developing for multiple platforms (delaying on fixing something like that until later will make the problems from the fix more severe). Sometimes you're developing on windows, but also need to do a linux build, and an include that would work fine on windows causes the build to break on linux. – Griffork Nov 12 '19 at 07:46
1

With NTFS (or FAT), a single git mv command does not solve the problem. This question shows a technique that works: git mv and only change case of directory

James Skemp
  • 8,018
  • 9
  • 64
  • 107
Rainer Blome
  • 561
  • 5
  • 15