2017-10-20

tobijibu

gitのパーミッション変更によるマージエラーに困惑する

思い出した時にしかやらないのですが、久しぶりにVimのプラグインをアップデートしました。 すると、あるプラグインのアップデートでエラーが発生しました。 エラーの内容から、gitのエラーであることが分かり、どうやらmergeで失敗していたようです。

しかし、心辺りがありません。 Vimのプラグインは全てPlugで管理していて、プラグインを書き換えるといったことはしていないからです。 とはいえ、書き換えたことを忘れている可能性もあるので、該当のプラグインを見てみました。

まずはエラーの確認です。 Plug内でのgit pullでエラーになっていたようなので、同じようにgit pullしてみます。

$ git pull
Updating c3dd9e4..660ec91
error: Your local changes to the following files would be overwritten by merge:
        plugin/matchit.vim
Please commit your changes or stash them before you merge.
Aborting

Plugと全く同じエラーが出ました。予想通りmergeに失敗していたことが分かりました。

次に変更箇所を確認です。変更していないつもりで、実は変更していたという可能性もあるので。

$ git status
On branch master
Your branch is behind 'origin/master' by 2 commits, and can be fast-forwarded.
  (use "git pull" to update your local branch)

Changes not staged for commit:
  (use "git add ..." to update what will be committed)
  (use "git checkout -- ..." to discard changes in working directory)

        modified:   .gitignore
        modified:   plugin/matchit.vim

no changes added to commit (use "git add" and/or "git commit -a")

2ファイルありました。気になるのは.gitignoreです。 このファイルは変更しないでしょう。

変更したmergeが必要な箇所を特定するためにgit mergetoolを使います。 その前に、git mergetoolを使う場合は、あらかじめmerge.toolを指定しておく必要があります。

私の場合はvimdiffを他のリポジトリでも使いたいので、 --globalオプションの指定と、ツールにvimdiffを指定しました。

$ git config --global merge.tool vimdiff

mergetoolを起動します。

$ git mergetool
No files need merging

mergeは必要無いそうです。念のためgit difftoolでも見ましたが、差分がありませんでした。

テキスト以外の差分は何だろう?と思い、git diffを試します。

$ git diff
diff --git a/.gitignore b/.gitignore
old mode 100755
new mode 100644
diff --git a/plugin/matchit.vim b/plugin/matchit.vim
old mode 100755
new mode 100644

差分が出てきました。ちなみに、tigで差分を確認したところ同じように表示されました。 今思えば最初からtigで確認しても良かったかもしれません。普段はtigで操作しているのに。

数字を見ると何となく予想が出来たのですが、diffの内容で検索です。同じ現象の方がいらっしゃいます。

Gitで変更していないはずのファイルが変更とみなされる

ファイルのパーミッションが変わっていたようです。パーミッションの変更は無視する設定を入れておきます。

$ git config core.filemode false

これで無事に差分が消えました。

$ git status
On branch master
Your branch is behind 'origin/master' by 2 commits, and can be fast-forwarded.
  (use "git pull" to update your local branch)

nothing to commit, working tree clean

ここで直接pullしてしまっても良かったのですが、Vimに戻ってPlugでアップデートしました。 無事にPlugの方でもエラーが消えました。


一方、問題は解消したのですが、今回のこの現象が何故発生したのか分かりません。 プラグインのコミットログを見てもパーミッションを変更したようなログがありません。

msys2を使っているのですが、msysが何らかの処理で、 いつの間にかパーミッションを変更してしまったのかな?不思議です。