【勉強用】Gitのコマンドを実際に動かしてみた（②コミット編）

# はじめに
この記事ではGitのコマンドを実際に動かして、バージョンの確認や変更について理解を深めたいと思います。参考図書はこちらの動かして学ぶ！Git入門を使用しました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3523467/0e2130b5-cccf-fa77-04fa-8dd77b3a5e9f.png)



# コマンド

### 9. git ls-files
ステージを直接操作すること珍しいですが、内容を見たくなることがたまにあります。
```Git:Git Bash
$ git ls-files
hello.txt
```
**-s**オプションを追加することで、さらに詳細な情報を得られます。

```Git:Git Bash
$ git ls-files -s
100644 7fe63068bb34171879220bcbf0cf85f999c14bd4 0       hello.txt
```
### 10. git reset
**git reset**コマンドはHEADの位置を移動させるコマンドですが、ステージや作業ツリーの内容をHEADに合わせる処理にも使えます。単に**git reset**とするとHEADの内容をステージのコピーします。特定のファイルだけHEADの状態に戻したい場合は**git reset <ファイル名>**とします。もし作業ツリーの内容もHEADに戻したい場合は**git reset --hard**とします。
それでは、`hello.txt`に新たに`Thank you!`という文章を追加し、**git diff --staged**でステージの内容を確認します。
```Git:Git Bash
$ git add hello.txt
$ git diff --staged
diff --git a/hello.txt b/hello.txt
index 7fe6306..abd6733 100644
--- a/hello.txt
+++ b/hello.txt
@@ -1,3 +1,4 @@
 hello!
 Hello, everyone!
-Goodbye!
\ No newline at end of file
+Goodbye!
+Thank you!
\ No newline at end of file
```
次に**git reset --hard**を実行して、HEADの内容をステージと作業ツリーに戻し、**git diff --staged**でステージとの差を確認します。
```Git:Git Bash
$ git reset --hard
HEAD is now at a454aad check diff
$ git diff --staged
#何も表示されません
```
無事作業ツリーの内容も戻りました。

### 11. git checkout ファイル名
一度ファイルを変更しステージングした後、再び変更を行ったが、ステージングした内容で良かったので内容を戻した。この場合は**git checkout ファイル名**コマンドを使うことで、ステージングした後の変更をなかったことにできます。
`hello.txt`に新たに`See you later!`という文章を追加し、ステージングします。その後、新たに`nice to meet you !`という文章を追加します。そして**git checkout hello.txt**を実行してみます。
```Git:Git Bash
$ git add hello.txt
#nice to meet you !を追加
$ git checkout hello.txt
$ git diff HEAD
diff --git a/hello.txt b/hello.txt
index 7fe6306..1dbe2a8 100644
--- a/hello.txt
+++ b/hello.txt
@@ -1,3 +1,4 @@
 hello!
 Hello, everyone!
-Goodbye!
\ No newline at end of file
+Goodbye!
+See you later!
\ No newline at end of file
```
無事に、`nice to meet you !`という文章が作業ツリーから無くなっていることが分かります。

### 12. git mv
`git mv`はファイル名やディレクトリの名前を変更するコマンドです。変更する際には`git mv 元の名前　新しい名前`という形で実行します。

それでは、`hello.txt`を`greeting.txt`というファイル名に変更します（これは後で元に戻します）。ステージの中を確認するために、**git ls-files**を実行しましょう
```Git:Git Bash
$ git mv hello.txt greeting.txt
$ git add greeting.txt
$ git ls-files
greeting.txt
```
無事、ファイル名の変更が確認できました。

### 13. git rm
`git rm`コマンドはファイルやディレクトリをステージから除外するコマンドです。`-r`オプションはそのディレクトリ以下のファイルやディレクトリも全て除外するというものです。実行すると、次のコミットから指定されたファイルやディレクトリは、無視されるためGitの管理から除外されます。ただし、すでに作成されたコミットから除外されるわけではありません。これらのコマンドを実行すると、**作業ツリーからもファイルが削除される**ので注意が必要です。作業ツリーに残したい場合は`--chached`オプションを追加します。強制的に削除したい場合は**-f**オプションを追加します。

それでは新たに、`rm.txt`を作成して削除してみましょう。

```Git:Git Bash
$ git add rm.txt
$ git status
On branch main
Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
        new file:   rm.txt

$ git rm -f rm.txt
rm 'rm.txt'

$ git status
On branch main
nothing to commit, working tree clean
```
無事、除外することが出来ました。

### 14. git checkout コミット名 --ファイル名
このコマンドでは指定したコミットから、指定したファイル名をステージと作業ツリーに取り出します。同盟のファイルがある場合は、**上書きされてしまう**ので注意が必要です。その場合は、ステージング、コミットをあらかじめ行い、クリーンな状態にしてから実行することをお勧めします。

それでは、2つ前のコミットから`hello.txt`を取り出してみましょう。
```Git:Git Bash
$ git checkout @~2 hello.txt
Updated 1 path from 80f2d4b

$ git diff HEAD
diff --git a/hello.txt b/hello.txt
index 7fe6306..3462721 100644
--- a/hello.txt
+++ b/hello.txt
@@ -1,3 +1 @@
-hello!
-Hello, everyone!
-Goodbye!
\ No newline at end of file
+hello!
\ No newline at end of file
```
無事、コミットから取り出すことが出来ました（後でHEADの状態に戻します）。

### 15. git show コミット名:ファイル名
このコマンドは上記の**git checkout コミット名 --ファイル名**とは異なり、ステージと作業ツリーに変更を加えることなく、指定したコミットの指定したファイル名の状態を確認することが出来ます。

それでは、2つ前のコミットから`hello.txt`を取り出し内容を確認してみましょう。
```Git:Git Bash
$ git show @~2 hello.txt
commit e6e9a3b54ed9da71de0ba63ccd612a9bd492d98a
Author: HANAKO <hanako@sample.com>
Date:   Fri Nov 3 14:59:10 2023 +0900

    first commit

diff --git a/hello.txt b/hello.txt
new file mode 100644
index 0000000..3462721
--- /dev/null
+++ b/hello.txt
@@ -0,0 +1 @@
+hello!
\ No newline at end of file

```
無事確認できましたね。

### 16. git reset --hard コミット名
このコマンドは指定したコミットの以降のコミットを削除し、指定したコミットを新たなHEADとするコマンドです。

それでは一つ前のコミットをHEADにしてみましょう。
```Git:Git Bash
$ git reset --hard @~1
HEAD is now at 714ed15 check status
```
無事HEADを一つ前に戻すことができました。

### 17. git commit --amend
コミットしてから、必要なファイルのステージをし忘れたり、コミットメッセージを変更したいことは良くあります。こういった状況で、作業ツリーとステージはそのままでコミットのみを捨てる処理を行いたい場合は**git commit --amend**があります。これは**git reset --soft**でも代用できます。

それでは`hello.txt`に新たに`Enjoy!`という文章を追加し、ステージング、コミットをします。その後、コミットのみを捨て、新たに"Have a nice day !"という文章に変更し、ステージング、コミットします。
```Git:Git Bash
#Enjoy !という文章を追加
$ git diff HEAD
diff --git a/hello.txt b/hello.txt
index 5a09d1c..5ae006b 100644
--- a/hello.txt
+++ b/hello.txt
@@ -1,2 +1,3 @@
 hello!
-Hello, everyone!
\ No newline at end of file
+Hello, everyone!
+Enjoy!
\ No newline at end of file

$ git add hello.txt
$ git commit -m "Enjoy !"
[main e80188c] Enjoy !
 1 file changed, 2 insertions(+), 1 deletion(-)

$ git show
commit e80188cb71a829f3020b5e09c87873345a433167 (HEAD -> main)
Author: HANAKO <hanako@example.com>
Date:   Fri Nov 3 20:32:42 2023 +0900

    Enjoy !

diff --git a/hello.txt b/hello.txt
index 5a09d1c..5ae006b 100644
--- a/hello.txt
+++ b/hello.txt
@@ -1,2 +1,3 @@
 hello!
-Hello, everyone!
\ No newline at end of file
+Hello, everyone!
+Enjoy!
\ No newline at end of file

$ git commit --amend
[main aa36595] Enjoy !
 Date: Fri Nov 3 20:32:42 2023 +0900
 1 file changed, 2 insertions(+), 1 deletion(-)
 
#Have a nice day !という文章を追加
$ git add hello.txt
$ git commit -m "Have a nice day !"
[main 0e420a2] Have a nice day !
 1 file changed, 1 insertion(+), 1 deletion(-)

$ git diff @ @~1
diff --git a/hello.txt b/hello.txt
index d80fb92..5ae006b 100644
--- a/hello.txt
+++ b/hello.txt
@@ -1,3 +1,3 @@
 hello!
 Hello, everyone!
-Have a nice day !
\ No newline at end of file
+Enjoy!
\ No newline at end of file
```
無事コミットのみを変更することができました。

### 18. .gitignoreの設定
一時ファイルや自動生成されるファイルなど、バージョン管理したくないファイルまで**git status**は追跡してしまいます。Gitに完全に無視させるには**.gitignore**というファイルを作成し、そこに無視したいファイル名を記載します。

```Git:.gitignore
a.out
*.txt
*.png
```

このように.gitignoreを書くと`a.out`という名前のファイルと`.txt`、`.png`で終わるファイルを無視します。
例外的にGitに無視させたくないファイルがある場合は、`!`で指定します。
```Git:Git Bash
*.txt
!hello.txt
```
.gitignoreも他のファイルと同様にバージョン管理を行います。
```Git:Git Bash
$git add .gitignore
$git commit -m "add .gitignore"
```

# まとめ
今回の記事ではステージやコミットの変更や、変更の削除方法などについて学習しました。次回からはブランチの操作について学習していきたいと思います。

[**前回：【勉強用】Gitのコマンドを実際に動かしてみた①（基本操作編）**](https://qiita.com/Yuhei0531/items/997d87e73889554c6ecd)
[**次回：【勉強用】Gitのコマンドを実際に動かしてみた（③ブランチ編）**](https://qiita.com/Yuhei0531/items/f6b3163a9115be5a6e27)

# 参考文献
[動かして学ぶ！Git入門](https://www.shoeisha.co.jp/book/detail/9784798170855)