sci

最果て風呂

Fork するタイプの Pull Request

はじめに

しばらく GitHub独り Pull Request をしていたのだけれど、ステップアップしてちょっと難しい Fork をするタイプのプルリクエスト (以降 PR とする) をすることにした。理解するポイントは、本家・リモート・ローカルの 3 つのリポジトリの関係と操作を把握することかな。(自分は当初、GitHub の中では本家とリモートのリポジトリは自動的に同期してくれるものだと思っていたのだ!)

今回は、とてもお世話になっていた vim-jp というコミュニティサイト内にある vimdoc-ja-working リポジトリ (Vim に付属しているマニュアルの日本語訳プロジェクト) に対して PR をしてみる。

プロジェクトを Fork する

f:id:nakinor:20160223213152j:plain

① ウェブブラウザでプロジェクトにアクセスし、右上にある Fork ボタンを押す。

f:id:nakinor:20160223213343j:plain

するとリポジトリがコピーされて自分のページに遷移してくる。これで GitHub 上での準備は完了した。

f:id:nakinor:20160223213407j:plain

② 次にリポジトリを下記のコマンドでローカル(自分のパソコン)に clone してくる。これでもろもろの準備は整った。

git clone origin git@github.com:nakinor/vimdoc-ja-working.git
cd vimdoc-ja-working

PR を作成する

f:id:nakinor:20160223213205j:plain

③ PR をするためのトピックブランチを作成する。

git checkout -b PR

いろいろと修正をしてトピックブランチに commit。コミットメッセージは中の人は英語しか使っていないけれども、日本語で書いても怒られないので安心。英語が出来なくても貢献は出来るッ。

git commit -am '日本語のコミットメッセージ'

④ PR をするトピックブランチを Fork してきた自分のリポジトリ (origin) に push する。

git push origin PR

⑤ ウェブブラウザーで自分のリポジトリ (origin) を開くと、先程 push したトピックブランチが中央付近にクリーム色で表示される。この右側にある緑色の「Compare & pull request」ボタンを押して PR を開始する。

f:id:nakinor:20160223213423j:plain

ボタンを押すと本家の「Open a pull request」というページに遷移する。ここで注意するのは「どのリポジトリのどのブランチに、自分の何を PR をするのか?」という部分。GitHub が自動的に選択してくれているので、ほとんどの場合はそのままで良いみたい。

f:id:nakinor:20160223213435j:plain

相手先にあいさつをして「Create pull request」ボタンを押せば完了。

f:id:nakinor:20160223213448j:plain

"This branch has no conflicts with the base branch" という緑色のマークが出ていれば問題なく PR が完了したことになる。思っていたよりは簡単だったね。

あとは merge されるも良し revert されるも良し、中の人はとても忙しいので気長に待ちましょうかね。

通常は一連の PR 作業が終るとリポジトリを削除して、必要になった際に再度 Fork からはじめるのが良いとのこと。これはたぶん初心者に向けての言葉だと思う。しかしこのリポジトリの場合は 163MB もあるので、気軽に何度も clone することはできない(回線が遅いもので……)。

ということで、手元のものを生かし続ける方法を調べていく。と、その前に……

PR がマージされたら

f:id:nakinor:20160226231413j:plain

上記のように紫色の「Merged」表示が出て、めでたく PR がマージされました。

f:id:nakinor:20160226231555j:plain

時間を取って確認をしてくれた中の人にあいさつをする。ありがとうございます。

f:id:nakinor:20160226231606j:plain

次に merge されたトピックブランチは不要になるので「Delete barnch」ボタンを押して削除してしまう。

f:id:nakinor:20160226231615j:plain

"deleted the PR branch just now" と表示されて PR ブランチが削除された。これは GitHub 上にある自分のプロジェクトの PR ブランチ (origin/PR) が削除されたに過ぎず、手元にあるローカルブランチはそのままになっているので注意!

ということで、これも削除してしまうことにする。upstream については下記の「本家に追随する」を参照。

git fetch upstream master
git merge upstream/master         ローカルを最新版に更新する
git branch -d PR                  -d で削除
Deleted branch PR (was 1234abc).  と表示されれば成功!

これでローカルにあるトピックブランチも削除することが出来た。もしもブラウザ上で「Delete branch」をしなかった場合は、続けて下記のようにする。

git push origin :PR  (origin/PR) を削除する

これで GitHub 上の PR ブランチが削除された。おつかれさま。

本家に追随する

PR をした際に、コンフリクトしてしまった場合はどうすればいいのか?というお話し。

f:id:nakinor:20160226231659j:plain

PR をしてから時間が経つにつれて、本家のブランチにはいろいろなコミットが積み重なっていく。時にコンフリクトが生じて、上記のように merge ができない状態になってしまうことがある。灰色のアイコンに "This branch has conflicts that must be resolved" というメッセージがそれ。

ここでは自分のリポジトリを本家に追随し、PR を merge してもらえるように更新することが目的だ。

f:id:nakinor:20160223213212j:plain

まずは下準備として本家のリポジトリを upstream という名前で登録しておく。URI は本家ページの中央付近にある HTTPS の部分。ここは打ち間違えると面倒なのでコピペした方がいい。

git remote add upstream https://github.com/vim-jp/vimdoc-ja-working.git

⑥ 自分のローカルリポジトリ の master を本家(upstream) の master に追随する。

自分は今 master ブランチにいることとします。

git fetch upstream
git merge upstream/master

これで手元の master が本家(upstream)の master に追随(同期)できた。もしかしたら git pull upstream master でも良いのかもしれない。ちなみに今までに自身の master には何も手を加えていないので、コンフリクトすることはないはず。この辺はまだ良くわかっていない。

この時点では GitHub にある自分のリポジトリ(origin) の master は何も変化していない。ローカルの master と本家(upstream) の master が同期しただけだ。

⑦ PR を master の更新に合わせる。

git checkout PR
git rebase master

とすると、下記のようにコンフリクトしている旨のメッセージが表示される(piyo.txt ファイルの内容が競合しちゃってるよ)。

> git rebase master
First, rewinding head to replay your work on top of it...
Applying: PR hoge fuga.
Using index info to reconstruct a base tree...
M   piyo.txt
Falling back to patching base and 3-way merge...
Auto-merging piyo.txt
CONFLICT (content): Merge conflict in piyo.txt
error: Failed to merge in the changes.
Patch failed at 0001 PR hoge fuga.
The copy of the patch that failed is found in: .git/rebase-apply/patch
 
When you have resolved this problem, run "git rebase --continue".
If you prefer to skip this patch, run "git rebase --skip" instead.
To check out the original branch and stop rebasing, run "git rebase --abort".

とりあえずは piyo.txt のコンフリクトを解消してステージングまでをする。

vim piyo.txt   あれこれ修正
git add .

ステージングしてから git status で確認すると、下記のメッセージが表示されて、次に何をすれば良いのか教えてくれる。いちいち親切だね。

rebase in progress; onto 1234abc
You are currently rebasing branch 'PR' on '1234abc'.
  (all conflicts fixed: run "git rebase --continue")

メッセージに書いてあるとおりに git rebase --continue を入力すると、"Applying: PR hoge fuga." と表示されてコンフリクト解消の作業は終了。あとは GitHub 上に反映だ。

⑧ 修正したトピックブランチを自分のリポジトリ (origin) に push してアップデートする。PR ブランチは rebase のためにコミット番号が変わっているので -f を付けて push する。

git push -f origin PR

⑨ PR ページを確認する。

f:id:nakinor:20160226231900j:plain

問題がなければ灰色から緑色のマークになっているので成功!もしもまだ問題があるのなら、灰色のままなので ⑥ から ⑧ を繰り返す。

PR をする前にコミットをひとつにしておく作法があるそうなので、それはまた調べてみたい。