こんにちは、RITエンジニアの三浦です。
Gitでディレクトリの大文字小文字の変更を反映するのに苦戦したので、解決方法を記します。
原因
Macのファイルシステムがディレクトリの大文字小文字をデフォルトで区別しておらず、Gitの大文字小文字変更検知がこれに依存しているのが原因みたいです。 masyus.work
解決策
以下流れでディレクトリの大文字小文字変更をnew fileではなく、renameとしてGitに認識させる必要があります。
- gitconfigでファイルの大文字小文字を区別するように設定を変更する
- 差分がrenameとなっていることを確認する
- commitする
具体的に見ていきます。
配下に2つのファイルを持つ小文字sampleディレクトリを大文字Sampleディレクトリに変更します。
sampleディレクトリ内に2つのファイルを作成してcommitしました。 この時点では、Gitにはファイルが正しく認識されています。
$ git ls-files sample/test1.tsx sample/test2.tsx
Gitはデフォルトの大文字小文字を区別していない状態です。
$ git config core.ignorecase
true
このとき、ディレクトリsampleをSampleに変更しても差分が認識されません。
$ mv sample/ Sample/ $ git status On branch master nothing to commit, working tree clean
理由は、Gitがデフォルトで大文字小文字を検知しない設定になっているためです。
$ git config core.ignorecase
true
Gitが大文字小文字を検知するよう変更します。
$ git config core.ignorecase false $ git config core.ignorecase false
差分(Sample/)が検知されるようになりました。
$ git status On branch master Untracked files: (use "git add <file>..." to include in what will be committed) Sample/
これをインデックスに追加します。 しかしこれでは、ディレクトリを大文字に変更しただけなのに、ファイルの新規作成としてGitに認識されてしまっています。
$ git add . $ git status On branch master Changes to be committed: (use "git restore --staged <file>..." to unstage) new file: Sample/test1.tsx new file: Sample/test2.tsx nothing added to commit but untracked files present (use "git add" to track)
インデックスされているファイルを見てみます。
$ git ls-files Sample/test1.tsx Sample/test2.tsx sample/test1.tsx sample/test2.tsx
このままcommitすると同じファイルが2つずつできてしまうのがわかります。
方法①:renameで認識させたところだけをcommitする
git rm コマンドでインデックス上から不要なファイルを削除します。
$ git rm sample/test1.tsx rm 'sample/test1.tsx' $ git rm sample/test2.tsx rm 'sample/test2.tsx'
インデックス上から削除されたことを確認します。
$ git ls-files Sample/test1.tsx Sample/test2.tsx
このとき、git status
で初めてフォルダの変更がnew file
ではなくrename
として認識されます。
$ git status On branch master Changes to be committed: (use "git restore --staged <file>..." to unstage) renamed: sample/test1.tsx -> Sample/test1.tsx renamed: sample/test2.tsx -> Sample/test2.tsx Changes not staged for commit: (use "git add/rm <file>..." to update what will be committed) (use "git restore <file>..." to discard changes in working directory) deleted: Sample/test1.tsx deleted: Sample/test2.tsx
最後にワーキングツリーの変更(deletedの2ファイル)はリセットしておきます。
$ git checkout .
Updated 2 paths from the index
これをcommitすることで、Github上で正しくディレクトリ名がリネームされていることが確認できました!
方法②:一度全く別のディレクトリ名に変更する
ディレクトリ名を一旦別の名前(_sample)に変更します。
$ mv sample/ _sample/ $ git add . $ git ls-files _sample/test1.tsx _sample/test2.tsx $ git status On branch master Changes to be committed: (use "git restore --staged <file>..." to unstage) renamed: sample/test1.tsx -> _sample/test1.tsx renamed: sample/test2.tsx -> _sample/test2.tsx
別の名前(_sample)から本来変更したかった名前(Sample)に変更します。
$ mv _sample/ Sample/ $ git add . $ git ls-files Sample/test1.tsx Sample/test2.tsx $ git status On branch master Changes to be committed: (use "git restore --staged <file>..." to unstage) renamed: sample/test1.tsx -> Sample/test1.tsx renamed: sample/test2.tsx -> Sample/test2.tsx
これをcommitすれば完了です!
まとめ
今後、ディレクトリの大文字小文字を変更するときは、git ls-files
でGitのインデックス上で正しくrenameとして認識されているかどうか常に確認するよう気をつけます。
また、チームで作業している場合に、別の人がこの変更をpullしたときも同様に大文字小文字が正しく変更されないので、事前に前述の手順でインデックス内のディレクトリの大文字小文字を変更しておく必要があります。
同じような事象で詰まっている方の助けになれば幸いです。