この記事の目的
この記事では、細かいこと・特定の製品に閉じたことは一旦抜きにして、未経験者がエンジニアとして働いていくうえで必要な最低限度のプログラミング能力を最速で身に着けることを目指しています。
特定の技術に特化した解説はしません。
使用言語はPythonです。もしも他の言語や特定の技術について調べている方は、別の記事を探しに行くことをお勧めします。
記事を書いている人
都内でエンジニアとして10年ほど働いている人です。
仕事の中で未経験者に教える機会があったので、せっかくだから再利用できるように記事にしています。
学習ロードマップ
学習は以下のような流れで進めていく想定です。第4回である今回は『4.複数人でプログラミングできるようになる』について解説していきます。
第3回はこちら。
複数人でプログラミングしたいよね
業務でプログラミングすることを目指す以上、十中八九チームで開発するので複数人開発の知識は必須といって良いでしょう。というか業務用のシステムをひとりで書き切るとかどんな苦行よ。
MS Office系の共同編集なら今時はいろいろな手段があるけれど、プログラミングの場合は所詮ただのテキストファイル...それぞれが手元で編集したファイルを共有サーバにアップロードしていたら「あれ!?徹夜してやった作業が上書きされてる!?」みたいな事故が起こるわけです。とてもつらい。
そんな時に使うのがGitです。
Gitを分かったつもりになる
Gitとは、大雑把に言えば 「プログラムの変更履歴を保存して、上書きされそうなときに教えてくれるツール」 です。
この機能は、
- 共有サーバにある元ファイル (リモートリポジトリ)
- 手元にある上のコピーファイルと作業ファイル (ローカルリポジトリとワークスペース)
の3つのファイルで成り立っています。厳密には違いますが、ベテランの皆さん怒らないで。
とりあえずGitを使えるようになるために、覚えておきたいのは以下の図です。
意味をざっくり説明すると、
- pull: 共有サーバから元ファイルを手元にコピーしてきて、作業できる状態にする
- add: 共有サーバに載せたい変更内容を"箱詰め"する
- commit: addで箱詰めされた変更内容を"出荷レーン"に載せる
- push: 出荷レーンに載っている変更内容を、共有サーバに"出荷"する
という感じ?とりあえずイメージです、イメージ。
上書きされそうなときに教えてくれるのは主に出荷時ですね。
もう少し実務に近い説明
業務でGitを活用していくならブランチに対する理解は欠かせません。もう少し真面目に説明をしていきます。
ブランチとは、プログラムの変更履歴を分岐させ、複数の開発作業を並行して行うための仕組みを指します。ソフトウェアの開発では、現在リリース中のバージョンの保守作業をしながら次期バージョンの機能開発を行ったり、複数の機能の開発を並行して行ったりする機会があります。そのような場面においてブランチは、複数人が同じ場所を更新したりして意図しない形で作業内容が混ざってしまうことを避けるために、非常に強力な仕組みとなります。
mainブランチ
リポジトリを新規作成した直後は、mainブランチのみが存在している状態となっています。以前はmasterブランチと呼ばれていたため、長期間保守管理されているプロダクトの場合や、チームメンバーのエンジニア歴が比較的長い場合には、masterブランチという名前が使われていることもあるかもしれません。
mainブランチは初期ブランチであるとともに、多くの場合はシステムの利用者が使うことが可能な最新バージョンのプログラムが管理されているブランチとなっています。要するに本番環境のプログラムです。
一般的なmainブランチの使われ方・ルールを記載しておきます。
- 常にテストされ実行可能な(既知のエラーが無い)状態とする
- 変更内容は直接mainブランチに反映させず、まずは別のブランチ(後述)でテストしてから、mainブランチに取り込む
実際はチーム内で決めたルールに従ってくださいね。
作業ブランチ
先ほどの「mainブランチには直接反映させない」というルールを適用するなら、実際にプログラムを編集するためのブランチを作らなくてはいけません。ブランチ名はこれもまたチーム内の取り決めに従って自由につけられるので、ここでは作業ブランチと呼ぶことにします。
作業ブランチの一般的な使われ方は、ある時点のmainブランチから分岐(コピー)して、プログラムを一通り変更し終わったら、その変更内容をmainブランチに統合するという方法です。図にするとこんな感じ。
作業ブランチの個数にはとくに制限はありません。したがって作業ブランチの作成においてなんらかの制限を設けないと、ブランチが乱立した無法地帯が出来上がってしまう可能性があります。そのため現場ではプロジェクトやシステムの規模・フェーズに応じて様々な管理体制が採られています。作業ブランチの切り方には様々な流派がありますが、大別すると3種類でしょう。
- 作業ブランチはだたひとつ。すべての更新作業を同じ作業ブランチで行う。小規模向け
- 作業者ごとに作業ブランチを別にする。Aさん用、Bさん用みたいな感じ。どちらかと言えば小規模向けかも。
- 作業内容ごとに作業ブランチを別にする。機能追加とか、バグ修正とか。中~大規模向け
こちらも実際の業務では、チーム内で決めたルールに従ってくださいね。
gitコマンドの使い方
細かい説明は分かったから、結局どうやったらそのブランチが使えるの?という疑問にそろそろ答えていきます。
世の中にはGitを使うための様々なGUIツールも存在していますが、私のおすすめはCUIのgitコマンドを使って操作していくことです。何かわからないことがあったときに、GUIツールだと自分と同じツールに特化した説明を探さないといけないですが、gitコマンドだと世の中にいくらでもサンプルが転がっているため、情報源に困ることはまずありません。よって下記はごく普通のgitコマンドです。
gitコマンドで調べるとたくさんのコマンドがヒットしますが、最低限これだけ使えればOKという内容を厳選しています。
git clone
git clone {リモートリポジトリのURL}
# 例
git clone https://github.com/xxxx/xxxx.git
このコマンドは、リモートリポジトリの内容をコピーして、ローカルリポジトリを作成します。作業を開始する前に一度だけ実行すれば良く、すでに手元にローカルリポジトリが作られている場合は実行する必要はありません。
git pull
# ローカルリポジトリの中に入った状態で
git pull
このコマンドは、リモートリポジトリの最新断面をローカルリポジトリに同期させます。要するに、他の人が作業した内容を自身の手元に持ってくるときに使うコマンドです。
図にするとこんな感じ。git pull
前は他の人が作業した内容はローカルリポジトリに反映されていません。
git pull
すると、前回情報を取り込んでからpullするまでの間の他の人の作業内容が、ローカルリポジトリのツリーに反映されます。作業ブランチ(他人)の枝が伸びる感じ。
git branch
このコマンドには2つの用途があります。現在のブランチ名の一覧を見るためと、新しいブランチを作成するための2つです。
# ローカルリポジトリの中に入った状態で
# 現在のブランチ名の一覧を見る場合
git branch -a
# 新しいブランチを作成する場合
git branch {新ブランチ名} {分岐元ブランチ名}
-
現在のブランチ名の一覧を見る
以下のような作業ツリーを想定した場合、git branch -a
を実行すると、ブランチ名の一覧は次のように表示されるでしょう。> git branch -a * 作業ブランチ(自分) main remotes/origin/作業ブランチ(自分) remotes/origin/作業ブランチ(他人A) remotes/origin/作業ブランチ(他人B) remotes/origin/main
頭に
remotes/origin/
とついているのはリモートリポジトリにあるブランチ名、そうでないものはローカルリポジトリにあるブランチ名です。ローカルリポジトリにあるブランチは、git checkout
(後述)して作業を開始することができます。
まだローカルリポジトリに存在していないブランチで作業を開始したい場合は、新しいブランチを作成してあげる必要があります。 -
新しいブランチを作成する
リモートリポジトリの最新断面のmainブランチから新しく自分の作業ブランチを作成したい場合は、以下のようなコマンドを実行します。# 記法: git branch {新ブランチ名} {分岐元ブランチ名} git branch 作業ブランチ(自分その2) origin/main
これを実行すると、作業ツリーはこうなります。(他人の作業ブランチは省略)
git checkout
# ローカルリポジトリの中に入った状態で
git checkout {ローカルリポジトリのブランチ名}
このコマンドを使うと、作業内容を記録するブランチを切り替えられます。例えば先述の作業ブランチ(自分)でプログラムの更新作業を行いたい場合、git checkout 作業ブランチ(自分その2)
と実行すれば、以降の編集内容は作業ブランチ(自分その2)に記録されていきます。
git status
# ローカルリポジトリの中に入った状態で
git status
このコマンドでは、現在の作業ブランチの状態を確認することができます。作業ブランチの状態とは、以下のようなものを指します。
- 新規作成/リネーム/更新/削除されたファイル一覧
-
git add
(後述)で作業ブランチに変更履歴として登録されるファイル一覧
出力内容はこんな感じ。
> git status
On branch 作業ブランチ(自分その2)
Your branch is up to date with 'origin/作業ブランチ(自分その2)'.
Changes to be committed: # 作業ブランチに変更履歴として登録されるファイル
(略)
new file: xxx/xxx/xxx.py # 新規作成されたファイル (=new file)
Changes not staged for commit: # 変更履歴には登録されないファイル
(略)
modified: xxx/xxx/xxx.py # 更新されたファイル (=modified)
git add
# ローカルリポジトリの中に入った状態で
git add {ファイルパス}
# 例
git add xxx/xxx/xxx.py
後述するgit commit
で、作業ブランチに変更履歴を登録したいファイルを"箱詰め" します。冒頭の簡易説明を思い出してください。
git commit
# ローカルリポジトリの中に入った状態で
git commit -m "{コミットメッセージ}"
git add
で箱詰めされたファイルの変更内容を、現在git checkout
中の作業ブランチの変更履歴に登録します。この時点では変更履歴はまだ手元のローカルリポジトリのみに登録され、共有サーバのリモートリポジトリには反映されていません。よってチームメンバーからは見ることができない状態であることに留意してください。
登録する際には、コミットメッセージと呼ばれる「変更内容を端的に説明したひとこと」を設定します。これにより後からこのコミットは何に対する変更であったかを簡単に確認できるようになり、未来の自分やチームメンバーがとても助かります。
作業ブランチ(自分その2)に変更内容をgit commit
した場合、作業ツリーは次のようになります。
git push
# ローカルリポジトリの中に入った状態で
git push
現在の作業ブランチの変更履歴を、共有サーバのリモートリポジトリにアップロードし、他の作業者から見えるようにします。
[補足] git merge
# マージされる側のブランチをcheckoutした状態で
git merge {マージするブランチ名}
ブランチの内容を統合し、ひとつのブランチにまとめます。商用ではあまり使いません。代わりにプルリクエストという機能を使って、他のメンバーから作業内容に関するレビューを受け、通過したものをマージする方式がとられます。
ブランチをマージすると、作業ツリーは次のようになります。
GitのNG行動
個人的にやってはいけない順で記載しています。上位ほど先に書いている感じ。他にもこれもやっちゃマズいよという事柄があれば、ぜひコメントしてください。
機密情報をGitに反映する
機密情報のGit公開は、IT業界で度々発生するセキュリティインシデントの代表格です。特に本番環境の機密情報については、絶対にGitに公開しないように重々注意してください。
機密情報とは、主に次のようなものを指します。
- データベースなどを操作するためのID、パスワード
- 外部サービスと連携するための鍵情報(APIキー等と呼んだりします)
- その他、企業の内部情報であり、外部に公開してはいけない情報
これらは商用システムを動作させていく上ではほぼ必須の情報でありながら、その性質上、漏洩すると意図しない不正アクセスの原因となるなど非常にセンシティブな内容となっています。通常、エンジニアはこれらの情報を.env
のようなファイルに隔離して.gitignore
でGit管理対象から除外する等で対策しています。
大きなファイルをアップロードする
必要以上の画像・動画ファイルや数百MB~単位のzipファイルなど、大きなファイルをGit管理下に置くことは通常非推奨です。これをやってしまうとpull等の操作に非常に長い時間がかかり、作業効率の大幅低下を招いてしまいます。
これらのファイルを使用する場合もまた、.gitignore
を活用してGit管理から外したうえで、別の(安全な!)ファイル共有サービスの活用を検討してください。
コミットメッセージを省略する
コミットメッセージは、未来の自分やチームメンバーが当時の作業内容を把握するために非常に重要なものです。これを省略してしまった場合、「あの時は何を変更・修正したんだっけ?」と確認したいときに、当時のプログラムの内容を逐一読まなければいけなくなります。
通常、コミットメッセージには次のような情報を含めると良いとされているので参考にしてください。
- 目的と変更内容を端的に記載する
例){エラー対象}の{エラー内容}を解決するために{変更内容}を実施 - ひとつのコミットにはひとつの意図を込め、コミットメッセージに内容を記載する。
例)機能追加のコミットとバグ修正のコミットは分ける。
例)別々の機能の追加はコミットを分ける。
次回予告
第5回では、いよいよ実践的なプログラミングにおけるオブジェクト指向について解説していきます。
(編集中)