はじめまして! SenogokuLabインターン生の高です!
今回の記事では、一回の開発業務に入る際、どのような流れで進めていくかを実践的に紹介します。作業を始めようとして、「あれ、どうすればいいんだっけ?」と困った時はこのページに立ち返ってください。
今までの記事と違い、Sourcetreeなどのツールを用いずコマンドラインをベースに進めていますが、最初の理解さえ乗り越えてしまえばむしろこちらの方がわかりやすいです。円滑な業務のため、頑張りましょう!
この記事を書いたモチベーション
11/18現在、SengokuLabではリポジトリ管理サービスGitLabを主に使用しています。しかし、操作方法や作業についてのアナウンスが十分ではなかったりして、業務環境が整理されているとは言い難い状況です。
実際、10,11月に作業に入った方々は色々トラブルがあったかと思います。前任者が直したコードの差分がわからなかったり、そもそも環境が違っているからうまく動作しない箇所があったり……
もちろん個々人のスキルアップ・創意工夫も必要ですが、作業の全体的なフローがあやふやだったことにも問題があるということで、今回の記事を執筆する運びとなりました。
開発業務に携わる上での一般的なワークフローなどについては別記事で解説するとして、この記事では、実際に開発を行う際にどういう手順を踏めば、チームで作業の共有ができるのかというところを話していきます。
(そもそもGitって何?という人はこちらの記事の前半部分などを参照してください。また、ブランチ・リモートレポジトリなどの用語がわからない人は、教則本の第3章を確認してください。コマンドについては記事中で説明していきます)
業務の流れって?
- レポジトリのデータを取得
- ブランチを切る
- 開発する
- 変更を反映させる(コミット)
- ブランチの統合を申請する(マージリクエスト)
だいたいこんな感じです。難しい? まあまあ、実際にやってみるとそうでもないかもしれません。
今回は、僕が研究を行なっているHouseSalesEstimationでの作業を実際に追いながら各工程を確認していきましょう!
Step1: リモートレポジトリのデータを取得する
まずはローカルの状態とリモートの状態を一致させましょう。みんながすでに直して次に進んでいるようなコードをせっせと見直していてもあまり意味はありません。
はじめて入る作業の場合は、まずリモートレポジトリからデータをローカルにコピーする必要があります。
まずSageMakerを立ち上げたら、ターミナルを開きます。
コンソール上で自分のディレクトリ(ない場合はmkdir [自分の名前]
で作成)に移動したあと、次のコマンドを叩きます。
git clone git@[レポジトリ名]
レポジトリ名の部分は、プロジェクトページからコピーします。SSHと表示が出ている欄の右のボタンをクリックするとコピーできますね。
今回の作業の場合だと、git@gitlab.com:{gitパス}
となります。
すると、今いるディレクトリの直下に、先ほどクローンしたフォルダが存在するのがわかります。ls
で確認できます。
作成したフォルダに移動します。ここから開発がスタートするわけですね。試しにgit status
で確認してみると、
On branch master
Your branch is up-to-date with 'origin/master'.
nothing to commit, working tree clean
と表示されます。今自分がローカルのmasterブランチにいて、コミットはされていないことを教えてくれます。
git status
は便利なので、自分が何をしているのか、どういう状況なのか知りたいときは、まずこれを使いましょう。
ついでに、現在リモートレポジトリに何を設定しているのか確認する方法も載せておきます。git remote -v
と打つと、
origin git@gitlab.com:{gitパス} (fetch)
origin git@gitlab.com:{gitパス} (push)
と表示され、リモートレポジトリ(origin)が先ほどクローンしてきたものと同一であることがわかります。
リモートレポジトリを追加したい場合はadd remote [変数名] [レポジトリの名前]
と打てばいいようですが、おそらく業務で使うことはないと思います。
以前同じプロジェクトで作業したことがあり、誰かの作業を引き継ぎたいというような場合には、まずgit fetch
でリモートレポジトリの更新分を確認します。
その後、問題ないようであれば,git merge origin/master
を打ってローカルレポジトリを更新しましょう。別途名称をしている場合は、origin部分を変更してください。
初めてプロジェクトに参加するにしろ、中途の更新を反映するにしろ、これで他の人と足並みを揃えることは完了です。
Step2: ブランチを切る
「よし、それじゃあ開発だ!」というわけにはいきません。
おそらく今見ているリモートレポジトリにはmaster,develop
などのブランチがあるはずです。具体的な説明は別記事に譲りますが、これらのブランチを直接編集してしまうと不都合が生じてしまいます。
そこで、今あるブランチをいじりたくはないが開発業務をしたい、という場合には新たなブランチを作る必要があります。この作業を「ブランチを切る」と言います。
今回の場合だと、現在のブランチがmasterとdevelopの二つ(gitlabのUIで確認可能)であり、developにはきちんと動作するコードのみを載せたいので、もう一つのブランチが欲しいところです。まず、
git branch
と叩いてローカル上のブランチを確認します。
*master
と返ってきています。アスタリスクは現在いるブランチをさしています。ブランチを移動するためにはgit checkout [ブランチ名]
と打ってください。今回はmasterではなくdevelopの内容を変更したいので、developに移動します。
git checkout develop
Switched to a new branch 'develop'
と返ってくれば成功です。念のためgit branch
で確認しましょう。
* develop
master
と表示され、ブランチを移動できました。次に、このdevelopブランチをもとにした新たなブランチを作成します。
git checkout -b [ブランチ名]
と叩くと、今いるブランチのコピーしたブランチを作成し、そのブランチに移動することができます。
git checkout -b feature
Switched to a new branch 'feature'
developをもとにしたfeatureブランチの作成に成功しました!
Step3 開発する
ようやく開発作業の時間です。jupyter notebookなどを開き、前もって指示を受けている部分をガリガリやっていきましょう。
今回の作業では、今後多用するだろうstatsmodelsモジュールを用いた状態空間モデルの計算作業をクラス化したファイルを作成しました。こんな感じです。
(注)sagemaker上ではなくローカル環境上のVSCでコーディングしています。
ごくごく簡単なものですが、とりあえず形にはなったのでこの日の作業を終了することにしましょう。動作確認も完了しており、バグはないです。
Step4 コミット・プッシュする
さて、これで終了というわけではありません。今行なっていた作業はローカルレポジトリの中なので、この変更をリモートレポジトリに反映する必要があります。
その前にまず、ローカルでの変更を登録します。これをコミットするといいます。
ファイルの内容を変更したり処理を行うと、色々な副産物(.DS_Storeとか見たことありませんか?)が発生したり、実際に使いたい変更点が1ファイルだけだったりするので、作業した結果の中でも選ばれしものだけをローカル上でピックアップするというわけです。
作業を終えた(レポジトリ内のファイルに変更を加えた)後にgit status
を叩くと、今回の場合、次のようなメッセージが返ってきます。
On branch feature
Untracked files:
(use "git add <file> ..." to include in what will be committed)
scripts/statespace.py
.DS_Store
scripts/pycache/
Untracked fileというのは、変更されているけれどgitがローカルレポジトリの差分としては追加していないものを指しています。scripts/statespace.py
だけが今回のターゲットなので、コミット枠にこれを加えるためにgit add [commitしたいファイル名](=scripts/statespace.py)
と叩きます。
次にgit status
で様子を見ると、Changes to be commited:
の欄に目的のファイルが追加されているのがわかります
さて、コミット対象の選定も済んだので、いよいよローカルレポジトリにコミットしましょう!git commit
で、addしたファイルを全てコミットすることができます。
このとき、viというテキストエディタが開き、コミットメッセージを入力することができます。このコミットで何が変更されたのかを記録・共有するためのもので、メッセージのフォーマットなどはチームで話し合い、統一しておきましょう。今回の場合、「状態空間モデルの計算用クラスNGaussの作成」としておきます。
vimを利用する際の手順ですが、iを押してInsertmodeに入り、その後通常のエディタと同様にテキストを入力します。その後、escを押してInsertmodeを抜け、:wq
と打って入力完了です。詳しく知りたい方はこちらなどを参照してください。
vimの利用に不安を感じる方は、git commit -m [コミットメッセージ]
としてもOKです!
git log
でこれまでのコミット履歴を確認できるので、こちらも必要に応じて使ってください! vimを開くので:q
とすれば編集せずに閉じることができます。
さて、無事にローカルに変更履歴を記録したので、次はこの変更をリモートに共有します。これができてようやくチームの他のメンバーに自分の作業結果を共有できます。これを「プッシュする」と言います。
git push [リモート名] [ブランチ名]
と叩くことで、プッシュすることができます。今回の場合、リモート名はデフォルトのorigin、ブランチ名はfeatureなので、git push origin feature
とします。
これで自分の作業をリモートに反映することができました!
Step5 マージリクエストを送る
さて、これで一通り終わったように思えますが、実はまだ一番重要な部分が残っています。Step2でブランチを切ったのは覚えていますか?
例えば今回の場合、featureブランチにプッシュしたところで満足していると、開発の本筋であるdevelopには何も発展がないまま終わってしまうことになります。
正式なブランチであるdevelopに、いわば実験場であったfeatureブランチを統合して、ようやく作業終了です。遠回りに思うかもしれませんが、developブランチであれこれと実験するわけには行きませんよね? ここまで作業をしてきた方ならわかりますが、コミット・プッシュは個人で簡単/勝手にできてしまい、致命的なバグを見過ごしてしまうかもしれないのです。
マージリクエストはあくまでリクエストです。その際にチームの他のメンバーがリクエストの内容をチェックし、疑問に思った部分をたたき台にしてディスカッションが始まることでコードが精錬され、良い開発につながります。
手順自体は簡単で、GitLabのUIから[Merge Requests]→[New Merge Request]とすればマージリクエストの作成画面に入ります。
説明に関してはコミット同様、レビュワーが一目見て変更点を把握できるような説明にすることが望ましいです。
(必要があれば)Approverなどを設定して、マージリクエストを送信しましょう。これでひと段落つきました!
レビュワーからのコメントに答えてディスカッションを経て、問題なければリクエストが通ってマージが完了します。
マージリクエストに関しては、どの単位でブランチを切るかなど、ブランチ戦略との関係が非常に強くこの記事では簡単な概要説明に留めました。今後開発業務に携わっていく上で、チームとしてもっともうまくいく方法を適宜ピックアップしていく必要があるかと思います。
別途ブランチ戦略についての記事を参考にするなどして、チームでのコンセンサスをとっていってください。
今回の記事ではgitコマンドを用いた開発フローの全体について、Step1~5を通して紹介しました。わからないところがあれば、この記事を参照いただけると幸いです。頑張って開発していきましょう!