Gitを使いこなそう!【リセット編】

Git

こんにちは、ECF Techブログ
担当のMichiです。

Gitシリーズは8回目を迎えました。「Gitを使いこなそう!」とタイトルを新たにし、実際の開発業務などで役に立ちそうな、ちょっと応用編をお届けしたいと思います。

今回のテーマは「リセット編」。コミットしちゃったけどちょっと失敗したなという時に使えるgit resetコマンドをご紹介したいと思います。

本記事は、Gitシリーズ連載記事の1つとなっています。もし最初からご覧になりたい方は下のリンクをご活用ください。

Git
Gitの事を、学んで試せるページとなっています。初めてGitを利用される方に最適です。ぜひご活用ください。

対象読者

  • Gitの基本的な使い方pulladdcommitpushなどを使ったことがある方
  • gitをもう少しつっこんで学習したいという方

Gitが管理する領域

Gitのやり直し系コマンドは様々です。これらを使いこなすにあたり、Gitが管理する作業領域を理解することは大変重要となります。

Gitの管理領域は次の3つとなります。

作業フォルダ
いわゆるWindows上のフォルダであり、自由な作業場所です。最終コミット以降変更されたファイルやまだGitの管理対象になっていないファイルなどが混在します。
ステージングエリア
インデックスツリーという言い方が正式ですが、本記事では理解しやすいようにこの名前を使っています。git addコマンドで指定されたファイルがこちらに入ります。次回git commitの際に、コミット対象となるファイルが管理されています。
リポジトリ
ファイルの最新コミット状態を持っています。

git reset

管理領域の理解ができたところで、git resetコマンドについて、ハンズオン(実際に動作しながら学習する)形式で見ていきたいと思います。

まずは適当なフォルダでgit initコマンドを実行しましょう。

C:\work01>git init
Initialized empty Git repository in C:/work01/.git/

ファイルを1つ作成します。file.txtという名前のファイルです。次の内容とします。

A

Aという文字があるだけのファイルです。できたらコミットします。

C:\work01>git add .

C:\work01>git commit -m "commit A"
[master (root-commit) 34c67d7] commit A
 1 file changed, 1 insertion(+)
 create mode 100644 file.txt

もう1度file.txtを編集します。内容はつぎのようにします。

B

AがBに変更されただけです。保存したらコミットします。

C:\work01>git add .

C:\work01>git commit -m "commit B"
[master c5df9cf] commit B
 1 file changed, 1 insertion(+), 1 deletion(-)

この時点で各管理領域は次のようになっています。

3つの領域でfile.txtはすべて同じ内容です。ここでgitの状態を確認するgit statusを実行してみましょう。

C:\work01>git status
On branch master
nothing to commit, working tree clean

masterブランチを指し示していること、コミットすべきものがないことがわかります。

またgit logコマンドを使って、コミット履歴を確認してみましょう。

C:\work01>git log
commit c5df9cf1a0ebd1399e522b795c8717dc2185af71 (HEAD -> master)
Author: michi 
Date:   Fri Oct 18 20:15:50 2019 +0900

    commit B

commit 34c67d71bd2ec0c5eaca9f3872d4871815ba3fd2
Author: michi 
Date:   Fri Oct 18 20:02:55 2019 +0900

    commit A

2つのコミットオブジェクトがあり、現在は上のオブジェクトを指していることが分かります。

ではここから、git resetコマンドを使っていきたいと思います。まずは次のコマンドを実行してください。

git reset --soft HEAD~

git resetの基本的な文法は次のとおりです。

コミットへの移動方法
コミットへの移動方法はオプションです。上の例では--softですが、ほかに--mixed--hardがあります。省略した場合は自動的に--mixedが適用されます。

対象コミット
対象コミットの表し方は色々あります。今回使用したHEAD~はHEADが指すコミットの1つ前のコミットを指します。

3つのオプションを使いこなす

--softオプション

では、コミットへの移動方法について見ていきましょう。--softの場合各管理領域は次のようになります。

HEADが移動し1つ前のコミットを指しています。行われた変更はこれだけです。コミットの内容とステージングエリアの内容が異なっているため、git statusコマンドを実行すると、次のように表示されます。

C:\work01>git status
On branch master
Changes to be committed:
  (use "git restore --staged ..." to unstage)
        modified:   file.txt

ここでコミットをすることでメッセージを変更したりすることができます。再度コミットしておきましょう。

C:\work01>git commit -m "ReCommit B"
[master 0802995] ReCommit B
 1 file changed, 1 insertion(+), 1 deletion(-)

--mixedオプション

次に--mixedです。git reset --mixed HEAD~を実行すると各管理領域は次のようになります。

行なわれたことは2つです。

  • HEADポインタが1つ前に戻る
  • ステージングエリアの内容がHEADが指すコミット内容で置きかわる

よって、git statusコマンドを実行すると・・・・

C:\work01>git status
On branch master
Changes not staged for commit:
  (use "git add ..." to update what will be committed)
  (use "git restore ..." to discard changes in working directory)
        modified:   file.txt

no changes added to commit (use "git add" and/or "git commit -a")

git addコマンドでステージングエリアに上げてから、コミットしましょう。といったメッセージが出ます。

というわけで再度、addcommitをしておきましょう。

C:\work01>git add .

C:\work01>git commit -m "mixed Test"
[master c9ae784] mixed Test
 1 file changed, 1 insertion(+), 1 deletion(-)

--hardオプション

最後に--hardです。git reset --hard HEAD~を実行すると各管理領域は次のようになります。

行なわれた作業は3つです。

  • HEADポインタが1つ前に戻る
  • ステージングエリアの内容がHEADが指すコミット内容で置きかわる
  • 作業フォルダの内容がHEADが指すコミット内容で置きかわる

3つ目の作業は重要です。なぜなら作業フォルダの変更が消えてしまうからです。今回の例だと「B」という変更はどこを探してもありません。今回は1度コミットしているため復元することができます。しかし作業フォルダにコミットしていないものが含まれていた場合は、戻すことができませんので注意が必要です。

リセットをリセット

--hardオプションを使用して作業内容「B」が戻せなくなってしまいましたので、コミットした内容から復元しましょう。

まずは戻したいコミットオブジェクトを探します。git reflogコマンドを実行します。

C:\work01>git reflog
c9ae784 (HEAD -> master) HEAD@{0}: commit: mixed Test
34c67d7 HEAD@{1}: reset: moving to HEAD~
0802995 HEAD@{2}: commit: ReCommit B
34c67d7 HEAD@{3}: reset: moving to HEAD~
c5df9cf HEAD@{4}: reset: moving to HEAD@{1}
34c67d7 HEAD@{5}: reset: moving to HEAD~
c5df9cf HEAD@{6}: commit: commit B
34c67d7 HEAD@{7}: commit (initial): commit A

resetやcommitをくり返した履歴が確認できます。新しい方が上で古い方が下に見えています。今回は下から2番目の「commit B」とコメントしていたコミットに戻ります。コマンドは次です。

git reset --soft HEAD@{6}

実行後はfile.txtが元(「B」と書かれている状態)に戻っていることがわかります。

おわりに

本日はここまでとさせていただきます。最後までご覧くださりありがとうございました。やり直し系のコマンドはまだまだ奥深く紹介しきれていないところもありますが、少しずつお伝えできればと思っています。ぜひ、ひきつづきご覧ください。


合同会社イー・シー・エフでは、子ども向けプログラミングなどの教育講座を実施しています。プログラミング教室の案内や教育教材の情報、また関連するご相談・問い合わせにつきましては下記よりご確認ください。

ECFエデュケーション
タイトルとURLをコピーしました