gitには特定のコミットから最新までの差分や、特定のコミット間の差分をzipにするコマンドがあります。
$ git archive --format=zip HEAD `git diff --name-only --diff-filter=d 古いコミットハッシュ 新しいコミットハッシュ` -o archive.zip
こんな感じのやつです。
このコマンドをシェルスクリプトにして配布しているサイトはいくつもあるけどfish shellでの書き方を紹介しているサイトが見つからなかったので紹介します。
注意
シンプルなスクリプトにしているのでHEAD~3
のようにHEADからコミットを遡るパターンには対応していません
完成形
まずは完成形のロジックを紹介します。
# gitzip.fish
function gitzip
set -l d (date '+%y%m%d_%H%M')
set -l p (basename $PWD)
set -l diff ""
set -l length (count $argv)
if test $length -ge 2
set diff $argv[1] $argv[2]
else if test $length -eq 1
set diff $argv[1] HEAD
end
command git archive --format=zip HEAD (git diff --name-only --diff-filter=d $diff) -o ~/Downloads/$p-$d.zip
end
これで$ gitzip コミットハッシュ
でコミットハッシュから最新まで。
$ gitzip 古いコミットハッシュ 新しいコミットハッシュ
でコミットハッシュ間の差分をDownloadディレクトリにzipで作成します。
※新しいコミットハッシュ、古いコミットハッシュの順でも動作はします
それでは一つずつ解説していきます。
zipファイル名をプロジェクト名-日付.zipにする
archive.zipのように決め打ちでもいいですがそれだと上書きされたりするし、放置したときになんのアーカイブか分からなくなる事もあるのでユニークにします。
# 日付
set -l d (date '+%y%m%d_%H%M')
# 現在いるディレクトリ名
set -l p (basename $PWD)
アーカイブを作成するときにはたいていプロジェクトディレクトリからコマンドを打つはずなのでそのディレクトリ名をファイル名にします。
引数の数で特定コミット間か最新コミットまでかを判断する
引数が一つの場合はコミットからHEADまでを取得し、2つのときはそのコミット間をセットするようにします。
ちなみに3つ以上のときは前2つのみしか使いません。
set -l diff ""
set -l length (count $argv)
if test $length -ge 2
# 引数が2つ以上の時
set diff $argv[1] $argv[2]
else if test $length -eq 1
# 引数が1つの時
set diff $argv[1] HEAD
end
fishの場合、引数は$argv
で取得できる決まりになっています。
引数の数はcount(xxx)
で取得できますが、count(xxx)
と書くとログに出力されるためif文が動作しません。
そこでset -l length (count $argv)
と一度変数に入れて置きます。
if test [条件式]
でファイルや文字列数値のテスト行います。
if test $length -ge 2
だとJSでいうif ($length >= 2)
に該当します。
-eq
は=
になります。
条件式に関してはfishのtestを参照。
gitコマンドを実行する
command git archive --format=zip HEAD (git diff --name-only --diff-filter=d $diff) -o ~/Downloads/$p-$d.zip
アーカイブを生成するためのgitコマンドを書きます。コマンドはcommand
で実行できます。
~/Downloads/
はMacのDownloadsディレクトリを指します。
Windowsや他の場所にしたい場合は適宜変更するのもよしです。
※diff-filter=d
は削除ファイル以外というフィルタになります
fishで使えるようにする
ここまで作成したロジックをgitzip.fish
(fishはfishファイルの拡張子)で保存します。
保存する場所はどこでもいいです。
このファイルを起動時に読み込むようにするためcongig.fish
に下記を追加します。
config.fish
はMacだと~/.config/fish/config.fish
にあります(Windowsはちょっとわかりませんが…)
set -x PATH $PATH 保存場所のパス/gitzip.fish
これでgitzip
コマンドが利用できます。
利用方法
$ gitzip コミットハッシュ
# or
$ gitzip コミットハッシュ1 コミットハッシュ2
第1引数のコミット位置を基準に第2引数までのコミット(省略した場合はHEAD)までの差分ファイルを取得
fishでもシェルスクリプトファイルと同じようにgit archiveを自動化したい人は参考にしてください。