やりたいこと:
特定のコミット間で差分があったファイルだけ、アーカイブしたい。
納品済みソースを改修した際に、差分ファイルだけ納品したい場合など。
gitでコミット間の差分ファイル一覧を取得する
まず、gitコマンドでコミット間の差分を取得する。
git diff --name-only $old_sha $new_sha --diff-filter=ACMR
※–diff-filterで、追加・複製・変更・リネームされたファイルのみを指定
(これがないと、削除されたファイルまで取得してしまい、アーカイブ作成時にエラーとなる。)
差分ファイルをアーカイブ:ファイル数が少ない場合
archiveコマンドに、先ほどの差分取得コマンドを繋げて、差分だけをアーカイブする。
git archive --format=zip --prefix=arc/ --output=arc.zip --worktree-attributes $new_sha $(git diff --name-only $old_sha $new_sha --diff-filter=ACMR)
※–worktree-attributesは、.gitattributesファイルを有効にするためのオプション。
.gitattributesでは、アーカイブ時に除外するファイルを指定することができる。(環境依存ファイルやテスト用資材など)
問題点:対象ファイルが多いとエラーになる。
※ファイル名やパスの長さによるが、大体1500~2000ファイルでエラーになった。
「Argument list too long」
(対象ファイルが少ない場合はこれでOK。)
差分ファイルをアーカイブ:xargsで渡す(失敗)
次に試したこと:xargsで差分ファイルを渡す。
git diff --name-only $old_sha $new_sha --diff-filter=ACMR | xargs git archive --format=zip --prefix=arc/ --output=arc.zip $new_sha
エラーは出なくなるが、問題あり。
アーカイブファイルの中をみると、ファイルが足りない。
(表面上はエラーがでなくなったが、アーカイブの中のファイルが足りない。。)
xargsは、引数が長い場合に自動で分割して複数回実行してくれるらしいので、結局archiveコマンドが複数回呼ばれて都度上書きされ、最後に実行した分のzipファイルだけになってしまっている。
今回の用途では使用できない。
差分ファイルをアーカイブ:対象ファイルをコピーしてからアーカイブ
最終的には、差分ファイルをディレクトリ構造ごとコピーして、それをまるごとアーカイブする方法とした。
Windows+Git Bashのみで動作させる必要があったため、zip圧縮は一旦stashしてからarchiveしている。(∵git archiveはコミットがないとアーカイブできない)
※参考にPowerShellを使用する場合と、tarを作成する場合も記載。
■shell
コメント