リモートにプッシュした差分を同じコミット内で修正する方法（CLI）

今回はリモートにプッシュしたコードの差分を同じコミット内で修正する方法を紹介します。

【対象者】
- 初学者
- コミット&プッシュのやり方は覚えたけど、誤ってプッシュした内容を後から変更したい人

:::note warn
この方法は以下を条件としています。
- 修正したい内容が作業ブランチと同一ブランチであること

上記の条件を満たしている場合リモートにプッシュした差分を、修正することができます。
:::

【環境準備】
VScodeまたCursorに拡張機能の「Git Graph」を入れる ←おすすめ✨
![スクリーンショット 2024-03-01 0.08.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2559448/0f6b6f6a-7979-65a0-5be8-7da457012077.png)


:::note info
「下準備」が不要な方は「[リモートにプッシュした内容（差分）を修正してみる](https://qiita.com/ken0426/items/86cfb4618de56647f61a#%E3%83%AA%E3%83%A2%E3%83%BC%E3%83%88%E3%81%AB%E3%83%97%E3%83%83%E3%82%B7%E3%83%A5%E3%81%97%E3%81%9F%E5%86%85%E5%AE%B9%E5%B7%AE%E5%88%86%E3%82%92%E4%BF%AE%E6%AD%A3%E3%81%97%E3%81%A6%E3%81%BF%E3%82%8B)」までスキップしてください。
:::

# やりたいこと
![間違えたコミット内容.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2559448/69969b59-a911-412f-4abf-b19536679b62.png)
リファクタリングや修正などで、改めてコミットを作り修正するのではなく、作業したブランチでリモートにプッシュしたコミット内容を変更したい！

それでは早速やっていきましょう！🔥

# 下準備

### ①適当なプロジェクトを作る

今回はNext.jsでプロジェクトを作りますが、ここは今回の内容と関係ないため何でもよいです。
以下のコマンドを実行しNext.jsの雛形を作成します。
```terminal
npx create-next-app@latest
```

プロンプトを選択しますが、ここはご自身で決めてください。
```terminal
What is your project named? my-app
Would you like to use TypeScript? No / Yes
Would you like to use ESLint? No / Yes
Would you like to use Tailwind CSS? No / Yes
Would you like to use `src/` directory? No / Yes
Would you like to use App Router? (recommended) No / Yes
Would you like to customize the default import alias (@/*)? No / Yes
What import alias would you like configured? @/*
```
雛形の作成が完了したらプロジェクトをVSCodeまたはCursorで開きます。
![スクリーンショット 2024-02-29 23.49.17（3）.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2559448/8ac82bd1-8dfa-b1cf-1089-8fc141fb3f2b.png)

次にGitHubでリポジトリを作り、リポジトリに表示されたコマンドを実行し、先程作った雛形をリモートにプッシュします。
```terminal
git remote add origin https://github.com/ご自身のGitHubのアカウント名/ご自身のリポジトリ名.git
git branch -M main
git push -u origin main
```
GitHubにプッシュされたことを確認します。
![スクリーンショット 2024-02-29 23.55.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2559448/5373d43c-f039-9301-71f0-6226af78f9c2.png)

# 適当にブランチを切る
:::note info
mainブランチでする方はこの手順をスキップしてください。
:::
今回はGUI操作でブランチを切ってみます。
VSCodeまたはCursor画面の左下にある「main」をクリックし「Create new branch...」をクリック後ブランチ名を決めEnterキーを押します。
今回は「develop」ブランチというブランチで進めていきます。
![スクリーンショット 2024-02-29 23.58.38（3）.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2559448/c2a9c7f9-80d7-1350-6cfd-92cc5f431084.png)
![スクリーンショット 2024-03-01 0.04.11（3）.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2559448/a585b781-d43e-6c50-618c-8a55261964cf.png)

# 適当にいくつか差分を作りコミット&プッシュをしてみる
次にいくつか差分を作りコミットをしてみます。
まずはapp>page.tsxのmainタグの中身をすべて削除した差分を作ってコミットします。
（ここで不要なインポートも一緒に削除しておきます）
![スクリーンショット 2024-03-01 0.11.56（3）.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2559448/54c9b138-518d-d5c2-a8d0-69bccda2b437.png)
コミットメッセージは以下のようにしました。
`不要な記述を削除`

次にmainタグの中身にpタグを追加し、Helloという文字を追加してコミットしてみます。
![スクリーンショット 2024-03-01 0.18.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2559448/3bd36dcf-ba88-fed8-f4f3-71ee2f4d2692.png)
コミットメッセージは以下のようにしました。
`Helloを追加`

同じようにpタグにHTMLという文字を追加し、コミットメッセージを`HTMLを追加`でコミット、
pタグにCSSという文字を追加し、コミットメッセージを`CSSを追加`でコミット
pタグにJavaという文字を追加し、コミットメッセージを`JavaScriptを追加`でコミット
pタグにReactという文字を追加し、コミットメッセージを`Reactを追加`でコミット
![スクリーンショット 2024-03-01 0.25.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2559448/ebfb8df0-ed11-67b8-a7ea-9166f53d6e82.png)

ここで一旦プッシュをしてみましょう。
VScodeもしくはCursorであればGUI操作でプッシュができます。
![スクリーンショット 2024-03-01 0.25.51（3）.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2559448/9f879053-be8a-6eb2-e2af-e85105da73fb.png)
![スクリーンショット 2024-03-01 0.27.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2559448/94dd6107-cfe8-634b-ff04-fc610775a056.png)

GitHubでコミットした差分が反映されているか確認しましょう。
今回はdevelopブランチで実装したため、GitHub上でもdevelopブランチで確認します。
![スクリーンショット 2024-03-01 0.28.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2559448/d4a6c174-c385-9c15-c982-08aa241dc346.png)
![スクリーンショット 2024-03-01 0.30.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2559448/42ae6409-237c-ae42-a5cc-e53f9884ead8.png)
GitHub上でも実装した内容が反映されていることが確認できます。

# リモートにプッシュした内容（差分）を修正してみる
ここからリモートにプッシュした内容（差分）を同じブランチ&同じコミットで修正をしていきます。
変更する箇所は以下になります。
```diff_tsx
export default function Home() {
  return (
    <main className='flex min-h-screen flex-col items-center justify-between p-24'>
      <p>Hello</p>
      <p>HTML</p>
      <p>CSS</p>
-     <p>Java</p>
+     <p>JavaScript</p>
      <p>React</p>
    </main>
  );
}

```

## コミットIDを確認する
VSCodeまたはCursor画面左下の`Git Graph`をクリックし、修正したいコミットIDを確認
![スクリーンショット 2024-03-01 0.39.36（3）.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2559448/d58b8468-af2d-7959-9d0a-59612dae5a8a.png)
今回の場合であれば`beeadb9a`が修正したいコミットIDになります。
![スクリーンショット 2024-03-01 0.44.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2559448/39e511f0-a240-5321-0840-42bf0f23b4b4.png)

## git log --onelineコマンドで履歴を確認する
エディター上からターミナルを開き、プロジェクトのディレクトリで以下のコマンドを実行します。
```terminal
git log --oneline
```
コマンドを実行すると以下のように表示されるはずです。
![スクリーンショット 2024-03-01 0.49.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2559448/b7277d4a-4a58-cc16-dfcc-97450e54d3bb.png)
今回の場合であればコミットIDが`beeadb9a`の箇所を確認します。
すると上から2番目にあることが確認できます。
```terminal
0bc4f7d → 1番目
beeadb9 → 2番目（このコミット内容を変更したい）
b251adc → 3番目
27bdd3c → 4番目
cf2da08 → 5番目
accefd1 → 6番目
2dc35ae → 7番目
```

## リベースを行う
以下のコマンドを実行しリベースを行います。
```terminal
git rebase -i HEAD~{指定する番号}
```
今回の場合であれば2番目のコミット内容を変更したいので以下のコマンドを実行します。
```terminal
git rebase -i HEAD~2
```
コマンドを実行するとvimに切り替わります。
![スクリーンショット 2024-03-01 0.58.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2559448/6840d0c5-02ee-a51e-cb58-d590fefdb684.png)

この状態でキーボードの「i」キーを押し、該当のコミットID`beeadb9a`横にあるpickを`e`に変更します。
```diff_markdown
- pick beeadb9 JavaScriptを追加
+ e beeadb9 JavaScriptを追加
pick 0bc4f7d Reactを追加

# Rebase b251adc..0bc4f7d onto b251adc (2 commands)
以下略
```
その後、キーボードの「esc」キーを押し「:wq」と入力し保存します。
この状態で、エディター上では特に変化がありませんが、よく見ると画面左下に「コミットID（リバースしています）」と書かれており、現在リベースモードであることが確認できます。
![スクリーンショット 2024-03-01 1.03.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2559448/b43497a1-24e8-6279-7491-eadaf43006a7.png)
また、ソースコードではReactの記述をした行が消えていることが確認できるはずです。
![スクリーンショット 2024-03-01 1.05.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2559448/1e0170dc-a1f4-2969-ad2f-d8964349f1fa.png)
この状態は、リベースモードで7行目に「Java」と追加したコミットまで戻ってきているため、これより後にコミットしたReactの行はありません。
では、7行目の「Java」を「JavaScript」に変更し保存をしてみましょう。
```diff_tsx
export default function Home() {
  return (
    <main className='flex min-h-screen flex-col items-center justify-between p-24'>
      <p>Hello</p>
      <p>HTML</p>
      <p>CSS</p>
-     <p>Java</p>
+     <p>JavaScript</p>
    </main>
  );
}
```
変更し保存まで完了できたら次に修正した差分をステージングに上げます。
VSCodeまたはCursorであれば以下のようにGUI操作でステージングに上げることができます。
（※CLI操作でステージングにあげても構いません）
![スクリーンショット 2024-03-01 1.13.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2559448/e546498b-1272-23d3-6edf-c116a7ad50a6.png)
![スクリーンショット 2024-03-01 1.15.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2559448/00ec1163-be24-b1f5-de05-4d7188e835a7.png)
差分をステージングに上げることができたら、次に以下のコマンドをプロジェクトのディレクトリで実行します。

```terminal
git rebase --continue
```
コマンドを実行すると以下のような画面に切り替わるはずです。
![スクリーンショット 2024-03-01 1.18.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2559448/169396a1-2bf0-19be-f783-a4a5565ec1c3.png)
ここでコミットメッセージも変更することができますが、今回はそのまま「JavaScriptを追加」のコミットメッセージにしたいため、「:wq」を入力してEnterKeyを押します。
すると以下のようにコンフリクトが発生しました。
![スクリーンショット 2024-03-01 1.23.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2559448/563e9987-b456-8061-7f79-988edb64c1a4.png)

修正内容によってはコンフリクトは発生しませんが、今回はコンフリクトが発生しました。
理由は簡単で先ほど「:wq」を入力しEnterを押した時点で「JavaScriptを追加」のコミットは正常に完了できましたが、「Reactを追加」のコミットを行った際に「Reactを追加」の差分では
```tsx
<p>Java</p>
<p>React</p>
```
となっており、`Java`が正しいのか`JavaScript`の修正が正しいのか不明になったためです。

:::note info
コンフリクトが発生しなかった場合は以下の「コンフリクトの解消」はスキップしてください。
:::

:::note warn
リベース作業を取り消す場合は以下のコマンドを実行してください。
```terminal
git rebase --abort
```
:::

## コンフリクトの解消
今回の場合であれば、
```tsx
export default function Home() {
  return (
    <main className='flex min-h-screen flex-col items-center justify-between p-24'>
      <p>Hello</p>
      <p>HTML</p>
      <p>CSS</p>
      <p>JavaScript</p>
      <p>React</p>
    </main>
  );
}
```
としたいため、以下のように修正します。
（※やり方は一例です）
今回は修正差分が少なかったため、エディター上に表示されている「両方の変更を取り込む」をクリックします。
![スクリーンショット 2024-03-01 1.31.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2559448/af28b174-140b-f51e-9d4b-2dfa5ee79350.png)
すると以下のようになりました。
![スクリーンショット 2024-03-01 1.33.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2559448/75b1bc4e-9767-d21a-16a5-630b23f13731.png)
ここでは8行目のJavaの記述は不要なため、その1行を削除し、保存をします。
```diff_tsx
export default function Home() {
  return (
    <main className='flex min-h-screen flex-col items-center justify-between p-24'>
      <p>Hello</p>
      <p>HTML</p>
      <p>CSS</p>
      <p>JavaScript</p>
-     <p>Java</p>
      <p>React</p>
    </main>
  );
}
```
保存ができたら、ステージングに上げます。
（※ファイルのpage.tsxは赤い状態で「！」がついていますが、そのままステージングに上げて大丈夫です。）
ステージングに上げると、Reactだけ追加されていることが確認できます。
![スクリーンショット 2024-03-01 1.39.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2559448/6fc08e3c-9a66-6a7e-1a9f-803694c2acdc.png)
この状態で再度プロジェクトのディレクトリで以下のコマンドを実行します。
```terminal
git rebase --continue
```
するとまた以下のようにvimが立ち上がるので「:wq」を入力しEnterを押します。
![スクリーンショット 2024-03-01 1.42.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2559448/c6b7be82-0e7f-e65e-84b9-c4c2e24dd2e6.png)

これでコンフリクトも解消しました！✨

## 修正した内容（差分）をプッシュする
最後に以下のコマンドをプロジェクトのディレクトリで実行しリモートにプッシュします。
```terminal
git push --force-with-lease origin {元々プッシュしていたブランチ名}
```
今回の場合だと`develop`ブランチにプッシュしていたので以下のようになります。
```terminal
git push --force-with-lease origin develop
```
コマンドを実行できたら修正した内容がリモートに反映されているはずです。
エディター左下の「Git Graph」から修正内容が反映されているか確認してみます。
![スクリーンショット 2024-03-01 1.47.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2559448/ec056f02-7804-9ea2-d9bb-48d8c9fa171a.png)
![スクリーンショット 2024-03-01 1.48.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2559448/8863433a-59cd-df9f-1725-4283e9aca6a3.png)
![スクリーンショット 2024-03-01 1.48.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2559448/55c8050c-f12b-ab46-9126-b0a9e707a5e1.png)
（※GitHub上でも確認してみましょう！）
元々`Java`でコミットしていた箇所が同じブランチ、同じコミットで`JavaScript`に変更ができています！！✨

お疲れ様でした！🍺

# まとめ
今回はリモートに上げた内容を後から同じブランチ、同じコミット内で修正し、余分なコミットを増やすことなく修正する方法を紹介しました。
覚えて慣れるまでは、少し大変かもしれませんが、慣れるととても便利なので、実務や個人開発でも使ってみてください！
プロジェクトによっては無駄なコミットを増やしたくない。または、1文字修正するだけなのに、リファクタリングのコミットを増やしたくない。という時などで活用してみるといいかもしれません。