はじめに
IT知識ゼロの文系から新卒でSEになった私が、現場配属されてすぐ直面したのが「Git」の壁でした。それ以前(研修期間)は勉強したものの、ブランチの切り替えもやったことがないレベル。正直、リポジトリが何者かや、リモートとローカルの違いもよくわかっていませんでした。
そこから約3か月間の実務の中で、「これってやって大丈夫?チームのコードに影響ない?」という不安な場面や、「間違えた!最初からやり直し、、、?」と冷や汗をかく場面に何度も直面しました。
そこで、実務中に救われたコマンドのメモを、当時の自分と同じように焦っている人に向けて記録として残しておきます。
プッシュ前かプッシュ後かで変わる焦り度
「やばい!」と思った時、今の自分の状況が以下のどちらなのかで焦り度が変わります。
-
間違えてコミットしてしまったとき(プッシュ前)
👉 大丈夫、内容はいくらでも修正できます。手元のパソコンの中だけの話なので、誰にも気づかれずにやり直せます。 -
間違えてプッシュしてしまったとき(プッシュ後)
👉 MR(マージリクエスト)を作ってマージされる前であれば、いくらでも修正して安全にプッシュし直せます。
それぞれの状況で私を救ってくれたコマンドを紹介します。
対応①:間違えてコミットしてしまった時(まだプッシュしていない)
まだプッシュしていないなら、以下のコマンドで手元を修正したあと、普通の git push をすれば何事もなかったかのように綺麗な履歴がリモートに送られます。
1. 状況に合わせて使い分ける「git reset」3種類
コミットを取り消す時の基本です。直前のコミットを取り消す場合は、末尾に HEAD^ をつけます(例:git reset --soft HEAD^)。
-
git reset --soft- 変更内容:そのまま
- addの状態:そのまま
- コミット:取り消される
- 使いどころ: 一部のファイルを少しだけ修正してコミットし直したい時。(resetを使い始めのときは、hardやmixedはよくわからなくて「なんとなく怖いからこれ使っとこう」という場面もありました)
-
git reset --mixed(デフォルト)- 変更内容:そのまま
- addの状態:取り消される
- コミット:取り消される
- 使いどころ: 変更内容ごとにコミットを整理してからプッシュし直したい時。(マージされた後にコミットごとの変更内容が整理されていると、変更意図が伝わりやすい、流用しやすいなどの利点があります)
-
git reset --hard- 変更内容:取り消される
- addの状態:取り消される
- コミット:取り消される
- 使いどころ: コミットした内容がすべて不要になったため、何もなかったことにしたい時。変更内容を加える前の状態に完全にリセットしたい時。
2. コッソリ直前を上書きする「git commit --amend」
直前に行ったコミットに対して、新しい変更を追加したり、コミットメッセージ(名前)だけを書き換えたりできるコマンドです。
「reset --soft で一旦戻せばよくない?」と思っている過去の私へ。
--amend には以下の良い点があります。
-
良い点① 手間が減る
reset --softを使う場合は「1. コミットを取り消す 2. ファイルを修正する 3. もう一度新たにコミットし直す」という3ステップですが、--amendなら「1. ファイルを修正する 2.--amendで上書きする」の2ステップで済みます。 -
良い点② 同じメッセージを再入力する手間が減る
ファイル修正後、git commit --amend --no-editと書くだけで、メッセージを変えずにファイルの中身だけコッソリ修正完了します!
しかし難点もある(私的使い分け)
--amend は、直前のコミットで修正した箇所が一目でわかりません。
reset --soft の場合は、addしているファイルが一目でわかり、エディタ上で変更差分が色付きで表示されます。そのため私は以下のように使い分けています。
-
git commit --amendを使う時: 直前に作業した内容にミスを見つけたとき(修正箇所が明確なとき) -
git reset --soft HEAD^を使う時: コミットしてから時間がたっていて、修正したい箇所を探し直す(可視化する)必要がある場合
対応②:間違えてプッシュしてしまった時
対応①の reset や --amend を使って手元を綺麗に修正した。さあプッシュしよう!
……と思った時、もし間違った状態ですでに一度プッシュしてしまっていた場合は、普通の git push をすると「リモートの歴史と違うぞ!」とエラーになります。
3. 歴史を上書きする最終奥義「git push --force」
そんな時は、手元の綺麗な状態をリモートにねじ込むために強制プッシュを使います。
- 前述の
resetや--amendでローカルを正しい状態に直す -
git push --forceでプッシュする
これで、リモートにあった間違ったコミットが、手元の綺麗な状態に上書きされます!
※実務での超重要ルール(なぜ私がこれで大丈夫だったのか)
私がこの --force を使ってチームのコードを破壊せずに済んだのは、「自分だけが作業している、マージ前のブランチ」に対して使っていたからです。
もし自分以外の誰かも触っているブランチ(先輩が手伝ってくれているブランチや、チーム共通の main ブランチなど)でこれをやると、他人の作業履歴ごと問答無用で吹き飛ばす大惨事になります。
💡 おまけ:より安全なコマンド
もし複数人で同じブランチを触る可能性がある場合は、安全装置付きの git push --force-with-lease というコマンドを使うのが推奨されているそうです(誰かが新しくプッシュしていたら、上書きをストップしてくれる機能)。私はまだソロ作業ブランチなので --force で生きていますが、今後のために覚えておこうと思います!
このメモが、Gitの黒い画面の前で冷や汗をかいている誰かの救いになれば嬉しいです!
※この記事は、AIとの対話を壁打ち相手としつつ、筆者の実体験と独自の解釈を加筆・構成して作成しました。