01 / 11
Git を使う最大のメリットは「安全に戻れること」
これまでの章では commit を「残す」操作を学んできました。しかし、バージョン管理システムを使う最大の恩恵は、過去の任意の時点へ確実に巻き戻せることにあります。
「いつでも安全に戻れる」という安心感があるからこそ、大胆なリファクタリングやコード変更に挑戦できます。
この章では4つの主要な取り消しコマンドを学びます。重要なのは「どの領域の変更を戻したいのか」によって使うコマンドが異なるという点です。
変更の取り消しと reset
INPUT · スライド
01 / 11
これまでの章では commit を「残す」操作を学んできました。しかし、バージョン管理システムを使う最大の恩恵は、過去の任意の時点へ確実に巻き戻せることにあります。
「いつでも安全に戻れる」という安心感があるからこそ、大胆なリファクタリングやコード変更に挑戦できます。
この章では4つの主要な取り消しコマンドを学びます。重要なのは「どの領域の変更を戻したいのか」によって使うコマンドが異なるという点です。
02 / 11
Git の3つの領域(working tree・stage・repository)ごとに、取り消しコマンドが明確に分かれています。
git restore <file>git restore --staged <file>git resetgit revert「変更を戻す」と一口に言っても、対象の領域によって実行すべき操作は全く異なります。対象領域を意識することが迷わない秘訣です。
03 / 11
ファイルを編集したものの、その変更が不要になった場合は git restore <ファイル名> を実行します。
直前の commit 時の状態に working tree のファイルが一瞬で復元されます。
ただし、一度破棄した未 commit の変更は二度と復元できません。commit されていない変更は Git のデータベースに記録されていないためです。
$ git restore nedan.txt$ git statusOn branch mainnothing to commit, working tree clean04 / 11
git add を実行した後に「このファイルは今回の commit に含めたくない」と気づいた場合は、--staged オプションを付けて実行します。
staging area から除外されるだけで、working tree で編集したファイル内容は一切消えません。
--staged を付け忘れると working tree の編集内容そのものが破棄されてしまうため、実行前にオプションの有無を必ず確認しましょう。
$ git add .$ git restore --staged himitsu.txt$ git statusChanges to be committed: new file: recipe.txtUntracked files: himitsu.txt05 / 11
commit message を書き間違えた場合や、ファイルを1つ commit に含め忘れた場合は、git commit --amend を使用します。
新しい commit を追加するのではなく、直前の commit の内容を上書き(作り直し) します。ファイルの追加忘れがある場合は、先に git add してから --amend を実行します。
内部的には古い commit を破棄して新しい commit hash で再生成するため、commit ID が変化します。
$ commit -m "とりあえ"$ git commit --amend -m "メモを置いた"[main 7c1e4a9] メモを置いた06 / 11
commit ID が変わるということは、Git の履歴が書き換わることを意味します。
すでに git push してチームメンバーと共有済みの commit に対して --amend を行うと、同じ内容に見えても ID が異なる commit が local に作られ、remote repository と履歴が分岐・衝突します。
鉄則として、git commit --amend はまだ remote へ push していない local commit に対してのみ実行してください。
07 / 11
commit そのものを取り消して過去の時点に戻したい場合は git reset を使います。
branch が指している HEAD ポインタを、過去の commit(例: HEAD~1 で1つ前、HEAD~2 で2つ前)へ付け替えます。
git reset には影響範囲の異なる3つの主要オプションが存在します。
$ git log --oneline9f2a1c4 不要な変更のコミット3b7e5d1 正常なコミット$ git reset --soft HEAD~1$ git log --oneline3b7e5d1 正常なコミット08 / 11
巻き戻した際に「手元の作業内容をどこまで残すか」が異なります。
--soft … commit のみ取り消す。staging area と working tree の変更はそのまま保持される--mixed(オプション省略時のデフォルト) … commit と stageを取り消す。working tree の変更は保持される--hard … commit・stage・working tree のすべてを取り消す。未 commit の作業内容も含めて完全に破棄される「commit をやり直したいだけ」なら --soft または --mixed を使います。
--hard は作業内容が完全に消失し、取り返しがつきません。実行前に必ず内容を確認しましょう。
09 / 11
git reset は履歴を直接書き換えるため、すでに remote repository へ push 済みの commit には使用できません。
remote 共有済みの commit を取り消したい場合は git revert <commitID> を使用します。
これは過去の commit を消去するのではなく、「その commit の変更内容を逆向きに打ち消す新しい commit」を追加するコマンドです。履歴が改変されないため、他の開発者と競合することなく安全に修正を共有できます。
$ git revert HEAD[main 4d8b2f1] Revert "まちがえて消した"$ git log --oneline4d8b2f1 Revert "まちがえて消した"9f2a1c4 まちがえて消した3b7e5d1 値段表を作成10 / 11
判断基準は極めて明確です。
git reset(履歴をきれいに保つ)git revert(安全に打ち消し commit を追加する)自分だけの local 環境であれば reset で柔軟に修正し、チームに共有した後は revert で安全に対処する、と覚えておきましょう。
11 / 11
この章の演習では、意図的に誤った操作や commit が行われた状態からスタートします。
まず git status や git log --oneline を実行して、現在の working tree・stage・commit 履歴の状態を把握してから適切なコマンドを実行しましょう。