Site icon Tips Note by TAM

git コマンドで差分納品 zipを作る (かつ、不要ファイルは含めないようにしたい)

受託案件あるあるなのですが、普段の開発では git でコード管理していても、納品は zip ファイルにまとめて渡さなければならないことがありますね。gitでは、コマンドの組合せで差分の zip ファイルの作成もさくっと行えますので、その方法をご紹介いたします。

また、「開発時は git管理しているけど納品物には含めたくない」というファイルがある場合も、.gitattributes ファイルの設定を組み合わせることで zipから除外することが可能です。(たとえば sass ファイルだったり、テストデータだったり)

[TL;DR] 結果のコマンド

説明が長くなりそうなので最初に結果のコマンドを書いておきます。

git archive master --format=zip -o 出力ファイル名 --prefix=data/ `git diff --name-only --diff-filter=d コミット1 コミット2`

これと、.gitattributes ファイルでの設定とを組み合わせます。

しくみの解説

3つの要素を組み合わせていまして、順番に解説していきますね。

git diff で差分ファイルのリストを求める

git diff コマンドで、2つのコミット間の差分を取り出すことができます。

git diff --name-only --diff-filter=d コミット1 コミット2

コミット1 コミット2 のところで、差分の元になるコミットを指定します。これは

  • コミットID
  • ブランチ名
  • タグ名

などのどれでも構いません。
たとえば、前回納品時のコミットに version1 というタグをつけていたとして、現在の master との差分を求めたい場合は以下のようになります。

git diff --name-only --diff-filter=d version1 master

--name-only は、差分の内容ではなくファイル名のみをリスト出力するオプションです。また、 --diff-filter=d で、削除されたファイルはリストに出力させないようにしておきます(納品物作成には不要なため)。

これで、2つのコミット間の差分ファイル名が機械的にリストアップできます。

git archive で zip にまとめる

git archive コマンドで、指定されたコミットのファイルをアーカイブ化できます。master ブランチの内容を zip にまとめるならこんな感じです。

git archive master --format=zip -o 出力ファイル名 --prefix=data/

--format でアーカイブのフォーマット(tar または zip)を、-o では出力するファイル名を指定します。
--prefix=data/ は無指定でも動作するのですが、これを入れておくとアーカイブファイル内にフォルダ階層を作ってくれるのでちょっと便利です。この例の場合、data/ というフォルダ内に差分ファイルをまとめてくれるようになります (末尾にスラッシュがないとフォルダを作らず、ファイル名のプレフィクスとして動作するので要注意)。

これらを組み合わせる

git archive コマンドの後ろにはファイルリストを並べることができます。これによって、アーカイブ対象とするファイルを選択可能です。なので、git archive の後ろに、先ほどの git diff の結果を埋め込んでやります。

git archive master --format=zip -o 出力ファイル名 --prefix=data/ `git diff --name-only --diff-filter=d コミット1 コミット2`

これで差分ファイルのリストをもとに、アーカイブ化して zip を作ってくれるようになりました!

不要なファイルは除外したい

たとえば /test 配下のファイルは、アーカイブ内に含めたくないという場合、.gitattributes ファイルというもので設定が可能です。

/test export-ignore

このような内容の .gitattributesファイルがある状態で、先ほどの git archive を実行します。すると export-ignore と指定されたファイルやフォルダはアーカイブから除外されるようになりました。べんり。

長くなりましたが以上です

こんな感じで gitコマンドを組み合わせて、コミット間の差分データを(不要ファイルは除外しつつ) zip にアーカイブすることができました。
gitのリポジトリ管理で納品まで終えられればいいんですけどね、差分納品zipが必要になった場合などでご活用ください。

参考