実務に入っても慌てないために覚えておくべきgitコマンド

独学でgitをよく使っていてgit完全に理解したなと思っていたのですが、実務に入ってから突然**cherry-pickしといて**と言われ**ん？チェリー？？え、え**とパニックに陥った経験があります。
今回はそんな実務に入りたての自分が事前に知っていたら助かったなというコマンドを、ケース別にまとめてみたいと思います。

未経験エンジニアが実務で一番最初に取り組むプロジェクトは、すでにある程度形になっているアプリケーションのバグ改修業務が多いのでは無いでしょうか？今回はそんなプロジェクトを任された過去の筆者を例にとって解説していきたいと思います。

> こちらで紹介するのは筆者が経験したプロジェクトでの使い方です。組織内でルールが規定されている場合はそちらに従うようにしてください。

# 対象読者
* 実務未経験の方
* gitの基本的なコマンドをある程度使いこなせるようになってきた方


# "〇〇の機能を実装して"と言われたら

**ポイントとなるコマンド**

```
git checkout -b <任意のブランチ名> <基点としたいブランチ名>
```

最初に開発環境を整えるためにプロジェクトのリポジトリをクローンしてきます。

```
$ git clone <gitURL>
```

以下のコマンドでプロジェクトにどんなブランチがあるか確認してみましょう。

```
$ git branch -a
```

基本的には以下3種類のブランチがあると思います。

* main(master)ブランチ：本番環境にデプロイするブランチ
* developブランチ：featureブランチで作成した機能の検証をするブランチ
* featureブランチ：アプリケーションの機能を開発するブランチ

今回は新しい機能を実装するよう言われているので、developブランチを基点としてfeatureブランチを新しく作成します。

```
$ git checkout -b feature/implement_〇〇_feature origin/develop
```

これで作業用のブランチを作成することができました。

```
$ git branch
feature/implement_〇〇_feature
```

developブランチを基点としたのには理由があります。

developブランチはfeatureブランチで実装した機能を検証するためのブランチです。したがって今回作成した`feature/implement_〇〇_feature`ブランチも、開発が完了すればdevelopブランチにマージされ機能が検証されます。**featureブランチが最終的にマージされる先がdevelopブランチのため**developブランチを基点としてfeatureブランチを作るのです。

またdevelopブランチは様々な開発者のfeatureブランチがマージされています。つまり、プロジェクトの最新状態が反映されたブランチなのです。ここを基点とすることで最新のコード上で開発をすることができるというのがもう１つの理由になります。

開発が完了したらおなじみのコマンドでcommit&pushし、developブランチにプルリクエストを送ればOKです。

実務では**どこを基点としてブランチを作成するか**を意識できるとgoodjobです。


# "差分だけプルリクエストしといて"と言われたら
無事新しい機能の追加をすることができました。
developブランチで検証も完了し一安心です。しかしこんなことを言われてしまいます。

上司「developブランチで動作確認できたからmainブランチにfeatureブランチの差分だけプルリクしといて」
筆者「？？？？？」

今回のポイントなるコマンドは`cherry-pick`です。

```
git cheryy-pick <コミットID>
```

`cherry-pick`は特定のコミットを抽出して適用することができるコマンドです。
どういうことか詳しく説明していきます。

まず、先ほどの`feature/implement_〇〇_feature`ブランチで追加した機能の検証が終わったため、この機能をmainブランチに反映させたいです。

しかしdevelopブランチをmainブランチにマージしようとすると、他の開発者が作成した検証途中の機能もマージされてしまいます。

またfeatureブランチを直接mainブランチにマージさせようとしても、featureブランチはdevelopブランチが基点となっているため同じように検証途中の機能がマージされてしまいます。

そこで、`feature/implement_〇〇_feature`ブランチで作った機能だけをmainブランチに反映させたいときに`git cherry-pick`コマンドが役に立ちます。

まず`feature/implement_〇〇_feature`ブランチで`git log`コマンドを打ちます。

```
$ git branch
feature/implement_〇〇_feature
$ git log
commit asd8dfgeff817ec66f445da521402690a937
Author: test name <test@test.com>
Date:   Mon May 7 20:02:11 2021 -0000

    implement 〇〇 feature
```

実装した機能のコミット情報が表示されるので、commitID:`asd8dfgeff817ec66f445da521402690a937`をコピーしておきます。

次にmainブランチを基点として新たにreleaseブランチを作成します。

```
$ git checkout -b release/implement_〇〇_feature origin/main
$ git branch
release/implement_〇〇_feature
```

そしてcherry-pickコマンドを用いてfeatureブランチのコミットをreleaseブランチに反映させます。

```
$ git cherry-pick asd8dfgeff817ec66f445da521402690a937
```

これで`feature/implement_〇〇_feature`ブランチで追加した機能のみを反映したブランチを作成することができました。

これをpushしてmainブランチにプルリクエストを送れば、追加した機能の差分のみを反映させることができます。

# "緊急で別の機能対応して"と言われたら

**ポイントとなるコマンド**

```
git stash
```

`feature/implement_〇〇_feature`ブランチで新しい機能を開発している途中「緊急で別の機能対応して」と言われてしまいました。対応するために別のブランチに移行しようとすると以下のエラーが出てしまいました。

```git
error: Your local changes to the following files would be overwritten by checkout:
test.app
Please, commit your changes or stash them before you can switch branches.
```

この時に取れる対策は以下の３つです。

* 変更を破棄する
* 変更をコミットする
* 変更を退避させる

せっかく途中まで作った機能なのでコードの破棄はしたくありません。しかしコミットするには中途半端なところまでしか作れていない…。そんなときは`git stash`コマンドで変更を退避させましょう。

```
$ git stash
```

これにより今までの変更が一時的に退避され、他のブランチに移行することができるようになります。

```
$ git checkout feature/implement_other_feature
```

`feature/implement_other_feature`ブランチでの作業が完了したら元のブランチにcheckoutし下記コマンドで退避させた内容を元に戻すことができます。

```git
$ git stash list
stash@{0}: WIP on feature/implement_〇〇_feature: xxxx
stash@{1}: WIP on release/implement_other_feature: xxxx

$ git stash apply stash@{0} <- 元に戻したい変更
```
# おわりに
gitコマンドをまとめておくだけでもよかったのですが、実際に実務の中でどうやって使われるのかイメージしてもらいたかったので、ケース別に解説をしてみました。
この記事が少しでもどなたかの役に立ったのであれば幸いです。