Git を普段から使い倒し 1ヶ月で余裕で使える状態にする

# Git とは

分散型バージョン管理システムです

----

# まあそんなことは

どうでもいいので、とりあえず使うところから始めましょう

----

# 前提

- git をコマンドラインで使える状況であること
    - Windows であれば [Git for Windows](https://gitforwindows.org/) をインストール
    - Mac であれば `brew install git` (homebrew をインストールしている前提)

GUI で git を使うものは裏側で何の処理をやっているのか分からない不安な物が多い (分かろうとしていないなだけかもｗ)

----

# 適当に git のローカル議事録置き場を作る

例：議事録置き場

```
└── Documents
     └──  Minutes
```

----

# Document/Minutes に移動し git 初期化

```
$ cd Documents/Minutes
$ git init
```

これで準備完了
よく使う確認コマンドとして、 `git status` `git log` `git diff` `git show` `git grep` があります。

----

# アジェンダを残します

```
$ vim 20200115-SRE-cost-down-MTG.md

## アジェンダ

1. ほげ: 卜部 (10分)
2. ふが: 真一 (5分)
3. うぎゃー: 発表者未定 (10分)
```

----

# 作りかけなのですが、コミットします。

ファイルをステージに追加し、"アジェンダ作りかけ" という説明でコミットします。

```
$ git add 20200115-SRE-cost-down-MTG.md
$ git commit -m "アジェンダ作りかけ"
```

---

# おや、修正が必要となりました

`3.` は決定ではないですが、 `1.` は決定で以下のように修正してほしいとのこと

```
$ vim 20200115-SRE-cost-down-MTG.md

## アジェンダ

1. ほげほげほげ: 卜部 (10分)
2. ふが: 真一 (5分)
3. うぎゃー: たろう (10分)
```

----

# 以下のようにコミットしましょう

```
$ git add -p
 # (1/1) Stage this hunk [y,n,q,a,d,s,e,?]?  のように 聞かれます。
 # 決定した 1 だけコミットしたいので s で応答し、分割する範囲をさらに絞ります。
 # 1 の差分の選択肢がでましたら y (yes)、 3 の差分の選択肢がでたら n (no) を選びます

$ git commit -m "○○先輩からの 1 の修正事項を反映"
```

---

# おやおや、さらに修正が必要となりました

`3.` はまだ決定ではないですが、 `2.` は決定で以下のように修正してほしいとのこと

```
## アジェンダ

1. ほげほげほげ: 卜部 (10分)
2. ふが: はなこ (10分)
3. うぎゃー: たろう (10分)
```

---

# ３の修正が邪魔なので、以下のように対応します

※ `git add -p` のコマンドの癖をつけておくと、普段から関係のないコミットがまざらなくなるので便利

```
$ git stash save "決定していない修正" # コミットされていない 3 の修正を退避
$ vim 20200115-SRE-cost-down-MTG.md # エディタで 2 を修正
$ git add -p # 2 の修正を選択
$ git commit -m  "★★先輩からの 2 の修正事項を反映"
```

---

# 3 の内容が先程退避した内容で決定したとのこと

```
$ git stash list # 先程退避した修正を確認
$ git stash show stash@{0} -p # 表示された退避分の差分を確認
$ git stash pop stash@{0} # 退避した差分を戻す
$ git add -p # 差分をステージに反映
$ git commit -m "○○先輩からの 3 の修正事項を反映"
```

----
# 別の MTG のアジェンダを考える必要がでてきました

コミットを混ぜたくないので、別のブランチを作って作業を行います。

```
$ git checkout -b feature/20200201-SRE-security-MTG

# アジェンダを残します

$ vim 20200201-SRE-security-MTG.md

## アジェンダ

1. AWS の人からサービス紹介: Mr.AWS (10分)
2. OZV 側から質技応答: 真一 (15分)

$ git add 20200201-SRE-security-MTG.md
$ git commit -m"AWS の人との MTG アジェンダ"
```
----

# それぞれ MTG が終わったので、master ブランチにマージします

```
$ git checkout master
$ git merge feature/20200201-SRE-security-MTG --no-ff
```

----

# 便利機能: gitconfig

git には .gitconfig をいう自分用の設定をエイリアスなどで定義することができます

[こちらの gist](https://gist.github.com/oz-urabe/80d4e52c3b3d13602685582ffdf5632f) の 
 `~/.gitconfig` の設定を参考に alias を追加してみましょう。

上記の エイリアス追加後、以下のコマンドを打ってみましょう

```
$ git l # コミットログが グラフ表示されます (gitk と打つと gui のグラフを人によっては表示できます)
$ git di # 単純に git diff のエイリアスです
```

----

# 便利機能: 別サービスからパッチファイルを作り、適用しよう

```
$ git clone https://github.com/php/php-src.git
$ cd php-src
$ git format-patch 127d6f3f39235478d124635822343c2cd1205f4d..f6fbe13717c817cd9b4761bfad9f62fd8d3fa6b4

$ ls *.patch # バッチファイルが2つほど作成される
$ git checkout -b hogehoge 127d6f3f39235478d124635822343c2cd1205f4d
$ cd ..
$ git clone -b hogehoge php-src new-php-src # hogehoge ブランチベースで関係のないリポジトリを作る
$ cd new-php-src; rm -rf .git; git init; git add .; git commit -m"全然違うリポジトリ" #  関係のないリポジトリを初期化

$ cp -v ../php-src/000*.patch .
$ git am -3 *.patch # パッチが順番に適用される
$ git l # 履歴ができた
```

----

# 便利機能: git-grep

高速に grep できるので便利です。

```
$ git grep -i "urabe"  # 大文字小文字区別しない
$ git grep -E "[a-z]+0(1|hoge)"  # 正規表現
$ git grep -w "urabe" # 単語として検索 -> urabebebebe はヒットしない
$ git grep -B2 "urabe" # ヒットした文字プラス前2行を表示
$ git grep -A2 "urabe" # ヒットした文字プラス後2行を表示
$ git grep -C2 "urabe" # ヒットした文字プラス前後2行を表示
$ git grep -e "urabe" --and -e "shinichi" # and 検索: 同じ行に該当2つの文字列がある
$ git grep -e "urabe" --or -e "shinichi" # or 検索: 同じ行にいずれかの文字列がある
$ git grep -l "urabe" # ヒットしたファイルをだす
$ git grep -c "urabe" # ヒットした件数をだす
$ git grep "urabe" -- src/AppBundle # src/AppBundle 配下だけ検索
$ git grep "urabe" -- ':!src/AppBundle' ':!src/HogeBundle'  # src/AppBundle と src/HogeBundle は検索対象としない
$ git grep -W "urabe"  # 該当箇所が含まれる関数のスコープで検索
$ git grep --untracked "urabe" # バージョン管理外のファイルも検索
```