背景
以前、SourceTree: 特定のコミットのファイル一覧をクリップボードにコピペ で便利だなと思った後で、追加したものがあったので供養しておく
ただ、結局はあまり使ってはいないんだけど。
概要
今回追加したスクリプトは 2 つ(+おまけ 1 つ):
- CommitInfo2Markdown.bat - コミット情報を Markdown 形式でクリップボードにコピー
- OpenChangedFilesInVSCode.bat - 変更ファイルを VSCode で一括オープン
- GeneratePRTemplate.bat - PR テンプレートを自動生成(※おまけ)
PR テンプレートは Template 機能使うから普通は不要
コミット情報から何か成型したいとき用のSampleみたいなものかな
SourceTree への設定方法
まずは共通の設定手順から。
- SourceTree を起動
- ツール → オプション → カスタム操作 タブ
- 追加 ボタンをクリック
- 以下を設定:
- メニュー表示名: 好きな名前
- バックグラウンドで実行する: ✅ チェック。Defaultの筈
- スクリプト: bat ファイルのフルパス
-
パラメータ:
$SHA
スクリプト 1: コミット情報を Markdown でコピー
何ができる?
選択したコミットの情報を Markdown 形式でクリップボードにコピーする。
レビュー依頼やドキュメント作成時に便利。
出力例
## コミット: 197550fbad317d49d86429411d2aeb21ff2fb751
**Author:** 開発者 A
**Date:** 2025-12-02 16:54:24 +0900
### コミットメッセージ
Ollama モデルリストが、再ダウンロードされる問題の修正
### 変更ファイル
```text
local_llm/setup_and_run.ps1
```
コード
@echo off
chcp 65001 > nul
setlocal enabledelayedexpansion
REM 引数からSHAを取得(空でない最初の引数を使用)
set "SHA="
for %%a in (%*) do (
if not defined SHA (
if not "%%~a"=="" set "SHA=%%~a"
)
)
REM SHAが取得できなかった場合
if not defined SHA (
echo エラー: コミットSHAが指定されていません。
pause
exit /b 1
)
REM コミット情報をMarkdown形式でクリップボードにコピー
echo ## コミット: %SHA% > %TEMP%\commit.md
echo. >> %TEMP%\commit.md
REM コミット詳細情報
for /f "tokens=*" %%a in ('git log -1 --pretty^="**Author:** %%an" %SHA%') do echo %%a >> %TEMP%\commit.md
for /f "tokens=*" %%a in ('git log -1 --pretty^="**Date:** %%ai" %SHA%') do echo %%a >> %TEMP%\commit.md
echo. >> %TEMP%\commit.md
echo ### コミットメッセージ >> %TEMP%\commit.md
git log -1 --pretty=%%B %SHA% >> %TEMP%\commit.md
echo. >> %TEMP%\commit.md
echo ### 変更ファイル >> %TEMP%\commit.md
echo ```text >> %TEMP%\commit.md
git diff-tree --no-commit-id --name-only -r %SHA% >> %TEMP%\commit.md
echo ``` >> %TEMP%\commit.md
type %TEMP%\commit.md | clip
echo コミット情報をMarkdown形式でクリップボードにコピーしました!
exit /b 0
SourceTree 設定
| 項目 | 設定値 |
|---|---|
| メニュー表示名 | コミット情報をMarkdownでコピー |
| パラメータ | $SHA |
スクリプト 2: 変更ファイルを VSCode で開く
何ができる?
選択したコミットで変更されたファイルを VSCode で開く。
コミット履歴の変更ファイルを複数開きたいとき用
とはいえ、大量に開くとやばいので、上限設定をしてある
まぁ、個別に開けばええやってなったけど ![]()
特徴
- 最大ファイル数を指定可能(デフォルト 3 個)
- 存在しないファイルはスキップ(削除されたファイル等)
- パス変換対応(Git 形式 → Windows 形式)
出力例
開く: Tools\package-lock.json
開く: pythonScripts\DesignLab\README.md
開く: pythonScripts\DesignLab\pythonScripts\requirements.in
スキップ: pythonScripts\DesignLab\pythonScripts\requirements.txt
========================================
[OK] 3 個のファイルをVSCodeで開きました
[--] 1 個のファイルは上限のためスキップ
========================================
コード
@echo off
chcp 65001 > nul
REM =============================================
REM 変更ファイルをVSCodeで開く
REM 使い方: OpenChangedFilesInVSCode.bat [SHA] [最大数]
REM 最大数を省略すると 3 ファイルまで開く
REM =============================================
REM 引数からSHAと最大数を取得
set "SHA="
set "MAX_OPEN=3"
set "first="
for %%a in (%*) do (
if not "%%~a"=="" (
if not defined first (
set "first=1"
set "SHA=%%~a"
) else if not defined second (
set "second=1"
set "MAX_OPEN=%%~a"
)
)
)
if not defined SHA (
echo エラー: コミットSHAが指定されていません。
pause
exit /b 1
)
REM Gitリポジトリのルートディレクトリを取得
for /f "delims=" %%r in ('git rev-parse --show-toplevel') do set "REPO_ROOT=%%r"
set "REPO_ROOT=%REPO_ROOT:/=\%"
REM 一時ファイルにファイル一覧を出力
git diff-tree --no-commit-id --name-only -r %SHA% > "%TEMP%\changedfiles.txt"
REM カウンター初期化
set /a opened=0
set /a notfound=0
set /a skipped=0
REM ファイルを処理
for /f "usebackq delims=" %%i in ("%TEMP%\changedfiles.txt") do call :processfile "%%i"
REM 結果表示
echo.
echo ========================================
if %opened% gtr 0 echo [OK] %opened% 個のファイルをVSCodeで開きました
if %skipped% gtr 0 echo [--] %skipped% 個のファイルは上限のためスキップ
if %notfound% gtr 0 echo [NG] %notfound% 個のファイルは現在のブランチに存在しません
if %opened% equ 0 if %skipped% equ 0 if %notfound% equ 0 echo 変更ファイルがありませんでした
echo ========================================
exit /b 0
:processfile
set "relpath=%~1"
set "relpath=%relpath:/=\%"
set "fullpath=%REPO_ROOT%\%relpath%"
if exist "%fullpath%" (
if %opened% lss %MAX_OPEN% (
set /a opened+=1
echo 開く: %relpath%
code --reuse-window "%fullpath%"
) else (
set /a skipped+=1
echo スキップ: %relpath%
)
) else (
set /a notfound+=1
echo [存在しません] %relpath%
)
exit /b
SourceTree 設定(複数パターン推奨)
| メニュー表示名 | パラメータ |
|---|---|
VSCodeで開く (3個まで) |
$SHA |
VSCodeで開く (5個まで) |
$SHA 5 |
VSCodeで開く (10個まで) |
$SHA 10 |
VSCodeで全部開く |
$SHA 999 |
用途に応じて使い分けられる!
(おまけ)スクリプト 3: PR テンプレート自動生成
Pull Request Template 機能を知らずに作って
すぐに気が付いて、おバカさを露呈したやつです、はい ![]()
何ができる?
選択したコミットから Pull Request のテンプレートを自動生成してクリップボードにコピー。
あとは貼り付けて、ちょっと編集するだけ。
出力例
# Pull Request
## 概要
Azure リソース名生成ツールと命名規則の仕様を追加
## 変更内容
### 変更ファイル一覧
| ファイル |
| ------------------------------------------------------- |
| `pythonScripts/DesignLab/bookmarklets/createRsNames.js` |
| `pythonScripts/DesignLab/bookmarklets/specification.md` |
## テスト確認事項
- [ ] 動作確認済み
- [ ] コードレビュー依頼済み
## 備考
コード
@echo off
chcp 65001 > nul
setlocal enabledelayedexpansion
REM 引数からSHAを取得(空でない最初の引数を使用)
set "SHA="
for %%a in (%*) do (
if not defined SHA (
if not "%%~a"=="" set "SHA=%%~a"
)
)
REM SHAが取得できなかった場合
if not defined SHA (
echo エラー: コミットSHAが指定されていません。
pause
exit /b 1
)
REM PRテンプレートを自動生成してクリップボードにコピー
echo # Pull Request > %TEMP%\pr.md
echo. >> %TEMP%\pr.md
echo ## 概要 >> %TEMP%\pr.md
git log -1 --pretty=%%B %SHA% >> %TEMP%\pr.md
echo. >> %TEMP%\pr.md
echo ## 変更内容 >> %TEMP%\pr.md
echo. >> %TEMP%\pr.md
echo ### 変更ファイル一覧 >> %TEMP%\pr.md
echo ^| ファイル ^| >> %TEMP%\pr.md
echo ^| --- ^| >> %TEMP%\pr.md
for /f "tokens=*" %%i in ('git diff-tree --no-commit-id --name-only -r %SHA%') do (
echo ^| `%%i` ^| >> %TEMP%\pr.md
)
echo. >> %TEMP%\pr.md
echo ## テスト確認事項 >> %TEMP%\pr.md
echo - [ ] 動作確認済み >> %TEMP%\pr.md
echo - [ ] コードレビュー依頼済み >> %TEMP%\pr.md
echo. >> %TEMP%\pr.md
echo ## 備考 >> %TEMP%\pr.md
echo. >> %TEMP%\pr.md
type %TEMP%\pr.md | clip
echo PRテンプレートをクリップボードにコピーしました!
exit /b 0
SourceTree 設定
| 項目 | 設定値 |
|---|---|
| メニュー表示名 | PRテンプレートを生成 |
| パラメータ | $SHA |
ハマったポイント
SourceTree からの引数の渡され方
SourceTree からスクリプトを実行すると、引数が以下のように渡される:
スクリプト.bat "" SHA値
最初に空文字 "" が入ってくるので、単純に %1 で受け取ると空になる。
そのため、空でない最初の引数を探すループ処理が必要だった。
パス形式の違い
Git は / 区切りのパスを返すけど、Windows は \ 区切り。
set "REPO_ROOT=%REPO_ROOT:/=\%" で変換してる。
遅延展開の罠
バッチファイルの for ループ内で変数を更新・参照するとき、遅延展開 (!変数!) が必要なケースがある。
でも SourceTree の実行環境だと動作が不安定だったので、サブルーチン方式 (call :label) で回避した。
入力プロンプトは使えない
最初は set /p で「何個開く?」って聞くようにしてたんだけど、SourceTree の実行環境では標準入力が受け付けられなかった。
なので、引数で最大数を渡す方式に変更。複数のカスタムアクションを登録して使い分ける形に落ち着いた。
あとがき
前回の記事 のシンプルなスクリプトから発展させて、いくつか追加してたけど、供養してなかったので記録として。
カスタムアクション、一度設定すると忘れがちだけど、定期的に「もうちょっと便利にできないかな」って見直すと、地味に効率上がるはず・・・なんだけど、普通は 他にもっと良い機能があるものよね・・ Pipeline だったり、Template だったり・・