タイトル: ローカルをリモートリポジトリの状態に戻す
SEOタイトル: 【git】ローカルをリモートリポジトリの状態に戻す
| この記事の要点 |
|
最短手順
ローカルの変更をすべて捨てて、リモートリポジトリと同じ状態に戻すには、ローカルリポジトリ上で次のコマンドを実行します。
git fetch --all
git reset --hard origin/master
現在の GitHub や GitLab では、新規リポジトリの既定ブランチ名が main になっていることが多いため、その場合は次のようにします。
git fetch origin
git reset --hard origin/main
自分のブランチ名とリモート追跡ブランチの名前は git branch -a で確認できます。
各コマンドが何をしているか
git fetch: リモートの最新コミットをダウンロードし、ローカルにあるorigin/main(リモート追跡ブランチ)を更新します。作業ファイルにはまだ触れません。--allを付けると登録されている全リモートから取得しますgit reset --hard origin/main: 今いるブランチの指す先をorigin/mainと同じコミットに付け替え、インデックス(ステージ)と作業ツリーもそのコミットの内容で上書きします
git pull は「fetch + マージ」なので、ローカルの変更とリモートの変更を統合しようとします。それに対して reset --hard は、ローカル側を捨てて置き換える操作です。目的に応じて使い分けてください。
実行前に:消えるもの・消えないもの
| 対象 | reset --hard 後 |
|---|---|
| 追跡中ファイルの未コミットの変更 | 消える(reflog にも残らない) |
| ステージ済み(add 済み)の変更 | 消える |
| 未 push のローカルコミット | ブランチから外れる(reflog から一定期間は復元可能) |
| Git 管理外の新規ファイル(untracked) | 残る |
| .gitignore 対象のファイル(.env など) | 残る |
| 他のローカルブランチ | 影響なし |
未コミットの変更は一度消えると Git では戻せません。少しでも残したい可能性があるなら、先に退避しておきます。
# 今の状態をブランチとして残しておく(コミット済みの内容の保険)
git branch backup-before-reset
# 未コミットの変更を一時退避する(untracked も含める場合は -u)
git stash push -u -m "before reset"
未追跡ファイルも消してリモートと完全一致させる
ビルド成果物や試しに作ったファイルなど、Git 管理外のファイルも削除したい場合は git clean を使います。必ず -n(ドライラン)で削除対象を確認してから実行してください。
git clean -n -d # 削除されるファイル・ディレクトリを表示するだけ
git clean -f -d # 実際に削除
-x を付けると .gitignore で無視しているファイル(.env や node_modules、vendor など)まで消えます。設定ファイルを失うことがあるため、意図がない限り付けないでください。
特定のファイルだけリモートの状態に戻す
ブランチ全体ではなく、一部のファイルだけリモートと同じにしたい場合は次のようにします(git restore は Git 2.23 以降)。
git fetch origin
git restore --source=origin/main -- path/to/file.php
# 古い Git の場合
git checkout origin/main -- path/to/file.php
確認方法
git status
# On branch main
# Your branch is up to date with 'origin/main'.
# nothing to commit, working tree clean
git log --oneline -1 # HEAD のコミット
git log --oneline -1 origin/main
2 つのコミット ID が同じで、git status に「up to date」「working tree clean」と表示されれば、リモートと同じ状態になっています。untracked のファイルが表示される場合は、上の git clean で対応します。
間違えて reset したときの戻し方
コミット済みだった内容は、git reflog に HEAD の移動履歴が残っているため復元できます。
git reflog
# a1b2c3d HEAD@{0}: reset: moving to origin/main
# 9f8e7d6 HEAD@{1}: commit: 作業中の修正
git reset --hard HEAD@{1} # reset 直前の状態に戻す
# または退避ブランチから
git reset --hard backup-before-reset
reset の直後であれば ORIG_HEAD も reset 前のコミットを指しているため、git reset --hard ORIG_HEAD でも戻せます。
よくある質問
push 済みのコミットを取り消したい場合も同じ手順?
いいえ。この記事の手順は「ローカルをリモートに合わせる」ものです。リモートに push 済みのコミットを取り消したい場合は git revert で打ち消しコミットを作るのが安全です。共有ブランチで reset して force push すると、他の人の履歴と食い違います。
サブモジュールがある場合は?
reset の後に git submodule update --init --recursive を実行し、サブモジュールも親リポジトリが指すコミットに合わせます。