RAKUS Developers Blog

株式会社ラクスのエンジニアブログ

Git初心者のためのローカル作業時の備忘録

はじめに

皆さんはじめまして。新人エンジニアのsts-250rrです。
本年度新卒として入社し、1年目の私ですがよろしくお願いいたします。

Git初心者である方の中には、Gitの大枠がどんなものかは知っているし、使ったこともある。
でも機械的git status,git add -Aとしていたり、git commitをしていた。
というような方もおられるのではないでしょうか?(私はその口でした・・・)

各コマンドの正しい知識を持たずに機械的にコマンドを実行するのでは、 業務を行う上で正しい操作ができないことも考えられます。チームの開発ではなおさら御法度といえるでしょう。
私自身含め、そのような方が今後Gitで失敗をしてしまわないように手助けができればと思います。

本記事では、ローカル環境で作業をする際のGitの構成であるリポジトリやワークツリー・インデックスに関してまとめ、利用するコマンドがどのような操作であるのかを再確認していきます。 それらを把握したうえで、よく利用するGitコマンドをシーン別に分けて紹介し、コマンドによる操作のイメージを持っていただきたいと思います。
加えて、コミットの流れやコミットで失敗してしまったときの対処法も載せておきましたので、困ったときの参考になると幸いです。

リポジトリ・ワークツリー・インデックスって?

Gitではローカルで作業する際に以下のような構成でプロジェクトを管理しています。 この部分の構成を理解していると、addやcommitによってどのような操作がなされるのかがわかってくるかと思います。

f:id:sts-250rr:20171001103103p:plain

  • リモートリポジトリ[Remote repository]
    サーバに配置されており、複数人でプロジェクトを共有する場所。
    *本記事での話題の対象ではありません。

  • ローカルリポジトリ[local repository]
    ローカル環境内でのプロジェクトのファイルやディレクトリの変更履歴を記録する場所。

    • ヘッド[HEAD]:最新のコミット状態を示す。
  • インデックス[index]
    ローカルリポジトリにコミットを行う準備をする場所。ワークツリーから登録された内容をgit commitでコミットする。
    インデックスが存在することで、ワークツリー内の必要のないファイルはコミットしないといったことができる。

  • ワークツリー[work tree]
    実際に作業を行っているディレクトリであり、編集を行った最新のファイルが存在する。
    ここでの作業内容をgit addすることでインデックスに変更を登録する。

これらローカル内の3つの構成により、Gitではプロジェクトの管理が行われています。 この部分が理解できればaddcommit、それらの操作を取り消すresetといった操作が理解しやすくなったのではないでしょうか。

シーン別:よく使うGitコマンド

前節まででローカル環境でのGitの構成の大枠は掴んでいただけたでしょうか?
本節では、多様なgitコマンドの中からよく使うコマンドを3つのシーンに分けてまとめています。
逆引きのように利用していただけると幸いです。

編集を確認したいとき
  • log
    • git log :最新までのコミットログを確認。
    • git log --oneline :コミットログを簡潔に確認。
  • status
    • git status:ローカルで編集されたファイルの一覧を表示。
  • diff
    • git diff:インデックスとワークツリーの全ての差分を表示。
    • git diff ファイル名:インデックスとワークツリーのしてファイルの差分を表示。
編集したものをリポジトリにコミットしたいとき
  • add
    • git add -A:ワークツリーの内容をすべてインデックスに登録。
    • git add <ファイル名>:編集した1ファイルのみをインデックスに登録。
    • git add <ファイル名1> <ファイル名2>:複数の編集をインデックスに登録。
  • commit
    • git commit:インデックスの内容を全てコミットする。
    • git commit -m 'message':コミットと同時に1行メッセージを書く。
addやコミットを取り消したいとき
  • reset
    • git reset:git addの内容を取り消す。
    • git reset --soft HEAD^:直前のコミットのみを取り消す。
    • git reset --hard HEAD^:現時点のインデックスやワークツリーごと直前のコミットを取り消す。

コミットするときの流れ

本節では実際コミットをするまでの流れを以下のTest.javaファイルと共に確認していきます。

public class Test {
    public static void main(String[] args) {

    }
}

Test.javaにある編集を加えました。編集は正しく反映されているでしょうか?
自身の編集が完了したらgit statusで現在の状態を確認します。

$ git status
On branch master
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

        modified:   src/test/Test.java

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

Test.javaに変更があったようです。ソース内ではどのような変更があったのかgit diffで確認します。

$ git diff
diff --git a/src/test/Test.java b/src/test/Test.java
index 8e11c08..b625295 100644
--- a/src/test/Test.java
+++ b/src/test/Test.java
@@ -2,5 +2,6 @@ package test;

 public class Test {
        public static void main(String[] args) {
+               System.out.println("Test");^M
        }
 }

出力部分が追加されたようですね。ではこの編集をインデックスに登録しましょう。
確実にインデックスに追加したい自身の編集ファイルのみ git add src/test/Test.java で登録しましょう。

再度、現在の状態を確認します。

$ git status
On branch master
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

        modified:   src/test/Test.java

Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

インデックスに登録されている様子が確認できました。 それではコミットしていきましょう。

$ git commit -m 'Test出力の追加'
[master 2eb4313] Test出力の追加
 1 file changed, 1 insertion(+)

問題なくコミットできたようです。
最後にコミットの履歴のログを確認しておきましょう。

$ git log --oneline
2eb4313 (HEAD -> master) Test出力の追加
8823cc3 Test.javaの作成
97fde21 first commit

ここまでの作業が完了すればローカルでの編集内容が履歴として記録されることになります。
以降は同様に編集→コミットしていけばよいわけですね。
個人的にコミットまでの注意点は

  • git diffで変更差分を確認すること。
  • git addで必要のないファイルまでインデックスに登録しないこと

この2点だと思っています。
この点を意識できているかどうかだけでも、Gitに対する理解が深まるのではないでしょうか。

コミットで失敗したとき

次に、今までやってきた「addやcommitをやり直したい」そんなときの流れを簡単に確認します。
例として、前節で行ったコミットが間違えていたのでなかったことにしましょう。
git resetのオプションを指定して直前のコミットをなかったことにします。

$ git reset --soft HEAD^

ログやステータスを確認してコミットが取り消されていることと現在の状態を確認します。

$ git log --oneline
8823cc3 (HEAD -> master) Test.javaの作成
97fde21 first commit

$ git status
On branch master
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

        modified:   src/test/Test.java

直前のコミットTest出力の追加が取り消されています。 ここまでで、直前のコミットを取り消し、編集内容がインデックスに登録されているという状態が確認できました。 次にこのadd自体も取り消してみましょう。
この場合はオプション無しのgit resetです。

$ git reset
Unstaged changes after reset:
M       src/test/Test.java

$ git status
On branch master
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

        modified:   src/test/Test.java

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

addされた内容がインデックスの登録から外れた様子も確認できました。
ここまでで直前のコミットを取り消し、編集内容も取り消しました。つまり、2つ前のコミットの状態まで戻ったことになります。ここからは引き続き作業を行っていきましょう。

おわりに

最初にも述べたように機械的に行うcommitaddはGitを利用していく上で良いことではありません。
自身が利用するツールに関してはどのような利用方法があるのか、どのような操作であるのかを確認して利用していくと良いかと思います。

自身の学習を踏まえた記事ではありますが、読んで頂いた方々の参考になれば幸いです。

Copyright © RAKUS Co., Ltd. All rights reserved.