2013年以前からの古いリポジトリにMacで作った日本語ファイルが含まれていると、clone/checkoutしたときにファイルのstatusが変な状態になってしまいました。
% git clone oldman oldman2 # <- 古いリポジトリをclone
Cloning into 'oldman2'...
done.
% cd oldman2 # <- 新しいリポジトリに入る
% git status # <- statusを見ると、cloneしたばっかりなのにコミットされていないファイルがあるとか
On branch master
Your branch is up-to-date with 'origin/master'.
Untracked files:
(use "git add <file>..." to include in what will be committed)
ほげ.txt
nothing added to commit but untracked files present (use "git add" to track)
% git ls-files # <- そのファイルはリポジトリ内のファイルなんだけど、、、??
ほげ.txt
%
原因は、utf-8-macのファイル名でコミットされたファイルがあると、現在のデフォルトであるcore.precomposeunicode=trueの状態では比較が取れないことのようです。
core.precomposeunicodeはファイル名の文字コード問題を解決するためのオプションですが、1.7.12で導入され、1.8.5でデフォルトtrueになったようなので、それ以前からあるリポジトリを現在の環境に持ってくると問題が起きる場合があるようです。
対処
対処1.core.precomposeunicode=falseにする
新しくコミットすることは無かったり、今だけなんとかなればよいのであれば、現状の設定を変更することで問題は見えなくなります。
% git config core.precomposeunicode false
% git status
On branch master
Your branch is up-to-date with 'origin/master'.
nothing to commit, working directory clean
%
対処2.文字コードを変更する
今後も更新の予定があったり、別の人もcloneする可能性がある場合は文字コードを変更してコミットしておいた方がよいでしょう。
- core.precomposeunicodeをfalseにして対象ファイルを一旦削除(git remove)して、
- core.precomposeunicodeをtrueにして対象ファイルを追加(git add)する。
- 変更をコミットする
% git rm ほけ<3099>.txt # 対象ファイルを削除する
rm 'ほげ.txt'
% git status
On branch master
Your branch is up-to-date with 'origin/master'.
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
deleted: ほげ.txt
% cp ../oldman/ほけ<3099>.txt ./ # 同じファイルを持ってくる
% git config --unset core.precomposeunicode # core.precomposeunicodeをデフォルト(=true)に戻す
% git add ほげ.txt # ファイルをindexに追加
% git status # statusを確認すると、リネームとして認識してくれている
On branch master
Your branch is up-to-date with 'origin/master'.
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
renamed: ほげ.txt -> ほげ.txt
% git commit -m "convert filename (utf-8-mac -> utf8(NFC))" # 変更をコミット
[master 8b77f78] convert filename (utf-8-mac -> utf8(NFC))
1 file changed, 0 insertions(+), 0 deletions(-)
rename ほげ.txt => ほげ.txt (100%)
% git status # statusを確認
On branch master
Your branch is ahead of 'origin/master' by 1 commit.
(use "git push" to publish your local commits)
nothing to commit, working directory clean
注意点
このような文字コードの変更コミットをmerge/pullしようとするとエラーになってしまう場合があります。
ローカルリポジトリへは次のような方法で反映することができます。
方法1
- 対象ファイルを作業コピーから一旦削除してから、merge/pullを実行
方法2
- ローカルのブランチを一旦破棄して、変換後のブランチを新たにチェックアウトしなおす。
複数人で開発している場合は、ほかのメンバーにこのような作業をお願いする可能性があるため、事前にタイミングを相談しておくとよいでしょう。
疑問点
- Mac以外のプラットフォームではどのように見えているのか
ご存知の方が居ましたら教えてください。