1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

git rebase --abortをフックする

Posted at

gitでrebaseに失敗すると辛い気持ちになるので牛に励ましてもらいます (環境はLinuxです)。

方法

以下のスクリプトをgitディレクトリの中に./git/hooks/post-index-changeとして保存します。

#!/bin/bash
comm="$( tr -d '\0' < /proc/$PPID/cmdline )"
if [ "$comm" = "gitrebase--abort" ]; then
        # insert your favorite command
        cowsay "You failed me."
fi

rebaseをabortすると上のコマンドが実行されます。

$ git rebase --abort
 ----------------
< You failed me. >
 ----------------
        \   ^__^
         \  (oo)\_______
            (__)\       )\/\
                ||----w |
                ||     ||

なおグローバルなgithoooksを設定する方法(参考)を使用すればgitディレクトリの中にスクリプトを置かなくても良くなります。

説明

githooksを利用することでgitのさまざまなポイントに独自の処理(スクリプト)を埋め込むことができます。例えばpre-commitのフックを利用するとコミットの前にコードをフォーマットしたりテストを実行したりすることができます。デフォルトの設定では./git/hooks以下に各フックの名前に対応するスクリプトを用意します。フックの一覧はgithooksのmanページやドキュメントにあります。

さてドキュメントを見てもgit rebase --abortがフックできるかはよくわかりません。とりあえずフックできるのならばスクリプトをopenしているはずなのでabort時のstraceを確認してみます。

$ strace git rebase --abort 2>&1 | grep ".git/hooks"
access(".git/hooks/post-index-change", X_OK) = -1 ENOENT (No such file or directory)
access(".git/hooks/reference-transaction", X_OK) = -1 ENOENT (No such file or directory)
access(".git/hooks/reference-transaction", X_OK) = -1 ENOENT (No such file or directory)
access(".git/hooks/reference-transaction", X_OK) = -1 ENOENT (No such file or directory)
access(".git/hooks/reference-transaction", X_OK) = -1 ENOENT (No such file or directory)
access(".git/hooks/reference-transaction", X_OK) = -1 ENOENT (No such file or directory)

straceの結果はstderrに出力されるのでgrepするために2>&1のリダイレクトが必要です。結果よりaccess(2)を使ってpost-idnex-changeとreference-transactionフックのスクリプトの存在を確認している事がわかります(何もフックを設定していない = ファイルが存在しない = -ENOENTのエラー)。reference-transactionは複数呼ばれているのでここではpost-index-changeを利用することにします。

ということで./git/hooks/post-index-changeを用意すれば良いわけですが、名前から推測されるようにgitのindexが変わるたびに呼ばれるフックなのでgit rebase --abort以外でもこのスクリプトは呼ばれます(abortの例ではabortによりrebaseの途中から元の場所にindexが戻るので呼ばれる)。このため冒頭で示したスクリプトでは親プロセスのcmdlineの値からgit rebase --abortから呼ばれたかを(無理矢理)判定しています。なお/proc/<pid>/cmdlineからそのPIDのプログラム名と引数の文字列が取得できますが、それらは'\0'で区切られた文字列となっているためtrコマンドで'\0'を削除しています。同様の方法でmerge --abortam --abortもフックできるでしょう。

以上

1
0
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
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?