独学で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ブランチがマージされています。つまり、プロジェクトの最新状態が反映されたブランチなのです。ここを基点とすることで最新のコード上で開発をすることができるというのがもう1つの理由になります。
開発が完了したらおなじみのコマンドで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
ブランチで新しい機能を開発している途中「緊急で別の機能対応して」と言われてしまいました。対応するために別のブランチに移行しようとすると以下のエラーが出てしまいました。
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.
この時に取れる対策は以下の3つです。
- 変更を破棄する
- 変更をコミットする
- 変更を退避させる
せっかく途中まで作った機能なのでコードの破棄はしたくありません。しかしコミットするには中途半端なところまでしか作れていない…。そんなときはgit stash
コマンドで変更を退避させましょう。
$ git stash
これにより今までの変更が一時的に退避され、他のブランチに移行することができるようになります。
$ git checkout feature/implement_other_feature
feature/implement_other_feature
ブランチでの作業が完了したら元のブランチにcheckoutし下記コマンドで退避させた内容を元に戻すことができます。
$ 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コマンドをまとめておくだけでもよかったのですが、実際に実務の中でどうやって使われるのかイメージしてもらいたかったので、ケース別に解説をしてみました。
この記事が少しでもどなたかの役に立ったのであれば幸いです。