Gitに不慣れな人はとりあえずgit statusを打ちまくっておけば大体なんとかなる説

# まずは結論

Gitに不慣れなうちは、何か操作をする前にとりあえず `git status` を打ちまくりましょう。
エラーでトラブっている時だけでなく、うまくいっている(と思っている)時も含めてです。
それがミスを未遂にとどめたり、困ったときの指針になったりします。


# 想定読者

Gitの基本は一通り学習済みだけど、以下のようにコマンド操作にはまだ自信がない人。

- トラブルが起きたらとりあえず `git reset --hard HEAD` で初期状態に戻してやり直してる
- ググって出てきたコマンドを打って雰囲気で解決してるけど、あまり理解できてない
- PRをレビューしてもらうとき、Gitの操作起因で間違った状態になっていることの指摘を多く受けたり、その解消に時間を費やしがち


# `git status` が役立つ事例紹介

ここからは、後輩の指導などでも発生した事例をもとに、どこで `git status` を使っていくか説明します。
実際に私は後輩を指導する時も「とりあえず `git status` しよう」と何度も言っています。


## ケース1: 「PRで表示されるファイルに過不足がある！」を防ぐ (元のブランチの状態が正しくない場合)

### `git status` するタイミングと場所

トピックブランチを作成する前に、そのトピックブランチの派生元になるブランチで

### `git status` で確かめたいこと

派生元ブランチとそのリモート追跡ブランチを比較して、状態が一致していること

### 出ても大丈夫なメッセージ

```
On branch main
Your branch is up to date with 'origin/main'.
```

```
On branch main
Your branch is behind 'origin/main' by 1 commit, and can be fast-forwarded.
  (use "git pull" to update your local branch)
```

これら2つの場合はOKです。
`git pull` でブランチを最新化して、再度 `git status` を確認してからトピックブランチを作成しましょう。
(前者の場合も、リモート追跡ブランチとローカルブランチ両方が古いかもしれないので、必ずやりましょう)

### 出たら危ないメッセージと対応方法

```
On branch main
Your branch and 'origin/main' have diverged,
and have 1 and 1 different commits each, respectively.
  (use "git pull" if you want to integrate the remote branch with yours)
```

```
On branch main
Your branch is ahead of 'origin/main' by 1 commit.
  (use "git push" to publish your local commits)
```

これらが出るときは、派生元のリモートブランチ(ここでは `main`)には存在しないコミットがローカルブランチに存在しています。

トピックブランチの作成前なので、そのコミットをプッシュして解決な可能性は低いでしょう。
誤って直接コミットすべきでないブランチに直接コミットした可能性が高いので、`git log` で自身の間違ったコミットがないか確認しましょう。
その後、必要に応じて修正を退避しつつ `git reset --hard origin/main` でリモート追跡ブランチの状態に合わせるのが基本的な解消方法です。

自分の間違ったコミットが見当たらないときは、誰かが `git push -f` した可能性もあります。
この場合、他の人にも被害が広がっているかもしれないので、迷わず助けを求めましょう。
(リポジトリの設定で `git push -f` できないよう制御できるので、基本的には起きないはず)

参考になる記事：
https://qiita.com/hnw/items/5ac4416c72dd567b263f

**【注意】**
- 大きな機能開発でトピックブランチを入れ子にしているなど、単一のブランチに対して複数人で作業している場合にも起きる可能性はあります。採用しているブランチ戦略にもよるのでこの内容が全てではありません
- メッセージ内で `git push` とか `git pull` とか促されていますが、それが通用するのはローカルブランチの状態が意図したものである時だけです。よくわからないまま促されるがままに上記コマンドを打つのはやめましょう


## ケース2: 「PRで表示されるファイルに過不足がある！」を防ぐ (コミット内容に過不足がある場合)

### `git status` するタイミングと場所

コミットする前に、トピックブランチで

### `git status` で確かめたいこと

コミットするファイルに過不足がないこと

### 出てほしいメッセージ

```
Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
        modified:   修正するファイル.txt
        new file:   追加するファイル.txt
```

上記のセクションに、**コミットしたいファイルと過不足がない**ことを確認しましょう。
過剰なファイルは言われた通り `git restore --staged` で除外します。

### 要注意なメッセージ

```
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
        modified:   修正するファイル.txt
```

```
Untracked files:
  (use "git add <file>..." to include in what will be committed)
        追加するファイル.txt
```

`Changes to be commited` セクションに不足があった場合はここに出ます。
足りないファイルをステージングするコマンドも教えてくれてますね、 `git add` です。
見落としの原因になるので、不要な変更をため込みすぎないよう心がけましょう。


## ケース3: コンフリクト発生時に何をすべきか確かめる

### `git status` するタイミングと場所

`git pull` などしてコンフリクトが発生した場合に、コンフリクトが発生しているブランチで

### `git status` で確かめたいこと

コンフリクトがどこで発生していて、どう修正したらいいか

### 状況例

`修正するファイル.txt` にトピックブランチで修正を入れた

```plaintext:git diffの結果(トピックブランチ)
diff --git a/修正するファイル.txt b/修正するファイル.txt
index 77300f2..e66f8b0 100644
--- a/修正するファイル.txt
+++ b/修正するファイル.txt
@@ -1 +1,2 @@
 修正するファイルです
+トピックブランチで修正した
```

一方、 `main` ブランチでも `修正するファイル.txt` に修正が入った

```plaintext:git diffの結果(mainブランチ)
diff --git a/修正するファイル.txt b/修正するファイル.txt
index 77300f2..8eed519 100644
--- a/修正するファイル.txt
+++ b/修正するファイル.txt
@@ -1 +1,2 @@
 修正するファイルです
+別のブランチからのPRで修正した
```

`main` ブランチのコミットが進んでいると気づいたので、トピックブランチで `git pull origin main` して修正を取り込もうとしたところ、コンフリクト発生

```
From https://github.com/your-username/your-repo
 * branch            main       -> FETCH_HEAD
Auto-merging 修正するファイル.txt
CONFLICT (content): Merge conflict in 修正するファイル.txt
Automatic merge failed; fix conflicts and then commit the result.
```

### 表示されるメッセージと対応方法

何はともあれ、困ったときはまず `git status` です。

```
On branch issue-1
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:   修正するファイル.txt
```

上記のメッセージを読むだけでも以下のことがわかります。

- 作業内容について
  - コンフリクトの解消ができたら `git commit` をすればよいこと
  - コンフリクト解消済とするには `git add` をすればよいこと
  - コンフリクト解消を諦めて作業(ここでは `git pull origin main`)をやめるには `git merge --abort` をすればよいこと
- コンフリクトしているファイルについて
  - `修正するファイル.txt` がコンフリクトしていること

なので、 `修正するファイル.txt` を開いて状態を確認するとコンフリクトしていると確認できます。

```plaintext:修正するファイル.txt
修正するファイルです
<<<<<<< HEAD
トピックブランチで修正した
=======
別のブランチからのPRで修正した
>>>>>>> ce43ccbda699b09928fc8fd4a3364da763ad6df0
```

コンフリクトを解消してファイルを保存したら、言われた通りに `git add` して `git commit` しましょう。


# おわりに

とりあえず `git status` を乱打してみようという気にはなりましたか？
こんなこと元から気を付けているよ！という方も多いかもしれませんが、「こんなミスやりがちだな」「ここ苦手だな」がある人は雑に `git status` するクセをつけてみてはいかがでしょうか。

Gitは概念も複雑で一見とっつきづらいですが、次のアクションを(時には具体的なコマンドレベルで)かなり教えてくれるとても親切なツールなんです。
`git status` 以外のコマンドもさまざまなことを私たちに教えてくれます。
コマンドを打ったらおしまいではなく、その出力を少しずつ読むようにして、それを理解して、を重ねれば理解も深まるでしょう。

本記事を読んだ方を少しでも「Git思ったより怖くないじゃん！」という気持ちにできていれば幸いです。