GitHubでforkやプルリクエストを使ったチーム開発をするときに、よく使うコマンドをまとめてみました。
ローカルに作業環境を準備する
あらかじめ、オリジナルとなるリポジトリのgithubページから、自分のgithubアカウントへリポジトリをフォークしておきます。
- オリジナルリポジトリのアカウント名:
__ORIGINAL__
- 自分のアカウント名:
__SELF__
- リポジトリ名:
awesomeapp
# まずはローカルに自分のリポジトリをcloneする
git clone https://github.com/__SELF__/awesomeapp.git
# uptreamという名前でフォーク元のリポジトリを参照する
git remote add upstream https://github.com/__ORIGINAL__/awesomeapp.git
# topic1ブランチで作業開始
git checkout -b topic1
この状態でgit remote -v
とすると、
origin https://github.com/__SELF__/awesomeapp.git(push)
origin https://github.com/__SELF__/awesomeapp.git(fetch)
upstream https://github.com/__ORIGINAL__/awesomeapp.git(push)
upstream https://github.com/__ORIGINAL__/awesomeapp.git(fetch)
というように、origin
・upstream
の2つのremoteが設定されており、それぞれ自分・フォーク元のリポジトリを参照するようになります。
自分のリポジトリからフォーク元へプルリクエストを出す
topic1ブランチで作業が終わったら、フォーク元のmasterブランチへプルリクエストを出します。
- 自分の作業ブランチ: origin/topic1
- フォーク元の統合ブランチ: upstream/master
# topic1ブランチへ移動
git checkout topic1
# フォーク元の最新をローカルに持ってくる
git fetch upstream
# ローカルで変更しているファイルがあるときは、rebaseの前にstash
git stash
# コミット履歴を一本化する
git rebase upstream/master
# コンフリクトしたら修正......
# プルリクエストに含まれるコミットを一つにまとめる
git rebase -i $(git log -n 1 upstream/master --pretty=format:"%H")
# コミットメッセージの変更...
# rebaseしているのでforce push
git push -f
# stashしていたら、元に戻す
git stash pop
この状態でプルリクエストを作ると、upstream/master
に対して、コミットが一本化された1つのコミットだけを含んだプルリクエストが作られます。コミット履歴をクリーンに保つことができます。
git rebase -i
の後ろの$(git log -n 1 upstream/master --pretty=format:"%H")
では、upstream/master
の最新のコミットIDを取得しています。upstream/master
の最新のコミットにつなぐ形でコミット履歴が一本化されます。
また、git rebase -i
をすると、
pick a9ca5b4f コミットメッセージ1
pick 85b03ac4 コミットメッセージ2
pick 86d93e18 コミットメッセージ3
のようにコミット履歴の編集画面が開きます。一番上のコミットだけを残して、2番目以降のコミットのpick
をsquash
(あるいは単にs
)にするとコミットを1つにまとめることができます。
共同作業者のプルリクエストをローカルでチェックするとき
共同作業者がupstream/master
に作成したプルリクエストを、ローカルに取り込んでチェックします。
- 共同作業者のアカウント名:
__SOMEONE__
- チェックしたいブランチ:
someonerepo/topic2
# まだローカルになければ、共同作業者のリポジトリのremoteを追加
git remote add someonerepo https://github.com/__SOMEONE__/awesomeapp.git
# 共同作業者のリポジトリの最新をローカルに持ってくる
git fetch someonerepo
# カレントブランチを変更
git checkout someonerepo/topic2
# someonerepo/topic2ブランチの最新を取り込む
git merge someonerepo/topic2 # Fast-forwardマージになるはず
git reset --hard someonerepo/topic2 # force pushされているときはこっち
この状態でgit remote -v
とすると、
origin https://github.com/__SELF__/awesomeapp.git(push)
origin https://github.com/__SELF__/awesomeapp.git(fetch)
upstream https://github.com/__ORIGINAL__/awesomeapp.git(push)
upstream https://github.com/__ORIGINAL__/awesomeapp.git(fetch)
someonerepo https://github.com/__SOMEONE__/awesomeapp.git(push)
someonerepo https://github.com/__SOMEONE__/awesomeapp.git(fetch)
というように、someonerepo
のremoteが追加されており、共同作業者のリポジトリを参照するようになります。
force pushされているブランチをローカルへpullしたいとき、一度ローカルのブランチを削除してから取り込んでいる方も多いと思います(わたしがそうでした)。上記のように、git reset --hard
を使うといちいちブランチを削除せずに取り込めます!