pull request って面倒

github で pull request する手順としてよく説明されるのは,

  1. 本家を fork する
  2. fork したものを clone する
  3. トピックブランチを切って作業する
  4. push する
  5. pull request する

でしょうか. 更に,コミットは1つに squash しろなんてマナーが付きます. みんな,ホントにこんなことしてるの? というのが,今日の話題です.

普通は fork から始まらない

pull リクエストをしたくなるプロジェクトには,まず ユーザってところから関わるんだと思います. 例えば,僕は,Mew のユーザなので,本家を clone して使っています. それで,時々 pull したりして平和に暮らしている.

# 本家から clone
% git clone git://github.com/kazu-yamamoto/Mew.git
# ときどきアップデート
% git pull

使っている内にバグや改善点を見付けるので,思わずコード書換えたりしますよね. でも,commit とかしないでしょ? 面倒だし.

% vi mew.el

しばらく使ってみて調子がいいと,pull request しとくか,ってなりますよね. だって,本家から pull する度に conflict に怯えるのは嫌でしょう?

で,おもむろに commit しちゃって,

% git add mew.el
% git commit -m 'My great hack.'

この日は,ここで力尽きて寝ちゃったりします. その後,微調整のコミットが3つぐらい伸びて放置という状態.

conflict から始まる pull request

それで,しばらく忘れて平和に暮らしている訳ですが,本家に追従したくて, pull してみると,conflict したりします.で,いよいよ pull request 欲が上がってきます. まず,落ち着いて,conflict 前に戻しましょう.

# origin/master と master の位置関係を確認.心配ならメモっとく.
% git graph
# master を元の位置に戻す
% git reset --hard ORIG_HEAD
# やらなくてもいいけど何となく
% git fetch

git graph は ~/.gitconfig に書いた alias です.ブランチの関係を確認するのによく使います.

graph = log  --format='%h %Cgreen%an%Creset, %ar%Cred%d%Creset%n  %s%n' --graph --all --color

さて,ここからが,本気出すところです.

  1. 本家の master に rebase します.

    % git rebase origin/master
    
  2. 場合によっては,commit を 1つにまとめます.commit log もマジメに書き直しましょう.

    % git reset --soft origin/master
    % git commit -m 'My humble hack.'
    

これで,push する準備ができました.

github で fork しよう

自分の github アカウントで本家を fork しましょう. これは,ポチッとするだけですね.すると,

git@github.com:yoshinari-nomura/Mew.git

という remote ができたとします.これを clone する必要はありませんよ.

次に,これを remote として追加してやりましょう.nom という名前にしてみました.

% git remote add nom git@github.com:yoshinari-nomura/Mew.git

滅多に使わないこのコマンドを覚えるのが面倒なら .git/config に以下を加えます. origin をコピーして書換えればいいのでラクです.

[remote "nom"]
        url = git@github.com:yoshinari-nomura/Mew.git
        fetch = +refs/heads/*:refs/remotes/nom/*

それで,topic branch っぽい名前 (my-humble-hack) に push します.

% git push nom master:my-humble-hack

この間に origin/master が動いていないか確認したほうが親切です.commit が伸びたりしていたら, rebase しなおした方がいいかもしれません.そのへんは,自分が本家の人とどれぐらい仲良しかによって決まります. これがソーシャルコーディングですね.

ちなみに,この topic branch は使い捨てなので,手元で branch にするまでもないでしょう. 長生きしそうなら,branch を切って,かつ remote tracking branch にしておく場合もあります. 例えば,こう:

% git branch my-humble-hack
# -u で remote を track する
% git push -u nom my-humble-hack:my-humble-hack

めでたくマージされたら,また平和な生活に戻ります. こんな感じで,三角パスが簡単にできるのが,DVCS のいいところだと思います.