非常に今更ながらGitHubでSVNHubを使ってみた

GitHub があるぐらいだから SVNHub なんてのもあるんじゃないかと思って探してみたら、ありました。

SVNHub

f:id:wnoguchi0727:20140820233110p:plain

2013年ぐらいに最初ここを見た時はジョークサイトで、SVNHubなんてものがないか探してきた人に対して「そんなことよりGit使おうぜ!!」って言ってるだけかと思ったんだけど、今になって何を思ったか、またSVNHubでぐぐって再度ここに訪れてみてよくよく見ると違った。
リンク先のエントリを見ると意外とまじめにSVNHubとしての機能が実装されているようで、GitHubSVNクライアントのプロトコルをうまい具合にハンドリングしてくれるようだ。
しかも記事の書かれた時期が2010年とか書いてあるから4年も前から実装されてるのね、これ。

  1. Announcing SVN Support
  2. Improved Subversion Client Support

暇なやつだなって思われるかもしれないですが、実際にリポジトリ作ってやってみました。

もろもろの情報

使った SVN のクライアントのバージョンは

% svn --version
svn, version 1.7.14 (r1542130)
compiled Aug 19 2014, 23:56:41

です。

使ったリポジトリは以下。

wnoguchi/svnhub_test

SVNでチェックアウトするときのURL

GitではリポジトリをクローンするURLは

https://github.com/wnoguchi/svnhub_test.git
git@github.com:wnoguchi/svnhub_test.git

な感じになるけど、SVNでは

svn co https://github.com/wnoguchi/svnhub_test/trunk svnhub_test

な感じになる。

svn+ssh秘密鍵で認証してコミットできたほうが僕は好きなんだけど、これはサポートされていないみたいだ。

svn co svn+ssh://git@github.com/wnoguchi/svnhub_test

使ってみた

チェックアウト

% svn co https://github.com/wnoguchi/svnhub_test/trunk svnhub_test
A    svnhub_test/LICENSE
A    svnhub_test/README.md
Checked out revision 1.

コミット

次の内容で変更したとする。

% svn diff
Index: README.md
===================================================================
--- README.md (revision 1)
+++ README.md (working copy)
@@ -1,4 +1,13 @@
-svnhub_test
-===========
+SVNHub Test
+===============
-SVNHub Test Repository.
+SVNHub Test Repository.
+SVNHub のテストです。
+aaaaaaaaaaaaaaaaaaaaaa.
+bbbbbbbbbbbbbbbbbbbbbb.
+cccccccccccccccccccccc.
+dddddddddddddddddddddd.
+eeeeeeeeeeeeeeeeeeeeee.
+ffffffffffffffffffffff.
+gggggggggggggggggggggg.
+

ここで2段階認証等を設定している場合は設定であらかじめSVNクライアント用に認証トークンを払いだしてそれをパスワードとして与えないといけないので注意。

% svn commit
Authentication realm: <https://github.com:443> GitHub
Username: wnoguchi
Password for 'wnoguchi':
Sending        README.md
Transmitting file data .
Committed revision 2.

コミットできてるか確認する。

% svn update
Updating '.':
At revision 2.
% svn log
------------------------------------------------------------------------
r2 | wataru.noguchi | 2014-08-20 22:20:52 +0900 (水, 20  8 2014) | 2 lines
Update README.
------------------------------------------------------------------------
r1 | wataru.noguchi | 2014-08-20 22:15:42 +0900 (水, 20  8 2014) | 2 lines
Initial commit
------------------------------------------------------------------------

GitHub上で確認するとちゃんとコミットが送信されていることがわかる。

f:id:wnoguchi0727:20140820233111p:plain

空ディレクトリを追加しようとしたらどうなるか

% mkdir testdir
% svn add testdir
A         testdir
% svn commit
Adding         testdir
svn: E160024: Commit failed (details follow):
svn: E160024: Empty directories are not supported: trunk/testdir
svn: E160024: Your commit message was left in a temporary file:
svn: E160024:    '/Users/wnoguchi/Documents/tmp/svnhub_test/svn-commit.tmp'

そんなものはサポートされてねーって怒られました。
ですよねー。

じゃあGitの定石にしたがって .gitkeep を作成して追加してみる。

% touch testdir/.gitkeep
% svn add testdir/.gitkeep
A         testdir/.gitkeep
% svn commit -F svn-commit.tmp
Adding         testdir
Adding         testdir/.gitkeep
Transmitting file data .
Committed revision 3.

いけたいけた。
ログ確認。

% svn log
------------------------------------------------------------------------
r3 | wataru.noguchi | 2014-08-20 22:25:53 +0900 (水, 20  8 2014) | 2 lines
Add blank directory.
------------------------------------------------------------------------
r2 | wataru.noguchi | 2014-08-20 22:20:52 +0900 (水, 20  8 2014) | 2 lines
Update README.
------------------------------------------------------------------------
r1 | wataru.noguchi | 2014-08-20 22:15:42 +0900 (水, 20  8 2014) | 2 lines
Initial commit
------------------------------------------------------------------------

ほんとにできてんの?

これほんとにGitHubを中央リポジトリとして見て毎回ちゃんとデータ見に行ってるの?って疑問がわいたのでネットワーク接続を切ってみました。
これでログを確認してみます。

% svn log
svn: E175002: Unable to connect to a repository at URL 'https://github.com/wnoguchi/svnhub_test/trunk'
svn: E175002: OPTIONS of 'https://github.com/wnoguchi/svnhub_test/trunk': Could not resolve hostname `github.com': Host not found (https://github.com)

失敗した。想定通り。

ブランチを切る

GitHubではSVNHubとしての機能を実装するにあたってSVNの標準的なリポジトリレイアウトを採用しているようです。
つまり

  • trunk: origin/master相当
  • branches: ブランチはここに格納される
  • tags: タグはここに格納される

という対応となっている。

ということでブランチを作成してみる。ここでは test というブランチを作成。

% svn cp https://github.com/wnoguchi/svnhub_test/trunk https://github.com/wnoguchi/svnhub_test/branches/test
Committed revision 5.

ただSVNでブランチを切るにはコミットメッセージの入力が必要です。
適当にコミットメッセージを入力してコミット。
GitHub上で見るとブランチが作成されています。

f:id:wnoguchi0727:20140820233112p:plain

そしてさっきのコミットメッセージを入れた空コミットが作成されているようでした。
こんなコミット作れるのか・・・。

f:id:wnoguchi0727:20140820233113p:plain

マージしてみる

今度はマージを試してみます。

まずはtrunk上でコミット。

% svn diff
Index: README.md
===================================================================
--- README.md (revision 3)
+++ README.md (working copy)
@@ -9,5 +9,6 @@
dddddddddddddddddddddd.
eeeeeeeeeeeeeeeeeeeeee.
ffffffffffffffffffffff.
+chage of trunk.
gggggggggggggggggggggg.
% svn commit
Sending        README.md
Transmitting file data .
Committed revision 6.

次は先ほどの test ブランチに切り替えてコミットします。

% svn sw https://github.com/wnoguchi/svnhub_test/branches/test
U    LICENSE
U    README.md
U    testdir/.gitkeep
Updated to revision 6.
% svn log
------------------------------------------------------------------------
r5 | wataru.noguchi | 2014-08-20 22:27:16 +0900 (水, 20  8 2014) | 2 lines
Create branch: test
------------------------------------------------------------------------
r4 | wataru.noguchi | 2014-08-20 22:25:53 +0900 (水, 20  8 2014) | 2 lines
Add blank directory.
------------------------------------------------------------------------

次のような変更を加えました。

% svn diff
Index: README.md
===================================================================
--- README.md   (revision 6)
+++ README.md   (working copy)
@@ -3,6 +3,8 @@
SVNHub Test Repository.
SVNHub のテストです。
+ああああああ
+いいいいいい
aaaaaaaaaaaaaaaaaaaaaa.
bbbbbbbbbbbbbbbbbbbbbb.
cccccccccccccccccccccc.

コミット。

% svn commit
Sending        README.md
Transmitting file data .
Committed revision 7.

ログを見る。

% svn log --stop-on-copy
------------------------------------------------------------------------
r7 | wataru.noguchi | 2014-08-20 22:35:28 +0900 (水, 20  8 2014) | 2 lines
Update README on test branch.
------------------------------------------------------------------------
r5 | wataru.noguchi | 2014-08-20 22:27:16 +0900 (水, 20  8 2014) | 2 lines
Create branch: test
------------------------------------------------------------------------
r4 | wataru.noguchi | 2014-08-20 22:25:53 +0900 (水, 20  8 2014) | 2 lines
Add blank directory.
------------------------------------------------------------------------

ここでGitHub上のそれぞれのブランチの様子を見てみる。

  • trunk の様子

f:id:wnoguchi0727:20140820233114p:plain

  • test ブランチの様子

f:id:wnoguchi0727:20140820234459p:plain

これをマージする。
まずは trunk に切り替え。

% svn sw https://github.com/wnoguchi/svnhub_test/trunk
U    LICENSE
U    README.md
U    testdir/.gitkeep
Updated to revision 7.

マージする。

% svn merge -r 4:HEAD https://github.com/wnoguchi/svnhub_test/branches/test
--- Merging r5 through r7 into '.':
U    README.md

マージに成功したのでコミット。

% svn status
M       README.md
% svn commit
Sending        README.md
Transmitting file data .
Committed revision 8.

タグ付けする

最後にタグ付けして完了だ。

svn copy https://github.com/wnoguchi/svnhub_test/trunk https://github.com/wnoguchi/svnhub_test/tags/v1.0

f:id:wnoguchi0727:20140820233116p:plain

できた。
どうやらタグ付けの際にコミットメッセージを入力するけど、このメッセージは無視されるみたいだ。

まとめ

とりあえずGitHub上でもひととおりのSVN操作はできることがわかりました。
すごいね・・・。
ただ、試してないけどさすがに svn propedit とかで svn:ignore をセットするのとかはSVNメタデータレベルの処理なので無理なんじゃないかな・・・。

当然だけど Git リポジトリとしてクローンすることは普通にできる。

% git clone git@github.com:wnoguchi/svnhub_test.git svnhub_test_git
Cloning into 'svnhub_test_git'...
remote: Counting objects: 24, done.
remote: Compressing objects: 100% (19/19), done.
remote: Total 24 (delta 6), reused 16 (delta 2)
Receiving objects: 100% (24/24), done.
Resolving deltas: 100% (6/6), done.
Checking connectivity... done.
% git log
commit 808c1703ac1af2eee14152817f569a27c5b872e0
Author: Wataru Noguchi <wnoguchi.0727@gmail.com>
Date:   Wed Aug 20 22:50:42 2014 +0900
Add Scala sample.
commit c70b6295ce45f4b822455a01a447c9a112794ecb
Author: Wataru Noguchi <wnoguchi.0727@gmail.com>
Date:   Wed Aug 20 22:38:49 2014 +0900
Merge test branch.
commit 37587c2e9e166dcb751f91db6a45cca86ffe8f55
Author: Wataru Noguchi <wnoguchi.0727@gmail.com>
Date:   Wed Aug 20 22:32:18 2014 +0900
Update README on trunk.
commit 52d1556cdd28c52efbdd7d5f341980678870dbba
Author: Wataru Noguchi <wnoguchi.0727@gmail.com>
Date:   Wed Aug 20 22:25:53 2014 +0900
Add blank directory.
commit cc0240711aeae832546b8d4fdd2d5545976ad723
Author: Wataru Noguchi <wnoguchi.0727@gmail.com>
Date:   Wed Aug 20 22:20:52 2014 +0900
Update README.
commit a349debc3aba2374c8cdd37ea6901fa02e93ab39
Author: Wataru Noguchi <wnoguchi.0727@gmail.com>
Date:   Wed Aug 20 22:15:42 2014 +0900
Initial commit
% git branch -a
* master
remotes/origin/HEAD -> origin/master
remotes/origin/master
remotes/origin/test
% git tag
v1.0

まあ、特に理由がなければ Git 使いましょう。
いじょ。

入門者の本

入門git

入門git

Subversion実践入門:達人プログラマに学ぶバージョン管理(第2版)

Subversion実践入門:達人プログラマに学ぶバージョン管理(第2版)

References

  1. SVNHub
  2. Improved Subversion Client Support
  3. Announcing SVN Support

GitHubのpull requestワークフローについてメモ

基本的なこと

  • マージ前に必ずリベース
  • ホットフィックス、フィーチャーにマージする意味が無い(git-flow)
  • 基本的に Fast-forward しない

コミットメッセージについて

Gitコミュニティにパッチを送る際に学習したことですが、
1行目に50文字以内でそのコミットの概要を記載する。
空行を開けて3行目以降には詳細を説明する。

Issue #1122 hogehoge.rb: [AAA] aaaaa
XXXにした。
  • なるべく豊富なコミットメッセージを残す。
  • 経緯・歴史がわかるように。

参考文献

拡張子を指定してgit grep

そのままgrepかけるとログファイルとか引っかかることがあったので、このような感じで拡張子指定できるようです。否定はないのかな。

git grep foobar -- "*.php"

msysGitのマルチバイトファイルパス

つかれた。
msysGitであげた不具合のお返事がなくなって、正直みんなこのあたりで困ってないんだろうなー、パッチ送ってもOS依存の PATH_MAX まわりがからんでるから容易には取り込まれないだろうし、3流プログラマのぼくには修正は難しくて、とりあえず最適化無効にしてビルドすれば動くからそれで諦めてたんだけど、最近だれかがまたパッチ投げてくれたっぽい。末尾をゼロ埋めする strlcpy を使うようにしてるみたい。ものすごい長い英文で議論が始まってついていけないので、遠くから見る。Reported-byがついてたから微妙に嬉しい。
うむ、つかれた。