303

While I found similar question I didn't find an answer to my problem

When I try to rename the directory from FOO to foo via git mv FOO foo I get

fatal: renaming 'FOO' failed: Invalid argument

OK. So I try git mv FOO foo2 && git mv foo2 foo

But when I try to commit via git commit . I get

# On branch master
# Untracked files:
#   (use "git add <file>..." to include in what will be committed)
#
# foo
nothing added to commit but untracked files present (use "git add" to track)

When I add the directory via git add foo nothing changes and git commit . gives me the same message again.

What am I doing wrong? I thought I'm using a case-sensitive system (OSX) why can't I simply rename the directory?

Community
  • 1
  • 1
oschrenk
  • 4,080
  • 4
  • 22
  • 25
  • 12
    OS X's file system isn't case-sensitive. – mipadi Jun 10 '10 at 04:47
  • 2
    @mipadi It can operate in case-sensitive mode but that's usually off by default. – GordonM Jun 15 '12 at 12:07
  • 1
    This question & its answers are useful in Windows, too. Consider untagging "osx" – Barett Jan 21 '15 at 21:50
  • 1
    See http://stackoverflow.com/a/24979063/6309: since git 2.0.1, a simple `git mv` works. – VonC Mar 27 '15 at 06:45
  • On windows youo can use the regular `git mv foo Foo` if you use a cygwin shell. – Andrew Scott Jun 24 '17 at 09:51
  • A couple of days ago I reported the "Invalid argument" error mentioned here to the Git mailing list as a bug, which it seems nobody ever did previously over the 11 years and 86000 views since this question was opened. Here's the thread: https://lore.kernel.org/git/CAD8jeghpOQoibk0xM0QgLsOwLNw9GdM=4rhYuzV-NSkw8LinMQ@mail.gmail.com/. Maybe this will be fixed in a new release in the near future. – Mark Amery May 05 '21 at 16:22

12 Answers12

471

You are in a case insensitive environment. Further, adding without the -A will not take care of the remove side of the mv as Git understands it. Warning! Ensure that no other changes or untracked files are around when you do this or they will get committed as part of this change! git stash -u first, do this and then git stash pop after. Continuing: To get around this, do the following:

mv foo foo2
git add -A
git commit -m "renaming"
mv foo2 FOO
git add -A
git commit --amend -m "renamed foo to FOO"

That's the drawn out way of changing the working directory, committing and then collapsing the 2 commits. You can just move the file in the index, but to someone that is new to git, it may not be explicit enough as to what is happening. The shorter version is

git mv foo foo2
git mv foo2 FOO
git commit -m "changed case of dir"

As suggested in one of the comments, you can also do an interactive rebase (git rebase -i HEAD~5 if the wrong case was introduced 5 commits ago) to fix the case there and not have the wrong case appear anywhere in the history at all. You have to be careful if you do this as the commit hashes from then on will be different and others will have to rebase or re-merge their work with that recent past of the branch.

This is related to correcting the name of a file: Is git not case sensitive?

Liran H
  • 9,143
  • 7
  • 39
  • 52
Adam Dymitruk
  • 124,556
  • 26
  • 146
  • 141
  • 1
    Thanks. This was driving me crazy. I didn't know about the -A or the --amend option. – oschrenk Jun 10 '10 at 05:18
  • 7
    Careful with the -A, since it will recursively add all content in your current directory, including untracked stuff. Might be better to just `git add foo2`. – rich.e Dec 22 '12 at 04:00
  • 2
    That is correct. However you will need to stage both the removal of foo2 as well as the addition of FOO separately. `-A` takes care of both. Vice versa for the first step. I'll add the warning. Thanks! – Adam Dymitruk Dec 23 '12 at 20:00
  • You can also clean up your history with an interactive rebase `git rebase -i HEAD~2`. Note: To simplify this, set the final message in your first commit and fixup the second one. – Alex B. Aug 21 '13 at 12:47
  • First method works great in Windows (second one doesn't) – Jaime Hablutzel Aug 08 '14 at 10:00
  • Tested the shorter version works on OSX, git version 2.3.2 (Apple Git-55), and also on Windows git version 1.8.3.msysgit.0. (with git's default config core.ignorecase = true) – Johnny Wong Apr 21 '15 at 03:36
  • This is an overkill when there's `git mv -f`. – Nick Volynkin Jun 11 '15 at 17:14
  • 5
    I had success with git mv foo foo2; git mv foo2 FOO; git commit – Chris Jul 02 '15 at 19:04
  • This fails after you quit Xcode and relaunch your project. Tested in Xcode 6.3 – Alex Zavatone Jul 07 '15 at 16:04
  • it's 2022, I still had to go for renaming solution `git mv foo foo2; git mv foo2 FOO; git commit` as suggested. Thought things would have change to detect case sensitvity. – JavaQuest Aug 22 '22 at 17:47
164

You want to set the option core.ignorecase to false, which will make Git pay attention to case on file systems that don't natively support it. To enable in your repo:

$ git config core.ignorecase false

Then you can rename the file with git mv and it'll work as expected.

mipadi
  • 398,885
  • 90
  • 523
  • 479
  • 2
    I think this may have undesirable effects elsewhere. Case insensitive systems should let Git think that it's the same dir. – Adam Dymitruk Jun 10 '10 at 05:00
  • 2
    I added the option to my global config but it didn't help – oschrenk Jun 10 '10 at 05:20
  • 3
    I see some weird behavior using this with OSX. hrm `I modified a file that doesn't exist` .. hrm `error: The following untracked working tree files would be overwritten by checkout:` but ... those files don't exist. – Skylar Saveland Aug 26 '11 at 15:04
  • This was exactly what I was looking for. I am running CentOS 5.6 and it did not pick up the change of case. – crmpicco Apr 10 '14 at 08:31
  • Ya the marked correct answer didn't work AT ALL for me on OS X due to case-insensitive directories. Not sure if this answer will solve it or not though. – Joshua F. Rountree May 16 '14 at 15:53
  • Mine still says invalid argument even after setting this config. – Joshua F. Rountree May 16 '14 at 16:02
  • Our dev machines are OSX, but the code runs in a VM under CentOS. This saved me so many headaches. – orca Mar 13 '15 at 22:05
  • 5
    This doesn't work! On Git 1.8.3, Git will treat the renamed file as a new file, instead of removed + added. Committing such will leave the repository with two same file, e.g. foo and FOO both exist! But when checkout only one file appear (but one case may dominate over the other case) – Johnny Wong Apr 21 '15 at 03:44
  • `git mv -f` is a better option to avoid dealing with the hassle of leftover files. – Ben Creasy Sep 23 '16 at 16:56
96

I was able to resolve this, using git 1.7.7 by using a temporary filename:

$ git mv improper_Case improve_case2
$ git mv improve_case2 improve_case
$ git commit -m "<your message>"
CodeCaster
  • 147,647
  • 23
  • 218
  • 272
mgadda
  • 1,429
  • 12
  • 13
21

(git mv-free variant.)

I ran into this problem in Git on Mac OS X 10.9. I solved it as follows:

git rm -r --cached /path/to/directory

That stages the directory for deletion in Git but does not actually remove any physical files (--cached). This also makes the directory, now with the proper case, show up in untracked files.

So you can do this:

mv /path/to/directory /path/to/DIRECTORY
git add -A /path/to/DIRECTORY

Git will then recognize that you have renamed the files, and when you do git status you should see a number of renamed: lines. Inspect them and ensure they look correct, and if so, you can commit the changes normally.

wizonesolutions
  • 577
  • 3
  • 15
  • I found that the `mv` command didn't work to actually rename the directory; I had to rename it within Finder. Other than that this fix works perfectly. – Adam S Sep 12 '14 at 13:40
  • Worked perfectly as described for me, thank you! – Liran H Aug 27 '21 at 14:25
  • And if you're doing something in a case-insensitive OS like Windows (which is what I am doing), you can rename the folder to something completely different before renaming it to the correct case (otherwise Windows will ignore the rename). Worked like a charm for me. – Mike Loux May 25 '23 at 13:50
12

This is a quick and bug-safe solution:

git mv -f path/to/foo/* path/to/FOO/

Warning! Always rename all files in the renamed folder (use /*).

Do not rename single files. This leads to a bug, described in this answer.

If you first want to see the outcome first, use -n:

git mv -f -n path/to/foo/* path/to/FOO/

After you've made an mv:

  1. Commit changes
  2. Checkout to any other revision
  3. Checkout back.

Now Git should have renamed the folder BOTH in its internal files and in file system.

Community
  • 1
  • 1
Nick Volynkin
  • 14,023
  • 6
  • 43
  • 67
  • Is this only for Git 2.0.1 as I mentioned in the question comments above? (referring to http://stackoverflow.com/a/24979063/6309) – VonC Jun 11 '15 at 19:29
9

Force it with -f option:

git mv -f FOO foo
konyak
  • 10,818
  • 4
  • 59
  • 65
  • Not work for me. My setting is .git/config's "ignorecase = true". The rename cannot be staged in staging area by this way. (Git version 1.8.3.msysgit.0) Adam Dymitruk's solution is the only right answer. – Johnny Wong Apr 21 '15 at 03:31
  • @JohnnyWong change your setting to `false`, it worked for me – Inder Kumar Rathore Oct 30 '15 at 10:42
  • Will this then update on all other user's computers if they pull, even if their computer is set to ignore case? – Bryce Dec 21 '16 at 15:53
  • @Bryce No, you will need to commit the changes and push them to the central repo before other users can pull the changes. – konyak Dec 21 '16 at 20:18
5

I had one related issue.

One folder named 'Pro' (created first) and another 'pro' (created by mistake). In Mac, it is the same thing, but different according to git.

$ git config core.ignorecase false

the git config rename the files to the right folder(thanks), and also created ghost files in 'pro' (No!!). I could not add ghost file changes to the track and I could not checkout other branches unless carry those those files with me, and i also could not reset it somehow.

Instead of that, i did

$ git rm -r --cached pro
$ git status // => pro files removed, new Pro files untracked
$ git add Pro

To make it extra safe, i did it in a separated fix branch, and then i merged back to main branch

For the ghost file issue created by , can any guru explain How and Why? Thanks in advance.

Seeliang
  • 2,321
  • 1
  • 13
  • 18
2

This worked great for me on Windows. Used powershell with the following:

  1. mv .\Folder-With-Wrong-Casing .\temp
  2. git add -A
  3. git commit -m "renamed folder with wrong casing to temp"
  4. mv .\temp .\Folder-with-Correct-Casing
  5. git add -A
  6. git commit --amend -m "Renamed to proper casing"
  7. (optional) git push

Thanks to Adam's answer above.

Tony
  • 329
  • 3
  • 2
1

Improving Adam Dymitruk's answer (silly that SO doesn't let me comment his answer), using "git mv" will automatically stage exactly the moved files. No stashing is needed and the risky "git add -A" can be avoided:

old="abc";    new="ABC";
tmp="$old-renamed";
git mv "$old" "$tmp";
git commit -m "Renamed '$old' to '$tmp'.";
git mv "$tmp" "$new";
git commit --amend -m "Renamed '$old' to '$new'.";
Rainer Blome
  • 561
  • 5
  • 15
1

Here's a really simple solution around all the gitfoo on this page.

  1. Copy the files out of your project manually.
  2. git rm all the files.
  3. git commit like normal.
  4. add the files back manually.
  5. git add all the files.
  6. git commit like normal.
  7. profit.
Askdesigners
  • 419
  • 5
  • 15
  • 1
    This works locally, but if someone else does a pull it won't change their case. – Jason Oct 13 '15 at 20:34
  • Thanks for this in helping me fix the double entries in git with different cases. I used a variant of this. Just renamed the parent folder. Did a commit. Then renamed parent folder back to original. And did a second commit. Now the older entries with the different case are gone. – dreamerkumar Apr 12 '17 at 18:49
1

You're not using a case-sensitive filesystem in OS X unless you explicitly choose such. HFS+ can be case-sensitive, but the default is case-insensitive.

Nicholas Knight
  • 15,774
  • 5
  • 45
  • 57
  • 6
    Using the case-sensitive file system on OS X is not a good idea. A lot of apps do NOT work correctly, I learned from trying this. One particular problem is that Adobe Photoshop will refuse to install saying that case-sensitive file system is not supported. – jpswain Sep 09 '11 at 17:01
1

Here is a simple way of doing it.

  1. Make sure your working directory is empty.

  2. Temporarily disable git ignore case

git config core.ignorecase false
  1. Rename any directories (e.g. Folder => folder)
  2. Add changes to working directory
git add --all
  1. Stash your changes.
git stash
  1. The original directories should be now deleted. Make a local commit.
git add --all
git commit -m "Rename directories"
  1. Pop changes
git stash pop
  1. Amend this to your previous commit.
git add --all
git commit --amend
  1. You should now have a commit with directories renamed. You may now restore the original ignorecase config:
git config core.ignorecase true
nomadoda
  • 4,561
  • 3
  • 30
  • 45