Gitを使いこなしたい！〜仕組みとコマンド24選〜

便利そうなコマンドがあることは知っているけれどなんとなくGit操作が怖い、という方向けにGit情報をまとめました。
怖さを低減する1番の近道は、たくさんコマンドを使ってみることだと思います。
ぜひ、一緒にコマンド使いましょう！

◯おすすめサイト情報
Git公式サイト：[Book](http://git-scm.com/book/ja/v2) 
Gitってなにそれおいしいの...？という方向け：[サル先生のGit入門](https://backlog.com/ja/git-tutorial/)
Gitの仕組みについて参考になったサイト：[Learn git concepts, not commands - DEV Community ](https://dev.to/unseenwizzard/learn-git-concepts-not-commands-4gjc)

#Gitについて

Gitとは、分散型バージョン管理システムのことです。

バージョン管理システムとは変更履歴などを記録・管理するためのシステムで、形態としては集中型と分散型に分けられます。
分散型では「リポジトリ」と呼ばれる「ファイルやデータの貯蔵庫」を個人の作業環境に丸ごと複製して作業を行うため、個人の開発環境内だけで作業が完結でき、どこかのリポジトリで不具合が起きた際にも復元しやすいという特徴があります。
このような分散型バージョン管理システムの中で現在広く使われているものがGitです。

Gitでは変更の履歴や差分などを簡単に記録できるため、過去の状態の復元や複数人での作業などにも役立ちます。

また、Gitを使用するためのプラットフォームとしてGitHubやBitbucket、GitLabなどがあります。
これらのサービスに登録することで誰でも簡単にGitを利用できるようになります。


##Gitの仕組み

Gitでバージョン管理をするにあたり、その仕組みを理解することは大切です。
ここではGitの仕組みを理解するためにおさえておきたい用語についてまとめました。
個人的にGitの仕組みは縦のつながりと横のつながりの2種類から構成されていると解釈したため、今回は縦のつながりと横のつながりに分けてまとめました。
全体は以下のようなイメージです。
![aab.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1396691/018692c5-534d-c033-d9fc-640fe6d8cbee.png)




###◯縦のつながり編

####リモートリポジトリ
複数人で共有するためのリポジトリで、通常GitHubなどのサイトに配置します。
上の図では「リモートリポジトリ」から1つの「個人の開発環境」しか繋がっていませんが、リポジトリを共有する開発環境の数に合わせて繋がる本数が増えるイメージです。
リモートリポジトリはローカルリポジトリと繋がっており、そこから変更情報のやりとりをします。

####ローカルリポジトリ
個人で利用するためのリポジトリで、手元のマシンに配置します。
個人の開発環境内で変更履歴を管理する場合や、変更履歴を他の人に共有したい場合に利用します。

####インデックス / ステージングエリア
ローカルリポジトリとワーキングツリーの間に位置する部分です。
変更したファイルをこの場所に追加することで変更内容を集約し、コミットを作成するための準備を行います。

####ワーキングツリー
実際にファイルの編集作業を行う場所です。
コードエディタなどで開くファイルはこの場所に位置します。

以上の場所を変更情報が行き来することで、リポジトリに「コミット」と呼ばれる変更情報の記録が作成されます。

###◯横のつながり編

####ブランチ
作業履歴を分岐して記録するためのもので、一連のコミットを指す言葉です。
例えば、「機能を追加するためのブランチ」や「バグを修正するためのブランチ」を作成することで作業の種類ごとに履歴を残すことができます。
他のブランチの影響を受けないため、同時平行で複数の変更を進めることが可能です。

また、「あるブランチに移動する」といえば、そのブランチにある最新コミットの状態に移動します。
このように、ブランチとは暗黙的に一連の流れにある最新コミットを指し、図で表す場合は先ほどの全体図のように最新コミットを指す形でブランチ名が示されます。


####コミット
`git commit`コマンドで作成される、変更情報の記録のことです。
コミットは親コミットと呼ばれる前回のコミットにつながる形でブランチの最新情報を更新します。
コミットにはインデックスで集約された変更点の他、親コミットの情報、コミットの作成者、コミットメッセージなどの情報が含まれます。

####HEAD
自分が作業しているブランチの最新コミットを指す言葉です。
先ほどの全体図ではHEADがpotatoブランチにあったことから、自分がいるブランチはpotatoブランチであると分かります。
この場合、potatoブランチが指すコミットとHEADの位置は同じです。
もしも最後にコミットした後にワーキングツリーで作業を進めているのであれば、それはワーキングツリーがHEADよりも進んでいる状態といえます。


#おすすめコマンド24選
今回はたくさんあるGitコマンドの中から、これを押さえていれば一通り操作できる！というものを独断と偏見で選びました。
まだまだ便利なコマンドはたくさんありますので、これを機に他のコマンドについてもチャレンジしてみましょう！

##縦のつながり編


###git clone [リモートリポジトリのURL]
リモートリポジトリ全体をローカルに複製するコマンドです。
コマンドを実行した階層の1つ下にディレクトリが作成され、その中にリポジトリが複製されます。
Gitを利用する際にはリポジトリを用意することから始まりますので、リモートリポジトリがある状態で最初に実行するコマンドは`git clone`となります。
リモートリポジトリのURLはGitHubなどのサイトで取得可能です。

```
$ git clone git@github.com:yourname/curry.git  ◆git clone [URL]を実行
Cloning into 'curry'...  ◆curryリポジトリをクローン中
remote: Enumerating objects: 3, done.
remote: Counting objects: 100% (3/3), done.
remote: Total 3 (delta 0), reused 0 (delta 0), pack-reused 0
Receiving objects: 100% (3/3), done. 　◆クローン完了
```
<img width="80%" alt="clone.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1396691/1872ef7b-a238-c87e-f756-7a6d79ed3cd9.png">

空のリポジトリをクローンした場合は以下のような警告が出ます。
まだ何も変更を追加していないのであれば問題ありませんが、既に変更を記録したはずという場合は確認が必要です。

```
$ git clone git@github.com:yourname/curry.git　　◆git clone [URL]を実行
Cloning into 'curry'...
warning: You appear to have cloned an empty repository.  ◆リポジトリが空の場合の警告
```

###git fetch
リモートリポジトリの最新状態を、ローカルリポジトリの「リモート追跡ブランチ」にダウンロードするためのコマンドです。
リモート追跡ブランチにダウンロードするだけであり、ローカルブランチへの影響はありません。
ローカルブランチに変更点を反映するには別途`git merge`などの対応が必要です。

リモート追跡ブランチとは、他のリポジトリのブランチを追跡するブランチのことで、ローカルリポジトリ内に存在します。
例えば下記の`origin/rice`は、`origin`というリモートリポジトリにある`rice`ブランチを追う「リモート追跡ブランチ」を表します。
また、`origin`はGitがリモートリポジトリのサーバーに付ける名称です。
この名称は`git remote`コマンドで確認でき、基本的にはoriginが設定されています。

```
$ git fetch  ◆git fetchを実行
remote: Enumerating objects: 4, done.
remote: Counting objects: 100% (4/4), done.
remote: Compressing objects: 100% (2/2), done.
remote: Total 3 (delta 0), reused 0 (delta 0), pack-reused 0
Unpacking objects: 100% (3/3), done.
From github.com:yourname/curry
 * [new branch]      rice       -> origin/rice  ◆新たにリモートリポジトリのriceブランチを追跡するブランチが作成された
```
<img width="80%" alt="fetch.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1396691/6fc4886c-8f5f-4056-3a3a-ae8ddcbab161.png">

###git pull origin [リモートブランチ名]
リモートリポジトリの最新状態をローカルブランチに反映するためのコマンドです。
`git pull`は`git fetch`と`git merge`が組み合わさってできています。
そのためリモートリポジトリからリモート追跡ブランチへ変更された情報をダウンロードし次第、ローカルブランチにも変更点が反映されます。

```
$ git pull origin potato  ◆リモートリポジトリのpotatoブランチをpull
From github.com:yourname/curry
 * branch            potato     -> FETCH_HEAD  
Updating 8ca7964..95805ad  ◆ローカルブランチのコミットを更新
Fast-forward  ◆Fast-forwardマージを実行
 wash_potatoes.txt | 2 ++
 1 file changed, 2 insertions(+)  ◆1つのファイルに2箇所の内容の追加があったことが確認できる
```
<img width="80%" alt="pull.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1396691/24536508-b7a6-fe82-eada-79504d0aa35e.png">

コマンドの`origin [リモートブランチ名]`は、上流ブランチを設定している場合に省略が可能です。
上流ブランチとはローカルブランチが履歴を追跡するブランチのことで、大抵の場合はリモート追跡ブランチを設定します。

###git add [ファイル名]
変更したファイルをインデックスに追加するためのコマンドです。
心配な時は`git status`や`git diff`でよく確認をしてから実行するのが吉です。

```
$ git status  ◆現在の状況を確認（詳しくはgit stashへ）
On branch potato
Untracked files:
  (use "git add <file>..." to include in what will be committed)

	boil_potatoes.txt  ◆3つの新しいファイルがある
	cut_potatoes.txt
	wash_potatoes.txt

nothing added to commit but untracked files present (use "git add" to track)
$ git add wash_potatoes.txt　 ◆wash_potatoes.txtというファイルをインデックスに追加
$ git status  ◆再度現状を確認
On branch potato
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

	new file:   wash_potatoes.txt  ◆インデックスに追加されている

Untracked files:
  (use "git add <file>..." to include in what will be committed)

	boil_potatoes.txt
	cut_potatoes.txt
```
<img width="80%" alt="add.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1396691/d4c6a264-ef98-c759-b3fd-aa60bed051b9.png">

###git commit -m "[コミットメッセージ]"
ローカルリポジトリにコミットを作成するためのコマンドです。
コミットを作成する場合にはコミットメッセージが必須であり、コミットの内容が分かるように記載します。

```
$ git status  ◆現在の状況を確認
On branch potato
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

	new file:   wash_potatoes.txt  ◆インデックスに追加されたファイルがある
![push.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1396691/ce9b3b69-157d-d162-dd2c-d3b8a92fda28.png)

$ git commit -m "add how to wash"  ◆git commitを実行
[potato 1cffb4e] add how to wash    ◆potatoブランチにコミットが作成された
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 wash_potatoes.txt  
$ git status  ◆再度現状を確認
On branch potato
nothing to commit, working tree clean  ◆インデックスに追加されたファイルはなくなっている
```
<img width="80%" alt="commit.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1396691/e832712b-2fd7-3d57-ad9e-02b7d6a39539.png">

###git push origin [リモートブランチ名]
ローカルリポジトリに作成したコミットをリモートリポジトリにアップロードするコマンドです。
このコマンドを実行することでリモートリポジトリ内の変更履歴がローカルリポジトリと同じ状態になり、自分の変更履歴を他の人と共有することができます。

`git pull`と同様、上流ブランチを設定している場合は`origin [リモートブランチ名]`の省略が可能です。

```
$ git push origin potato  ◆リモートのpotatoブランチにpushする
Counting objects: 2, done.
Delta compression using up to 2 threads.
Compressing objects: 100% (2/2), done.
Writing objects: 100% (2/2), 261 bytes | 261.00 KiB/s, done.  ◆書き込みまで完了
Total 2 (delta 0), reused 0 (delta 0)
remote:  ◆GitHubからプルリク作れる旨のメッセージ。スルーしてOK。
remote: Create a pull request for 'potato' on GitHub by visiting:
remote:      https://github.com/yourname/curry/pull/new/potato
remote:
To github.com:yourname/curry.git
 * [new branch]      potato -> potato  ◆potatoブランチが更新された
```
<img width="80%" alt="push.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1396691/f8b305c0-9bbb-cf50-d3cb-af9ecef33dec.png">

##縦のつながり番外編
addやcommit、pushをするにあたり何も確認せずに行うのは怖さが伴います。
ということで、それらのコマンドを扱う際に変更点を確認できるコマンドをまとめました。

###git diff
インデックスに追加していない、ワーキングツリーでの変更箇所を確認するためのコマンドです。
ワーキングツリーをインデックスと比較します。
`git add`前に変更箇所を確認したい場合におすすめです。

```
$ git diff
diff --git a/cut_potatoes.txt b/cut_potatoes.txt
index f4231fa..08cea19 100644
--- a/cut_potatoes.txt
+++ b/cut_potatoes.txt
@@ -1 +1,3 @@
-1.prepare Kitchen knife and cutting board. ◆「1.prepare Kitchen knife and cutting board.」という文が削除されていることが確認できる
+1.Make sure the potatoes are washed.  ◆「1.Make sure the potatoes are washed」という文以下3行が追加されていることが確認できる
+2.Prepare Kitchen knife and cutting board.
+3.Cut potatoes into bite size pieces.
```

###git diff --cached
インデックスに追加済みで、次のコミットに入る予定の変更箇所を確認するためのコマンドです。
ステージングされた変更を最後のコミットと比較します。
`git commit`前に変更箇所を確認したい場合におすすめです。

```
$ git diff --cached
diff --git a/wash_potatoes.txt b/wash_potatoes.txt
index e69de29..567657a 100644
--- a/wash_potatoes.txt
+++ b/wash_potatoes.txt
@@ -0,0 +1 @@
+1.Wash your hands.  ◆「1.Wash your hands.」の一文がファイルに追加されていることが確認できる
```

###git status
前回のコミットから変更のあるパスを表示するコマンドです。
①インデックスと前回のコミットの差分、②ワーキングツリーとインデックスの差分、③追跡も未追跡登録もされていないファイルの3区分で表示します。

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

	new file:   wash_potatoes.txt ◆インデックスに新しく追加されたファイル
	
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:   cut_potatoes.txt ◆ワーキングツリーで編集されたファイル

Untracked files: ◆③
  (use "git add <file>..." to include in what will be committed)

	boil_potatoes.txt ◆Gitの管理下ではない(1度もaddされていない)ファイル
```

何も変更がない場合は以下のようにパスは表示されません。

```
$ git status
On branch potato
nothing to commit, working tree clean
```


##横のつながり編

###git branch
ローカルブランチを確認するコマンドです。
現在作業中のブランチには * がつきます。
`git commit`や`git push`の際、ブランチが間違っていないかを確認するためによく使用します。

```
$ git branch
* master　 ◆現在作業中のブランチ
  potato
  tomato
```
ブランチを確認するための他に影響のないコマンドのため、コマンドが使えるか否かなどの確認にも便利です。
ちなみにリポジトリが設定されていない場所でGitコマンドを使用すると以下のようになります。

```
$ git branch
fatal: not a git repository (or any of the parent directories): .git
```
もしも意図せずこのように表示された場合は、git操作対象のディレクトリが間違っていないかを確認しましょう。


###git branch -a
git branchのオプションに `-a`を設定することで、ローカルリポジトリ内にある全てのブランチを確認できます。
リモート追跡ブランチは`remotes/origin/`が付いた状態で表示されます。

```
$ git branch -a
* master
  potato
  tomato
  remotes/origin/master  ◆masterという名前のリモート追跡ブランチ
  remotes/origin/onion   ◆onionという名前のリモート追跡ブランチ
```

###git checkout [移動先のブランチ名]
指定したローカルブランチに移動するためのコマンドです。
当たり前ですが、移動したいブランチが存在しない場合は移動できません。

```
$ git checkout potato  ◆potatoブランチに移動する
Switched to branch 'potato'  ◆potatoブランチに移動した
```
移動した後には`git branch`で確認をすると安心できます。

###git checkout .
ワーキングツリー内の変更をインデックスの状態に戻すためのコマンドです。
ブランチを移動する際など、ワーキングツリー内の変更を一括で削除したい場合に使用します。

```
$ git status  ◆git stashで現状を確認
On branch potato
Your branch is up to date with 'origin/potato'.
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:   cut_potatoes.txt  ◆ワーキングツリー内に変更点がある

$ git checkout .  ◆git checkout . を実行
$ git status
On branch potato
Your branch is up to date with 'origin/potato'.
nothing to commit, working tree clean  ◆ワーキングツリーの変更点がなくなっている
```
ワーキングツリー外の新規作成ファイルなどは対応外のため、削除したい場合は別途`git clean -df`などで対応が必要です。

###git checkout -b [作成したいブランチ名] 
ローカルに新しいブランチを作成し、作成したブランチに移動するためのコマンドです。
1度に作成と移動が可能な便利なコマンドです。

```
$ git checkout -b carrot 　◆carrotという新しいブランチを作成し、移動する
Switched to a new branch 'carrot'  ◆新しい'carrot'というブランチに移動した
```
ただし、このコマンドでは上流ブランチの設定は行いません。
必要な場合は別途`git branch -u`などでの対応が必要です。

###git checkout -b [作成したいブランチ名] [上流ブランチ名]
このコマンドは以下の3動作が1度に行えるハイパー便利なコマンドです。
・新しくローカルブランチを作成する
・作成したローカルブランチに上流ブランチを設定する
・作成したブランチに移動する

上流ブランチを設定することで、`git pull`や`git push`の際に反映したいブランチ名を毎回指定する必要がなくなります。
上流ブランチにはリモート追跡ブランチを設定することが多く、その場合は [上流ブランチ名] を`origin/ブランチ名`の形で指定します。

```
$ git checkout -b onion origin/onion　 ◆origin/onionという上流ブランチを持つonionブランチを作成、移動
Branch 'onion' set up to track remote branch 'onion' from 'origin'.  ◆onionブランチがoriginのonionブランチを追跡するよう設定
Switched to a new branch 'onion'  ◆作成したonionブランチに移動
```
ここまで4種類の`git checkout`が登場しました。
「`git checkout`は色々機能があるんだな...(悩)」と思った方も多いと思います。
その通り、使用用途は大きく2種類「ブランチの変更」と「ファイルの復元」がありました。
このように`git checkout`の用途が多岐に渡っていることを踏まえ、[Git 2.23](https://github.blog/2019-08-16-highlights-from-git-2-23/)では新しく`git switch`と`git restore`が追加されました。
これらは`git checkout`の用途を明確にするために試験的に導入されているコマンドです。
「ブランチ変更」の際は`git switch`を、「ファイル復元」の際は`git restore`を用いることができます。
今後の動向は分かりませんが、合わせておさえておきたいところです。

###git merge [統合したいブランチ名]
複数のブランチを1つにまとめるためのコマンドです。
このコマンドを実行するブランチに、指定したブランチの変更が取り込まれます。

マージには2つの取り込み方があります。
####Fast-forwardのマージ
派生元のブランチが、指定したブランチを作成した時と比べて進んでいない場合の統合方法です。
この場合はブランチ名が指すコミットが移動するだけで完了します。

```
$ git merge potato  ◆masterブランチにpotatoブランチを取り込む
Updating 4b571eb..29695f7  ◆コミットを示すハッシュ値がpotatoブランチのものに更新
Fast-forward  ◆Fast-forwardマージが実行された
 boil_potatoes.txt | 2 ++
 cut_potatoes.txt  | 3 +++
 text.txt             | 0
 wash_potatoes.txt | 3 +++
 4 files changed, 8 insertions(+)
 create mode 100644 boil_potatoes.txt
 create mode 100644 cut_potatoes.txt
 delete mode 100644 text.txt
 create mode 100644 wash_potatoes.txt  ◆マージ完了
```
<img width="100%" alt="ffmerge.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1396691/9ec33582-fe40-ea0d-dda1-d4c59dda01db.png">

####recursive strategyのマージ
派生元のブランチが、指定したブランチを作成した時よりも進んでいる場合の統合方法です。
この場合はマージコミットと呼ばれる新しいコミットを作成して統合します。
コマンドを実行するとマージコミットの作成のためのvimが表示されますが、今回はそのまま`esc`+`:`+`q`で終了しました。

```
$ git merge carrot  ◆masterブランチで実行

----------------マージコミットを作成するためにvimが表示された様子-----------------
Merge branch 'carrot'
# Please enter a commit message to explain why this merge is necessary,
# especially if it merges an updated upstream into a topic branch.
#
# Lines starting with '#' will be ignored, and an empty message aborts
# the commit.
------------------------------------------------------------------------

Merge made by the 'recursive' strategy.  ◆recursive strategyなマージが行われた
 boil_carrot.txt | 0
 cut_carrot.txt  | 0
 wash_carrot.txt | 2 ++
 3 files changed, 2 insertions(+)
 create mode 100644 boil_carrot.txt
 create mode 100644 cut_carrot.txt
 create mode 100644 wash_carrot.txt  ◆マージ完了
```
<img width="100%" alt="rstrategym.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1396691/524a35ce-42cb-5e96-e5ed-01778a150812.png">

####もしもコンフリクトが起きたら
もしも取り込み先のコミットで同じ箇所を変更していた場合、コンフリクト(競合)が起きます。
その場合はコンフリクト発生のメッセージが出ますので、落ち着いて解消しましょう。

（例）potatoブランチとcarrotブランチでcut_carrot.txtの同じ箇所を変更してコンフリクトが発生した

```
$ git merge potato  ◆carrotブランチにpotatoブランチを取り込もうとした
Auto-merging cut_carrot.txt  
CONFLICT (content): Merge conflict in cut_carrot.txt  ◆コンフリクト発生
Automatic merge failed; fix conflicts and then commit the result.

-------コンフリクトの箇所をエディタで開いた様子--------
<<<<<<< HEAD  
hogehoge  ◆carrotブランチ(HEAD)の変更箇所
=======
hugahuga   ◆potatoブランチの変更箇所
>>>>>>> potato  
--------------------------------------------
↓ 変更を残したい部分のみ残し、他の部分は削除する
---------
hogehoge
---------

$ git status  ◆git statusで状況を確認する
On branch carrot
You have unmerged paths.
  (fix conflicts and run "git commit")
  (use "git merge --abort" to abort the merge)

Unmerged paths:
  (use "git add <file>..." to mark resolution)

	both modified:   cut_carrot.txt  ◆コンフリクトを起こしているファイル

no changes added to commit (use "git add" and/or "git commit -a")
$ git add cut_carrot.txt  ◆コンフリクトを修正した状態で再度 git add
$ git status  ◆git statusで状況を確認する
On branch carrot
All conflicts fixed but you are still merging.  ◆コンフリクトは直したが、マージが途中とのこと
  (use "git commit" to conclude merge)
$ git commit -m "fix conflict"  ◆git statusで確認した通り、git commitで修正を反映し、完了
[carrot e3bb7d7] fix conflict
```

###git rebase [統合元にしたいブランチ名]
複数のブランチを1つにまとめるためのコマンドです。
ただしmergeとは異なり、統合元のブランチが、自分がいるブランチを作成した時から進んでいる場合でもマージコミットを作成せずに履歴を残すことができます。
`git rebase`は、コミットの履歴を付け替えることでブランチをまとめます。

[注意] もしもrebaseするブランチから別のブランチが派生していた場合、履歴の付け替えにより親コミットを改変してしまう可能性があります。
ブランチが派生していないことを確かめてから行いましょう。

```
$ git rebase master
First, rewinding head to replay your work on top of it...
Applying: add 3 files  ◆コミットメッセージが「add 3 files」のコミットが統合された
Using index info to reconstruct a base tree...
Falling back to patching base and 3-way merge...
```
`git log`でコミットの履歴を確認すると、`git rebase`前後でコミットを表すハッシュ値が変わっていることが確認できます。
<img width="100%" alt="rebase.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1396691/6a5a6300-4893-6ebf-af36-851b5575b3ed.png">

###git cherry-pick [コミットID]
別のブランチにある特定のコミットを自分がいるブランチにコピーするためのコマンドです。
ブランチをマージするには取り込みたくないコミットがある場合に用います。
コミットIDは`git log`コマンドで調べられます。

```
$ git cherry-pick 98c9dda373623b61013c7edb5bd31eba36c13957
[carrot db56f85] cut potatoes
 Date: Sun Sep 26 11:33:22 2021 +0900
 1 file changed, 1 insertion(+)
```
<img width="100%" alt="cherry-pick.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1396691/20f4ea22-865b-6a9b-0da7-fda718dfb8db.png">

###git log
コミットの履歴を表示するためのコマンドです。
最新のコミット履歴が一番上に表示されます。

```
commit 98c9dda378625b61017c7edb5bd71eba36c18957  ◆コミットのハッシュ値（コミットID）
Author: your name <your@address>  
Date:   Sun Sep 26 11:33:22 2021 +0900

    cut potatoes  ◆コミットメッセージ

commit b33b29fc38b1337646e53da836e0a3c082ce3f7f
Author: your name <your@address>
Date:   Sat Sep 25 11:24:17 2021 +0900

    wash potatoes
```

##その他のコマンド
gitには便利なコマンドがまだまだたくさんあります。
特におすすめなものを紹介します。

###git stash
ワーキングツリーの変更を一時退避するためのコマンドです。
ブランチを移動する際にコミットはしたくない、変更点を持っていきたくもない、破棄もしたくないという場合に用います。

```
$ git stash
Saved working directory and index state WIP on master: 16272b3 add 3 files  
◆stashした旨のメッセージ、WIP on [ブランチ名]: [HEADのハッシュ値] [コミットメッセージ]が表示される
```
また、stashをする際にメッセージをつけて分かりやすくしたい、という場合には`git stash save ["stashメッセージ"]`のコマンドを使います。

```
$ git stash save "stash message"
Saved working directory and index state On master: stash message
◆stashした旨のメッセージ、WIP on [ブランチ名]: [stashメッセージ]が表示される
```

###git stash -u
変更を一時退避する`git stash`の-uオプションで、新しく作成したファイルも合わせて退避するためのコマンドです。

```
$ git stash -u
Saved working directory and index state WIP on master: 16272b3 add 3 files
◆stashした旨のメッセージ、WIP on [ブランチ名]: [HEADのハッシュ値] [コミットメッセージ]が表示される
```

`-u`オプションを用いてかつstashメッセージをつけたいという場合は、`git stash save -u ["stashメッセージ"]`の語順で使用します。

```
$ git stash save -u "stash message2"
Saved working directory and index state On master: stash message2
◆stashした旨のメッセージ、WIP on [ブランチ名]: [stashメッセージ]が表示される
```

###git stash list
`git stash`した作業の一覧を確認するためのコマンドです。
直近にstashしたものほどstash番号が小さい値になります。

```
$ git stash list
stash@{0}: On master: stash message2  ◆stashメッセージを設定した場合、stash番号に続いてstashメッセージが表示される
stash@{1}: WIP on master: 16272b3 add 3 files  ◆stashメッセージを設定しない場合、stash番号に続いてHEADの情報が表示される
stash@{2}: On master: stash message
stash@{3}: WIP on master: 16272b3 add 3 files
```

###git stash pop
`git stash`で一時退避した作業を元に戻すためのコマンドです。
何事もなく元に戻せた場合は、stashの記録は削除されます。

```
$ git stash pop stash@{0}
Already up to date!
On branch master
Untracked files:
  (use "git add <file>..." to include in what will be committed)

	fuga.txt  ◆stashしていたファイルが戻ってきた

nothing added to commit but untracked files present (use "git add" to track)
Dropped stash@{0} (e5e7a221351f76395c9e16d6611210cd185bf45a)  ◆stashの記録が削除された
```

###git reset HEAD
インデックスにある変更をHEADの状態にリセットするためのコマンドです。
間違えて`git add`をしてしまったファイルを一括で取り消す場合などに使用します。
ワーキングツリーはリセットしないため、変更点はそのままに続きから作業を進めることができます。

```
$ git reset HEAD  ◆インデックスをリセットする
Unstaged changes after reset:
M	wash_potatoes.txt  ◆インデックスから戻されたファイル
```

以上、おすすめコマンド24選でした！
最後までお読みいただきありがとうございました。

##参考
[Git公式Book](https://git-scm.com/book/en/v2) 
[サル先生のGit入門](https://backlog.com/ja/git-tutorial/)
[Learn git concepts, not commands - DEV Community ](https://dev.to/unseenwizzard/learn-git-concepts-not-commands-4gjc)
[Qiita：いまさらだけどGitを基本から分かりやすくまとめてみた](https://qiita.com/gold-kou/items/7f6a3b46e2781b0dd4a0#git%E3%81%A8%E3%81%AF)
[Qiita：Git で「追跡ブランチ」って言うのやめましょう](https://qiita.com/uasi/items/69368c17c79e99aaddbf)
[OTTANXYZ：Git初心者が最初から学ぶGitの入門（リモートリポジトリ） ](https://www.ottan.xyz/posts/2019/04/git-basis-beginner-remote-repository-20190404/)