0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

[origin/私][3章]旧友とのmerge-baseは高校で止まっている

0
Last updated at Posted at 2026-06-21

目次

──「心をgitで管理する世界」の物語で、昔話しかできなくなる理由をgitで説明する

2章へ

〈ショートストーリー〉

二十年ぶりに会った田中は、まず高校の話をした。文化祭、屋上、誰それの噂。

私は合わせながら、少し身構えた。——この男、まだ十八歳のつもりなのか。

なら、付き合ってやる。手首をさすって、唱える。

git checkout 高3

当時の口ぐせが前へ出てくる。気分が、あの頃に戻っていく。

どっちが先に担任のあだ名を言い出したか。くだらない言い争いが、本気で二十分続いた。結論は出ない。出す気もない。頼んだのはコーヒーだけ。終電を気にする頭が、どこかへ行っていた。

そこからの二時間は、よかった。本当に、よかった。

途中、田中が財布を落とした。隙間から子どもの写真がのぞく。

「上が今年、受験でさ」彼は笑った。「お前んとこは?」

私も、いまの話をした。仕事のこと、子どものこと。田中は、へえ、と笑って、すぐに屋上の話に戻した。私のほうも、彼の受験生の話を、本当には受け取れていなかった。

二人そろってcheckoutできる場所は、もう高3しか残っていなかった。マージベース。

別れぎわ、田中が言った。「お前、変わらないなあ」

私も同じことを思っていた。変わっていないんじゃない。互いの変化を一度も取り込まないまま来た、というだけだ。

別れて、駅のホームでgit checkout いまの私

戻った私は、今夜の楽しさを持ち帰ろうとして、高3をmergeした。

CONFLICT (content): Merge conflict in 私
<<<<<<< HEAD(いまの私)
明日は七時に起きる。遅刻はしない。
「今度飲もう」の今度は、来ない。
=======
朝まででも付き合う。明日のことは、明日でいい。
会いたいやつには、会いに行く。
>>>>>>> 高3

両方は、残せない。朝までバカ話をする私と、会社に遅れず行く私が、同じ一行を奪い合う。高校のときは、こんなことは起きなかった。あの頃は、失うものがまだ何もなかったからだ。

一行目は、いまの私を採用した。二行目は、高3を採用した。

コミットした。いまの私が少し重くなり、消したぶんだけ軽くなった。

高3のタグは、消さずに残してある。読み取り専用のまま、いつでも会いに行ける。

ただ、そこに新しい一日を書き足すことは、もう、二人ともできない。


〈技術ノート〉── tag / merge base

ノートは答え合わせではない。物語が嘘をついた、ちょうどその場所の地図である。

物語が嘘をついた場所

帰り道、私は「今夜の楽しさを持ち帰ろうとして、高3をmergeした」。

ここが嘘だ。

一日ぶんの履歴ごと取り込みたいならmergeでいい。だが、欲しかったのは一行だけだった。「朝まででも付き合う」という、あの一行。一行だけを別の枝から今の自分へ移す操作は、mergeではない。git cherry-pickだ。

  • merge ── 二つの履歴を合流させ、相手のcommit列をまるごと自分の系譜に取り込む。だからmerge base(共通祖先)が要る。差分の基準がそこにしか無いからだ。
  • cherry-pick ── 特定のcommitの差分だけを、今いる枝に新しいcommitとして載せる。履歴は継がない。共通祖先も要らない。

物語がmergeと言った瞬間、本当は私はcherry-pickしていた。一行を選び、残りは置いてきた。それは合流ではなく、移植だった。

正しい名前

物語の言葉を、gitの正名に接続する。

物語の言葉 gitの正名 定義
二人そろってcheckoutできる、もう高3しか残っていない merge base 二つの分岐の共通祖先git merge-base 高3 いまの私で求まる。分岐後に各自が積んだcommitは、ここには含まれない
二人でpushし合っていた頃 共有リポジトリ(remote) 両者がclone・push・pullしていた関係のrepo。pull済みの共通履歴は各自のlocalにも残る(分散)。卒業後pushが止まりstaleに
朝までゲームvs遅刻しない、同じ一行の奪い合い merge conflict 両側が同じ箇所を別々に変更したとき、gitは自動で選べず、人間に解決(resolution)を委ねる
一行目は私、二行目は高3を採用した conflict resolution どちらを残すか一行ずつ選び、選び終えてからcommitして確定する
高3のタグは、消さずに残してある。読み取り専用 tag 特定のcommitを指す、動かない名前。ブランチと違い、新しいcommitで先へ進まない

共有リポジトリと、その後 ── なぜ一人でもcheckout 高3できるのか

高3は、もともと二人でpushし合っていた共有リポジトリだった。同じ部室、同じ毎日を、二人でそこにcommitしていた。

gitは分散している。共有リポジトリからpullしたものは、そのまま自分のlocalにも丸ごと残る。だから卒業後、その共有リポジトリに誰もpushしなくなって(stale)も、私のlocalには、高3までの共通の履歴がぜんぶ残っている。一人でcheckout 高3できるのは、これだ ── 手元に、そのcommitがあるから。田中も、同じ(彼のlocalにも、共通分が残っている)。

そして卒業後、二人の履歴はdivergeした。私は私のlocalに、就職や子どものcommitを積む。田中は田中のlocalに、彼の二十年を積む。共有していたのは、高3まで。その先は、各自の人生(local)に、別々に伸びている。

だから、再会の会話は二層になる。

  • 高3の話=共有履歴。二人とも持っているから、すらすら噛み合う。
  • 受験や仕事の話=各自がlocalにdivergeさせた、別の履歴。互いにfetch / pullしていないから、聞いても、本当には噛み合わない(「受け取れていなかった」)。

高3のタグが指すのは、その、二つのdivergeした人生の、最後の共通コミット ── merge baseだ。共有リポジトリはstaleになり、新しい共通の一日は、もうpushされない。けれど、それぞれのlocalには、高3がいつまでも残る。会いには、行ける。書き足せない、だけだ。

要点

  1. 一行だけ持ち帰るのはcherry-pick。履歴ごとならmerge。 どちらを使ったかで、「何を受け継いだか」が変わる。物語はmergeと呼んだが、私がしたのはcherry-pickだった。
  2. merge baseは固定されない、はずだった。 普通は、二人が会い続ければ共通祖先は前へ進む。高3で止まったのは、卒業後どちらも相手の枝を一度も取り込まなかったから。merge baseが高3のままなのは、二人の怠慢の化石だ。
  3. tagは読み取り専用。 だから、いつでもcheckout 高3で会いに行ける。だが、そこに新しい一日をcommitすることは、二人とももうできない。会えることと、続けられることは、別だ。
  4. 高3は、共有リポジトリの最後の共通コミット(merge base)。 gitは分散しているので、pull済みの共通履歴は各自のlocalに残る。共有repoがstaleでも一人でcheckoutできるのは、そのため。卒業後の人生(受験・仕事)は、各自のlocalにdivergeして積まれている ── だから持ち出せるし、だから噛み合わない。

4章へ

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?