0
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

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

Last updated at Posted at 2025-01-21
git

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

シェル

ポイントはgit diff--name-status --diff-filter={差分シンボル}オプションでコミット間の指定の差分ファイルを抽出できる

sh
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*はリネーム認識精度 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コミットには存在しないためエラーになる
sh
#!/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コミットには存在しないためエラーになる
sh
#!/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

powershell
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

powershell
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(コミットハッシュ)を指定するとコミットハッシュを引数にしてスクリプトを実行してくれる。

image.png

アーカイブを作成する

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

image 2.png

出力されたアーカイブ

こいつを展開したら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 < これ
...
0
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?