■参考

スクリプト機能 - WinSCP Wiki - WinSCP - OSDN
https://ja.osdn.net/projects/winscp/wiki/scripting

コマンドリファレンス - WinSCP Wiki - WinSCP - OSDN
https://ja.osdn.net/projects/winscp/wiki/script_commands

WinSCPスクリプト 及び実行 - Qiita
https://qiita.com/aimoriu/items/a36b231d3fd26b222452

■メモ

cd C:\Program Files (x86)\WinSCP

winscp.exe          ... GUIで起動
winscp.exe /console ... CUIで起動

以下、CUIで起動して操作する例

open ftp://webmaster@203.0.113.1  ... FTPで接続
open sftp://webmaster@203.0.113.1 ... SFTPで接続

cd /html/test/winscp
ls
option transfer ascii
put C:\Users\refirio\WinSCP\files\text.txt
option transfer binary
put C:\Users\refirio\WinSCP\files\image.jpg

-nopreservetime を付けると、アップロード&ダウンロード時にタイムスタンプを更新する
-permissions=644 を付けると、アップロード時にパーミッションを変更する(FTPでは利用できない)

■バッチ処理

winscp.exe /console /script=C:\Users\refirio\WinSCP\upload.txt

option batch on
option confirm off
open ftp://webmaster:xxxxx@203.0.113.1
option transfer ascii
put -nopreservetime -permissions=644 C:\Users\refirio\WinSCP\files\text.txt /html/test/winscp/text.txt
option transfer binary
put -nopreservetime -permissions=644 C:\Users\refirio\WinSCP\files\image.jpg /html/test/winscp/image.jpg
close
exit

■WinSCP.vbs

Option Explicit

Dim localDir, remoteDir, commandOpen, commandPut, asciiPattern, targetFile, resultFile
Dim fso, reg, file, line, command, asciiBuffer, binaryBuffer, result

' 設定
localDir     = "C:\Users\refirio\WinSCP\"
remoteDir    = "/html/test/winscp/"
commandOpen  = "open ftp://webmaster:xxxxx@203.0.113.1"
commandPut   = "put -nopreservetime -permissions=644"
asciiPattern = "\.(am|asp|bat|c|cfm|cgi|conf|cpp|css|dhtml|diz|h|hpp|htm|html|in|inc|java|js|jsp|lua|m4|mak|md5|nfo|nsi|pas|patch|php|phtml|pl|po|py|qmail|sh|shtml|sql|svg|tcl|tpl|txt|vbs|xhtml|xml|xrc)$"
targetFile   = "target.txt"
resultFile   = "result.txt"

' ファイルシステムオブジェクトを作成
Set fso = WScript.CreateObject("Scripting.FileSystemObject")

' 正規表現オブジェクトを作成
Set reg = CreateObject("VBScript.RegExp")
reg.Pattern = asciiPattern
reg.IgnoreCase = True
reg.Global = True

' ファイルを読み込み
Set file = fso.OpenTextFile(targetFile, 1, False, 0)

Do Until file.AtEndOfStream
	line    = file.ReadLine
	command = commandPut & " " & localDir & Replace(line, "/", "\") & " " & remoteDir & line

	If reg.test(line) Then
		asciiBuffer = asciiBuffer & command & vbCr
	Else
		binaryBuffer = binaryBuffer & command & vbCr
	End If
Loop

file.Close

' 出力内容を作成
result = result & "option batch on" & vbCr
result = result & "option confirm off" & vbCr
result = result & commandOpen & vbCr
result = result & "option transfer ascii" & vbCr
result = result & asciiBuffer
result = result & "option transfer binary" & vbCr
result = result & binaryBuffer
result = result & "close" & vbCr
result = result & "exit"

' ファイルに書き込み
Set file = fso.OpenTextFile(resultFile, 2, True)
file.WriteLine result
file.Close

' 完了メッセージを表示
Call MsgBox("アップロードスクリプトの出力が完了しました。", vbInformation + vbOKOnly, "WinSCP")
'Call MsgBox(result, vbInformation + vbOKOnly, "WinSCP")

■git

Sourcetree上では、変更ファイルの一覧を表示できてもコピーはできないかも?
(どちらにしても、ファイル名をコピーしただけでは「追加」「更新」「削除」などを判別できないのでイマイチ
  また、「ファイル1つをアップロードするだけ」という場合には面倒なので、もっと簡単にしたい
  実行するとコミットIDを2つを尋ねられて、入力するとWinSCP用スクリプトが書き出される…くらいにできるか)
以下、ターミナルからコピーする方法

Gitでcommit間の変更ファイル一覧を出力 - Qiita
https://qiita.com/motokiee/items/6d8b34f4419c604bb23e

$ git diff --stat --name-only <コミットID A> <コミットID B>

$ git diff --stat --name-only 06d1ad74ec43ab631bc06237644d19e7eb49d065 867c6396db838ff6a1e8bb0a58c1fc43fa8e0a07
libs/cores/basis.php
libs/cores/version.php

一つ前のコミットとの差分比較が必要なので注意

■ファイル名の変更やファイルの削除に対応するための考察

$ git diff --stat aae06841634185d0ae2cdb729169e16eceef9bd8 4e866a9b882e0dbc11b47e3287ecc95912249040
 html/images/top/img_about_en.jpg                      | Bin 0 -> 76067 bytes
 html/images/top/{img_about.jpg => img_about_ja.jpg}   | Bin
 html/images/top/img_question.jpg                      | Bin 45428 -> 0 bytes
 html/images/top/img_question_en.jpg                   | Bin 0 -> 39092 bytes
 html/images/top/img_question_ja.jpg                   | Bin 0 -> 40287 bytes
 html/images/top/img_temple_en.jpg                     | Bin 0 -> 49991 bytes
 html/images/top/{img_temple.jpg => img_temple_ja.jpg} | Bin
 levis/app/controllers/home/index.php                  |  13 +++++++------
 levis/app/views/home/index.php                        |   6 +++---
 9 files changed, 10 insertions(+), 9 deletions(-)

ファイル名の変更や削除がある場合でも、以下のように表示される

$ git diff --stat --name-only aae06841634185d0ae2cdb729169e16eceef9bd8 4e866a9b882e0dbc11b47e3287ecc95912249040
html/images/top/img_about_en.jpg
html/images/top/img_about_ja.jpg
html/images/top/img_question.jpg
html/images/top/img_question_en.jpg
html/images/top/img_question_ja.jpg
html/images/top/img_temple_en.jpg
html/images/top/img_temple_ja.jpg
levis/app/controllers/home/index.php
levis/app/views/home/index.php

判別できないので、現状は新規&上書きアップロードにのみ使用できる
不要ファイルの削除は手動での対応が必要

$ git diff --name-status aae06841634185d0ae2cdb729169e16eceef9bd8 4e866a9b882e0dbc11b47e3287ecc95912249040
A       html/images/top/img_about_en.jpg
R100    html/images/top/img_about.jpg   html/images/top/img_about_ja.jpg
D       html/images/top/img_question.jpg
A       html/images/top/img_question_en.jpg
A       html/images/top/img_question_ja.jpg
A       html/images/top/img_temple_en.jpg
R100    html/images/top/img_temple.jpg  html/images/top/img_temple_ja.jpg
M       levis/app/controllers/home/index.php
M       levis/app/views/home/index.php

これなら、リネーム前のファイル名も、削除されたファイルも判る
これをもとに、WinSCP用のコードを作るといいかも

AやDなどの意味は、以下などを参考にする

Gitを使って差分ファイルと差分情報を簡単に納品するコマンドのメモ - Qiita
https://qiita.com/hironaito/items/9b5135698ea1a497a3c0