Git初心者向け_よく使うコマンド&よくあるミスの修正編

# はじめに

どうも、データエンジニアとして勤務しているシロシタです。
この記事は、Gitをはじめて使う人とアサインされたプロジェクトで、初心者がよくミスっており、復旧をする度に私の手が止まっていたので、備忘録を兼ねた記事です（n番煎じですがご了承を）。
また、インストールや認証回り等は設定済み、ホスティングサービスはGitHubの前提です。
# よく使うコマンド

## リポジトリのクローン

初心者の場合や運用フェーズからアサインされる場合には、基本的に作成済みのリポジトリを更新していくことになるかと思います。
まずは、下記を使って、ローカルリポジトリを作りましょう。

```sh:クローン
git clone <リポジトリのURL>
```

URLの取得は[こちら](https://docs.github.com/ja/repositories/creating-and-managing-repositories/cloning-a-repository)を参照してください。

## ブランチ発行

チーム開発の場合には、レビュアーがいて更新の可否を判断して、mainブランチを更新します。
ブランチ名にはPrefixをつけましょう。管理がしやすくなります。

```:Prefix例
add:ファイルの追加
feature:機能の追加
fix:バグ修正
refactor:リファクタリング
remove:ファイル削除
:
:
```

下記のコマンドでブランチを切った後、作成ブランチに移動します（ブランチ作成してチェックアウトは面倒なので）。
**作成元を指定しなければ、カレントブランチからブランチを生やすことになるので注意を！**

```sh:ブランチ発行
git checkout -b <ローカルに作成するブランチ名> <origin/作成元のリモートのブランチ名>
```

作成したブランチをリモートリポジトリに反映登録。
VSCodeなどの統合開発環境をお使いでしたら、GUIで操作できます（詳細は割愛）。
```sh:リモートに発行したブランチの反映
git push -u origin <作成したブランチ名>
```

## コミットからプッシュまで

ブランチを切ったらそこでファイルの追加や編集を行います。その変更の記録をするのがコミットです。
コミットにはタイトルとメッセージの形で、「どういった意図」「どのような変更」をしたかを記録します。
コミットのタイトルはブランチ名と同様にPrefixをつけるようにしましょう。
書き方はチーム内で決めると思うのでここでは省略します。

下記コマンドがコミットからプッシュまでの一連の流れです。

```sh:ステージング
git add <変更・追加したファイル名もしくはディレクトリ名>
```

```sh:コミット(テキストエディタ使用版)
git commit
# テキストエディタを使用して編集する場合に使用します。
# Gitのセットアップ時に設定したエディタで編集して、保存して終了したらコミットができます。
```

```sh:コミット(簡易版)
git commit -m "<変更の説明>"
```

```sh:プッシュ(ブランチをリモートに発行されている場合)
git push
```

```sh:プッシュ(ブランチをリモートに発行されていない場合)
git push -u origin <作成したブランチ名>
```

## プルリクエスト

プッシュをしたら変更をmainブランチに取り込むためにプルリクエストを作成します。
対象のリポジトリにWebブラウザでアクセスして、GUIで操作していきます。
詳細は下記の公式ドキュメントを参照してください。
[pull request の作成](https://docs.github.com/ja/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/creating-a-pull-request)

基本的にはここまでできたら初心者は十分です。

# よくあるミスからの復旧

## 派生元のブランチを間違えた

これは私もよくします。ブランチを切るときに派生元を指定すればミスが減りますが、楽をしたいのが人の常ですよね…
下記のコマンドで修正できます。

### 方法1
こちらの方法は一人で作業しているブランチにとどめておきましょう。共同作業者がいる場合に影響が出てしまいます。

```sh:編集をすでに進めちゃっていた場合
git stash
# 編集していたら一度変更を退避します。
```

```sh:派生元ブランチの変更
git rebase --onto <本来親にしたかったブランチ> <間違って親にしてしまったブランチ名> <親を変更する作業ブランチ名>
```

```sh:プッシュ済みでない場合
git push
```

```sh:プッシュ済みの場合
git push -f origin <親を変更する作業ブランチ名>
```

```sh:編集内容を適用（必要に応じて）
git stash apply
```

### 方法2

こちらはコミットが混在していたり、`rebase --onto`で復旧が難しい場合に新しく作り直す方法です。

```sh:新規ブランチ生成
git checkout -b <新規ブランチ> <親ブランチ>
```

```sh:特定のコミットを適用
git cherry-pick <コミットID>
```

```sh:不要なブランチを削除
git checkout <削除対象ブランチ以外のブランチ>

# マージ済みの場合
git branch -d <削除したいブランチ>
# マージ済みでない場合
git branch -D <削除したいブランチ>
```

## ワークブランチを間違えた

たまにやってしまいますよね。Push前であれば簡単に戻せます。
ここでは、途中のコマンドまでの紹介ですが十分に対応可能です。
紹介した方法を取った後はいつも通りのコミットからPushの流れです。

### Push前かつコミット前の場合

```sh:変更内容を退避
git stash
```

```sh:正しいワークブランチに移動
git checkout <正しいワークブランチ>
```

```sh:変更内容を適用
git stash apply
```

### Pash前でコミット後の場合
紹介するのはステージング前に戻すコマンドです。

```sh:コミットを取り下げ
# 直近のミスの場合
git reset HEAD^

# 複数のコミットをしてしまった場合
git reset <戻りたい時点のcommit ID>
```

```sh:変更内容を退避
git stash
```

```sh:正しいワークブランチに移動
git checkout <正しいワークブランチ>
```

```sh:変更内容を適用
git stash apply
```

### Push後の場合
ここで紹介している、コマンドは一人で使っているブランチに限りましょう。
複数人使用するブランチの場合は管理者に相談してください。
Gitホストサービスを利用している場合は、PRベースでマージしていくので、重要なmainブランチなどへの影響はほとんどありません。

```sh:本来のワークブランチに移動
git checkout <本来のワークブランチ>
```

```sh:間違ったコミットを取り込む
git cherry-pick <取り込みたいcommit ID>
```

```sh:コミットを取り消す
git checkout <コミット取り消し対象ブランチ>
git reset --hard HEAD~<戻したいコミット数>
```

```sh:強制Push
git push --force origin <コミット取り消し対象ブランチ>
```

# 読んでおくと良いサイト

[チーム開発においてGit初心者が踏みがちな地雷まとめ](https://techracho.bpsinc.jp/morimorihoge/2020_09_09/16856)

# まとめ
簡単な初心者向けかつ私の備忘録として、よく使うコマンドをまとめました。
一緒にアサインされたメンバーが不慣れで度々復旧に時間を取られていたので、早めに作っておけばスムーズに作業ができたのかと反省しております。
初心者でも基本を押さえておけば、イレギュラーなGit操作をしなくてよくなるし、変更履歴がカオスにならなくて済みます。
他にも似たような記事を書かれている方もいるので、自身にとってわかりやすい記事を見つけましょう！


# 弊社について
株式会社ジールはMicrosoft Azure やAWS（Amazon Web Services）、Google Cloud Platform（GCP）、Oracle Cloud Infrastructure（OCI）など、多彩なクラウドプラットフォーム構築・運用の知見を有しています。そのため、複数のクラウドサービスを組み合わせるマルチクラウド環境においても、ベンダーロックインを回避し、お客様のご要望に応じた最適なクラウドプラットフォームの構築・運用への対応が可能です。
https://www.zdh.co.jp/products-services/cloud-data/