Gitでbuildしたファイルを別ブランチで管理し、差分を取得する
この記事で得られるもの
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行追加しました。
コマンド等は適宜プロジェクトにあわせて調整してください。
泥臭い仕事はまだまだあると思います。何かの手助けになれば幸いです。
Discussion