しばしばアプリケーションを移行したり、運用中のモノ全体をまとめたりする必要があります。そういった時、プログラムのある場所によっては Git 管理されている範囲のソースコードは Git 経由で取得し、Git 管理されていない部分のみコピーした方が楽になります。そういった時には Git 管理外ファイルのパスのみを抽出し、それらをコピーする方法が欲しくなります。これを紹介します。
ざっくりコピーするだけなら次で十分です。
#!/bin/sh cd /my/project/root # Git管理されているプロジェクトのルートディレクトリをカレントディレクトリにする # 管理外のファイルのみを複数行テキストとして出力し、 # 渡された行を cp コマンドに渡す。-R オプションで再帰的に dist_dir 以下にコピーされる git ls-files --others | xargs -I {} cp -R {} dist_dir
これはgit ls-files --others
で複数行テキストとしてファイルパスを出力し、xargs -I {} cp -R {} dist_dir
でそれらを引数として dist_dir 以下へのコピーを実行するコマンドです。ファイルパスを複数行テキストとして扱っている都合上、改行コードを含むファイル名などで期待通り動かなくなりますが、そのようなファイルがなければ問題ありません。
git ls-files
は Git の視点から ls コマンドを実行するイメージです。Gitのステージングやインデックス、実際のファイルリストを元にして様々な条件のファイル一覧を表示できます。ここでは –others で管理されていない他のファイルを表示しましたが、 git ls-files でググると他の便利な使い方も色々でてきます。
Git – git-ls-files Documentation
xargs -I {} cp -R {} dist_dir
はパイプでわたされた複数行のテキストを元にコピーコマンドを実行するコマンドです。xargs -I {}
はコマンド部の”{}”の部分を渡された文字列に入れ替えて実行する、というオプションです。ここではcp -R 渡されたファイルパス dist_dir
となる様にしています。”渡されたファイルパス”と書きましたが厳密には”渡された行”です。ファイルパスの中に改行が含まれていたりすると1行=1ファイルパスという想定が崩れて、処理が期待通りになされません。
また、パッケージマネージャーで管理してあるライブラリはコピー対象外にする、というのであれば次の様にライブラリが置かれているディレクトリ以下を grep -v で弾く様にするのがいいです。
#!/bin/sh cd /my/project/root # Git管理されているプロジェクトのルートディレクトリをカレントディレクトリにする # 管理外のファイルのみを出力 git ls-files --others \ | grep -v -E "^node_modules\|^vendor" \ | xargs -I {} cp -R {} dist_dir # 渡されたファイルパスを cp コマンドに渡す。dist_dir以下にコピーされる