git rebaseを体験してみる

# 目的

- 何気なく業務でgit rebaseを使っているが毎回危ない橋を渡っている気がするので自分のテスト環境でちゃんと理解してみる

# 環境

- Gitバージョン: 2.28.0

# お願い

- もしもっと良い方法があったらどしどしコメントをお願いいたします。。。！

# 情報

- 筆者は下記の方法でMacにHomeBrewでGitを導入した。
    - [Mac ネイティブのGitからHomebrewでインストールしたGitに切り替えた話](https://qiita.com/miriwo/items/68a372ef7bc69d120444)
- 下記の方法を参考にローカルリポジトリを用意しGitHubのリモートリポジトリと紐付けた。
    - [Git ローカルリポジトリを作ったらやること](https://qiita.com/miriwo/items/35d7c3fdfdd1c35ffe14)
- masterブランチのREADME.mdには下記の内容が記載されている。

    ```README.md
    # リポジトリの説明

    - gitのあれこれをテストするためのリポジトリです。
    ```

- README.mdが登録されただけのmasterブランチからrebase_masterブランチを作成した。
- masterブランチからただ分岐しただけのrebase_masterブランチからrebase_No01ブランチを作成した。
- rebase_masterブランチ、rebase_No01ブランチ作成後に各ブランチでプッシュを行いリモートブランチへの反映を行った。
- 説明で実行するコマンドは特筆しない限り前のコマンドと同じディレクトリで実行するものとする。

# 準備

1. リポジトリ内の「.git」があるディレクトリで下記コマンドを実行してrebase_masterブランチに移動する。

    ```terminal
    $ git switch rebase_master
    ```

1. 下記コマンドを実行してREADME.mdを開く。

    ```terminal
    $ vi README.md
    ```

1. 下記のようにREADME.mdを修正する。

    ```README.md
    # リポジトリの説明

    - gitのあれこれをテストするためのリポジトリです。
    - これはrebase_masterブランチでの変更です。
    ```

1. 上記の変更を「rebase_masterブランチでの説明を追加」というコミットメッセージを追加してコミットとプッシュを行った。
1. 下記コマンドを実行してrebase_No01ブランチに移動する。

    ```terminal
    $ git switch rebase_No01
    ```

1. 下記コマンドを実行してREADME.mdを開く。

    ```terminal
    $ vi README.md
    ```

1. 下記のようにREADME.mdを修正する。

    ```README.md
    # リポジトリの説明

    - gitのあれこれをテストするためのリポジトリです。
    - これはrebase_No01ブランチでの変更です。
    ```

1. 上記の変更を「rebase_No01ブランチでの説明を追加」というコミットメッセージを追加してコミットとプッシュを行った。

# ここまでの状況確認

1. 現在の情報をまとめる
    1. rebase_masterブランチのREADME.mdの内容

        ```README.md
        # リポジトリの説明
        
        - gitのあれこれをテストするためのリポジトリです。
        - これはrebase_masterブランチでの変更です。
        ```

    1. rebase_No01ブランチのREADME.mdの内容

        ```README.md
        # リポジトリの説明
        
        - gitのあれこれをテストするためのリポジトリです。
        - これはrebase_No01ブランチでの変更です。
        ```

1. rebase_No01ブランチはrebase_masterから分岐しているが、README.mdに変更が加わる前に分岐しているのでrebase_No01ブランチには当然rebase_masterの変更は加わっていない。（rebase_No01ブランチのREADME.mdには「- これはrebase_masterブランチでの変更です。」の記載がされていない。）
 
# git rebaseを行う

1. `$ git rebase`コマンドを使って、rebase_No01のブランチの分岐もとを最新のrebase_masterに変更してみる。
1. 下記コマンドを実行してrebase_No01ブランチに移動する。

    ```terminal
    $ git switch rebase_No01
    ```

1. 下記コマンドを実行してrebaseを実行しrebase_No01ブランチの分岐点を最新状態のrebase_masterに変更する。

    ```terminal
    $ git rebase rebase_master
    ```

1. 下記のような内容がターミナル上に出力された。当たり前だが同じファイルの同じ行に変更が加わっていたのでコンフリクトした。

    ```
    Auto-merging README.md
    CONFLICT (content): Merge conflict in README.md
    error: could not apply 6cf625f... rebase_No01ブランチでの説明を追加
    Resolve all conflicts manually, mark them as resolved with
    "git add/rm <conflicted_files>", then run "git rebase --continue".
    You can instead skip this commit: run "git rebase --skip".
    To abort and get back to the state before "git rebase", run "git rebase --abort".
    Could not apply 6cf625f... rebase_No01ブランチでの説明を追加
    ```

1. 上記の出力内容を簡単に訳す。

    ```
    git rebaseを実行したらコンフリクトが発生しました。
    コンフリクトを手動で解決して$ git addかrmを実行して$ git rebase --continueを実行してください。
    スキップするには$ git rebase --skipを実行してください。
    中止してrebase前の状態に戻したいなら$ git rebase --abortを実行してください。
    ```

1. 「コンフリクトしたからなんとかして解決してね。解決したらこれやってね」的なことを言われているようだ。とりあえずまず手動でコンフリクトを解決するところから始める。
1. README.mdを開いて確認すると下記のようにコンフリクトした印が追記されている。

    ```README.md
    # リポジトリの説明
    - gitのあれこれをテストするためのリポジトリです。
    <<<<<<< HEAD
    - これはrebase_masterブランチでの変更です。
    =======
    - これはrebase_No01ブランチでの変更です。
    >>>>>>> 6cf625f... rebase_No01ブランチでの説明を追加
    ```

1. 今回はrebase_masterブランチの内容とrebase_No01ブランチの修正を両方残したいので下記のように修正した。

    ```README.md
    # リポジトリの説明
    - gitのあれこれをテストするためのリポジトリです。
    - これはrebase_masterブランチでの変更です。
    - これはrebase_No01ブランチでの変更です。
    ```

1. エディターによっては簡単にコンフリクトを直すことができるボタンが表示される事がある。筆者はVScodeを使用しており下記のように表示された。この場合両方のブランチの変更を取り込みたいので「両方の変更を取り込む」をクリックすると自動でソースをきれいに修正してくれる。

    ![Menubar_と_README_md_—_laravel6_と_work_ticket_md_—_j-project.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/1ab94d42-a41d-7b8c-4ad8-e8184f7507b1.png)

1. これでコンフリクトは解決できたので先程の`$ git rebase`を実行したときに出力された案内に沿って`$ git add`や`$ git rebase --continue`を実行してみる。まずは下記コマンドを実行する。

    ```terminal
    $ git add README.md
    ```

1. コンフリクトを解消したファイルをインデックスに登録できたので下記コマンドを実行する。

    ```terminal
    $ git rebase --continue
    ```

1. コミットメッセージの入力画面が開くがとりあえず特にいじらず保存する。
1. これでrebase_No01ブランチの分岐点を最新のrebase_masterに変更することができた。
1. 下記コマンドを実行して最新のrebase_No01をプルする。

    ```terminal
    $ git pull origin rebase_No01
    ```

1. 先程のようにコンフリクトするのでREADME.mdを開き下記のようになるように修正する。

    ```README.md
    # リポジトリの説明
    - gitのあれこれをテストするためのリポジトリです。
    - これはrebase_masterブランチでの変更です。
    - これはrebase_No01ブランチでの変更です。
    ```

1. 下記コマンドを実行して修正点をインデックスに登録する。

    ```terminal
    $ git add README.md
    ```

1. 下記コマンドを実行してコミットする。

    ```terminal
    $ git commit 
    ```

1. このコミットはマージコミットになるので特に必要なければコミットメッセージは記載されたままいじらずに保存する。
1. 下記コマンドを実行してrebase_No01の内容をリモートのrebase_No01ブランチの反映する。

    ```terminal
    $ git push origin rebase_No01
    ```