コピペで学ぶチュートリアル: GitHub Pull Request の update手法2種類を試す
導入
GitHub の pull request では、base ブランチの変更を取り込んで pull request の同期を維持するために、 Update with merge commit と Update with rebase という 2 つの方法があります。
- GitHub 公式: ベース ブランチと pull request の同期の維持
- GitHub blog: More ways to keep your pull request branch up-to-date
これら 2 つの方法は、上画像のようにトグルボタンひとつで切り替えられますが、どちらを選んでいいか悩む方もいると思います。自信をもって選ぶためには、手を動かして 2 つ手法の違いを実際に確認することは役立つでしょう。本記事ではほぼコピペで貼り付けるだけで簡単に手順を再現できるようにしています。
merge conflict がある場合、本記事で紹介する手法は使えません
本記事で対象とするのは pull request に merge conflict がない場合のみ適用できる手法です。merge conflict が発生しているときに解決する手法とは区別してください。後者については以下を参考にしてください。
pull request の merge 手法との区別
本記事で対象とするのは pull request『内』で merge conflict を解決する手法なので、pull request 自体を base ブランチへと merge する手法とは区別してください。後者については以下を参考にしてください。
準備
GitHub レポジトリの作成
まずはローカル環境で git レポジトリを作成します。
mkdir pull-req-update-experiments
cd pull-req-update-experiments
git init
GitHub 上にレポジトリを作成しましょう。Web ブラウザではなくコマンドを使えば一発で終わります。
gh repo create pull-req-update-experiments --public --source=. --remote=origin
上記の gh コマンドは何?
gh コマンド(GitHub CLI)を使えば、GitHub 上でのリポジトリ作成など作業をローカルからコマンドひとつで行えます。まだインストールしていない方は、ぜひインストールを検討してください。gh repo create サブコマンドの説明にもありますが、上記のコマンドのオプションと引数の意味はこちらです。
-
pull-req-merge-experiments
: GitHub 上のレポジトリ名 -
--public
: public レポジトリとして作成 -
--source=.
: ローカルレポジトリのパスはカレントディレクトリ.
-
--remote=origin
リモートレポジトリを origin に指定
update(rebase) branch ボタンを表示するための GitHub 設定
update(rebase) branch ボタンを表示するためには GitHub での設定が必要です。以下の 2 種類のうち、本記事では後者の設定を採用しています。
1. Require branches to be up to date before merging (update branch 必須)
マージ前にステータスチェック必須
2. Always suggest updating pull request branches (update branch 必須ではない) - 本記事で採用
プルリクエスト ブランチを更新する提案の管理
GitHub blog - More ways to keep your pull request branch up-to-dateで以下のように説明されています。
A new repository setting lets admins opt into having the Update branch button always available whenever a pull request's branch is not up to date with the base branch. Previously, this button was only available when the Require branches to be up to date before merging branch protection setting was enabled.
手法 1 - Update with merge commit
上記の GitHub 設定を終えたら、ここから先の手順に従って、update branch の動作確認を行いましょう。まずは、変更対象のテキストファイル pull-req-update-with-merge.txt
を作成します。
cat << EOF > experiment1.txt
a
b
c
EOF
git add --all
git commit -m "create experiment1.txt"
git push origin main
ファイルの内容はこちらです。
a
b
c
次に、pull request を作成します。
git switch -c pr-1
sed -i 's/a/aaaaa/' experiment1.txt # ファイル中のaをaaaaaに置き換え
git add --all
git commit -m "update a in pr-1"
git push --set-upstream origin pr-1
gh pr create --title pr-1 --body "" --base main --head pr-1
pull request 作成時点では、base ブランチは最新なので、update(rebase) branch ボタンは表示されません。
base ブランチに直接変更を加え、push しましょう。
git switch main
sed -i 's/b/bbbbb/' experiment1.txt # ファイル中のbをbbbbbに置き換え
git add --all
git commit -m "update b in main"
git push origin main
base ブランチの push が pull request の file diff に反映されない?
base ブランチの変更を push しただけでは、pull request の file diff は更新されません。下画像のように、3 行目がb
1 文字のままであることがわかります。
これは、GitHub では pull request の file diff は base ブランチの変更を取り込まないようになっているからです。base ブランチの変更を取り込むには、この先の update(rebase) branch ボタンを押す操作が必要です。
これで update(rebase) branch ボタンが表示されるので、Update with merge commit を選択します。
Update with merge commit が完了すると、Merge branch 'main' into ...
と pull request の Commits に表示されています。
Update with merge commit が完了すると、update(rebase) branch ボタンは消えます。Merge pull request ボタンを押しましょう。
ターミナルから pull request をマージしたい場合
gh pr merge pr-1 --merge --delete-branch
Merge pull request 後に main ブランチの git log をみるとこうなっています。
上画像では履歴が一直線に見えて分岐がわからないので、git log コマンドで分岐の様子を確認しましょう。
git switch main
git pull origin main
git log --oneline --decorate --graph
* 445be72 (HEAD -> main, origin/main) Merge pull request #14 from richardimaoka/pr-1
|\
| * 5f433ab (origin/pr-1, pr-1) Merge branch 'main' into pr-1
| |\
| |/
|/|
* | 59518cb update b in main
| * 0930aeb update a in pr-1
|/
* a154b57 create experiment1.txt
手法 2 - Update with rebase
次に、Update with rebase の動作確認です。
変更対象のテキストファイル experiment2.txt
を作成します。
cat << EOF > experiment2.txt
a
b
c
EOF
git add --all
git commit -m "create experiment2.txt"
git push origin main
ファイルの内容はこちらです。
a
b
c
pull request を作成します。
git switch -c pr-2
sed -i 's/a/aaaaa/' experiment2.txt # ファイル中のaをaaaaaに置き換え
git add --all
git commit -m "update a in pr-2"
git push --set-upstream origin pr-2
gh pr create --title pr-2 --body "" --base main --head pr-2
Pull request の Commits はこのようになっています。
pull request 作成時点では、base ブランチは最新なので、update(rebase) branch ボタンは表示されません。
base ブランチに直接変更を加え、push しましょう。
git switch main
sed -i 's/b/bbbbb/' experiment2.txt # ファイル中のbをbbbbbに置き換え
git add --all
git commit -m "update b in main"
git push origin main
これで update(rebase) branch ボタンが表示されるので、Update with rebase を選択します。
Update with rebase が完了すると、pull request の Commits には pull request 作成時と同じコミットだけが残っています。
ただしコミットハッシュは違います。上記の rebase 後はf7edabc
ですが、rebase 前はb577aa0
でした。
Update with rebase が完了すると、update(rebase) branch ボタンは消えます。Merge pull request ボタンを押しましょう。
ターミナルから pull request をマージしたい場合
gh pr merge pr-2 --merge --delete-branch
Merge pull request 後に main ブランチの git log をみるとこうなっています。
git switch main
git pull origin main
git log --oneline --decorate --graph
* 49d8c7b (HEAD -> main, origin/main) Merge pull request #16 from richardimaoka/pr-2
|\
| * f7edabc (origin/pr-2, pr-2) update a in pr-2
|/
* d84f7bf update b in main
* 8c363e6 create experiment2.txt
Discussion