この夏、株式会社Progateさんの5Daysインターンに参加してきました。今年で一番濃密かつ学びの多かった一週間でした。
参加のきっかけ
自己紹介
そもそもお前だれやねんとお思いのばかりでしょうから、軽い自己紹介から入らせていただければと思います。私はもともと趣味でプログラミングをしたり部活の活動に関するWebアプリを作ったり、プログラミング教育のバイトをしたりと、Progateさんの事業ドメインの浅瀬をふらふらとしていたような人間です。 とはいえ高校からずっと文系、専攻は心理学と大学では表面上、情報系とは無縁の生活を送っています。
Progate Pathとの出会い
学部3年生となり、大学院への進学を微塵も考えていなかった私は、インスタでふとProgate Pathの広告を目にしました。「一人前のエンジニアを目指すなら」というストーリー型のものです。 学生は無料という素晴しい文言にまんまと釣られ、流れるようにアカウント登録を済ませて、プロフィール登録を済ませ、ちまちまとタスクをこなしていました。
インターン参加の打診を受ける
ある日、Progate Pathの求人メッセージでインターンのお誘いをProgateさんからいただきました。 生まれも育ちも大阪、東京の街を歩くと冷や汗をかくような人間が果たして5日間も社会人みたいなルーティンで生きていられるか……?という特大の不安を抱えつつも、素晴しいサービスを提供してくださっている会社さんから、出社できる、一週間の、Gitを自作するなんて言う高難易度のインターンに誘われた、という事実にまあまあテンションが上がり、ほぼ即答くらいの勢いで「やります」とタイプしていました。
いざ東京へ
無事面接などを突破し、インターン参加が決定しました。5日間も家を離れるのは何気に人生初(インドアが過ぎる)。新大阪を出発したときは余裕があったのですが、横浜を過ぎると表情が硬くなってきたのを自覚しました。
どうでも良いことですが、東京の街は苦手です。宿泊場所のハッカソンハウスから渋谷のオフィスまで、最短経路で到達できたのは木曜日になってからでした。大阪駅近辺なら目をつぶってもそこそこ歩けるんだけども。やはり格が違いますね、東京は。
1日目
到着して早々、CTOの島津さんからバージョン管理システムの仕組みについての講義を受けました。 なんとなくでしかなかったGitのイメージをビシバシと具現化していく解説には目から鱗といいますか、ほんとうにすごいなの一言しかひねり出せませんでした。
gitを完全に理解したら、 git log のサブコマンドを一人で再現するタスクに入ります。
スライドやドキュメントを見つつ、以下のような処理を完成させました。
.git/ディレクトリを見つける- HEADが指すコミットを特定
- ハッシュ値からコミットオブジェクトのファイルを探しだし、zlibを用いて生のコミットオブジェクトを文字列で取得し、文字列に対して良い感じに処理をして出力
- 親コミットがあれば再び3.のコミットオブジェクトの取得関数を実行(再帰)
再帰なのでスタックオーバーフローの危険性はありますし、マージコミットにぶつかると見事爆散しますが、基本的な git log の実装をギリギリ終わらせることが出来ました。
2日目
2日目はProgate社内で実際に使用されているツールを用いた設計段階です。 1日目はおぼろげながら見えていたものをはっきりと見た感じですが、この日は完全に新概念ばかりでした(Design Doc, Asanaなどなど、完全ソロの個人開発では使わないものばかりです。)
Design Docでは目的やゴール、ゴールにしないこと、設計の詳細や実装方針などを詳細に定めます。 一番苦労したのはここで、そもそものgitの機能について詳しくない状態では、どうしても議論が公式ドキュメントなどとの答え合わせになってしまい、うまく結論を纏めることが出来なかった上に、内容に偏りが生じてしまいがちになりました。
とはいえ、かなり時間をかけてドキュメントを読み解いたgit addが何をしているのか、などもDesign Docの時点でかなり深掘りしておいたおかげで、実装時の認知的な負荷をかなり低減できたと感じました。
四苦八苦しながら捉えたGitの構造(家に帰ってから清書したもの)
| ファイルがある | ファイルがない | |
|---|---|---|
| インデックスされている | 編集 | 削除 |
| インデックスされていない | 新規追加 | エラー |
Design Docで作成したAdd時の操作の条件分岐
3,4日目
開発祭りです。ひたすらに機能作成とPR、レビュー、マージを繰り返しました。 「PRは小さければ小さいほど良い」というメンターさんの金言に従い、相方のAlice君と二人で1時間に2つのペースでPRを捌きました。このペースでありながら、GitHub Copilotも活用したことでレビューでの議論やコードリーディングも活発に行うことが出来たため、Design Docsと併用することで自分が実装していないコードでも楽に使用できるなど、チーム開発の効率性を感じることが出来ました。
3日目には3on1でエンジニアの方々と面談をしていただきました。普段のランチの時間も含め、このように社員さんとお話しできる機会がたくさんあり、キャリアや働き方について、考えや実態をお聞きしたり、自分のキャリアの相談をしたりと有意義な時間でした。
5日目
開発の集大成と、成果発表でした。
開発の中で興味深かったことは、ファイルシステム上の差異をGitがどのように吸収しているのか、という話題です。 .git/indexにはステージングされているファイルらのメタデータが含まれています。 これらにはファイルの作成日時や修正日時、アクセス権限、リポジトリ内の相対パスなどのファイルシステムからの情報が含まれています。
ところで、*nix系ではおなじみの ls -i hoge や stat hoge あるいは node:fsのstatSync() などで取得できるhogeのinodeですが、Windows環境になった途端、様子がおかしくなりました。
fs.statSync() が取得するino(inodeに相当する)は、Windowsでは他のシステムの倍くらいデカい数だったのです。(当時は修正にいっぱいいっぱいだったのと手元にWindows機がないので検証はできません)
それが原因で.git/index書き込みを試みた際にバイナリデータがあふれ出してしまい、失敗するという現象に遭遇しました。
最も大きな問題は本家のGitがどのようにプラットフォームの互換性を維持しているのか、という点でした。
結論から述べれば、Windows版GitではこれらのStatをmode以外使用していないということでした。
(Microsoft Learn: Git Internals)
要らんかったんですね。知ってたら.git/indexの生成時ほぼ0埋めでできたのにな……と思いつつも小規模な変更のみで対応可能だったため、さくっとAlice君が修正を上げてくれ、無事完了。
かと思ったんですが、なんか最後の最後で「ファイル削除をステージングできない」ようになってしまっており、報告会では上手く動きませんでした!残念!(動作確認したところでリリースタグ切ったんですけどね……。)
感想
なんか最後の最後ですっ転んで躓きながらゴールテープに引っかかったみたいな感じですが、完走とさせてください。
良かった点・気付き
Gitの内部について知れた
Gitって呪術(≠jj-vcs/jj)みたいな感じで使っていたんですが、今回、 add と commit を実装する上で、Git内部でのデータの表現や効率化の仕組みを詳しく知ることが出来ました。
特に面白かったことに絞ると、このあたりになります。
- ほとんどのオブジェクトは単方向リストで表現できる
これにより複雑なファイルツリーであったりしても、1ファイルの編集なら大部分のオブジェクトを再利用できるんですね。
- Branchが指すのは単一のコミット
正直この仕組みが一番感動しました。単方向リストのおかげでたった一つの時点から過去の履歴を簡単に計算できるため、編集履歴の流れ全体を保存する必要がないんですね。
チーム開発ができた
いままでずっとソロ開発ばかりで、仕様書もレビューもないような環境でばしばしコードを書いているだけでした。 今回はDesign Docsを1日かけて書き上げましたが、実際のプロダクションレベルのものだと数週間かけることもあるそうです。ドキュメントを作成する時点で実装の流れを把握していることで、実装スピードが上がるだけでなく、自分以外の実装についても理解が進んだため、チーム開発における認識・仕様のすり合わせによる影響力の大きさを感じました。
また、私はこれまで一度もハッカソンやイベントに参加したことがなかったのですが、相方のAlice君はハッカソン経験も豊富で、自分も参加して見ようかな、と考えるようになりました。
LLMの活用について
GitHub Copilot、便利ですね。レビューもしてくれるなんて最高!と思いましたが、ある一つの問題に気付きました。
// このコードは後で実装
const hoge = () => {};
// eslint-disable-next-line
function fuga() {}
このようなコメントをコード内に見つけると、Attentionの特性なのか、コメントを律義に守って無視することがありました。 プロンプトの工夫で回避できそうではありますが、レビュー時にこういうところを見落とされるのは厳しいな、と感じました。
実際の業務に立ち会えた
Progate自体の開発には関わらなかったとは言え、(あんま詳しく書くと怒られそうなので詳細は省きますが)、社員さんと同じオフィスで活動することで、実際の業務の様子を伺うことができたのは良い経験でした。
やってない後悔
メンターさんたちに実装の相談ができなかった
「いや今めっちゃウェブ会議してるしな……」と遠慮などもあり、相談を躊躇してしまいやすかったのでもったいなかったな、と改めて思います。しょうもないことでも聞けば良かったです。懇親会で島津さんから「インターン期間中の最優先業務はインターン生の対応ですよ」とカッコいいことを言われてしまい、なおさら後悔です。
まとめ
この夏最高の一週間でした。技術的な向上はもちろんのこと、自らのキャリアについても改造度が高くなり、自分が本当にやりたいこと、というのを見つめる機会になりました。
このような機会を設けてくださったProgateの方々はもちろん、相方のAlice君にも最大限の感謝を述べさせていただきたいです。
とりあえずなにかしらのハッカソンに参加したいと思っているので、そういったイベントや、あるいはそれ以外の機会でも、また巡り合えたらな、と思います。 ありがとうございました。