Subversion tips - 過去のコミットメッセージを変更する

# 能書き

Subversionでも過去のコミットメッセージを変更できる、という事を最近知りました。あんまり一般的ではありませんが。というかデフォルト設定では変更できないようになっています。

という訳で、その為の設定と、実際にやってみたレポートです。

# svnadmin setlog

Subversionの管理コマンド```svnadmin```を使えるユーザであれば、```svnadmin setlog```で普通に変更できます。

参考文献: [リポジトリのお掃除 - リポジトリの保守 - 5. リポジトリの管理 - Subversion によるバージョン管理 For Subversion 1.2](http://jtdan.com/vcs/svn/svn-book/svn.reposadmin.maint.html#svn.reposadmin.maint.cleanup)

まず、現在の状況。実は[前の記事](https://qiita.com/katz_engineer/items/29bb4672f69e70944a80)の続きとして書いているので、ちょっとそういう感じです。

```console
# svn log
------------------------------------------------------------------------
r2 | root | 2020-07-06 01:23:01 +0900 (Mon, 06 Jul 2020) | 1 line

set svn:ignore
------------------------------------------------------------------------
r1 | root | 2020-07-05 23:37:52 +0900 (Mon, 05 Jul 2020) | 1 line

first commit
------------------------------------------------------------------------
```

実験ですので、最後の revision2 ではなく、過去の revision1 のメッセージを修正します。新しいメッセージはファイルに格納して指定するようですが、bashの機能を使って標準入出力をパイプします。

```console
# echo "change" | svnadmin setlog /etc/.svn_repo/ -r 1 --bypass-hooks /dev/stdin
# svn log
------------------------------------------------------------------------
r2 | root | 2020-07-06 01:23:01 +0900 (Mon, 06 Jul 2020) | 1 line

set svn:ignore
------------------------------------------------------------------------
r1 | root | 2020-07-05 23:37:52 +0900 (Mon, 05 Jul 2020) | 2 line

change

------------------------------------------------------------------------
```

1点気になるのは、テキスト末尾に改行があると、空行と認識されてしまうようです。```echo```コマンドなら改行を出力しないオプションがあります。

```console
# echo -n "change" | svnadmin setlog /etc/.svn_repo/ -r 1 --bypass-hooks /dev/stdin
# svn log
------------------------------------------------------------------------
r2 | root | 2020-07-06 01:23:01 +0900 (Mon, 06 Jul 2020) | 1 line

set svn:ignore
------------------------------------------------------------------------
r1 | root | 2020-07-05 23:37:52 +0900 (Mon, 05 Jul 2020) | 1 line

change
------------------------------------------------------------------------
```

# svn propset svn:log

一般ユーザーでも使用可能な```svn```コマンドでも、コミットメッセージ変更の手段はあります。が、その為の設定が必要です。

## 余計な事はしない

とにかくササッと実験。

### 設定

バージョン化されてなくて変更前の歴史を忘れてしまうような文書は、なるべく変更させたくないってのがSubversionの哲学らしい。

参考文献: [フックスクリプト - リポジトリの作成と設定 - 5. リポジトリの管理 - Subversion によるバージョン管理 For Subversion 1.2](http://jtdan.com/vcs/svn/svn-book/svn.reposadmin.create.html#svn.reposadmin.create.hooks)

ここの「pre-revprop-change」「post-revprop-change」の項目に従ってフックスクリプトを作成します。リポジトリの中に```hooks```ディレクトリがあるようです。ここに雛形が置かれていて、中身を読むと```pre-revprop-change.tmpl```だけ有効にすれば良さそうなんですが、実際にやってみるとpost側も用意しないとエラーになります。

今回は```post-revprop-change```は何もしない物にしてみます。

```console
# cd /etc/.svn_repo/hooks/
# cp -p pre-revprop-change.tmpl pre-revprop-change
# echo '#!/bin/sh' >post-revprop-change
# chmod +x post-revprop-change
# ls -l *-revprop-change
-rwxr-xr-x 1 root root   12 Jul  6 20:14 post-revprop-change
-rwxr-xr-x 1 root root 3437 Jul  5 23:13 pre-revprop-change
```

### コミットメッセージ変更

現状を確認。

```console
# cd /etc
# svn log
------------------------------------------------------------------------
r2 | root | 2020-07-06 01:23:01 +0900 (Mon, 06 Jul 2020) | 1 line

set svn:ignore
------------------------------------------------------------------------
r1 | root | 2020-07-05 23:37:52 +0900 (Mon, 05 Jul 2020) | 1 line

change
------------------------------------------------------------------------
```

参考文献: [属性の操作 - 属性 - 7. より進んだ話題 - Subversion によるバージョン管理 For Subversion 1.2](http://jtdan.com/vcs/svn/svn-book/svn.advanced.props.html#svn.advanced.props.manip)

ここのカラム「リビジョン属性のマージ」にコミットログ修正の方法が書いてありますが… なぜかここ以外では触れていませんね。特殊な属性の紹介の中に svn:log が書かれていません。

まぁいいか。実際にやってみます。

```console
# svn propset --revprop -r1 svn:log "first commit"
property 'svn:log' set on repository revision 1
# svn log
------------------------------------------------------------------------
r2 | root | 2020-07-06 01:23:01 +0900 (Mon, 06 Jul 2020) | 1 line

set svn:ignore
------------------------------------------------------------------------
r1 | root | 2020-07-05 23:37:52 +0900 (Mon, 05 Jul 2020) | 1 line

first commit
------------------------------------------------------------------------
```

## 変更を記録に残す

メールではなくて systemd-journald に残すようにしてみました。

```/etc/.svn_repo/hooks/post-revprop-change
#!/bin/bash

systemd-cat -t etcmgr <<___
REPOSITORY="$1"
REVISION="$2"
USER="$3"
PROPERTY="$4"
ACTION="$5"
OLD MESSAGE:
$(cat)
___
```

やってみます。

```console
# cd /etc
# svn propset --revprop -r1 svn:log "change"
property 'svn:log' set on repository revision 1
# svn log
------------------------------------------------------------------------
r2 | root | 2020-07-06 01:23:01 +0900 (Mon, 06 Jul 2020) | 1 line

set svn:ignore
------------------------------------------------------------------------
r1 | root | 2020-07-05 23:37:52 +0900 (Mon, 05 Jul 2020) | 1 line

change
------------------------------------------------------------------------
# journalctl -at etcmgr
-- Logs begin at Sun 2020-06-28 21:46:01 JST, end at Mon 2020-07-06 20:34:41 JST. --
Jul 06 20:34:41 〈マシン名〉 etcmgr[2046]: REPOSITORY="/etc/.svn_repo"
Jul 06 20:34:41 〈マシン名〉 etcmgr[2046]: REVISION="1"
Jul 06 20:34:41 〈マシン名〉 etcmgr[2046]: USER="root"
Jul 06 20:34:41 〈マシン名〉 etcmgr[2046]: PROPERTY="svn:log"
Jul 06 20:34:41 〈マシン名〉 etcmgr[2046]: ACTION="M"
Jul 06 20:34:41 〈マシン名〉 etcmgr[2046]: OLD MESSAGE:
Jul 06 20:34:41 〈マシン名〉 etcmgr[2046]: first commit
```

やったね:thumbsup_tone1: