Git リポジトリのルートで以下を実行。
$ git ls-tree -r HEAD | cut -f1 | cut -d ' ' -f3 | xargs -i{} sh -c 'git rev-list --objects --all | grep {}' | cut -d ' ' -f2 | tr '\n' '\0' | xargs -0 -i{} file -Z {} | grep -i crlf | sed -e 's/:[^:]*$//' | tr "\n" "\0" | xargs -0 -iF awk 'BEGIN{RS="\r";ORS="\n";c=""} { c=c "" $0} END{printf("%s", c) > ARGV[1]}' F2020-10-25追記: 最初のバージョンではパス名に細工されるとコマンドを挿入できてしまう脆弱性がありました(上記のものは対応はしてあります)。
注意点
- 作業ツリーがクリーンな状態が前提
git rev-list --objects --allを使うので、大きめのリポジトリだと遅いです。- CRLF から LF への変換でメモリ上にファイルを読み込むので大きなファイルだと失敗すると思います。
- CodeSandbox でファイルを新規作成すると改行コードが
CRLFだったので(2020-10-25 時点では保存時などでもLFに変換されないので)、とりあえず書いたもの。よって動けばいいやくらいの気持ちで。
参考
- Git - Gitオブジェクト
- git - Getting SHA hash of file in specific commit - Stack Overflow git
- Git - finding a filename from a SHA1 - Stack Overflow git sha1
License: CC0 1.0 http://creativecommons.org/publicdomain/zero/1.0/deed.ja