【Git】Gitで状態を戻す方法を考える

■ はじめに

Git で開発する際に、自分や他のメンバーがミスって
状態を戻したい場合の対処方法を調べて、まとめる

今回は、リモートリポジトリの状態を戻すことに絞る
(ローカルや個人ブランチは、下手にやるより、
 最悪、取り直して、再度、修正をしたほうが安全だし)

※ Github 上で管理している場合は、以下の関連記事も参照。

Githubで状態を戻す方法を考える
https://dk521123.hatenablog.com/entry/2022/08/03/000000

目次

【1】リモートリポジトリの状態を戻す
【2】基本的な考え方
【3】サンプルケース

※関連する文法やコマンドについて

関連する文法やコマンドは、記事がながすぎてしまったので、
以下の関連記事に分割した

https://dk521123.hatenablog.com/entry/2020/07/12/103726

【1】リモートリポジトリの状態を戻す

* まず、知っておくことは、
 「リモートリポジトリの状態を戻す」用のコマンドは用意されていない
 => コマンドを一発うって終わりって便利なことはできない
 (ローカルで作業してたら git pushはする)
 => 組み合わせて対応する
* 以下のサイトが分かりやすい

https://tmtms.hatenablog.com/entry/20101221/git

* 発生した時点で、他の開発メンバに知らせて、
 リモートサーバに対して、Clone/Push/Pull etcしないように
 知らせておくことも重要

【2】基本的な考え方

Gitを扱っているサーバに直接アクセスできる訳でなければ
以下を GUI でも Gitコマンド のどちらでもいいので、行えばいい
(状況にもよって簡単にできるケースもあるみたいなので、
 あくまで、参考程度で、、、)

手順概要

[1] 対象ブランチのリモートリポジトリをローカルに持ってくる
[2] バックアップ用のブランチを切る(任意だが何が起こるかわからないので)
[3] ローカル上で戻したい状態にする
[4] ローカル上のブランチをリモートリポジトリにPushする
[5] バックアップ用のブランチを削除

【3】サンプルケース

サンプルケースとして、状況は、Githubで
以下の「状態イメージ」のように、
間違って 「M (Miss)」をコミット・Pushしてしまった場合に
この M を取り除くことを行う

状態イメージ

リモート: A-B-C-D-M     develop

# "M" : 間違ったコミット状態

[1] 対象ブランチをローカルに持ってくる

* 対象ブランチのリモートリポジトリをローカルに持ってくる

コマンド例

# git clone [リモートリポジトリのHost] -b [対象ブランチ]
git clone https://github.com/xxxxxx/xxxxxx.git -b develop

状態イメージ

リモート: A-B-C-D-M     develop
ローカル: A-B-C-D-M     develop

[2] バックアップ用のブランチを切る

* 作業前に念のため、バックアップ用のブランチを切る
 => GithubでGUI操作可能であれば、[1] の前に行ってもいい

コマンド例

# ローカルブランチ「develop」を、リモートレポジトリ「origin」に
# リモートブランチ「develop_backup」って名前で push する
git push origin develop:develop_backup

状態イメージ

リモート: A-B-C-D-M     develop
リモート: A-B-C-D-M     develop_backup
ローカル: A-B-C-D-M     develop

[3] ローカル上で戻したい状態にする

* 戻し方は、reset や revert コマンドなど色々な方法があるので、
 それぞれの特性やデメリットを理解した上で選択したほうがいい

https://dk521123.hatenablog.com/entry/2020/07/12/103726
コマンド例:最新コミットを取り消す場合

# 最新のコミットの前(HEAD^)に戻り
# 最新コミット M を捨てる
git reset --hard HEAD^

状態イメージ

リモート: A-B-C-D-M     develop
リモート: A-B-C-D-M     develop_backup
ローカル: A-B-C-D       develop

コマンド例:特定のコミットまで戻りたい場合

# i) git log で戻す対象のハッシュ値を調べる
git log

commit aa1ecxxxxxxxx ...

# ii) git reset --hard [ハッシュ値] でそこまで戻す
# (今回は「aa1ecxxxxxxxx」まで戻す)
git reset --hard aa1ecxxxxxxxx

コマンド例:最新コミットを打ち消す場合

# i) git log で戻す対象のハッシュ値を調べる
git log

commit bb1ecxxxxxxxx ...

# ii) 最新コミット M を打ち消す W を生成する
# git revert<対象MのコミットID>
git revert bb1ecxxxxxxxx

# iii) コミットする
git commit

状態イメージ

リモート: A-B-C-D-M     develop
リモート: A-B-C-D-M     develop_backup
ローカル: A-B-C-D-M-W   develop

[4] ローカル上のブランチをリモートリポジトリにPushする
https://tmtms.hatenablog.com/entry/20101221/git

のようにリモートブランチを削除してからpushするとか
強制Pushするとか、マージ・Pushとか色々あるかと。

コマンド例:強制Pushする場合

git push -f origin develop

状態イメージ

リモート: A-B-C-D     develop
リモート: A-B-C-D-M   develop_backup
ローカル: A-B-C-D     develop

[5] バックアップ用のブランチを削除

# リモートレポジトリ「origin」に対して、
# リモートブランチ「develop_backup」を削除する
git push --delete origin develop_backup

状態イメージ

リモート: A-B-C-D     develop
ローカル: A-B-C-D     develop

参考文献

https://www.lancard.com/blog/2015/03/20/git-%E3%83%AA%E3%83%A2%E3%83%BC%E3%83%88%E3%83%AA%E3%83%9D%E3%82%B8%E3%83%88%E3%83%AA%E3%82%92%E3%82%AC%E3%83%84%E3%83%B3%E3%81%A8%E5%B7%BB%E3%81%8D%E6%88%BB%E3%81%99/

参考文献

http://www-creators.com/archives/2020

関連記事

Git ~ 入門編 ~
https://dk521123.hatenablog.com/entry/2018/06/29/104028
状態を戻す際には ~ reset / revert etc ~
https://dk521123.hatenablog.com/entry/2020/07/12/103726
Githubで状態を戻す方法を考える
https://dk521123.hatenablog.com/entry/2022/08/03/000000