Git と Visual Studio 2017 その 14 : リモートにプッシュ後のコミットの修正

前回の記事では、Visual Studio 2017 によるアイテムの比較を紹介しました。今回はすでにリモートにプッシュ済みのコミットを修正する方法を見ていきます。

リセットと取り消し

これまでに リセット (reset) を本シリーズでは何度も使ってきましたが、リモートのプッシュしたものは修正する場合、 リセットすべきではありません。理由は他の人が既にクローンしていた場合、履歴の内容が異なるためです。そこで取り消し (revert) の出番です。

取り消し : Git

1. まず ‘git log --oneline --graph --all’ で現状確認。ブランチが 2 つあるが、リモートはない。ただし revert にリモートは必須ではないため、今回はこのまま。

image

2. ‘echo “間違った情報” >> README.md’ を実行てから ‘git commit -am “間違ったコミット”’ でコミット実行。再度 ‘git log --oneline --graph --all’ で状況確認。

image

3. 仮にこの状態でプッシュした場合、最後のコミットを取り消すには revert コマンドを利用。‘git revert --no-edit HEAD’ を実行して HEAD を取り消し。--no-edit オプションを付けるとコメント編集をスキップできる。取り消し実行後 'git log --oneline --graph --all' および ‘type README.md’ で状況確認。リセットと異なり新しいコミットが追加。

image

4. コミットの中身を比較。’git cat-file commit d2badd7’ と ‘git cat-file commit a188e4b’ を実行。同じツリーオブジェクトをポイントしていることを確認。

image

5. 取り消された内容を見る場合は、‘git diff HEAD~1 HEAD’ で比較可能。

image

6. 複数のコミットを取り消したい場合も 1 コマンドで実行可能。最新 3 つのコミットを取り消したい場合、‘git revert HEAD~3...HEAD’ を実行。

image

7. 次の検証のため、’git reset --hard fafb509’ を実行。

取り消し : VS

1. master ブランチの履歴を表示。取り消したいコミットを右クリックして ”元に戻す” を選択。確認メッセージで ”OK” をクリック。

image

2. 履歴を更新して Revert コミットが作成されていることを確認。

image

3. Visual Studio 2017 で複数のコミットを選択した場合は、”元に戻す” はグレーアウトしている。

image

リセットして強制的にプッシュ

取り消しではなくリセットをしたい場合に手段はあります。

1. ‘git remote add origin https://github.com/kenakamu/VS\_Git.git’ および ‘git push -u origin master’ リモートを構成して最新の状態をプッシュ。

2. GitHub からもコミット確認。尚、人の画像が出ていないのは、名前だけ直してメールアドレスを直し忘れたため (反省)。'git config user.name <username>' と 'git config user.email <mail address>' は重要。

image

3. ‘git reset --hard d2badd7’ および ‘git log --oneline --graph --all’ で現状確認。ローカルの master ブランチがリモート追跡ブランチ より古いコミットをポイント。

image

4. ‘git push’ を実行。リモートのコミットの方が新しい旨エラーで表示。

image

5. ‘git push -f’ でプッシュを強制実行。GitHub でもコミットが消えていることを確認。

image image

万事解決に見えますが、すでに他の人がクローン済みの場合、そちらからプッシュされると状況によってはエラーになるか、強制プッシュされるとまたコミットは戻ります。よって関係者で事前に周知する必要があるでしょう。

まとめ

Visual Studio 2017 は ”同期” という便利な機能があり、またコミット時に ”すべてをコミットして同期” という強力なオプションがあるため、以前はよくコミット同時にリモートに変更を反映させていました。しかしリセットと取り消しの概念を学んでからは、まずローカルにコミットを行い、必要に応じて修正をしてからプッシュするように習慣が変わりました。次回はこのローカルでコミットした内容を修正する方法について見ていきます。次の記事へ

中村 憲一郎