2012年5月6日日曜日

bitbucketで一人pullrequestとかしてた

bitbucketで遊んでみた

ちなみにGW中bitbucketとずっと戯れていたわけじゃないよ。猫と戯れていただけだよ(´;ω;`)

bitbucket は自分のリポジトリをforkできます。
→確か前々回ぐらいの #TokyoMercurial で @troter さんがそんなことを呟いていましたが、確かにできましたw
githubはしらん。

まあ、普通しないよね。練習以外に何に使うのだろう…

あとpull request そのものについて詳しい訳じゃないので間違っている場合はご指摘ください。
名前からして「ねー、ねー。僕のリポジトリ(ブランチ)pullしてよ〜」なんですよね。



準備

とりあえず適当にリポジトリを作ります

作ったらテキトーにコミットしてpushしておきます

bitbucketに戻ってforkしてみます


普通他の人からforkするときはリポジトリ名はそのままでしょうけど、自分で自分のリポジトリをforkするので名前は変えたほうがいいと思います。

fork結果を見るとこんな感じで、何をforkしたのかという情報とかがオリジナルと違う点のようです。

compare fork というのを選ぶと、hg in/out を実行した結果が見られます。
作ったばっかりなので当然差分はありません。



とりあえずdefaultブランチのままぶん投げてみる

forkした側を適当に修正して、pull requestをしてみます

自分のどのブランチを相手のどのブランチに送り込むのか選択する感じ?

compare forkを見てみたところ
さっきと違ってoriginalとの差分がわかります

pull requestを受け取った側

とりあえず受け入れてみる

フツーにpullした状態が出来ます。

調子に乗って2個コミットした状態でRequestを投げてみます

compare fork だと hg diff -r b68e677f670d とやったような感じ
(2個分まとめての差分)

受け入れた結果。
何も問題なさそうです。



拒否ってみる(拒否られてみる)

テキトーにコミットしてpull Requestしてそれを拒否ってみました

Rejectボタンを押すとこんな画面で、拒否理由を書いてRejectするようです

拒否完了


じゃあ、肝心の拒否られた側ですが…
どうやらInboxにメールが届いているだけで、視覚的にダメだったお!みたいなのはなさそうです。
まあ受け入れられたときもそんな感じですが。
俺が気がついていないだけでもっと視覚的な何かがあるんでしょうか?

ところで拒否られたらどうすればいいんでしょう?
個人的にはstripしてなかったことにしてしまえばいいかと。
もしくは再度forkすればいいんじゃね?


backoutがいいんじゃね?的なこと書いてありますが、forkしたリポジトリが複数人でガンガンコミットしたり…
ってことは無いでしょうし。わかんないけど。
あとこの作業後にbackupファイルがDL出来るみたいです。

ローカル側はまあ適当に直せますしね。



下図みたいにpull requestしようとしたら元側が更新されていた…みたいな場合
まあrebaseしろって話でしょうけど、やってみる



受け入れ側…よく見たら「Accept and merge」になっている…
ということはマージして受け入れるんだろうなぁ

押してみたらコミットメッセージが書けるようになっていた



結果 まあ当然の結果



pull requestを受け入れてもらったわけですが、当然下記のように元リポジトリとfork側で違う歴史になりました
揃えないといけませんがどーしましょう


別にfork側のリポジトリを消して再度forkしてもいいと思いますが、改めてcompareを見てみるとコマンド書いてます。
ので、このまま実行してみます。


cd fork_repo_path
hg pull -r default ssh://hg@bitbucket.org/orginal/orginal_repo
hg update default

hg serve でローカルの状態見てみるとこんな感じになる。
これでfork側がoriginal側を追従できた

あとはpushしてやればOK



ていうかpull requestを取り込むかどうか、ローカルで確認したいんですけど!という受け入れ側(original側)はどうすれば?
というのも実質さっきのやつと一緒

forkした側で見れるcompareのoutgoingに書いてある通りに実行でいいんじゃね


# オリジナル側 forkした側じゃないよ
cd orignal_repo_path
hg pull -r default ssh://hg@bitbucket.org/fork/fork_repo

上記みたいにpull requestしてきた人のデータを直接pullすればローカルでじっくり確認できます。

ちなみにこのrequest結果をローカルでみて、
「いけるいける!!」
と思いオリジナル側がこのままpushしたらどうなるのか…

なんと、受け入れた事になりました!
ちゃんと受け入れたよ!ってメッセージも発行しているし、さすが。





正直ここまで来たらもう先は読めたしやらんでもいい気がするけど、ブランチ切ってpull request も試してみる。
一応下記を試す
すべてRequest側はhogeブランチを切るとして

  • hogeブランチをdefaultに取り込んでもらえるかどうか
  • hogeブランチをhogeブランチとして取り込んでもらえるかどうか

というわけで一つ目。
まあこんな感じでsend requestを投げた



requestを投げた側なんだけど、compare forkに差分表示が無い…
なにかしら表示してくれると思ったんだけど、もしかしてdefault ブランチのみを追従しているのかな?
(だからcompare に表示されるコマンドが -r オプションつけているかも…?)

受け入れる側も差分とかは出るものの、ブランチ切られているってことは
ローカルで確認しようとした時にヤヤコシイよね。
ブランチ名指定しなかったら下手したら腐るほどデータ引っ張ってきちゃうし。

まあとりあえず受け入れて…と思ったら、これはAccept and pull なのか。へ~


っておい、やっぱりマージじゃねーかorz


でもまあpull request的に
「hogeブランチだけどdefaultに取り込んでね!」
って明示してんだから動作的には正しいですよね。

でもマージ時のコミットメッセージ書けなかった…


次、hogeブランチとして取り込んで!!!




フツーにpullして終わりました。めでたしめでたし





pull requestの内容が競合するようなものだったらどうなるのか

いやまあ正直requestする側がrebaseしてくれれば…ね… ってのもあると思うんですけど
pull requestと本家の更新が同時とかってこともあるだろうし、試さずにはいられない

compare forkを見る。もうおもいっきりコンフリクトって書いてある、赤字でw



それでも気にしないで送りつける



受け取った側。
コンフリクトしてるから取り込むなら自分で解消してねってところですかね。


送り手的にはcomapreで事前にコンフリクトがわかるわけですし、やっぱり解消した上で送ったほうがいいとは思います。
けどまあ送ることはできるということで。



競合した上にブランチ切ってあったらどうなるのか?
ブランチ切るとそれはcompareとして表示されなかったので、一見コンフリクトと見なされないのではないか?
(いやもちろんfork側がincomingを見て、差分があったら取り込んだ上でpushすればいいんだけど)

試してみると… なんだちゃんとコンフリクトって出ますね。




わたしoriginal側だけどforkした奴が素敵だから勝手に取り込みたいの!

pull request 出してくれているわけじゃないけど、いい修正だし欲しいなぁ…
みたいなとき

実際そんなパターンがあるのか?と思いますが、あったんですよこれが。

まあ、pull requestを取り込むかどうかローカルで確認したい時と同じでいいハズ
そして今更気がついたけど、コミットする人の名前変えればわかり易かった…


こんな状態で
cd original_repo_path
hg pull -r default ssh://hg@bitbucket.org/fork/fork_repo
#取り込むか確認したら
hg push

で、こうなる。



じゃあ開始時点がこんなだったらどうするか?


まあ諦めてマージな気がするなぁ

とりあえずpullして持ってきた状態


まずマージしてみる

至って普通


続いてrebaseなんだけど…そもそもこの場合ってrebaseは間違っている気がするんだなぁ…
なぜならpullして持ってきた状態って全部のphaseがpublicなので基本rebaseしない前提のはず…

まあでもやってみます

pullして持ってきた方を自分にくっつけることにした場合

cd original_repo_path
hg phase -d -f tip
hg rebase -d 9 -s tip
hg push

結果
一直線になっているし問題なさそうだけど、リビジョン番号が変わってしまうことに注意
まあそれ自体は別にわかりきっていることですが…

それよりもfork側のcompare forkから incomingを見るとこうなる

もちろんoutgoingもある

うーん、びみょー


逆版(自分のcommitをpullして持ってきたcommitにつなげる)ってのはもっとやらない気がする。
だってoriginal側を変更するということはstripしないと見た目おかしくなるし、
何より見ている人、触っている人がそれなりに居るだろうからまずやらないよね?

なので省略


有りなのかどうなのかわかりませんが、マージはしたくないけど取り込みたいし…の場合
「やあやあ、そのコミット リベースした上でpull requestしてくれないか!」と連絡するのが一番よかったりして…


色々とやってみたけど結局どうpull requestするのがいいんだろう?

GitHub的にはこちらのブログを見ると(pull request マナー でググってtopだった)
pull request用のブランチ切ってrebaseしてまとめてそれを投げるのが良いらしい。なるほど。

じゃあbitbucketというかhgの場合は…

適当に幾つか見て回りましたが、ほぼ default -> default だったので
特段pull request用にブランチ等は意識しなくて良いようです。多分。

なので pull request 前にoriginal側との差分を最小限にして(取り込んでrebaseして)から
やればまあいいんじゃないかなぁ…

手順的には

  • forkする
  • 作業する
  • original側をpullしてくる
  • 更新があったらrebase
  • push
  • pull request

みたいな手順になるんでしょうね。きっと。

何れにしても自分で自分のリポジトリをforkできるんで色々と試しておくといいのかもしれません。

あとは実際にpull requestしてダメだったら駄目出ししてくれるはず(他力本願

ついでに言うと #TokyoMercurial に参加すると誰かがやさしく教えてくれるかもしれない?(ステマ













2012年4月7日土曜日

Eclipse + Scala + sbt + Specs2 な環境を試してみた

水、木とJavaOneに行かれた皆様、どうでしたか?
ええ、私は会社にいましたよ…

http://togetter.com/li/283845 とか見て、とても楽しそうで羨ましい…って指咥えて仕事してました。

まあ指咥えてってのは嘘ですし、仕事し…



というわけで私も唐突にScala触ってみました。

その時のメモ

私の環境
Mac OSX 10.7.3
Eclipse 3.7.2
Scala IDE for Eclipse 2.0.0
sbt 0.11.2

まあ殆どこちらのブログ参考にしたんですけどね
http://blog.weblade.in/archives/1905

まずはEclipseを用意します
http://www.eclipse.org/downloads/

次にScala IDE for Eclipse というプラグインを入れます
http://scala-ide.org/
一応 For 2.9.x の安定版のリンクを選びました

続いてEclipse.iniを編集します。
http://www.assembla.com/wiki/show/scala-ide/Setup とか参考にして適当に
とりあえずヒープサイズだけでっかくしておけばいいと思います。たぶん。

Macの場合
Eclipse.app/Contents/MacOS/eclipse.ini
のはず

sbt(simple build tool)入れます。
homebrewで入れました
$ brew install sbt
多分今なら0.11.2が入ります

brewでインストールしたsbtを見ると
#!/bin/sh
# /usr/local/Cellar/sbt/0.11.2/bin/sbt
test -f ~/.sbtconfig && . ~/.sbtconfig
exec java -Xmx512M ${SBT_OPTS} -jar /usr/local/Cellar/sbt/0.11.2/libexec/sbt-launch.jar "$@"
とあるので
https://gist.github.com/1139288 を参考にSBT_OPTSを環境変数にでも追加すればいい気がします

export SBT_OPTS="-Dfile.encoding=UTF8 -Xmx1536M -Xss1M -XX:+CMSClassUnloadingEnabled -XX:MaxPermSize=256m"
特にエンコードは指定しておかないと、macのターミナルでsbt testとか実行した時に日本語表示が化けて悲しい事になりました。


さてここまでやったらあとはbuild.sbtを作成するのですが、eclipseプロジェクトを作っては消し…ってのを結構やるので
とりあえず最低限のプロジェクトが作れるようなshスクリプトでも作ってみました。
本当にいいのかどうかは正直sbtどころかmavenだってマトモに使ったことないのでさっぱりですけど。
内容は件名のようにSpecs2が使えればいいんじゃね?的な最低限のやつです。


※なおgiter8という素晴らしいものがあります。自分でスクリプト書いている場合じゃねえぜ!




上記スクリプト(hogeと仮定)をテキトーに保存して実行権限与えたとしてあとは

$ cd てきとーな場所
$ hoge hello-scala

とかやれば、eclipseのプロジェクトがhello-scala というディレクトリの下に作られます。
追加したいライブラリ等があるのなら、hello-scala/build.sbt の libraryDependencies に追加した後 hello-scala直下で

$ sbt reload update eclipse

でOK


出来上がったプロジェクトをEclipseでImportします。

するとこんな感じ?



さて、肝心のSpecs2ですが選定した理由は、「会社でRailsだしRspecだしなんとなく…」というだけです。
あとで見たらScalaTestでもSpec的なやつあったしw
これでなければならないということもなければ、むしろ組み合わせて使うことも可能なようです。
http://etorreborre.github.com/specs2/guide/org.specs2.guide.SpecStructure.html#ScalaCheck+values

Eclipse上で実行するときの注意点は以下のように対象クラスにJUnitRunnerを付け忘れないことだけみたいです。
http://scala-ide.org/docs/user/testingframeworks.html
import org.specs2.mutable._
import org.specs2.runner.JUnitRunner // 忘れないこと
import org.junit.runner.RunWith // 忘れないこと

@RunWith(classOf[JUnitRunner]) // 忘れないこと
class HelloSpecs2 extends Specification {

あとはフツーに走らせてやれば動きます。

もちろん sbt test で動かしてもテストは動きます。素晴らしい。(当たり前か)


おまけ

build.sbtに以下記述を追加するとSpecs実行結果がJUnit形式のxmlが出力されます
http://etorreborre.github.com/specs2/guide/org.specs2.guide.Runners.html#Simple+build+tool
testOptions in Test += Tests.Argument("junitxml")
// 贅沢にも全部出すのなら
testOptions in Test += Tests.Argument("junitxml", "html", "console")

出力先はxmlは target/test-reports 以下に
htmlは target/specs2-reports 以下 のようです。

なおhtml出力の場合は
"org.pegdown" % "pegdown" % "1.0.2"
みたいな感じでpegdownというものを依存関係に足さないと怒られます。

xmlを出力すればJenkinsさんとかもウマウマできますし便利ですね。


scala ide で設定できるformatterはscalariformというのを使っているようです。
http://mdr.github.com/scalariform/
で、sbtscalariform なんてものがあります。
https://github.com/typesafehub/sbtscalariform

入れるとコンパイル時にフォーマットしてくれるっぽいですね。素敵。
Eclipseを使わなくてもフォーマットはみんな統一できる、というかビルドサーバ(が、あればだけど)が勝手に整形してくれる
みたいなことができるんですよね、きっと。


さて、あとは使う人間のscala力を高めればいいのかな(白目

2012年3月31日土曜日

MercurialEclipseを使ってみてはいかがでしょう

今月一回もブログ書いてない…
Gistにゴミのようなメモがちょっと溜まったくらいだなぁ…今月

前回需要あるかなとか言ったんでちょっとだけ。
個人的にはすごくお世話になっています。
まあこの一ヶ月全然Eclipse触ってないけど。

基本的な使い方は
http://javaforge.com/project/HGE
に行ってとりあえず動画を見るのがいいんじゃないでしょうか?



とりあえずインストール


Macだと既にHgへのパスが入っている。winだと指定しないとダメかも知れない。


QuickDiffとかお好みで


設定しておくと、編集した箇所が一目でわかってちょっと幸せ




以下普段こんな感じで使っている系

まずいつも通りテキトーなプロジェクトを作ります。
テキトーに作ったら、リポジトリを作ります。ターミナルから(ぇ

$ cd path_to_project_root
$ hg init
もちろんプラグイン側から作ってもいいんですが、なんかinitだけはコマンドが楽なんです。俺は。

その他

workspace
├── project
└── projectTest

みたいな環境でworkspaceでリポジトリ(projectとprojectTestで1リポジトリ)作りたい!みたいな場合
多分eclipseから生成は出来なさそうだし…とか。まあ確認してませんが。
→ちなみに上記構成でもEclipseはちゃんと認識しますし、下記作業も当然可能です


eclipse に戻って読み込む



するとこんな感じ


とりあえずコミット…いや、せっかくだしMQ使いましょう


通常のコミットと同じ画面で作業ができて便利



二個目



コミットメッセージ間違えた?
さっきのパッチにもっと変更加えた(減らした)状態にしたい?
qrefreshでどぞー



こんな感じで常に qseries の状態が見えるような状態



リビジョングラフ的な。
Mercurialに限らず、やはり履歴の確認はGUIツールが断然いいですね


表示されない場合とかはShow Historyを選択してみたら意外と何とかなるかもしれない



編集して差分が発生したファイルはこんな感じで確認できる


ちょっと目立たないなぁ…とか思ったら色とか変えてみてはどうでしょう




みたいな感じでMQの機能全部では無いにしろ普段良く使いそうな部分はしっかり網羅されています
もちろんMQ以外もフツーに使えます。

ただ下記は残念ながらできなかった記憶があります

$ hg qrefresh hogehoge #存在しないパスを指定して未コミット状態に戻す
$ hg qpush hoge.diff --move
$ hg qguard

他にもrecordとか出来なかった記憶が。
あと、Mercurial自身のversionは2.1.1とかでも余裕で動きますが、当然phaseとかは無理
もちろん $HOME/.hgrc とかに各エクステンションを有効にする記述が必要

その他、ターミナルからコマンド叩いた結果はすぐには反映しなかったりとか、
使い込んでくると微妙に惜しい部分が出てきます。多分。

qfoldが使えるんで自分は
・qnewでこまめにパッチ発行
・qfoldで適当にまとめたのちリビジョン化
という使い方をやってます。

ちなみにこのプラグインに出会ってから「MQかわいいよ、MQ」状態になったのが俺です。


そういえばhgsubversionを有効にしていたら、このプラグイン経由でsubversionにpushとかできるのかな?
次回の #tokyomercurial で試してみよう。