Edited at

msysgit で guilt を利用する

More than 3 years have passed since last update.

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


インストールする


ファイルのコピー


makeinstall がある場合 (≒ MSYS, MINGW, Git for Windows SDK インストール済)

Git Bash を管理者権限で起動して、リポジトリのディレクトリで make install します。


makeinstall が未インストールな場合

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 から使う


guilt.cmd

@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\cmdC:\Program Files\Git\bin のどちらかにPATHを通してあると想定していますが、環境によってうまく動かないかもしれません。


不具合

手元では、差し当って下記のみです。


  • guilt help が動かない
    (Documentationディレクトリでmake installすればよさげ / msysgit にはそもそも man がない)