🐷

コピペで学ぶチュートリアル: GitHub Pull Request の update手法2種類を試す

2022/09/24に公開

導入

GitHub の pull request では、base ブランチの変更を取り込んで pull request の同期を維持するために、 Update with merge commit と Update with rebase という 2 つの方法があります。

update with merge commit

これら 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 必須ではない) - 本記事で採用

プルリクエスト ブランチを更新する提案の管理

https://docs.github.com/ja/repositories/configuring-branches-and-merges-in-your-repository/configuring-pull-request-merges/managing-suggestions-to-update-pull-request-branches

always-suggest-updating-pr

update with merge commit

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

ファイルの内容はこちらです。

experiment1.txt
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 branch up to date

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 行目がb1 文字のままであることがわかります。

pr-file-diff-1a

これは、GitHub では pull request の file diff は base ブランチの変更を取り込まないようになっているからです。base ブランチの変更を取り込むには、この先の update(rebase) branch ボタンを押す操作が必要です。

pr-file-diff-1b

これで update(rebase) branch ボタンが表示されるので、Update with merge commit を選択します。

update with merge commit

Update with merge commit が完了すると、Merge branch 'main' into ... と pull request の Commits に表示されています。

git log update with merge commit

Update with merge commit が完了すると、update(rebase) branch ボタンは消えます。Merge pull request ボタンを押しましょう。

base branch up to date

ターミナルから pull request をマージしたい場合
コピペして実行
gh pr merge pr-1 --merge --delete-branch

Merge pull request 後に main ブランチの git log をみるとこうなっています。

git log pr merged 1

上画像では履歴が一直線に見えて分岐がわからないので、git log コマンドで分岐の様子を確認しましょう。

コピペして実行
git switch main
git pull origin main
git log --oneline --decorate --graph
git log
* 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 の動作確認です。

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

ファイルの内容はこちらです。

experiment2.txt
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 はこのようになっています。

git log update with rebase

pull request 作成時点では、base ブランチは最新なので、update(rebase) branch ボタンは表示されません。

base branch up to date

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

Update with rebase が完了すると、pull request の Commits には pull request 作成時と同じコミットだけが残っています。

git log update with rebase

ただしコミットハッシュは違います。上記の rebase 後はf7edabcですが、rebase 前はb577aa0でした。

Update with rebase が完了すると、update(rebase) branch ボタンは消えます。Merge pull request ボタンを押しましょう。

base branch up to date

ターミナルから 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
git log
* 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
GitHubで編集を提案

Discussion