サイト買収前に見るべきコードの兆候

サイト買収前に見るべきコードの兆候
買い手がDDの初期に見ているのはコードの品質ではなく、コミットの時刻と曜日、直近半年の実質の開発人数、マージとタグの有無、lockfileの最終更新日、READMEが初期のままかといった「形跡」である。これらは数十分で読め、その事業がどう運営されてきたかを正直に映すため、引き継ぎコストの予測に直結する。ただし形跡から読めるのは仮説であり欠格事由ではない。用途は深掘り箇所の特定と、具体的な質問を作ることにある。

サイト買収のデューデリジェンスで、買い手のエンジニアがリポジトリの読み取り権限をもらった初日に、何をしているか。ソースコードを読んでいる、と思われがちですが、現場で起きていることはたいてい違います。多くの場合、最初の30分でやっているのは git log を叩くことです。コードそのものではなく、コードが積み上がってきた「形跡」のほうを、先に見ている。

これは手抜きではありません。むしろ順序として合理的です。数万行のコードを精読するには、どれだけ速いエンジニアでも数週間かかります。一方でDDに与えられる時間は、たいてい数十時間しかない。全部は読めないという前提を認めた瞬間に、「限られた時間をどこに使うか」という問いが立ち上がってきて、その答えがメタ情報なのです。

コミットの履歴、ブランチの構成、依存定義のファイル、設定の置き方、READMEの最終更新日。これらは数十分で読めます。そして厄介なことに、そこにはコードの品質ではなく、その事業がどう運営されてきたかがそのまま出ます。この記事では、買い手がコードを読まずに何を見ているのか、その兆候がそれぞれ何を意味するのかを、実際に叩かれるコマンドの順に整理していきます。

DDの初期に、コードを読む時間は存在しない

DDの初期に、コードを読む時間は存在しない

まず、この前提を共有させてください。ここがズレていると、以降の話が全部「なぜそんな細かいところを見るのか」という感想で終わってしまいます。

買い手が本当に知りたいことは、実はひとつしかありません。売り手がいなくなった後に、自分たちがこの事業を動かせるかです。買収は、今の状態を冷凍保存するために行うものではありません。買った後には必ず、やりたいことがある。広告の配置を変える、機能を足す、自社の別事業と繋ぐ、法改正に対応する。買収の意思決定は、たいていその「やりたいこと」が実現できるという期待値の上に立っています。

そして、その「やりたいこと」に着手できるまでの日数は、事業によって天と地ほど違います。ここで重要なのは、その日数を決めているのがコードの美しさではないという点です。変数名が綺麗で、関数が短くて、設計が現代的でも、動く環境がこの世に1台しか無ければ、買い手の最初の1ヶ月は環境構築で溶けます。逆に、多少ぐちゃぐちゃでも、誰でも再現できて、壊れたら戻せて、経緯が読める事業なら、買い手は翌週から手を入れられる。

つまり買い手が測りたいのは、コードの状態ではなく運営の状態なのです。そして運営の状態は、コードの中身よりも、コードの周辺に濃く出ます。誰が、いつ、どういうリズムで、どういう手順で触ってきたか。それは全部、リポジトリに記録が残っています。しかも、本人が意識して書いた記録ではないぶん、正直です。

IMや資料は、売り手が「見せたいもの」を整えて出してきます。それが悪いわけではなく、当然の営みです。ただ、コミット履歴は違います。誰も見せるつもりで書いていない。だからこそ、そこに実態が出てしまう。買い手が真っ先にそこを見るのは、そういう理由です。

コミットの時刻と曜日が、開発リソースの正体を明かす

コミットの時刻と曜日が、開発リソースの正体を明かす

最初に見られるのは、コミットが「いつ」行われてきたかです。難しい作業ではありません。コミット日時だけを吐き出して、時間帯と曜日で数えるだけです。

git log --date=format:'%a %H' --pretty=format:'%ad' | sort | uniq -c | sort -rn

これを集計すると、その事業の開発が実際に行われてきた時間帯が、ヒストグラムのように立ち上がってきます。そして、ここで平日の22時から26時あたりと、土日に山ができる事業があります。

買い手がこの形を見たときに考えるべきなのは、「この開発者はサボっている」ではありません。まったく逆です。この形が意味しているのは、本業を持ちながら、自分の可処分時間のほぼ全部を注ぎ込んで、このプロダクトを作り切ったという事実です。誰にも頼まれていないのに、平日の夜と休日を何年も差し出して、売上が立つところまで持っていった。これは敬意を払うべき形跡であって、減点材料として扱うのは筋が悪い。国内の個人開発プロダクトの多くは、この形をしています。

ただし買い手は、そのうえで、もうひとつ別の計算をします。この事業の開発リソースは、売り手個人の深夜と週末に等しいということです。そして買収が成立した瞬間、その深夜と週末は事業から離脱します。

ここが重要なところです。買い手が同じ機能追加を再現しようとすると、それは自社の営業時間内の工数、つまり人件費として顕在化します。売り手が「情熱」で払っていたコストが、買い手にとっては「原価」に化ける。事業の損益計算書には現れていなかった開発費が、買収した翌月から実費として発生し始める、という構造です。

この読み替えは、売り手からするとかなり理不尽に映ります。自分は無償で楽しくやっていたのだから、コストなど発生していない、と。それは事実です。ただ、その無償労働は売り手個人に紐付いていて、譲渡対象に含まれていないというだけの話なのです。

途切れの形も、同じくらい語る

時間帯の次に見られるのが、コミットが「途切れている期間」です。3ヶ月まったく動いていない空白が、周期的に現れる事業があります。これも人間として自然な波ですし、それ自体は何の問題もありません。

買い手が気にするのは、直近の空白です。ここ数ヶ月コミットが止まっているリポジトリは珍しくなく、理由もだいたい想像がつきます。売却を決めた時点で、手が止まるのは正常な反応です。ただし、その空白の長さは、そのまま「売り手が最後にこのコードを触った記憶の鮮度」を意味します。半年触っていないコードについて、引き渡し後に細かい質問へ即答できる人は、ほとんどいません(自分が3ヶ月前に書いたコードを他人のものだと感じた経験は、たいていのエンジニアにあるはずです)。

直近半年の「実質の人数」が、引き継ぎの難度を決める

直近半年の「実質の人数」が、引き継ぎの難度を決める

次に見られるのが人数です。ここも1コマンドで終わります。

git shortlog -sne --since='6 months ago'

直近半年で、誰が何コミットしたかが名前順に並びます。そして、ここで見られているのは合計人数ではありません。実質的に何人がこのコードを触れる状態にあるかです。この2つは、かなりの頻度で一致しません。

典型的なズレが2つあります。ひとつは名寄せです。同一人物がPCを買い替えた際に別のメールアドレスでコミットしていて、リストの上では2人に見える。数字上は複数人でも、実体は1人です。もうひとつは分布の偏りで、3人並んでいても、1人が980コミットで、残り2人がREADMEの誤字修正を1コミットずつ、というケース。これも実体は1人です。

この「実質1人」という状態は、買い手にとって欠格事由ではありません。むしろ個人開発の事業を買う以上、当たり前の姿です。問題はそこではなく、その1人が、契約上いつまで質問に答えてくれるのかという一点に集約されます。引き継ぎ期間が1ヶ月で、その間に聞ける質問の総量には限りがある。知識が1人の頭にしか無いなら、その1ヶ月で吸い出せなかった分は、永久に失われます。

もうひとつ、このリストで確認されるのが外部の開発者が混ざっていないかです。会社のドメインではないメールアドレスや、明らかに別人の名前が数十コミット分並んでいる場合、外注や、かつての共同創業者の可能性があります。ここは価格ではなく権利の話に直結するので、買い手は必ず契約書との突き合わせを求めます。「誰が書いたか」が曖昧なコードを買うのは、後から権利を主張されるリスクを抱え込むということですから、当然の確認です。

近年は、コミットにAIエージェントの署名が残っているケースも増えました。これ自体はもう当たり前の光景で、書かれ方をどうこう言う段階は過ぎています。ただ、Vibe Codingによる技術的負債のように生成プロセス側の論点は別途あるので、そこは主題を分けて扱ったほうが整理がつきます。ここで見ているのは、あくまで「引き継ぎ時に質問できる人間が何人いるか」です。

ブランチとマージの形は、戻れるかどうかを示す

ブランチとマージの形は、戻れるかどうかを示す

3つ目がブランチ構成です。ここでよく誤解が起きるので、先に立場をはっきりさせておきます。

git log --merges --oneline | wc -l がほぼゼロ、つまり全部が main への直接pushで積まれているリポジトリは、たくさんあります。プルリクエストも、レビューの記録も無い。ここを「レビュー不在=ずさんな開発」と断じるのは、控えめに言っても筋が通りません。1人で開発している事業に、レビューする相手はいないからです。自分のプルリクを自分で承認する儀式に意味はありませんし、それをやらなかったことは怠慢でも何でもない。

では買い手は何を見ているのか。壊したときに気づく仕組みと、戻る手段があるかです。

1人で開発している間は、これらが無くても実は困りません。全体を把握しているのは自分だけで、何を変えたかも覚えているからです。ところが買収後は、その前提が消えます。事業の全体像を知らない複数人が、同時に触り始める。そのとき、壊れたことに気づく仕組みが無いと、気づくのは顧客からの問い合わせということになります。

タグの有無は「先週に戻せるか」の答え

git tag を叩いて何も出てこない場合、その事業には「リリース」という単位が存在しません。これが効いてくるのは、障害が起きた瞬間です。

タグがあれば、「先週のリリースに戻す」は1コマンドで済みます。タグが無いと、まず「先週動いていたのはどのコミットか」を探すところから始まります。深夜に、燃えている本番を前にして、コミットログを遡って当たりをつける。この差は、平時には一切現れず、事故のときだけ牙を剥きます。

1年前で止まったブランチには、たいてい何かが眠っている

git branch -a --sort=-committerdate でブランチを最終更新日順に並べると、上のほうに現役のものが、下のほうに化石が並びます。そして、1年前で止まった feature/ ブランチが数本ぶら下がっている状態は、ごく普通に見られます。

これ自体は無害です。ただ、買い手が確認するのは中身のほうで、資料に「開発中」「今後実装予定」と書かれた機能の実体が、この止まったブランチであることがあるからです。8割できているのか、ディレクトリを切っただけなのかで、その機能に置くべき価値はまったく変わります。ここは兆候というより、資料との突き合わせ作業に近い。

初回コミットが数万行なら、履歴はそこで途切れている

もうひとつ、地味ながら効くのが最初のコミットの大きさです。git log --shortstat で見たときに、初回コミットが数万行の追加になっているリポジトリがあります。

これは、どこかからコードを丸ごと持ってきたか、リポジトリを作り直した痕跡です。悪いことではなく、事情はいくらでもあります(前のリポジトリに機密が入っていて作り直した、というのはむしろ健全な判断です)。ただし事実として、それ以前の経緯は失われています。「なぜこの実装なのか」を履歴から辿る手段が無いということなので、買い手はその分を売り手への質問で埋める必要が出てきます。

依存定義と設定ファイルは、環境が何個あるかを白状する

依存定義と設定ファイルは、環境が何個あるかを白状する

4つ目は、リポジトリ直下に置かれたファイル群です。ここは数分で終わります。

まず、lockfile が存在してコミットされているか。package-lock.jsoncomposer.lockGemfile.lockpoetry.lock。呼び名は違っても役割は同じで、今動いている構成を、そのまま再現するための設計図です。これが無い、あるいは .gitignore で除外されている場合、買い手は「本番と同じものを手元に作る」という出発点でつまずきます。

次に、その lockfile が最後に更新された日を見ます。git log -1 --format=%ad -- package-lock.json のような形です。ここで出てくる日付とリポジトリの最終コミット日が3年離れていれば、3年間、依存を一度も触っていないということになります。この数字が何を意味するかは、依存ライブラリのEOLが価格にどう跳ね返るかという別の論点に接続していきますが、形跡の検査という意味では、日付ひとつで済む話です。

設定がコードに埋まっているかどうか

もう一段、運営の実態が出るのが設定の置き方です。本番のホスト名、DBの接続先、APIのエンドポイント。これらがコードに直書きされているか、環境変数として外に出されているか。grep を数回叩けば分かります。

ここも「ハードコード=手抜き」という話ではありません。環境が1つしかないなら、外出しする理由が無いのは事実です。ただ、そこから読み取れることがあります。設定が外に出ていないということは、この事業には環境が1つしか存在しない、つまりステージング環境が無く、変更は本番で試されてきた可能性が高いということです。

この推測を裏取りする一次証拠が .env.example のようなファイルの有無で、これは「自分以外の誰かがこれを動かす」という状況を、一度でも想定したことがあるかを示します。あれば、その事業は少なくとも一度、他人の手に渡ることを考えたことがある。無ければ、引き渡し時にその作業が丸ごと発生します。環境構築の属人化という言葉で語られる現象の入口は、たいていここです。

なお、この確認の過程で、本番の認証情報がリポジトリに入ったままだと分かることもあります。その場合は形跡の話ではなく、コミット履歴に残る機密という別の領域の問題として、独立して扱う必要があります。ここでは深追いしません。

READMEの最終更新日という、たった一つの数字

READMEの最終更新日という、たった一つの数字

最後は、たぶん一番地味で、一番よく当たる指標です。

git log -1 --format=%ad -- README.md

この日付が、リポジトリの初回コミットとほぼ同じなら、答えは出ています。このプロダクトのドキュメントは、人の頭の中にあります

これも責める話ではありません。1人で作っているとき、READMEを書く相手は自分だけで、自分は全部知っているのだから、書く動機がそもそも存在しない。合理的です。ただし、その合理性は「自分が触り続ける」という前提とセットになっていて、売却はその前提を壊す行為です。

買い手から見ると、READMEが初期のままの事業は、質問できる期間が終わった瞬間に、暗号になる可能性を持っています。だから引き継ぎ期間の設計に神経を使うことになるし、引継ぎマニュアルの有無が、条件交渉の温度をはっきり変えます。

逆のパターンも書いておきます。READMEに、セットアップ手順、環境変数の一覧、デプロイの手順、詰まりやすい箇所の注意書きまで書かれている事業が、たまにあります。これは強烈に効きます。買い手のエンジニアは、その1ファイルを読んだ時点で「この人は引き継ぎを考えている」と判断しますし、他の項目に多少の粗があっても、評価の土台が変わる。数時間で書けるものが、これほど効く場所は他にあまりありません。

兆候は減点表ではなく、質問リストである

兆候は減点表ではなく、質問リストである

ここまでいくつもの見方を並べてきましたが、最後に、これらの正しい使い方を書いておきます。

これらは、どれ一つとして欠格事由ではありません。

深夜のコミットが多いことも、実質1人であることも、mainに直pushしていることも、READMEが初期のままであることも、それ自体は「悪い事業」の証拠ではありません。むしろ全部揃っている事業は、本業を持った1人の人間が、限られた時間の中で、売上が立つところまで持っていったという意味であって、普通に考えてすごいことです。そこを減点として突きつけるDDは、単に無礼なだけでなく、実務的にも間違っています。売り手を身構えさせて、聞ける話を減らすからです。

これらの兆候の正しい用途は2つあります。

1つ目は、限られたDD時間を、どこに使うかを決めることです。数十時間しかない中で、全部を等しく調べることはできません。形跡を先に読むと、深掘りすべき場所に当たりがつきます。lockfileが3年前で止まっているなら依存に時間を割く、止まったブランチが資料の「開発中」機能と対応しているならそこを詰める、といった具合です。

2つ目は、質問を作ることです。そして、これが本命だと言っていい。「このブランチが1年前で止まっているのは、どういう経緯ですか」「この時期にコミットが3ヶ月空いているのは何かありましたか」「初回コミットが2万行なのは、リポジトリを作り直したということでしょうか」。こうした質問は、資料を眺めていても絶対に出てきません。そして、こういう具体的な質問には、売り手も具体的に答えてくれます。技術的DDの質が上がるのは、質問が具体的になった瞬間からです。

ここで一つ、実務的な注意も書いておきます。形跡から読み取れるのは仮説であって、事実ではありません。深夜のコミットが、単にその人が夜型なだけということもあります。実質1人に見えて、実は隣にずっと相談相手がいたということもあります。形跡は質問の材料であって、結論ではない。ここを混同して、リポジトリを眺めただけで事業を断じるのは、Google Analyticsの数字だけ見て買うのと、精度において大差ありません。

買い手が測っているのは、コードではなく距離

買い手が測っているのは、コードではなく距離

結局のところ、買い手がリポジトリの周辺を眺めて測ろうとしているのは、売り手の頭の中にある知識と、自分たちの手元との距離です。

その距離が近い事業は、価格の議論がシンプルになります。買った後にやることが読めるからです。距離が遠い事業は、その遠さの分だけ、買い手が保守的な見積もりを置きます。これは売り手の人格や能力の評価ではなく、単に、引き継ぎ後に発生する作業量の予測です。

そして、この距離は、売り手側からもかなり縮められます。しかも、大工事は要りません。READMEにセットアップ手順を書く。lockfileをコミットする。設定を .env.example に一覧化する。止まったブランチを消すか、なぜ止まっているかを1行書き添える。どれも半日で終わる作業ですが、買い手が最初の30分で見る場所を、正確に射抜いています。

数字を1年かけて磨き上げてきた売り手が、この半日をやらないまま交渉に臨むのは、あまりにもったいない話です。逆に買い手の側は、この形跡を「減点表」として使わないでほしいと思います。そこに残っているのは、誰かが何年もかけて、本業の合間に積み上げてきた時間の記録です。それを踏まえたうえで、引き継ぎコストを冷静に見積もる。その順序を守れる買い手のところにだけ、売り手は本当のことを話してくれます。

コードを読む時間が無いなら、コードが歩いてきた道を読めばいい。そこには、資料には決して書かれない事業の実像が、驚くほど正直に残っています。

買収候補のコードにこうした兆候がないかは、デューデリジェンスでリポジトリを確認できる段階になれば、公開技術DDツールで機械的に洗い出せます。

この記事の著者

黒沢 大輔

株式会社studio C 代表取締役

これまで4回の事業譲渡を実現。上場企業にてエンジニア、制作ディレクション、SEO事業立ち上げを歴任。副業で始めた複数の掲示板サイトを国内最大規模まで成長させて事業譲渡。日本のM&Aに透明性と精度をもたらすべく、デジタル事業のM&Aプラットフォーム『RIKKA M&A』を立ち上げ。