【Git】ファイル名の大文字小文字を変更する
概要
Gitは、デフォルトではファイル名の変更に関して、大文字⇔小文字の変更を検知しません。(ファイル名としては大文字と小文字は区別され、どちらも存在することが可能)
そのため、手元の環境でディレクトリ名を大文字から小文字に変更した場合、そのままだとリポジトリに変更が反映されません。
環境
$ git --version
git version 2.37.1 (Apple Git-137.1)
対処法
git rm --cached
を使う(おすすめ)
方法1:名前を変更した後に、古いファイル名をgit rm --cached
として削除し、再度ステージしてコミットすると変更が認識されます。
$ mv Hoge.txt hoge.txt
$ git rm --cached Hoge.txt
$ git add hoge.txt
$ git commit -m "[rename] Hoge.txt -> hoge.txt"
ディレクトリ名の場合は
$ mv Hoge/ hoge/
$ git rm -rf --cached Hoge/
$ git add .
$ git commit -m "[rename] Hoge -> hoge"
git config --local core.ignorecase false
を使う(注意が必要)
方法2:ファイル名の大文字小文字の変更を無視する設定をfalse
にします。すべてのプロジェクトで区別したい場合は以下のようにglobalで設定してしまっても良いでしょう。
注意点として、core.ignorecase false
を設定する場合でも、旧ファイル名のキャッシュの削除が必要です。(理由は後述)
設定
$ git config --local core.ignorecase false
操作
$ mv Hoge.txt hoge.txt
$ git rm --cached Hoge.txt
$ git add hoge.txt
$ git commit -m "[rename] Hoge.txt -> hoge.txt"
実験
実際に、Git管理下でファイル名を変更して検証してみましょう。
$ mkdir test && cd test
$ git init
$ touch Hoge.txt
$ git add . && git commit -m "Hoge.txtを追加"
$ git ls-files
Hoge.txt
Gitで監視しているファイルはHoge.txtであることが確認できます。
さて、ファイル名を変更してみましょう。
$ mv Hoge.txt hoge.txt
$ ls
hoge.txt
$ git status
On branch main
nothing to commit, working tree clean
$ git ls-files
Hoge.txt
lsではhoge.txtが存在していることになっているのですが、gitではHoge.txtが存在していることになっています。(変更が検知されていない)
そこで、以下のように元のファイルのGit管理を削除します。
$ git rm --cached Hoge.txt
rm 'Hoge.txt'
$ git status
On branch main
Changes to be committed:
(use "git restore --staged <file>..." to unstage)
deleted: Hoge.txt
Untracked files:
(use "git add <file>..." to include in what will be committed)
hoge.txt
--cached
をつけないと、hoge.txtが削除されます。これは、Gitはhoge.txtはHoge.txtだと思っているためです。
$ git add hoge.txt
$ git status
On branch main
Changes to be committed:
(use "git restore --staged <file>..." to unstage)
renamed: Hoge.txt -> hoge.txt
$ git commit -m "[rename] Hoge.txt -> hoge.txt"
すると、Git管理されているファイル名と実際のファイル名が一致します。
$ git ls-files
hoge.txt
これで、ファイル名の変更が完了です。
core.ignorecase false
を使う場合
以下のように設定します
$ git config --local core.ignorecase false
ファイルを作成しコミットします
$ touch Hoge.txt
$ git add .
$ git commit -m "[add] Hoge.txt"
[main ea4f41b] [add] Hoge.txt
1 file changed, 0 insertions(+), 0 deletions(-)
create mode 100644 Hoge.txt
名前を変更してみます
$ mv Hoge.txt hoge.txt
すると、Gitはファイルの追加として検知します
$ git status
On branch main
Untracked files:
(use "git add <file>..." to include in what will be committed)
hoge.txt
nothing added to commit but untracked files present (use "git add" to track)
コミットしてみます
$ git add .
$ git commit -m "[rename] Hoge.txt -> hoge.txt
すると、GitとしてはHoge.txtも残っていることになっています。
$ git status
On branch main
nothing to commit, working tree clean
$ git ls-files
Hoge.txt
hoge.txt
このままリモートリポジトリなどにプッシュしてしまうと、二つのファイルが存在する状態が反映されてしまいます。
そのためcore.ignorecase false
を設定する場合でも、旧ファイル名のキャッシュの削除が必要です。
$ git rm --cached Hoge.txt
rm 'Hoge.txt'
$ git ls-files
hoge.txt
結論
どちらの方法でも、キャッシュを削除しないといけないことには変わりないので、個人的には方法1がおすすめです!
Discussion