kotas.tech

こたすの技術的なチラ裏 ( Twitter: @ksaito )

変態 git

git を変態的に使ったのでメモ。

どれもこれも、かなり特殊なシチュエーションなので参考になりません。多分。

SVN リポジトリを read-only で Git に取り込む

色々な都合により、コミットしてはいけない SVN リポジトリを git に取り込む必要があったので。(SVN サーバー側の hook 等は使えず)

普通に git-svn で取り込んだブランチを直接 git の中央リポジトリに push すると、他の人が clone して git svn dcommit とかできてしまうので、出来ないようにしたい。

そこで、git-svn で取り込んだ変更を、一度 Non-git-svn なブランチに merge し、そちらを push する運用にした。

レシピ

まず、空の git リポジトリを初期化。

$ mkdir hoge
$ cd hoge
$ git init
$ touch .gitignore
$ git add .gitignore
$ git commit -m 'initial commit'
$ git remote add origin REMOTE_GIT_REPOS
$ git push -u origin master

SVN リポジトリを取り込む。git svn clone ではなく、git svn init + fetch で一旦リモートブランチだけ作るのがミソ。

$ git svn init -R svn-hoge --prefix "svn-hoge/" SVN_REPOS_URL
$ git svn fetch -rHEAD svn-hoge
# でかい SVN リポジトリなので -rHEAD で最新のリビジョンだけ取り込んでます

作ったリモートの SVN ブランチ (svn-hoge/git-svn) をローカルブランチとして作成

$ git checkout -b svn-hoge svn-hoge/git-svn

この時点で、Non-git-svn な master と、git-svn な svn-hoge ブランチが出来る。

$ git branch -a
  master
* svn-hoge
  remotes/origin/master
  remotes/svn-hoge/git-svn

master と svn-hoge は全然関係ないブランチとなっているので、master では git svn rebase や dcommit は出来ない。

あとは、定期的に以下を行なって、master に SVN のブランチをマージ。

$ git checkout master
$ git merge --no-ff svn-hoge
$ git push origin master

git merge の際に --no-ff を付けておかないと、 master が git-svn 化してしまうので注意。

また、master を git 側で変更する場合、merge がコンフリクトする可能性があるけど、失敗した場合はアラート出して人間がマージします。

特定ワードをコミットメッセージに含むコミットだけ strategy を変えてマージ

色々な都合により、普通にマージすると特定のワードを含むコミットだけコンフリクトが起こるので、そいつらだけ --strategy=ours でマージしたかった。

結論から書くと、何回かにわけてマージする形で解決。

レシピ

git rev-list の --grep オプションを使うと、2つのブランチの差分のうち、特定のワードをコミットメッセージに含むコミットだけをリストアップできる。(git マジ変態。いい意味で)

# master 〜 hoge の差分の内、"特定のワード" を含むコミットをリストアップ (リビジョンのリストが返る)
$ git rev-list --grep="特定のワード" master..hoge

あとは、これで得られるリビジョンそれぞれについて git merge $rev^ + git merge -s ours $rev をする。($rev^ = $rev の1つ前のリビジョン)

$ git checkout master
$ for rev in `git rev-list --reverse --grep="特定のワード" master..hoge`; do
       git merge --no-ff "${rev}^" -m "early commit for merging hoge"
       git merge -s ours "${rev}"
   done
$ git merge --no-ff hoge -m "merged hoge"

とっても気持ち悪いですね^^

過去のコミット履歴から特定のワードを含むコミットを消し去る

git filter-branch を使うと、過去の履歴を改ざんできるのは git の 変態的 強みですが、それを使って特定のワードをコミットメッセージに含むコミットを無かったことにします。(もはや動機の説明に疲れたので割愛)

レシピ

git filter-branch --commit-filter でコミットを選択して無かった事にできます。

引数に渡したスクリプトが実行され、skip_commit "$@" するか、 git commit-tree "$@" するかでコミットするかどうか選択できるんですが、コミットメッセージは標準入力に渡されてくるので、普通に cat や grep しちゃうと、フィルター後のコミットのメッセージが空になってしまいます。

そこで、 /dev/stdin から読んで判定します。

$ git filter-branch --commit-filter '
  if [ `grep -c "特定ワード" /dev/stdin` -gt 0 ]; then
      skip_commit "$@";
  else
      git commit-tree "$@";
  fi' HEAD

これはそんなに変態じゃない、、、かな、、、?

社内向けWebサービス開発のススメ

社内向けWebサービス「ニコニコプロデュース」

例えば、コードレビューをしている時に誰かが鋭いツッコミを入れてくれた時。

例えば、社内のチャットで、ふと誰かが名言を書き込んだ時。

そんな「もっと評価されるべき」を、「評価」する手段が欲しい。

そんな思いから、社内向け Web サービス「ニコニコプロデュース」を作りました。

画面はこんな感じです。

f:id:kotas:20111227234221p:plain

使い方は簡単で、「だれうま」とか「GJ」とか思ったらポイントをあげる。それだけです。もらったポイントの使い道は特にありません。

こんな感じで、趣味としてちょこちょこ社内向けサービスを作ったり、簡単なツールを作ったりしているので、その魅力について語りたいと思います。

作っている間

なにせ自分で1から企画して自分で全て実装するので、作っている間はとても楽しいです。

「こういうページがあってー、こういう UI でポイントをつけれてー・・・あ、ユーザー認証はどうしようかな。えーい、社内グループウェアの情報を使うか。あとはランキングも欲しいなー」

みたいな感じで悶々と想像しつつ、要件定義書も設計書も無しで、簡単な1枚のメモを元に、ガンガンコードを書いていきます。何を作ればいいかは自分が知っているし、どう作るかも即断即決です。

また、趣味の開発なので、色々と実験的な試みができます。例えば、仕事で使った事のないフレームワークを採用してみたり、いっそ言語を変えてみたり、とにかくやってみたい事を全部つめこみます。

例として、上に書いたニコニコプロデュースでは、試しに PHP のマイクロフレームワークである「Limonade」を使ってみたり、作っている最中に Twitter 社から発表された「Bootstrap」をすぐに採用してみたり、やりたい放題しました。これがまた楽しい。

僕は開発も好きですが、使いやすい UI を考えるのも好きなので、コードを書くのと同じぐらい CSS の調整にも時間を掛けます。普段の仕事では出来ない事です。「ぼくがかんがえた最強のUI」を実現できるとドーパミンがドパドパします。

自由に作れるのは楽しい!

公開

そんなこんなで、ひと通り機能ができたら、ついに公開してみます。

僕の場合、社内チャットで「こんなんできたよー」と URL を貼ってみんなの反応を見ます。

この時点で「Webサービス企業に勤めていて」「社内チャットに参加している」というフィルタリングが掛かっているので、みんなリテラシが高く、すぐにサービスの意図を汲み取ってくれ、使い始めてくれます。

みんなが使い始めた様子がわかり、さらに、チャットで反応や感想が即座に返ってくるので、ドパドパが止まりません。まさにヘヴン状態。

さらには、口コミでどんどん社内の利用者が広がっていき、活発にやりとりが行われるようになります。そうなってくると、例えば「誰かからポイントをもらったらすぐに知りたい」といった要望が出てきます。

すると僕は、待ってましたとばかりにすぐに実装します。誰かがポイントをあげたら、社内チャット (IRC) にボットを書き込むようにしてみました。すると、僕に対してポイントが振られるのです。

作るのも楽しいですが、やっぱり使ってもらうのが一番楽しい!

その後

今では、ニコニコプロデュースはそれなりに定着し、僕の周りでは「ポイントあげとくねww」「10ポインツ!」などのやりとりが行われるようになっています。

想定していなかった使われ方もされ始めました。例えば、インフルエンザで休んだ人にみんなが「お大事に」とポイントをあげたり、「○○さんが変態発言をしたので」とワッフルワッフルしたくなるようなコメント付きのポイントをあげたり。

さらには、週に1度の定例会議でポイントランキングが発表され、1位の人を祝う新たな習慣まで出来てしまいました。この辺りは、弊社特有のノリもあると思いますがw

終わりに

自分で作ったサービスによってユーザーの間で新たなコミュニケーションが生まれる。考えてもいないような楽しみ方をしてくれる。

これらは一般のユーザー向けに提供する大規模 Web サービスでも強烈に味わう事ができます。僕は入社以来、この快感の虜になっていて、次の機能を作る原動力になっています。

社内向けのサービスというのは、この大規模 Web サービスの縮図に他なりません。会社という小さく閉じたサークルで公開するからこそ、反応がよりダイレクトに伝わり、身近な人たちを喜ばせる楽しみを味わう事ができます。

プログラミングが趣味の方も、そうでない方も、騙されたと思って、一度社内向け Web サービスを作ってみてはいかがでしょうか。きっと「ハマる」と思います。