Git で覚えていきたいコマンド

# はじめに

`git スキル` リファクタリングの時間です！！

最近`git`コマンドに慣れてきたので、新しいコマンドを覚えていきたい所存

```
「すぐ使えるもの」：RUNTEQ カリキュラムで使えるもの

「すぐ使えないけど絶対使うもの」：備忘録

「まだ重要度のわからないもの」：初心者（私）からするとわからないもの。
```

という形で書いていきます！


（↓ こちらの記事に触発されました。ありがとうございます🙇‍♂️🙇‍♂️）

https://qiita.com/uhooi/items/c26c7c1beb5b36e7418e
# すぐ使えるもの

今取り組んでいる RUNTEQ カリキュラム上、すぐに使って覚えていけそうなものです。

## git commit --amend

> 直前のコミットメッセージは `git commit --amend` で変更できます。  
> テキストエディタが開くので、コミットメッセージを変更して保存します。

まさに今日やりたかったことですね～便利。
## git branch

> | コマンド | 説明 |
> |---|---|
> |`git branch {ブランチ名}`|対象ブランチを新規作成する（チェックアウトしない）|

使うというよりは、「こういう挙動をしてしまう」というのは頭に入れておきたいですね。
人生で数回はやらかしそう。（作った覚えのないブランチができてそう）

> | コマンド | 説明 |
> |---|---|
> |`git branch -m {旧ブランチ名} {新ブランチ名}`|対象ブランチをリネームする|

リネームってこんなに簡単にできるんだ！！
作成時、間違えてないか、びくびくしながら入力してました。

また、別の記事のもの

https://zenn.dev/kou_pg_0131/articles/git-view-current-branch

>`git branch` に `--contains` フラグを付けることで自分が今いるブランチが出力される。
>
> ```shell:コマンド
> $ git branch --contains
> ```

ブランチが増えてくると、自分のいるブランチが一回で表示されないことも。
そんな時に使えますね。

## git checkout

現在はこの`checkout`コマンドより`git switch`が推奨されていると聞き、`switch`を常用してます。

~~余談ですが、「チェックアウトする」とは「(ブランチを) 切り替える」ということですね。~~
↓ コメントいただきました！ありがとうございます。

> どちらかというと「チェックアウトする」とは「レポジトリから作業コピーを取り出す」ということかと。  
> 「作業コピーを取り出す方法」のバリエーションとして、現在ブランチを切り替えて取り出すという動作があったり、レポジトリから取り出した内容で作業コピーを上書きする（作業コピーの変更を取り消す）という動作があったりします。


## git restore

> | コマンド | 説明 |
> |---|---|
> |`git restore {ファイルパス}`|ワークツリーにある対象ファイルの変更を取り消す|
> |`git restore .`|ワークツリーにある全ファイルの変更を取り消す|
> |`git restore --source {コミットID} {ファイルパス}`|対象ファイルの変更を対象コミットに戻す|

復習でコードのリファクタリングをしたり、何かを試す時に使えそうです。
ただ、`commit`を細かくやらないと真価を発揮できないものだとも思います。
`commit`を細かく。今の私の課題です。

## git reset

現在の`add`を最新の`commit`まで巻き戻すために使うようです。
「間違った`commit`をした / `commit`の取り消しをした」という履歴を残さずに`commit`の取り消しをするときにも使います。ローカル作業においての`commit`の取り消しはこれでよさそうですね。

> |コマンド|説明|
> |---|---|
> |`git reset HEAD {ファイルパス}`|ステージングにある対象ファイルをワークツリーに戻す（ `git add {ファイルパス}` を取り消す）|
> |`git reset HEAD`|ステージングにある全ファイルをワークツリーに戻す（ `git add -A` を取り消す）|

「細かく`commit`」のために使っていきたいですね。

`HEAD`の理解については、こちらの記事が参考になりました。

https://qiita.com/shuntaro_tamura/items/db1aef9cf9d78db50ffe#2-git-reset%E3%82%92%E4%BD%BF%E3%81%84%E3%81%93%E3%81%AA%E3%81%99

要点は「最新のコミット」が`HEAD`、「一つ前のコミット」が`HEAD~` (= `HEAD~1`) ですね。

また、`git reset`のオプションについてはこちらの記事ですね。

https://qiita.com/maejimayuto/items/30bfab250186a00ae884#%E7%9B%B4%E5%89%8D%E3%82%92%E6%89%93%E3%81%A1%E6%B6%88%E3%81%99-commit-%E3%82%92%E3%81%99%E3%82%8B

### git reset の詳しい話
`git reset [オプション] [どのコミットを参照するか]` という構文ですね。
デフォルトでは`--mixed`オプションで、`HEAD`コミットを参照します。

下記は取り消したい作業別のコマンドです。

|  | 最後より一つ前のコミット(`HEAD~` / `HEAD~1`) | 最後のコミット(`HEAD`) | 現在の作業（未コミット） |
| ---- | ---- | ---- | ---- |
| commit | `git reset --soft HEAD~2` | `git reset --soft HEAD~` | ✕ |
| add | 略 | `git reset HEAD~`<br>(=`git reset --mixed HEAD~`) | `git reset`<br>(=`git reset --mixed HEAD`) |
| ファイルの変更 | 略 | 略 | `git reset --hard`<br>(=`git reset --hard HEAD`) |

※`HEAD~`と`HEAD^`、`HEAD~1`は同義です。

## git push

> |コマンド|説明|
> |---|---|
> |`git push origin {ローカルブランチ名}`|対象ローカルブランチを `origin` にプッシュする|
> |`git push -d origin {リモートブランチ名}`|対象リモートブランチを `origin` から削除する|
> |`git push origin {タグ名}`|対象タグを `origin` にプッシュする|
> |`git push -d origin {タグ名}`|対象タグを `origin` から削除する|

「タグ」なるものがあるんですね。バージョン`v1.0.1`など、特定の時点をポイントするらしいです。
コミット履歴には残らないようです。

参考

https://www.atlassian.com/ja/git/tutorials/inspecting-a-repository/git-tag#:~:text=%E3%82%BF%E3%82%B0%E3%81%A8%E3%81%AF%20Git%20%E5%B1%A5%E6%AD%B4,%E3%81%95%E3%82%8C%E3%82%8B%E3%81%93%E3%81%A8%E3%81%AF%E3%81%82%E3%82%8A%E3%81%BE%E3%81%9B%E3%82%93%E3%80%82

## git stash

「スタッシュ」というのを初めて聞きました。

> コミットはせずに変更を退避したいとき

> 「とあるブランチで作業中だけど、いますぐやりたいことができた。作業がすごく中途半端だからコミットはしたくない。」  
> というときに、`stash`が使えます。

https://qiita.com/chihiro/items/f373873d5c2dfbd03250

なにそれ、すごい便利そう。

> |コマンド|説明|
> |---|---|
> |`git stash list`|スタッシュの一覧を出力する|
> |`git stash show`|スタッシュの変更を出力する|
> |`git stash push -m "{メッセージ}"`|メッセージを付け、変更をスタッシュにプッシュする|
> |`git stash pop`|スタッシュの変更をワークツリーに戻す（スタッシュから **消える** ）|
> |`git stash apply`|スタッシュの変更をワークツリーに戻す（スタッシュから **消えない** ）|
> |`git stash drop`|スタッシュから変更を削除する|
> 
> 2020/03/12現在、 `git stash save` は非推奨です。  
> 代わりに `git stash push` を使いましょう。

使いこなすまでは慣れが必要そうだけど、慣れたら強力そうですね。



# すぐ使えないけど絶対使うもの
## git clone

> | コマンド | 説明 |
> |---|---|
> |`git clone --depth {深さ} {リポジトリのURL}`|対象リポジトリのデフォルトブランチを指定したコミット数で切り詰めてクローンする|

`depth`という概念があるんですね。履歴の深さという意味ですね。
確かに、不要なコミットを除くことでリポジトリが軽くなるのは実用的です。
「触らないものは触れないようにする」のもエラーを防ぐために大切ですし。

注意点は、以下のものがあるでしょうか。
- `marge` の時に基底となる共通のコミットがないと問題が起きそう
  そもそも`--depth`を浅くしすぎない or `git fetch --deepen <additional-depth>`を使用することで対応できそう。
  
- デフォルトブランチのみの`clone`であること

> | コマンド | 説明 |
> |---|---|
> |`git clone -b {ブランチ名} {リポジトリのURL}`|対象リポジトリの対象ブランチをクローンする|

特定のブランチのみの`clone`も、同様の理由で好ましいです。
## git revert

`git reset`と同じく、間違ったコミットを取り消すのに使います。
違いは、「間違ったコミットを取り消した」ことが履歴に残ることです。
間違ったコミットをした際に、「そのコミットをベースに別人が作業している可能性がある場合」に有効です。

> |コマンド|説明|
> |---|---|
> |`git revert HEAD`|直前のコミットを元に戻すコミットを作成する|
> |`git revert {コミットID}`|対象コミットを元に戻すコミットを作成する|

## git blame

ざっくりですが、最後に編集したリビジョン（簡単に言えばコミット）と作者を表示するようです。
チーム開発で使いそう。

↓ コメントいただきました！ありがとうございます。
> ソースの行単位で、そこを変更したコミット を出してくれるものです。
> なので、「この行 変えたの、どのコミットだったかしら…」というケース向け。

詳しくはコメントまで！
`git rebase`, `git commit --amend`と併せて使用する、実際のケースがわかりやすく説明されてます。

追記：記事書きました！

https://qiita.com/kohki_takatama/items/7869a27b22be7c4123dd

## git show

対象コミットのメッセージ・作者・差分などがわかるらしい。
`git show HEAD`から仕事を始める、とかありそう。

# まだ重要度のわからないもの

どれも大切らしい、使うらしいというのは頭でわかっているのですが、まだ使ったことがありません。

これらを使うときを待ってます。

- `git version`
- `git rebase` （※コメントをもとに使用例を記事にしました！[`git blame`と`git rebase`の使用例](https://qiita.com/kohki_takatama/items/7869a27b22be7c4123dd)）


## git cherry-pick

初めて聞いた概念もありました。

> チェリー ピックとは、あるブランチのコミットを別のブランチに適用する操作のことです。
> チェリー ピックを実行するとコミットが複製されるため、チェリー ピックが使えるようなシナリオでも、従来のマージを使った方が良い場合が多くあります。

https://www.atlassian.com/ja/git/tutorials/cherry-pick#:~:text=git%20cherry%2Dpick%20%E3%81%AF%E4%BB%BB%E6%84%8F,%E6%88%BB%E3%81%99%E9%9A%9B%E3%81%AB%E4%BE%BF%E5%88%A9%E3%81%A7%E3%81%99%E3%80%82

なるほど。シチュエーションが思いつかない。

# おわりに
コメントで貴重な意見いただきました！ありがとうございます。

そちらもぜひご覧ください！

# 参考
https://qiita.com/uhooi/items/c26c7c1beb5b36e7418e

https://zenn.dev/kou_pg_0131/articles/git-view-current-branch

https://qiita.com/shuntaro_tamura/items/db1aef9cf9d78db50ffe#2-git-reset%E3%82%92%E4%BD%BF%E3%81%84%E3%81%93%E3%81%AA%E3%81%99

https://qiita.com/maejimayuto/items/30bfab250186a00ae884#%E7%9B%B4%E5%89%8D%E3%82%92%E6%89%93%E3%81%A1%E6%B6%88%E3%81%99-commit-%E3%82%92%E3%81%99%E3%82%8B

https://www.atlassian.com/ja/git/tutorials/inspecting-a-repository/git-tag#:~:text=%E3%82%BF%E3%82%B0%E3%81%A8%E3%81%AF%20Git%20%E5%B1%A5%E6%AD%B4,%E3%81%95%E3%82%8C%E3%82%8B%E3%81%93%E3%81%A8%E3%81%AF%E3%81%82%E3%82%8A%E3%81%BE%E3%81%9B%E3%82%93%E3%80%82

https://qiita.com/chihiro/items/f373873d5c2dfbd03250

https://www.atlassian.com/ja/git/tutorials/cherry-pick#:~:text=git%20cherry%2Dpick%20%E3%81%AF%E4%BB%BB%E6%84%8F,%E6%88%BB%E3%81%99%E9%9A%9B%E3%81%AB%E4%BE%BF%E5%88%A9%E3%81%A7%E3%81%99%E3%80%82