ローカル修正済みの(pushしていない)ファイルがリモートでフォルダ構成を移動されていた場合に、ローカルの対象ファイルを抽出するコマンド
そんなことある??????と思われるかもしれないが、あった。
フォルダ構成を(git mv
あるいはfilter-branch
を使わずに)変更した場合はファイルが削除&追加されてしまう。そのままマージすると、同じファイルが(別の履歴・内容を持った状態で)2つ存在することになるはずである。従って、ローカルのコミットに含まれる当該ファイルを排除した状態でマージを実行したい。
普通にdiff --name-status
を取るとリモートで移動したファイルがすべて(DおよびAで)表示されてしまう。今回は変更ファイルが数百程存在したため諦めた。
欲しいものは、ローカルの変更ファイルとリモートの移動済みファイルの集合である。
順序はどちらでも良いが、今回はローカル側の変更ファイルの方が少なかったため「ローカルの変更ファイルのうち、移動済みだったものを探す」方向で考えた。
$ git diff HEAD~..HEAD --name-only | xargs -n1 -I{} git diff --name-status --diff-filter=A origin/develop..HEAD {}
git diff <SHA1>..<SHA1> --name-only
の標準出力をxargs
コマンドによるパイプで繋いでorigin/develop
とのdiffに渡している。フィルダ構成が変わっている=gitは新ファイルとして認識しているので--diff-filter=A
で抽出している。diff
の--name-status
はdiff-filterと効果が被るが、分かり易さ優先で付けた。更にパイプで繋ぐ場合は--name-only
にすると良いと思う。
A some/file/path/and/file_name.cpp
A some/file/path/and/file_name.h
...以下差分ファイル一覧
今回は結局、ローカルのコミットが1つだけであり、さらに対象のファイルは2つだけだったため、一旦reset --soft HEAD~
してからgit reset */file_name.*
してコミットした。その後にマージしたりなんやかんやして、ローカルの変更をコピペで反映して事なきを得た。