使うようになってから少しだけ仕事が早くなったgitコマンド5選

## 背景

gitについて勉強していく中で、普通に使っているコマンドとは別に、
「知らなくてもいいけど、知っていたら少し仕事が早くなった」
というgitコマンドがあったので、それをまとめます。

## git add -p

git addはよく使うと思いますが、-pをつけると「hunk」という単位ごとに、addするかどうかを選択することができます。

git add -p を使うと以下のようなメッセージが出てきます。
```
(1/1) Stage this hunk [y,n,q,a,d,e,?]?
```
?を選択すると各選択肢の説明が出てきます。

```
y - stage this hunk
n - do not stage this hunk
q - quit; do not stage this hunk or any of the remaining ones
a - stage this hunk and all later hunks in the file
d - do not stage this hunk or any of the later hunks in the file
e - manually edit the current hunk
? - print help
```

読んでそのままですが、それぞれの使い方としては、
y - このhunkをgit addする。
n - このhunkをgit addしない。
q - このhunkとそれ以降のhunkをgit addしない。
a - ファイル内のこのhunkとそれ以降のhunkを全てgit addする。
d - ファイル内のこのhunkとそれ以降のhunkを全てgit addしない。
e - hunkを手動で編集する。

というような感じです。

それぞれのhunkごとに、これらの選択肢から操作を選ぶことができるので、
コミットの単位を細かくすることができます。


## git rebase -i

過去のコミットをインタラクティブに編集することができます。

まず、
```
git rebase -i HEAD~3
```
のようにHEADからまとめて、いくつのコミットを対象にするかを数字で指定します。

すると以下のような表示が出てきます。
```
pick 4dc7721 add test
pick da2f156 move file
pick 2f975f5 fix test

# Rebase 9ee8313..2f975f5 onto 9ee8313 (3 commands)
#
# Commands:
# p, pick <commit> = use commit
# r, reword <commit> = use commit, but edit the commit message
# e, edit <commit> = use commit, but stop for amending
# s, squash <commit> = use commit, but meld into previous commit
# f, fixup <commit> = like "squash", but discard this commit's log message
# x, exec <command> = run command (the rest of the line) using shell
# b, break = stop here (continue rebase later with 'git rebase --continue')
# d, drop <commit> = remove commit
# l, label <label> = label current HEAD with a name
# t, reset <label> = reset HEAD to a label
# m, merge [-C <commit> | -c <commit>] <label> [# <oneline>]
# .       create a merge commit using the original merge commit's
# .       message (or the oneline, if no original merge commit was
# .       specified). Use -c <commit> to reword the commit message.

```

この`pick`となっている部分を編集することでそれぞれのコミットをどのように操作するかを選ぶことができます。
その選択肢が、`Commands`以下に書かれています。

これも読んでそのままですが、説明すると、
p, pick　-　コミットをそのまま使う。
r, reword -　コミット内容はそのままで、コミットメッセージを編集する。
e, edit -　コミット自体を編集する。
s, squash -　1つ前のコミットとまとめる。コミットメッセージを編集する。
f, fixup -　1つ前のコミットとまとめる。コミットメッセージはそのまま。
x, exec -　シェルのコマンドを実行する。
b, break -　ここでrebaseを中断する。
d, drop -　このコミットを省く。

これ以降の、
l, label、t, reset、m, merge
の３つはややこしいのと、あまり使うことはなさそうなので省きます。

`pick`の部分を変えると、それぞれの操作をする画面になります。
コミットそれぞれに対しての操作が終わった後に、rebaseを続行する場合は、
`git rebase --continue`を、
それまでのrebaseの操作を全て廃棄して終わる場合には、
`git rebase --abort`を実行します。

これを使うことでコミット履歴を編集することができます。

## git clean -f 
`git status`を実行したときに
```
Untracked files:
  (use "git add <file>..." to include in what will be committed)
        app/sample.go
```
のようにuntracked filesが表示されることがあります。
untracked fileとは未追跡ファイルのことで、git addされていない新たに作られたファイルのことです。

それを削除するために`git clean`を使います。
-f オプションをつけることで、untracked fileを削除することができます。
-df オプションをつけることで、ディレクトリを削除することができます。

オプションなしで`git clean`実行すると
```
fatal: clean.requireForce defaults to true and neither -i, -n, nor -f given; refusing to clean
```
と出てきて、デフォルトでは実行できないようになっています。


## git log --oneline
`git log`はコミットの履歴を表示できますが、
--onelineオプションをつけることで、各コミットログを1行で表示できます。

普通のgit logと、--onelineオプションをつけている場合とをそれぞれ比べてみると、

`git log`
```
commit 2f975f5ea451ef476f275d1e8b880b3137fe37be (HEAD -> main, origin/main, origin/HEAD)
Author: hoge <hoge.fuga@mail.com>
Date:   Mon Oct 10 20:03:42 2022 +0900

    add test

commit da2f1569c269209708cad626d1bc35781fd580a5
Author: hoge <hoge.fuga@mail.com>
Date:   Mon Oct 10 20:02:36 2022 +0900

    move file

commit 4dc7721533c02676e3fdf3f7166666eca0728d92
Author: hoge <hoge.fuga@mail.com>
Date:   Mon Oct 10 14:53:36 2022 +0900

    fix test

```

とすると詳しく表示されますが、

`git log --oneline`
```
2f975f5 (HEAD -> main, origin/main, origin/HEAD) add test
da2f156 move file
4dc7721 fix test
```

このようにスッキリと表示されます。


## git stash -u
`git stash`を実行することで、コミットしていない変更した部分を退避することができます。
-u オプションをつけることで、新たに作成したファイルも退避することができます。

直近に退避した変更を戻すときには、`git stash pop stash@{0}`か
`git stash apply stash@{0}`を使います。

stashの履歴から削除する場合には、`git stash pop stash@{0}`、
stashの履歴から削除しない場合には、`git stash apply stash@{0}`を使います。


## 参考にさせていただいた記事

https://qiita.com/tmyn470/items/c8359e4ec92d1f462bdf

https://qiita.com/forest1/items/82ac22596fbe65187a8b

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

https://qiita.com/KTakata/items/d33185fc0457c08654a5

https://www-creators.com/archives/4939#-p_w_hyphenpatch