Gitはコマンドから慣れよう

## まずはコマンドから

Gitに慣れていない新入社員が入社した際は、基本的にはコマンドラインから操作してもらいます。
理由は[Pro Git bookにも書かれている](https://git-scm.com/book/ja/v2/%E4%BD%BF%E3%81%84%E5%A7%8B%E3%82%81%E3%82%8B-%E3%82%B3%E3%83%9E%E3%83%B3%E3%83%89%E3%83%A9%E3%82%A4%E3%83%B3)通りです。

> **コマンドライン**
> 
> 様々な方法でGitを使うことができます。 公式のコマンドラインツールがあり、用途別のグラフィカルユーザーインターフェースも数多く提供されています。 本書では、Gitのコマンドラインツールを使うことにします。 その理由は2つあります。まず、コマンドラインでのみ、Gitのコマンド群を全て実行できるからです。GUIの大半は、実装する機能を限定することで複雑になることを回避しています。 コマンドラインのほうを使えるようになれば、GUIのほうの使い方もおおむね把握できるでしょう。ただし、逆も真なり、とはいかないはずです。 2つめの理由として、どのGUIクライアントを使うかはあなたの好み次第、という点が挙げられます。一方、コマンドラインツールのほうは全員が同じものを使うことになります。

* Gitのコマンド群を全て実行できる
  * このGUIアプリの場合はどのような操作になるのか？そもそも可能？と考える必要がない
* 全員が同じものを使うことになる
  * 手順書や進め方の共有は数行のコマンドをテキストで送るだけで済む
  * トラブルシューティングの際にどのようなオペレーションをしたか、実行した履歴をテキストで送ってもらうだけで済む

コマンドに慣れGUIのアプリケーションでGit操作した際に「コマンドでいうと、こういうコマンドだな」と想像がつくようになれば、GUIを併用するのも良いと思います。

## 苦手な人の救世主

CUIに慣れていないと、意義を見出せなかったり、とっつき辛い部分もあるでしょう。
個人的には[Pro Git book](https://git-scm.com/book/ja/v2)が業務で利用する範囲はすべて網羅されており丁寧な説明でおすすめですが、沢山の文字が並んでいるのを受け付けない人もいるでしょう。

そんな人には下記の漫画がおすすめです。

https://www.r-staffing.co.jp/engineer/entry/20190621_1


## ちょっとしたTips

私は社内で仕事をするうえで、「なるべく頭を使わず出来るようにしよう」「ぼーっとしていてもミスが生じないやり方をしよう」とお話しています。
そのなかで、よく共有するTipsを紹介します。

### git commit時に `-m` オプションは基本的には使わない

`vim`が苦手だったり、作業ステップを省略するため`git commit`時に`-m`オプションを指定して、下記のようにするケースがあると思います。

```
git commit -m 'XXX機能の作成'
```

しかし、`git commit`で立ち上がるvimの画面は **“確かにこのファイルをコミットしたい”** とコミット前の最終確認に最適な表示です。

例えば、下記のような画面で `update_example_relative_file1.php` も含めて1つの機能修正なのに`git add`が漏れてことを気付くことがよくあります。
逆にコミット対象としたくないファイルが`Changes to be committed:`に含まれてると気づくこともあります。
間違いに気付いてキャンセルしたくなったら、`:q!`と保存せずvimを終了します。

```

# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
#
# On branch feature/example_branch
# Your branch and 'origin/feature/example_branch' have diverged,
# and have 1 and 1 different commits each, respectively.
#   (use "git pull" to merge the remote branch into yours)
#
# Changes to be committed:
#       modified:   README.md
#       modified:   update_example_file1.php
#
# Untracked files:
#       modified:   update_example_relative_file1.php
#
```

`git commit -m`でこの確認画面をスキップするとコミット前の最後の確認のチャンスを逃してしまいます。
git操作は後でどうにかなりますが、後になればなるほど面倒なことになります。

* コミット前のStagedの状態で意図通りにする
* `git status`や`git diff --cached`で確認して、想定外のStagedがあれば、`git restore --staged`で戻す
* コミット後に`--amend`でコミットをやり直す
* 何度かコミットを進めてからコミットログを作り直す
* `git push`してしまった後にコミットログを作り直す
* `main`にマージしてから操作を辿りやり直す

後ろになればなるほど、かかるコストが増えます。なるべく初期の状態からミスが混入しないようにしましょう。

### git pushでわざと一度怒られる

ブランチを作成後に初めてpushする際には下記のようにエラーが発生します。

```
% git push
fatal: The current branch feature/new_example_branch has no upstream branch.
To push the current branch and set the remote as upstream, use

    git push --set-upstream origin feature/new_example_branch

To have this happen automatically for branches without a tracking
upstream, see 'push.autoSetupRemote' in 'git help config'.
```

このため、常にgit pushの際に明示的にブランチを指定している人を見かけますが、
一度`--set-upstream`でpushするとそのタイミングで上流ブランチが設定され、それ以降は単純に`git push`で事足ります。
また、手作業で上流ブランチを指定すると入力間違いのリスクもあります。

例えばこのようなこともあり得ます。

```
% git checkout -b feature/new_example_branch
（なんらかの修正作業とコミット）
% git push origin feature/old_example_branch #間違って、以前つかっていたブランチにpush
```

「えーと、ブランチ名なんだっけな？上流ブランチ設定済だったっけな？」
ということに考えるコストを払うくらいなら、とにかく `git push` する。
`fatal: The current branch ...`となった場合は、表示されたコマンドをコピペしてそのまま使うというのと一番負荷が少ないです。

ブランチつくってからの最初の`git push`はわざと一度怒られるくらいの気持ちでいましょう。