Vimのリポジトリも code.google.com での mercurial ベースの運用から、github へリポジトリを移してきていて、そろそろ hg + mq によるパッチ管理から、git + guilt へ移行しなきゃな、という事で、msysgitでguiltを導入したメモです。
Git for Windows 2.7.0 で確認しました。
2016.09.05追記 Git for Windows 2.10.0 で確認し直したところ、変更点があったので追記しておきます。
以下は Git Bash での作業を想定しています。
guilt を clone する
http://repo.or.cz/w/guilt.git からリポジトリを clone します。
cd ~/Work
git clone http://repo.or.cz/guilt.git
ghq を使っている場合は、以下で clone できます。
ghq get -u --shallow http://repo.or.cz/guilt.git
インストールする
ファイルのコピー
make
と install
がある場合 (≒ MSYS, MINGW, Git for Windows SDK インストール済)
Git Bash を管理者権限で起動して、リポジトリのディレクトリで make install
します。
make
と install
が未インストールな場合
Git Bash を管理者権限で起動して、以下のようにファイルをコピーします。
(guilt のソースディレクトリに cd
している体で)
mkdir -p /usr/local/bin
cp guilt /usr/local/bin/
chmod 755 /usr/local/bin/guilt
mkdir -p /usr/local/lib/guilt
cp guilt-* /usr/local/lib/guilt/
chmod 755 /usr/local/lib/guilt/guilt-*
cp os.* /usr/local/lib/guilt/
追加の処理
msysgit (MSYS) 環境は元々サポート外です。
サポートされたOS環境かどうかは、/usr/local/lib/guit/os.(システム名)
というファイルが存在しているかで判断しています。
システム名は uname -s
の結果で判別していますので
cp /usr/local/lib/guilt/os.{Linux, `uname -s`}
もしくは
ln -s /usr/local/lib/guilt/os.{Linux,`uname -s`}
(Windows の NTFS でシンボリックリンクを貼りたい場合は管理者権限が必要なので注意)
として、動作するよう変更します。 (/usr/local/bin/guilt
の該当する箇所をLinux
に書き換えても可)
guilt サブコマンド打ち間違い時にエラーが出るのを修正する
このままで一応 guilt は利用可能なのですが、サブコマンドを指定せずに単体で guilt
を実行した場合や、
サブコマンドが見つからなかった場合に、Git for Windows では、以下のような理由によりエラーが表示されてしまいます。
guilt で利用されている find の -perm +111
とという指定の仕方が最近の find では未サポート
2016.09.05 追記
本現象については、2bd00ac2 にて対応がされたため、ほとんどの場合で下記修正は不要になりました。
http://stackoverflow.com/a/4458361 によると GNU find のバージョン 4.5.12 から +NNN
という指定はサポートされなくなった模様です。かわりに、 /NNN
もしくは -executable
を使うようになりました。
以下のように変更してください。
@@ -73,8 +73,8 @@
guilt_commands()
{
- find "$GUILT_PATH/../lib/guilt" -maxdepth 1 -name "guilt-*" -type f -perm +111 2> /dev/null | sed -e "s/.*\\/$GUILT-//"
- find "$GUILT_PATH" -maxdepth 1 -name "guilt-*" -type f -perm +111 | sed -e "s/.*\\/$GUILT-//"
+ find "$GUILT_PATH/../lib/guilt" -maxdepth 1 -name "guilt-*" -type f -perm /111 2> /dev/null | sed -e "s/.*\\/$GUILT-//"
+ find "$GUILT_PATH" -maxdepth 1 -name "guilt-*" -type f -perm /111 | sed -e "s/.*\\/$GUILT-//"
}
column
コマンドが Git for Windows には用意されていない
guilt が内部で使っている column
コマンドは、MSYS2 にはあるのですが、Git for Windows には用意されていないため、その場合は使用しないように変更する必要があります。
そこで、以下のように修正します。
# by default, we shouldn't fail
@@ -122,7 +122,7 @@
disp "Guilt v$GUILT_VERSION"
disp ""
disp "Pick a command:"
- guilt_commands | sort | column | column -t | sed -e 's/^/ /'
+ guilt_commands | sort | sed -e 's/^/ /'
disp ""
disp "Example:"
column
をかまさないように変更したため、サブコマンドなしで guilt
と実行した時に候補が縦に並んで表示されてしまいますが、そこは目を瞑りましょう。
2016.09.05 追記 Git for Windows 2.10 以降で、 guilt コマンド実行時にエラーになるのを修正する
これは自分だけの環境かもしれません。
Git for Windows 2.10.0 上で guilt
コマンドを実行すると、以下のエラーが出力されるようになりました。
C:\Git\mingw64/libexec/git-core/git-sh-setup: 6 行: .: git-sh-i18n: ファイルが見つかりません
辿っていくと, git-sh-setup からの git-sh-i18n の呼出が、以下のようなっており、この処理がエラーとなっているようです。
. git-sh-i18n
そこで、/mingw64/libexec/git-core/git-sh-setup
を以下のように修正します。
@@ -3,7 +3,7 @@
# a few helper shell functions.
# Source git-sh-i18n for gettext support.
-. git-sh-i18n
+. "$(git --exec-path)/git-sh-i18n"
# Having this variable in your environment would break scripts because
# you would cause "cd" to be taken to unexpected places. If you
guiltベースへ引越し
guilt init
guilt はgitのブランチ毎にパッチセットを管理できるようで、masterブランチでguilt init
した場合は.git/patches/master
にパッチ用のディレクトリが作らます。
ので、必要に応じてブランチを変更しておきます。
cd /path/to/git_repo
git checkout -b test
guilt init
これで .git/patches/test
ができているはず。
mqからの移行
mq で利用していたパッチセットをコピーしてきます
cp /path/to/hg_repo/.hg/patches/{*.diff,*.patch} /path/to/git_repo/.git/patches/test/
series
ファイルも (#-
/#+
によるパッチ適用/非適用のスイッチまで)互換性があるのでそのまま使えます。
cp /path/to/hg_repo/.hg/patches/series /path/to/git_repo/.git/patches/test/
mq と guilt で status
ファイルのフォーマットに互換性はないので、ファイルが空の時を除いてコピーしてきてはいけません。
mqのリポジトリをそのまま使う
よく考えたら、status
以外は互換性があるので、 mq のリポジトリを clone/checkout すればguiltにも利用できました。
mkdir .git/patches
hg clone https://bitbucket.org/path/to/mq .git/patches/test
guilt は空の status
ファイルがないとエラーになるので (mqのリポジトリではstatus
はignoreされている)、これだけは追加してやらないといけないようです。
touch .git/patches/test/status
CMD や PowerShell から使う
@For %%i IN ("git.exe") DO @SET GIT=%%~dp$PATH:i
@IF NOT EXIST "%GIT%" @GOTO :end
@For %%s IN ("sh.exe") DO @SET SH=%%~dp$GIT:s
@IF EXIST "%SH%" @GOTO :execute
@SET GIT=%GIT:~0,-4%bin
@For %%s IN ("sh.exe") DO @SET SH=%%~dp$GIT:s
@IF NOT EXIST "%SH%" @GOTO :end
:execute
@SETLOCAL
@SET PATH=%PATH%;%SH%..\usr\bin
@"%SH%sh.exe" /usr/local/bin/guilt %1 %2 %3 %4 %5 %6 %7 %8 %9
@ENDLOCAL
:end
のような内容を guilt.cmd
というファイル名で PATH の通ったディレクトリに保存しておけば、PowerShell等から guilt
コマンドが利用可能です。
git を使う上で、C:\Program Files\Git\cmd
か C:\Program Files\Git\bin
のどちらかにPATHを通してあると想定していますが、環境によってうまく動かないかもしれません。
不具合
手元では、差し当って下記のみです。
- guilt help が動かない
(Documentationディレクトリでmake installすればよさげ / msysgit にはそもそも man がない)