0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

「mainブランチの変更を個人ブランチに取り込んで」<-これって結局何をすればいいの?

0
Last updated at Posted at 2026-06-21

はじめに

「mainブランチの変更を個人ブランチに取り込んで」
初めてこの指示を受けたとき、すごく困った記憶があります。

なぜなら、今までmain1本のブランチ構成しか触ったことがなく、操作のほとんどがGUIによるものであり、CLIのgitコマンドもなんとなくでしか触ってこなかったからです。

gitコマンドは引数の省略が可能なこともあり、何を省略しているのかを理解しないままに叩くと、余計に理解のできない状態を生み出してしまいます。

後で見返せるようにしたいなという思いもあり、いわゆる"取り込み"で使用するgitコマンドについて整理し、この順番でCLIに貼り付ければok! な備忘録を作成してみました。
同じような壁にあたった方の役に少しでも立てたら嬉しいです。

忙しい人向け(結論)

mainの変更をfeature/xxx999に取り込むには、以下を順に実行します。
(なぜこの順番なのかは本文で解説します)

git fetch origin main
git switch main
git merge --ff-only origin/main
git rebase main feature/xxx999

本文

本文では、用語の定義前提条件を整理したのちに、使用するコマンドの整理を行い、結論を出します。

用語の定義

  • 個人ブランチは以後、feature/xxx999と言い換える
  • リモートリポジトリのmainブランチのことを、origin mainと呼称する
  • origin mainに対応するリモート追跡ブランチのことを、origin/mainと呼称する
  • origin/mainは最後にfetchしたときの、origin mainの状態を指すポインタである
  • ローカルリポジトリのmainブランチのことをmainと呼称する

前提条件

実際のコマンドの話をする前に、前提条件について整理します。
はじめにで書いたように、ブランチ構成が変わると、必要なコマンドも変化するためです。

ブランチ構成

今回の例では、GitHub Flowというブランチ構成を例とします。
具体的には以下のような構成です。

  • main
  • feature/xxx999
  • feature/xxx999

feature/xxx999xxx999は、任意の文字列かつ,複数のfeature/xxx999が存在しうることを表現しています。

ブランチ運用ルール

ブランチ運用ルールは以下のとおりとします。

  • mainに直接変更を加えてはならない
  • mainからorigin mainに、pushしてはならない
  • feature/xxx999からorigin mainに、pushしてはならない
  • feature/xxx999から、対応するorigin feature/xxx999には、push可能である
  • origin feature/xxx999からorigin mainpull requestを依頼することで、origin feature/xxx999の変更をorigin mainに反映する
  • origin feature/xxx999の変更がorigin mainに反映されたなら、対応するfeature/xxx999は新規コミットを積まずに削除する

条件から導出した実態

これらの前提条件から、以下のことが言えます。

  • 変更の反映の流れは、1方向にループしており、
    main -> feature/xxx999 -> origin feature/xxx999 -> origin main ->main
    のような流れである

  • mainに直接変更を加えてはいけないルールと、上述の1方向性から、mainのコミットの全てをorigin mainが知っている状態である

使用するコマンドの整理

ここでは、まずmainブランチ1本の構成の場合に変更を取り込むコマンドを確認したのちに、使用しているコマンドが引数になにをとるのか知ることで、mainブランチの変更を、featureブランチに取り込むコマンドを理解します。

mainブランチ1本の構成の場合に変更を取り込むコマンド

mainブランチ1本の場合に変更を取り込むコマンドは以下のとおりとします。

git fetch origin
git rebase origin/main

git pullについては当記事では言及しません。


次に、git fetchが引数に何をとるか知ることで、origin mainの変更をfeature/xxx999に取り込む場合にどう変化するかを理解します。

git fetch

構文

git fetch origin main
           ↑      ↑
          引数1   引数2
    (repository) (refspec)
  • repositoryには、リモートリポジトリ名をとる。省略した場合、現在のブランチに設定された追跡リモート(なければorigin)が使われる。複数リモートを扱わない限りは意識しなくてよい
  • refspecには、リモートリポジトリのブランチ名をとる。省略した場合、通常は全ブランチを対象となる

refspecは本来 <src>:<dst> という形式で「どのブランチを取得し、どのローカル追跡ブランチを更新するか」を指定します。
mainのようにブランチ名だけ書いた場合は main:(取得元だけ指定)の短縮形になります。
取得先を書かなくても、取得した内容は対応するリモート追跡ブランチ(今回の場合はorigin/main)に記録されます。

引数の省略

git fetchは引数1,引数2のいずれも省略することができ、引数の数に応じて以下のように動作します。

コマンド 動作
git fetch 現在のブランチの追跡リモート(なければorigin)の全ブランチを取得
git fetch origin origin の全ブランチを取得
git fetch origin main origin main だけ取得

今回実行するコマンド

以上の内容により、origin mainの更新を、origin/mainに取り込む場合、以下のコマンドを実行します。

git fetch origin main

次に、git rebaseが引数に何をとるか知ることで、origin mainの変更をfeature/xxx999に取り込む場合にどう変化するかを理解します。

git rebase

構文

git rebase origin/main main
            ↑           ↑
           引数1       引数2
        (upstream)   (branch)
  • upstreamには、commit-ish(リモート追跡ブランチまたは,ローカルブランチなど)を引数にとる。省略した場合、現在のブランチに設定された追跡ブランチとなる
  • branchには、rebaseの対象となるローカルブランチ名をとる。省略した場合、現在のブランチとなる

commit-ishは当記事で扱う範囲に絞って例示しています。
本来commit-ishがとりうる範囲から、大幅に絞って例示していることをご理解ください。

第2引数branchを渡すと rebase 前に自動でgit switch branchされ、終了後もそのブランチに留まります。
例えばgit rebase origin/main mainを実行した場合、現在ブランチがmainに変わります。

引数の省略

git rebaseは引数1,引数2のいずれも省略することができ、引数の数に応じて以下のように動作します。

コマンド 動作
git rebase 現在のブランチに設定されたupstream(のリモート追跡ブランチ)をもとに、現在のブランチをrebaseする
git rebase main mainをもとに、現在のブランチをrebaseする
git rebase origin/main main origin/mainをもとに、mainをrebaseする

git rebaseを引数なしで実行する場合、現在のブランチにupstreamが設定されていないとエラーで中止されます。

今回実行するコマンド

以上の内容により、origin mainの更新を、origin/mainに取り込む場合、git rebaseを2回実行することになり、それぞれ以下のコマンドが対応します。
origin/mainの更新を、mainに取り込む場合

git rebase origin/main main

mainの更新を、feature/xxx999に取り込む場合

git rebase main feature/xxx999

既にpush済みのfeature/xxx999を、rebase後にorigin feature/xxx999へ上げ直す際は、履歴が書き換わっているためgit push --force-with-leaseが必要になります。
しかし、当記事では取り込みまでをスコープとし、push以降には言及しません。


ところで、今回のブランチ運用ルールに基づいた場合、git rebase origin/main mainは、再適用すべきコミットが存在しないため、結果的にmainorigin/mainの位置まで進むだけになります。これはfast-forwardと同じ到達点です。

fast-forward とは

ブランチB(origin/main)の先端コミットの履歴をたどると、ブランチA(main)の先端コミットに到達できる(=AがBの祖先である)とき、AをBへfast-forwardできると言います。
このとき分岐が無いため、AのポインタをBの先端まで進めるだけで統合が完了します。

言葉が難しいので噛み砕くと、あるブランチAの全てのコミットを、別のブランチBが知っている状態 と言えるでしょう。

今回のブランチ運用ルールでは、mainに独自のコミットを作らないため、mainの全てのコミットは常にorigin/mainに含まれています。つまりorigin/mainmainの全コミットを知っており、mainは常にorigin/mainへfast-forward可能な状態に保たれているということになります。

結果、git rebase origin/main mainは、mainの最終的な到達コミットという意味で、以下のコマンドと同じ結果になります。

git merge --ff-only origin/main

厳密には、rebaseは「コミットの付け替え」操作であり、merge --ff-onlyの「ポインタの前進」とは仕組みが異なります。
あくまで「独自のコミットが無い前提での到達点が同じ」という意味です。

git rebaseを使用するのではなく、git merge --ff-onlyを使用するメリットは、fast-forwardによる取り込みであることを保証できる点です。
(fast-forwardできない場合はエラーメッセージを出してmergeが中止されるため、もしmainに意図せず独自コミットが入ってしまっていた場合、それに気づける。)

念のため、git merge引数に何をとるかを知っておきましょう。

git merge

構文

git merge --ff-only origin/main
            ↑        ↑
         オプション  引数1
                   (commit)
  • commitには、commit-ish(リモート追跡ブランチまたは,ローカルブランチなど)を引数にとる。省略した場合は現在のブランチに設定されたupstream(のリモート追跡ブランチ)がマージ対象となる

複数のcommit-ishを引数にとるmergeについては当記事では言及しません。

引数の省略

git mergeは引数1を省略することができ、引数の数に応じて以下のように動作します。

コマンド 動作
git merge 設定されたupstreamのリモート追跡ブランチを現在のブランチにマージする
git merge origin/main origin/main を現在のブランチにマージする

git mergeを引数なしで実行する場合、現在のブランチにupstreamが設定されていないとエラーで中止されます。

結論

mainブランチの変更を、featureブランチに取り込む場合、以下のコマンドを実行します。


origin mainの変更を、origin/mainに反映する。

git fetch origin main

mergeをmainに対して実行するため、明示的にブランチを移動。

git switch main

origin/mainからmainに対して、fast-forwardによるmergeを実行。

git merge --ff-only origin/main

rebaseをfeature/xxx999に対して実行するため、明示的にブランチを移動。

git switch feature/xxx999

mainからfeature/xxx999に対して、rebaseを実行。

git rebase main feature/xxx999

git fetch origin main
git rebase origin/main feature/xxx999
の順で実行すればswitchもmergeも省略できますが、switch -cで新規にfeature/xxx999を作成することを考慮し、省略していません。

おわりに

普段何気なく使っているgitコマンドを整理してみたいなと思い、初めて筆をとってみましたが、想定以上に長く、踏み込んだ内容になってしまいました。
なるべく確認しながら進めたつもりではありますが、内容に誤りがあれば是非ご教授いただけますと幸いです。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?