Git雑感


あけましておめでとうございます。

今年も宜しくお願い致します。m(__)m

 

という事で、2017年は「すぐやる」をテーマに余生を無駄なく過ごそうと考えております。

本年最初のエントリは仕事な話題ですが、「あぁ、米蔵はこんな仕事してんのか。」的に斜め読みして頂けると嬉しいです。

 

システム開発におけるバージョン管理システムの一つとして「Git」がありますが、この歳にしてようやく重すぎる腰を上げてちゃんと使い始めたので、「使い始めたばかりの初心者が思うこと」について書き残す。

相変わらず批判的文章の羅列になりそうだが、決して「もうやだ!」という感じではなく、それなりの恩恵は感じております。

まず、思いつく恩恵として、当然ですが作業履歴の確認が容易という点が挙げられる。

数百のソースファイルを日々改変・追加を行っていると、自分でも若年性なんちゃらを疑うほどに光速の速さで過去に行った作業内容を失念していきます。

ひどい時には先週行った作業の内容を思い出せないとか、「これ、いつ書いたんだっけ?」というような事がザラに起きる。

ましてや複数のエンジニアが混在するプロジェクトなどでは、ソース修正の全履歴を記憶するなど不可能に近い。

今までは記憶を頼りにソースを追いかけたり、指示メールなどを探して記憶をほじくり出していたんだが、Gitを使うことによって「いつ、どのブランチで誰が行った作業か」というのを検索できるようになったのは大きい。

特定のソースファイルについて、「この処理はなに!?」みたいな時も、Git上で行った作業ならば以下のコマンドでパッと履歴を確認できる。

git log -p ファイル名

自分の作業を忘れるような貧弱な記憶力を持つ私のような似非エンジニアにとって、これは素晴らしい機能である。

もう一つの素晴らしいと感じた機能は、コマンド一発で実環境への反映が一瞬で行えるという点がある。
※1 裏返すと「全修正や機能の追加内容が一瞬で反映されてしまう」とも言えるのだが、もちろん元に戻すのもコマンド一発で行えるので安心ではある
※2 ignoreでGit管理対象外とした設定ファイルなども更新する必要がある場合には、これまで以上に注意する必要がある。コマンド一発で反映OKという事に慣れてしまうと手動更新が必要な案件の場合にそれを失念する可能性が高まるという意味で。

ローカル環境で容易に開発・検証を行える事もGitの恩恵の一つだと言えるが(まぁこれはVMWareなどのゲストOS活用による恩恵がほとんどだが)、完成した機能を実環境・サーバへ反映するにも、mergeやpushなどのコマンドで一発反映できるのは、いままでチマチマと一つ一つのファイルについて確認しつつアップロードしていた身としては、隔世の感というのは言い過ぎとしても、作業時間の大幅な短縮やミスの撲滅という意味で、かなりの恩恵があると言える。

また、ブランチという機構によって作業内容を分割して管理でき、必要に応じて都度切り替えながら作業を行えるというのも、作業テーマを把握しやすく仕掛中の内容についてどのような作業を行ったのか確認しやすいというのも大きなメリットの一つである。

複数のエンジニアがよってたかって開発を行うようなプロジェクトにおいても、他人の作業内容をすぐに自環境へ取り込めるという点も素晴らしい。

あんまり使いたくないので、不勉強のままではあるが、基本的に修正や削除などはご法度とされる履歴の改変なども自由に行なえるし、よくできているシステムである。

ただ、今まで一つのシステムに対して複数の作業案件を抱えながら、並列的に作業を行い、都度検証環境や本番環境へ反映していた立場としては、上記で列挙したメリットが時としてデメリットにもなってしまう事に気付いた。

以降、多少批判的になってしまうが、それらデメリット(あくまでも今までの古いやり方と比較してであるが)を挙げていく。

 

Git初心者がほぼ確実にぶち当たる関門として「ブランチ作成時のmaster把握」というのがある。
※「そんな凡ミスやらかすのはお前だけ」という説もある

一つの案件を開始する時に、ブランチを作成してそこで作業を行っていく感じになるが、ここで問題となるのは「どのブランチから枝分かれさせているのか」という事の認識を疎かにしたまま突き進んでしまう事。

特にブランチがいくつも混在しながら開発を進めた状態で、よく分からないままデフォルトで提示されるブランチから枝分かれさせてしまうと、作業が完了して実環境へ反映した瞬間に不具合が多発するなどして大変な事になる。(なった)

要するに意図しない機能までもがリリースされてしまうという事。

Gitのリポジトリ構成はそれぞれのプロジェクトや設計者によって異なると思うが、どのようにして管理され、どのように自らのブランチを派生・管理するのかというのを、完全に把握しないと駄目だなと感じた。

ただ、この辺はGitの設計思想や操作方法をある程度理解しないと把握しずらい部分でもあるので、初めての環境やプロジェクトで、まずは既存システムの内容等を把握する事が最優先とされる場合に二重の負担となる事が予想され、ただでさえ頭に詰め込む情報量が多いのに、そこへ更にGitの仕組み・操作方法なども習得しなくてはならないというのは、特に初心者にとっては苦痛となるだろう。

なので(なんでもそうだが)「早いとこ始めておきなさい」という事ですね。
※今年こそはOCamlを…

 

Git運用の面倒な点としてコンフリクトの発生と解消を挙げている人も多く見られるが、個人的にはmergetoolやEmacs上で使えるmagitのediffで比較的簡単に解決できるため、それほど面倒だとは感じていない。(今のところは)

というか、それほどこのmergetoolやediffが素晴らしいという事なので、開発環境への導入は必須と言えるだろう。

コンフリクトは、もう「どちらのソースが正解か?」というのを見て判断するしかないし、システムを把握していればある程度は容易に解決できると思われる。

まぁ、他エンジニアとの調整などが発生すると、それはもう技術云々とは違う次元で面倒なのかも知れないが、今のところそのようなカオスな状況には遭遇していない。

 

前置きが長くなったが、現状で最も「これはやりにくいなぁ…。」と感じている部分。それはまさに案件毎にブランチを分ける事によるファイル・処理の住み分けである。

といっても私しか分からないかも知れないが。

 

例えば、Aという案件があって、Aブランチで作業を開始します。

サクサクと作業を進めていって、完成しました。

で、ここで新たにBという案件が差し込まれたとします。

Bブランチを作成して、ここでも作業を行いますが、新規で追加するファイルが大量に発生しました。

ここまでは特に問題は無いのですが、追加したファイルに対してA案件で作成した処理の一部を反映する必要が出てきました。

今までのやり方(バージョン管理システムを使わずに複数の要件を1ファイルに反映できる)では、特に問題無く、そのまま反映できたのですが、

ブランチで分割してしまうと、仕掛中のBブランチにA案件の処理を入れるのは難しくなります。

なぜかと言うと、もしA案件で追加修正などがあった場合にBブランチ上のファイルに対しても同じ修正を行わなければならなくなるというのと、そもそもブランチで案件を区切った意味が消失する(ような気がする)からです。
※A案件の作業内容をあとから把握したいとなった場合にBブランチの内容まで見る必要が出て来る

方法論的には、ここで「A案件の機能をB案件上で追加したファイルに反映する」というCブランチを作成して対応するべきなのかも知れません。

ただ、そうなると今度はもしAブランチを先にリリースした後でBブランチをリリースするとなった場合に、CブランチのリリースもBブランチのリリースと同時に行う必要が出てきます。

これをもし失念すると、Bブランチで追加した新規ファイルにはAブランチで開発した機能が盛り込まれないままとなり、不具合の要因となる可能性が出てきます。

それじゃやはり、BブランチにA案件の機能を盛り込んだファイルを作成するか…となると、もしAブランチに対して修正する必要が出てきた場合にBブランチに対しても同様の作業を行う必要が出てきます。

正直、この辺で

「うっわ、メンドクサー…。┐(´д`)┌ヤレヤレ」

となるのです。

なんだか、複数のブランチで共通のファイルを取り合っている感じです。

こんなケースは日常的に発生すると思うんですが、エンジニアの方々はどうやってるんだろうかと。

「そんなもん、一つのブランチでやっちまえばいいじゃないか。」という事なんだろうか。

 

「この案件が終わってから、次の案件にとりかかりますよ。終わらないうちは次の案件の作業はしません。」なんて現実には出来ないですもんね。

同一システム上の複数案件を並行して進めるというのが普通だと思います。

 

と、雑感というかほぼ初心者なりの「愚痴」なわけですが、上記の問題を除けば概ね素晴らしい仕組みです。

いや、こんな問題など問題でもなく、ちゃんとした解決方法ややり方が存在する可能性は99.9999%だと思います。

ただ、今は思いつかない…。

 

便利で自由で合理的、だから使うべき。という理屈が闊歩する世界でも、そこには使ってみないと分からない不便も束縛も理不尽さも時に存在するというような事を思った年初でありました。

それでは皆様、今年も良い一年にしましょう。

 

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です