Gitでbuildしたファイルを別ブランチで管理し、差分を取得する

4 min read読了の目安(約2800字

この記事で得られるもの

masterブランチにbuildしたファイルをコミットすることなく、git diffでbuildしたファイルの前回との差分を抽出できる。

例: distディレクトリは.gitignoreしてるけど、distディレクトリ内の差分をgit archiveで抽出したい。公開データ差分をzipで納品しなければならないなど。

はじめに

ソースをGitリポジトリで管理するのは当然ですが、buildしたファイルをリポジトリに含めるかという点においては賛否の分かれる話題です。

buildしたファイルをリポジトリに含めれば、ライブラリ等の配布において利用者にとって便利ですが、例えばウェブサイトの管理においてはコミットログが肥大化してしまい見づらくなってしまいデメリットが勝ります。

ただ今度はウェブサイトの管理において、buildしたデータの差分ファイルを抽出するというシチュエーションがしばしば発生しますが、リポジトリで管理しないとgit diffを使用して差分を抽出することができません。

今回、masterブランチではsrc等のデータを管理し、別ブランチでbuildしたファイルを管理し、その差分をgit diffで取得できる小技を紹介します。

今回のファイル構成

プロジェクトフォルダ

drwxr-xr-x   8 foo  staff   256  9 24 21:46 ./
drwxr-xr-x  14 foo  staff   448  9 24 21:19 ../
drwxr-xr-x  32 foo  staff  1024  9 24 21:29 node_modules/
-rw-r--r--   1 foo  staff   241  9 24 21:30 package.json
drwxr-xr-x   4 foo  staff   128  9 24 21:32 src/
-rw-r--r--   1 foo  staff  8197  9 24 21:29 yarn.lock

srcフォルダ

-rw-r--r--  1 foo  staff  245  9 24 21:32 about.ejs
-rw-r--r--  1 foo  staff  232  9 24 21:26 index.ejs

まずはinitial commitする

.gitignoreを作成し、git initする

すでにプロジェクトディレクトリは立ち上がっているものとし、.gitignoreを追加します。

# .gitignore
/dist
/node_modules
!.gitignore

次にgit initし、initial commitを追加します。

$ git init
$ git add .
$ git commit -m 'initial commit'

releaseブランチを作成し、buildしてcommitする

次にreleaseブランチを作成し、releaseブランチ上でbuildしてcommitをします。
git addする際には-fオプションをつけて、強制的にステージに上げます。

$ git checkout -b release
$ yarn ejs-cli --base-dir src/ '*.ejs' -o dist/
$ git add -f ./dist/*
$ git commit -m 'initial release commit'

これで準備が整いました。

実際に変更差分を取得してみる

早速試しに、masterブランチ上でsrc/index.ejsのみに変更を加えてcommitします。

<!-- src/index.ejs -->
-<% const message = 'Hello world' %>
+<% const message = 'Welcome to git world' %>
$ git commit -am 'update - トップページのウェルカムメッセージを変更'

release ブランチでcommitする

では先ほどの変更をreleaseブランチ上で適用して、差分を抽出します。

$ git checkout release
$ git merge master
$ yarn ejs-cli --base-dir src/ '*.ejs' -o dist/
$ git add -f ./dist/*
$ git commit -m 'release'
$ git archive --format=zip --prefix=archive/ HEAD `git diff --name-only --diff-filter=AMCR HEAD~1 HEAD` -o archive.zip

これで生成されたarchive.zipに差分のdist/index.htmlが格納されました。

Archive:  archive.zip
   creating: archive/
   creating: archive/dist/
  inflating: archive/dist/index.html

差分ファイル生成の手順をシェルスクリプト化する

さすがに上記の手順を毎回行うのは非常に手間なので、スクリプトファイルを作成しておくとよいと思います。

# make_diff_archive.sh
git checkout release
git merge master
yarn ejs-cli --base-dir src/ '*.ejs' -o dist/
git add -f ./dist/*
git commit -m 'release'
git archive --format=zip --prefix=archive/ HEAD `git diff --name-only --diff-filter=AMCR HEAD~1 HEAD` -o archive.zip
git checkout master

最後にmasterブランチに戻るように1行追加しました。


コマンド等は適宜プロジェクトにあわせて調整してください。
泥臭い仕事はまだまだあると思います。何かの手助けになれば幸いです。