Githubを使ったpull requestベースのワークフロー(pull request送る編)

f:id:toyoshi:20120814150050p:plain
あるプロジェクトをpull requestベースの開発に変更するので説明の練習もかねてワークフローのまとめ。(pull requestを送るところまで)
要点はブランチをきって作業することと、fork元の変更に追随してからpull requestを送るという2点。

※下記内容は僕のチーム向け(少人数向け)の内容です。日本語のドキュメントとしてはすでに「GitHubへpull requestする際のベストプラクティス - hnwの日記」という素晴らしいエントリがありますので、そちらを先に読むのがよいと思います。

ワークフロー

  1. (初回のみ)masterブランチをforkする
  2. (初回のみ)cloneする
  3. ブランチを作って作業をする
  4. コミットをまとめる(整理する)
  5. fork元の変更に追随する
  6. pushする
  7. pull requestを送る

実際の作業例

masterブランチをforkする

f:id:toyoshi:20120814141905p:plain
ただし各ユーザごとにリポジトリをもつと複雑になるので、小さなチームなどであれば元のリポジトリをそのままつかう場合も多いようです。

ローカルにcloneします

$git clone git@github.com:{username}/{repo_name}.git

ブランチを作って作業

masterで作業すると面倒なのでブランチを切るのがよい。
(特にfork元に追随するときに困る)

$ git checkout -b ticket002
Switched to a new branch 'ticket002'

コミットをまとめる(整理)する

作業が終わったらpush剃る前に、pull requestからtypoとかの歴史を消したり、できるだけレビュー側の人が読みやすいようにコミットをまとめる。(一つにまとめる必要はない)

それにはgit rebase -i(interactive)コマンドを使う

$git rebase -i HEAD~4 #4回前までのコミットについて操作する

するとエディタが開く

pick 02fff76 add file
pick fcda175 add text
pick 9285530 add name
pick 4800c2b fix typo

# Rebase 474dbff..4800c2b onto 474dbff
#
# Commands:
#  p, pick = use commit
#  r, reword = use commit, but edit the commit message
#  e, edit = use commit, but stop for amending
#  s, squash = use commit, but meld into previous commit
#  f, fixup = like "squash", but discard this commit's log message
#  x, exec = run command (the rest of the line) using shell
#
# If you remove a line here THAT COMMIT WILL BE LOST.
# However, if you remove everything, the rebase will be aborted.

上から4個分のコミットについてリストされる
"pick"と書いてある列を編集して保存して閉じることでこのコマンドは動作します。
今回はtypoのコミットをなしにしたいので以下のように編集します

pick 02fff76 add file
pick fcda175 add text
pick 9285530 add name
fixup 4800c2b fix typo

...省略...

これで保存してエディタを閉じると4800c2bが直前の9285530と統合されます。
なお他に出来る事は以下のとおり
pick...そのまま
reword...コメントを編集
edit...コミットを編集
squash...直前のコミットと統合してコメントを編集
fixup...統合
exex...(あとで調べる)

fork元の変更に追随する

普通は自分が開発している間にfork元も開発が進んでいる。
コンフリクトを起こすようなpull requestを送っても受け入れ側が大変なのでこちらで追随する

upstreamという別名でfork元をリモートリポジトリとして登録(初回のみ)

$ git remote add upstream git@github.com:{fork元username}/{repo_name}.git

ローカルのmasterにfork元の変更をpullして、変更をトピックブランチにつっこむ

$ git checkout master
$ git pull upstream master 
$ git checkout ticket002
$ git rebase master ticket002

pushする

$ git push origin ticket002

pull requestを送る

Githubの画面から作業して終了。
f:id:toyoshi:20120814145141p:plain