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/私][10章]gitは、なかったことにを許さない

0
Last updated at Posted at 2026-06-28

目次

──「心をgitで管理する世界」の物語で、否認した過去をgitだけが覚えている

9章へ

〈ショートストーリー〉

言ってしまってから、空気が止まった。

喧嘩の最中だった。たいした喧嘩じゃなかったはずだ。ただ、その日の私は、仕事がうまくいかなくて、妙にいらついていた。自分が小さく思えて。それを認めたくなくて。

強がって、見栄を張って ── 言わなくていい一言まで、口が滑った。

何を言ったかは書かない。ただ言った瞬間に、しまった、と思う種類の一言だった。妻の顔から、すっと色が引いた。私は自分でも驚いていた。そんなことを言うつもりは、なかったのに。

すぐに謝りたかった。いつもの私なら、もう謝っていた。

でも、その夜はできなかった。さっき強がった手前、今さら「ごめん」と折れるのが、かっこ悪い気がして。

妻は、何も言い返さず、寝室のドアを静かに閉めた。

私は、リビングに一人で残された。

手首の端末に、さっきのcommitが点いている。消えない。たった今、私が積んだばかりの、その一行。

二つ、道があった。

一つは、revert

言ったことは、消さない。その上に、新しいcommitを積む。「あれは、間違いだった。ごめん」。私が言ったことも、それを取り消したことも、両方、ログに残る。明日、妻がログを見れば、私の一言は、まだそこにある。打ち消しは、傷を消さない。傷の隣に、謝罪をもう一つ、並べるだけだ。

それは、かっこ悪い。みじめに頭を下げることだ。

もう一つは、reset --hard

あの一言の手前まで、HEADを戻す。さっきのcommitごと、なかったことにする。「そんなこと、言ってない」。きれいに消える。強がった私を、下ろさなくていい。

楽だった。あまりに、楽だった。

<<<<<<< 謝りたい私
ごめん。あれは、言いすぎた。
=======
何も、言ってない。
>>>>>>> 見栄を張ったままの私

同じ一行を、二人の私が奪い合う。

私は ── 弱かった。reset --hardを押した。

commitが消えた。ログが何事もなかった顔をして、さっきより一行短くなる。胸がすっと軽くなった。これでいい。なかったことに、なった ──

ならなかった。

ふと、git reflogを開いてしまった。

そこには、消したはずのあの一言。reflogは、私が捨てたものをまだ覚えていた。「なかったこと」になど、本当はなっていなかった。私は、ログの表から引っ込めただけだ。強がりごと、隠しただけ。

私は、長いこと、そのreflogを見ていた。

消しても、消えない。だったら ── と思った。だったら、ちゃんと残したまま、謝るしかない。なかったことにできないなら、せめて、その隣にごめんを並べるしか。

reflogから、消したはずのcommitを拾い直した。私が確かに言った、その一行を戻す。

そして、その上にrevertを積んだ。「ごめん。言いすぎた」。みじめでも、かっこ悪くても、それが、私にできるただ一つの正直だった。

翌朝、妻は、いつもどおり台所に立っていた。コーヒーを二つ、淹れていた。

私のぶんも、あった。

ゆうべ、妻が、私の一言をどう扱ったのか。revertしたのか、reset --hardしたのか。私には分からない。妻のrepoの中は、見えない。

ただ、コーヒーは、二つ、湯気を立てていた。

「……ゆうべは、ごめん」

今度は、ちゃんと言えた。強がりを、下ろして。

妻は、「うん」とも「いいよ」とも言わなかった。ただ、私のぶんのコーヒーを、私のほうへ、すっと押した。

それが、許しなのか、ただの惰性なのか、私には分からなかった。

でも、コーヒーは、温かかった。


〈技術ノート〉── revert / reset --hard

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

物語が嘘をついた場所

reset --hardで、なかったことにできる」── ここが、嘘だ。

確かに、reset --hardは、ログの表からcommitを消す。だが、消えてはいない

二つの操作を、正確に並べる。

  • revert ── 対象commitの逆diffを、新しいcommitとして積む。原因は履歴に残ったまま。「やった」事実と「取り消した」事実が、両方ログに並ぶ。履歴を書き換えないので、共有済み・push済みでも安全に使える。
  • reset --hard ── ブランチとHEADを、指定した手前のcommitへ戻し、作業ツリーごと上書きする--soft/--mixedと違い、--hardは手元の変更も捨てる)。それ以降のcommitは、ログから外れ、到達不能(unreachable) になる。

ここが肝心 ── 到達不能になったcommitは、すぐには削除されない。 オブジェクトは、まだデータベースに残っている。そしてgit reflogが、HEADやブランチがどこにいたかを記録しているので、そこから拾い戻せる(git refloggit reset --hard HEAD@{1}cherry-pick)。

主人公が見たのはこれだ。捨てたはずの一言が、reflogにまだ座っていた。

消えない、ということ ── 非情さと、救い

reflogのエントリには、寿命がある。既定で、到達可能なものは約90日、到達不能なものは約30日でexpireし、その後git gcがpruneして、ようやく本当に消える。

この「猶予」が、両刃だ。

  • 救い ── 取り乱してreset --hardした直後に後悔しても、reflogがあれば、取り戻せる。否認を、撤回できる。 物語の主人公は、これに助けられた。一度は否認(reset)に逃げたが、reflogが消させてくれなかったことで、彼は正直(revert)に引き戻された。消せない、という事実が、彼を謝罪へ押し戻した。
  • 非情さ ── 本気で消したくても、しばらくは消えない。「なかったこと」は、待たないと完成しない。そして ── ここをgitは決して直してくれない ── 相手のrepoにある分は、こちらのresetでは消せない。 妻が聞いた一言は、妻の履歴にある。私のreflogをいくら掃除しても、そこには届かない。

「否認」は、技術的にも、完成しないのだ。

正しい名前

物語の言葉 gitの正名
打ち消しを積む(謝罪) revert=逆diffを新しいcommitとして積む。原因は残る。共有履歴でも安全
なかったことにする(否認) reset --hard <手前> =ブランチとHEADを戻し、作業ツリーごと上書き。以後のcommitは到達不能に
消したはずが、まだある/拾い直す reflog=HEAD/ブランチの移動先の記録。到達不能commitも、ここから拾い戻せる
しばらくは消えない expireとgc=reflogは約90日/到達不能は約30日でexpire、その後git gcでprune。完全消去は、そこまで待つ

要点

  1. revertは足し算、reset --hardは引き算。 revertは打ち消しを積む(履歴は残る・共有安全)。reset --hardは履歴ごと戻す(作業ツリーを破壊・共有済みならforce-pushが要る=7章の領域)。
  2. revertは傷を消さない。 原因commitはログに残り続ける。消すのではなく、隣に取り消しを並べる謝罪だ。
  3. reset --hardも「なかったこと」にはならない。 reflogが拾える間は残り、相手のrepoは、そもそも消せない。否認は完成しない ── そして、その「消せなさ」が、人を正直さへ戻すこともある。

11章へ

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?