GitHub開発フロー
Gitとは
Gitはソースコードの変更履歴を記録・追跡できるバージョン管理ソフトウェアである。GitHub(Gitの仕組みを利用し、オンライン上でのバージョン管理できるようにしたWebサービス)とは明確に区別しておいた方が良いが、セットで利用する場合が多い。
Gitをうまく利用することで、ソースコードの変更理由(5W)を把握でき、必要に応じてコードへの理解を深めたり、任意の時点の状態を復元したりすることに役立つ。
When、Where、Who、Whatはシステム側に任せられるため、他人のアカウントを使ってコミットするなどをしなければその恩恵に預かれるが、Whyの部分は「なぜ(どんな目的で)コードを変更したのか」をきちんとコミットメッセージとして残しておく努力(あるいは仕組み)が必要となる。役に立たない変更日付のみのコミットメッセージなどを付けていると、test_0114.txt, test_0117.txt, …, test_0206.txtといったファイルの中から所望のファイルを探すのと大差なくなってしまう(もちろんdiffの恩恵は受けられるが)。
Gitアンチパターン
役に立たないコミットメッセージ
日付や著名などの不要な情報、エラー修正などの漠然とした情報しか記載されていないコミットメッセージは役に立たないコミットメッセージである。役に立たないコミットメッセージばかりだとどんな経緯で変更されてきたのかわからず、どの状態に戻せばよいのかもわからなくなる。
2022/11/02修正
部長の指示通りに修正
コミットの粒度が大きすぎる
コミットの粒度が大きすぎる場合、コードレビューが大変になるだけでなく、保存ポイントが少ないので修正が難しく、大きな手戻りが発生する可能性がある。コミットはノイズを含まない程度に小さくしておくと良い。適切なコミットメッセージが思いつかない場合は、たいていは粒度が大きすぎる。
masterブランチで直接作業する
masterブランチは常にデプロイ可能な状態にしておかなければならない。そのため、masterブランチで直接作業せず、必ずブランチを切って作業すると良い。
ブランチ名が適切でない
ブランチ命名規約はプロジェクトによって変わってくるが、何をするブランチなのか過不足なく表現するブランチ名にすると良い。
ブランチを切りすぎる
ブランチを切るとマージするときにレビューやコンフリクトの解消などで必ずコストが発生する。必要なところに時間をかけ、そうでないところにはあまり時間をかけないようにブランチ戦略を考えると良い。
不要なファイルが増えていく
Gitを使っているのに、test_old.txtなどの不要なファイルが増えていくことがある。バージョン管理はGitに任せて、元のファイルに変更を加えていくか、別のモジュールをして切り出して全く異なる名前をつけるかして、不要なファイルは作らないようにすると良い。
ファイル名を変更する
ファイル名を変更すると、Gitに新しく作成したファイルと認識され、それまでのファイルとは別物として管理される。そのため、ファイル名が異なっていて過去の対応するファイルを見つけられないなど、追跡が難しくなる可能性がある。
他人のアカウントでコミットする
共有PCを使っている場合など、他人のアカウントでコミットしてしまうことがある。これだと、誰が変更したのかわからなくなってしまう。
コードにコメントで変更履歴を残す
変更履歴はGitが管理してくれているため、コードへの記載は不要。コードに記載してしまうとそれはノイズとなり、コードの理解を妨げる。
# 変更履歴
# ------------------------------------
# 2019/10/09:get_description()メソッドの追加
# 2019/10/15:output_log()メソッドの追加
# 2019/10/23:Managementクラスの削除
# 2019/11/02:get_description()メソッドのエラーの修正
# ボブによる追加
メンバーの修正を無視してコンフリクトを解消
メンバーの修正を取り込まず、自分の変更のみを加えたコードで上書きしてしまう。これによって誰かの修正が無視される。自分が修正を加えた部分以外にdiffが発生している場合は、予期しない変更がないか確認すると良い。
.gitignoreに記載すべきファイルを記載していない
.envファイルのような共有してはいけないファイル、個人の開発環境固有の設定ファイルやログのような共有する必要のないファイルは、.gitignoreに記載してコミットに含めないようにすると良い。
Forkを利用しない開発
社内開発のようなクローズドな開発では、Fork機能は利用せず、対象のリポジトリを直接編集することで開発を行う。
開発の流れ
Forkを利用した開発
不特定多数の人が開発者になるOSSのようなパブリックな開発では、リポジトリへのアクセス権を開発者全員に付与できないため、Forkを利用して開発を行う。
開発の流れ
GitHub Flow
GitHub Flowは、Github社が提唱するブランチ戦略で、後述のGit Flowをよりシンプルにしたもの。GitHub社では、15~20人のチームでGitHub Flowを実践していて、経験上20人程度までは大きな問題は発生しないといわれている。masterとfeatureの2種類のブランチからなるシンプルな構成になっている。
開発の流れ
Git Flow
Git Flowは、Vincent Driessen氏が提唱しているブランチ戦略である。master、develop、feature、release、hotfixesの5種類のブランチを使用し、ブランチごとに用途が決まっている。使用するブランチの数が多く、小中規模の開発には複雑すぎる場合がある。
開発の流れ
あらゆる開発フローに共通するルール
masterブランチは常にデプロイできる状態にする
masterブランチを常にデプロイできる状態にすることで、大きなバグが入り込んだり、どのブランチが最新の状態かわからなくなったりといったことがなくなり、開発フローがシンプルになる。
トピックブランチを使う
チームで開発を行う際には、他の開発者とコンフリクトしないように、masterブランチからトピックブランチを作成する。トピックブランチでは一つのテーマに集中して作業を実施し、作業が完了したらmasterブランチにマージする。
デプロイ作業は自動化する
上記の開発フローでは、頻繁にデプロイを実施する。不要な手間や人的ミスが発生しないようにデプロイを自動化しておく必要がある。
テストを重要視する
デプロイする前には必ずテストを実施するため、デプロイと同様にテストも自動化が必要になる。同時に開発者各自によるテストも必要である。すべてのテストをパスして、テストのあるコードのみをmasterブランチにマージする。
必ず他の開発者からレビューを受ける
他の開発者のレビューを通すことで、思い込みやミスを未然に防ぎ、コードの品質を向上できる。
レビューを実施しやすいように工夫する
変更したコードの量が多かったり、変更の粒度が揃っていなかったりするとレビューの負担が大きくなる。しっかりとしたレビューを行うためには、プルリクエストのサイズを小さくしたり、タイポの修正のような不要なコミット履歴は削除するなど工夫する必要がある。
GitHub Flowを体験する
# src/sample.py
class GreetRes():
def __init__(self, request):
self.request = request
def get(self):
if self.request == "おはよう":
return "おはようございます。"
elif self.request == "こんにちは":
return "こんにちは。"
elif self.request == "こんばんは":
return "こんばんは。"
elif self.request == "おやすみ": # ←この行を追加
return "おやすみなさい。" # ←この行を追加
else:
raise Exception("予期しない入力値です。")
# src/sample.py
class GreetRes():
def __init__(self, request):
self.request = request
def get(self):
if self.request == "おはよう":
return "おはようございます。"
elif self.request == "こんにちは":
return "こんにちは。"
elif self.request == "こんばんは":
return "こんばんは。"
elif self.request == "おやすみ":
return "おやすみなさい。" # ←この行を修正
else:
raise Exception("予期しない入力値です。")
# src/test_sample.py
def test_Chatbot5(): # ←このテストを追加
chatbot = sample.Chatbot()
res = chatbot.get_response("おやすみ")
assert res == "おやすみなさい。"