SouceTreeでコミット間の差分ファイルを取得するカスタムアクションスクリプト



SourceTreeのカスタムアクションに登録すると、2点のコミット間のフォワード差分とリバート差分をサクッとアーカイブで出力出来るので、デプロイでやらかした時など緊急の切り戻し資材として便利。

シェル




ポイントはgit diff--name-status --diff-filter={差分シンボル}オプションでコミット間の差分ファイルを選択抽出できるのでforward/revertケースに合わせてフィルタしてawkでファイル名のトークンを選択する


git diff --name-status --diff-filter=ACMRD コミットハッシュ(from) コミットハッシュ(to)
A		{path/to/追加ファイル}
C		{path/to/コピー元ファイル}		{path/to/コピー先ファイル}
M		{path/to/変更ファイル}
R100		{path/to/リネーム前ファイル}	{path/to/リネーム後ファイル} < R*はリネーム認識精度(%)
D		{path/to/削除ファイル}

Mac版 - zshスクリプト版


forward


コミットハッシュ$fromから$toの次の差分ファイルを$toコミットから抽出してアーカイブする


  • --diff-filterで抽出する差分
    • 変更(M) - (awk:$2)
    • 追加(A) - (awk:$2)
    • コピー(C) - コピー先ファイル(awk:$3)
    • リネーム(R) - 変更後ファイル(awk:$3)
  • --diff-filterで抽出しない差分
    • 削除(D)されたファイル・・・$toコミットには存在しないためエラーになる

#!/bin/bash

if [ "$2" = "" ]; then
  to=HEAD
  from=${1}
else
  to=${1}
  from=${2}
fi

git archive --format=zip --prefix=forward/ ${to} `git diff --name-status --diff-filter=AMCR ${from} ${to} | awk '/^R|^C/ {print $3; next} /^A|^M/ {print $2}'` -o forward.zip

revert


コミットハッシュ$fromから$toの次の差分ファイルを$fromコミット時点から抽出してアーカイブする


  • --diff-filterで抽出する差分
    • 変更(M) - (awk:$2)
    • リネーム(R) - 変更前ファイル(awk:$2)
    • 削除(D) - 削除されたファイル(awk:$2)
  • --diff-filterで抽出しない差分
    • 追加(A)・・・$fromコミットには存在しないためエラーになる
    • コピー(C)・・・$fromコミットには存在しないためエラーになる

#!/bin/bash

if [ "$2" = "" ]; then
  to=HEAD
  from=${1}
else
  to=${1}
  from=${2}
fi

git archive --format=zip --prefix=revert/ ${from} `git diff --name-status --diff-filter=MRD ${from} ${to} | awk '{print $2}'` -o revert.zip

Windows - コマンド版


  • バッチではコマンド結果をワンライナーで中継できないので、ファイルリストを抽出してからgit archiveにわたす
  • awkコマンドはbusyboxからバイナリを取得&どこかに展開してシステム環境変数のパスを通しておく

forward


if "%2" EQU "" (
  set PARAM1=HEAD
  set PARAM2=%1
) else (
  set PARAM1=%1
  set PARAM2=%2
)

setlocal enabledelayedexpansion
set RET_DIR=
for /F "usebackq" %%i in (`git diff --name-status --diff-filter=AMCR %PARAM2% %PARAM1% ^| awk "/^R/ {print $3; next} /^C/ {print $3; next} /^A/ {print $2; next} /^M/ {print $2}"`) do (
  set RET_DIR=!RET_DIR! "%%i"
)

git archive --format=zip --prefix=forward/ %PARAM1% %RET_DIR% -o forward.zip

revert


if "%2" EQU "" (
  set PARAM1=HEAD
  set PARAM2=%1
) else (
  set PARAM1=%1
  set PARAM2=%2
)

setlocal enabledelayedexpansion
set RET_DIR=
for /F "usebackq" %%i in (`git diff --name-status --diff-filter=MRD %PARAM2% %PARAM1% ^| awk "{print $2}"`) do (
  set RET_DIR=!RET_DIR! "%%i"
)

git archive --format=zip --prefix=revert/ %PARAM2% %RET_DIR% -o revert.zip

SrouceTreeで使う



カスタムアクションにスクリプトを登録する


上記スクリプトファイルとパラメータに$SHA(コミットハッシュ)を指定するとコミットハッシュを引数にしてスクリプトを実行してくれる。

アーカイブを作成する


2点のコミットを選択する > コンテキストメニュー > カスタムアクション > スクリプトを選択


出力されたアーカイブ


こいつを展開したらforward/revertのファイル差分が入っている


ls -lav /path/to/this_repository

total 200
drwxr-xr-x  16 user  staff    512  2 16 21:51 .git
-rw-r--r--   1 user  staff  16701  2 16 21:54 forward.zip < これ
...
Share:

0 Comments:

コメントを投稿