psvn.el+Subversion 1.7がネストされたワーキングコピーでエラーになる件

  • 投稿日:
  • by
  • カテゴリ:

筆者はpsvn.elを6年くらい愛用している。仕事でSubversionを使ってるのだが、Subversionのクライアントソフトとして、周囲がTortoiseSVNを使う中、一人で頑にpsvn.elを使っている。マウス操作やトラックパッド操作が必要なく、全てがキーボード操作で完結するのが、個人的に気持ち良いのである。

最近、仕事で使うSubversionのバージョンが1.6から1.8に変わり、それまで使っていた、2009年のバージョンのpsvn.elが動かなくなった。Subversion 1.7でワーキングコピーの形式が大幅に変わったからである。

そこで、Subversion 1.7にも対応している、最新のpsvn.el(2015-07-20版)をダウンロードして使い始めた所、ワーキングコピーのルートディレクトリにチェックアウトしたワーキングコピーでM-x svn-statusすると、

Wrong type argument: stringp, nil
というエラーが出て使えなかった。つまり、
svn co (URL1) aaa
cd aaa
svn co (URL2) bbb
とした時のディレクトリbbbの下でM-x svn-statusができなかった。
svn coの代わりに、svn propsetでsvn:externalsを指定してbbbを取得しても同じエラーになった。
ディレクトリaaaの下でsvn switchして別のワーキングコピーを取得した場合は同じ問題が起こらないのだが、あいにくURL1とURL2とでSubversionのリポジトリが異なる為に、svn switchでbbbを取得することができないのである。

これが筆者としては非常に困ったので、自力で修正してみた。
変更箇所をdiff形式で示す。

修正案1

--- psvn.el.org	2015-07-20, 21:42:00
+++ psvn.el	2016-09-30
@@ -6063,6 +6063,7 @@
         ;; it doesn't, e.g we reached / already.
         (setq parent (expand-file-name (concat wc-root "..")))
         (or (and (< (length parent) (length wc-root))
+                 (not (file-exists-p (concat wc-root (svn-wc-adm-dir-name))))  ;; stop if .svn or equivalent exists
                  (svn-status-base-dir-1 (expand-file-name (concat wc-root ".."))))
             wc-root)))))
svn-status-base-dir-1関数の中で、ワーキングコピーのルートディレクトリを探すのに、できるだけ上位のディレクトリを探すようで、上に辿る途中にエラーになるので、.svnを発見したらそれ以上遡らないようにするものである。

修正案2

--- psvn.el.org	2015-07-20, 21:42:00
+++ psvn.el	2016-10-10
@@ -3084,7 +3084,7 @@
     (let ((svn-process-buffer-name "*svn-info-output*"))
       (when (get-buffer svn-process-buffer-name)
         (kill-buffer svn-process-buffer-name))
-      (svn-run nil t 'parse-info "info" ".")
+      (svn-run nil t 'parse-info "info" default-directory)
       (svn-status-parse-info-result)))
   (unless (eq arg t)
     (svn-status-update-buffer)))
原因がよくわからないが、途中にワーキングコピーのルートディレクトリがあると、そこから1つ上に遡った時に、カレントディレクトリがdefault-directoryでなく、もう1つ上のディレクトリにずれてしまうようで、カレントディレクトリがワーキングコピー中でないと svn info . がエラーになる(*)ので、 svn info する時に常にdefault-directoryを使うように変えるものである。

どちらも適切な修正かどうかはわからないが、とりあえず筆者の環境(Linux + Subversion 1.8 + Emacs 2.4)では標記の問題は解決した。


なお、上記(*)部分の理由により、ワーキングコピーのルートディレクトリでなく、もう1階層下に別のワーキングコピーを配置した場合は、同じエラーにはならない。

ちなみに、上記のURL1にあるのは、URL2にあるデータを処理するツールである。
そういう場合など、ワーキングコピーをネストさせたいユースケースは割とあると思うのだが、そうでもないのだろうか。

少なくとも、ワーキングコピーのネストがSubversion的に好ましくないという話は聞いたことが無い。 O'ReillyのSubversion本のexternalsの項にも

You could certainly set up such a scenario by hand—using svn checkout to create the sort of nested working copy structure you are trying to achieve.
とあるので、まず問題無いと思う。