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?

2 つの AI セッションが同じ作業コピーを触ると、index まで共有される——「自分のファイルだけ add」は安全ではない

0
Posted at

09-19 の朝、サイトのリポで git log を見たら、自分がまだコミットしていない原稿 3 本と図 4 枚が、別のセッションの commit に入って origin に届いていた。commit したのは同じ PC で走らせていたもう 1 つの Claude Code セッションで、当方の作業コピーをそのまま共有していた。

「同じリポで 2 つ走らせるな」は知っていました。守っていなかったのは、それがファイルの話ではなく index の話だと分かっていなかったからです。この記事は、起きた 2 例を git の写しで数え、「自分のファイルだけ git add すれば安全」が成り立たないことを捨てリポで 30 秒で再現し、今日から入れられる 3 段を並べます。

同じ作業コピーを 2 つのセッションが触ると何が乗るか

この記事の位置づけ(2026-09-26 追記)

  • 既に知られていること: 同じ作業コピーでは index(stage)も共有され、分けたいときは git worktree を使うこと(git の文書)。
  • この記事で新しく示すこと: AI のセッションを 2 つ同じ作業コピーで動かしたときに実際に起きた 2 例と、git commit --only で防げる範囲の最小再現。
  • 当てはまる範囲: 同じ作業コピーを 2 つのプロセスが触る場合全般。事故の件数は当方の 2 例だけです。
  • 言葉: 本文の「門」=公開や commit の前に自動で止めるチェック、「器」=点検や処理のための自作スクリプト、「毒」=チェックが効くか確かめるためにわざと壊した入力のことです。

数字の元データと再現の手順は、検証の記録(Lab)にまとめています。

1 例目: 他方の 1 commit に、自分の 24 本が乗っていた

他方の commit を git show --stat で開くと 44 files。パスで分類して CSV から数えると、当方の未コミット 24 本(本文 3・図 4・証拠 17)と他方の 20 本でした。他方が git add -A を打ったのか . なのか個別なのかは、git の履歴には残りません。最初は「-A が巻き込んだ」と書いていて、外部の精査で「それは残らない」と指摘され、「他方の commit に乗った」まで下げました。

2 例目: push していない commit が origin に居た

2 日後。当方は docs だけを commit(12:23:27)して push はしていない(当方の転写に git push は 0 件)。ところが 15 秒後にできた他方の commit(12:23:42)と同じ枝で、当方の commit が git branch -r --contains に出た。残っている事実はここまで=「当方は push していない」「その後 origin に含まれていた」。どの push で上がったかは git に残らないので、「他方の push に乗った」とは書けません。

commit の author で見分けようとしましたが、同じ PC・同じ git config なので 3 commit とも %an は同名でした。

30 秒で再現できる: git add a.txt でも b.txt が乗る

捨てリポで次の状態を作ります。他方が b.txt を変えて git add b.txt(stage だけ)、当方が a.txt を変える。ここで当方が「自分のファイルだけ」add して commit すると——

git add a.txt; git commit -m x        →  2 files changed   (b.txt も乗る)
git commit --only -- a.txt -m x       →  1 file changed    (b.txt は stage に残る)

3 回やって 3 回同じ。git add a.txt は a.txt を index に足すだけで、index に既に居る b.txt はそのまま commit に入ります。同じ作業コピーはファイルだけでなく index も 1 つなので、「自分のパスだけ add した」は「他方が stage したものも一緒に commit した」と同じ意味になります。

git commit --only -- <path> は index を無視して指定パスだけを commit する Git 公式の口で、これなら乗りません。ただし他方の stage は残ったままです。

表にすると

例 何が起きたか 数
1 例目(09-19) 他方の 1 commit に当方の未コミットが乗って origin へ 44 files 中 当方 24・他方 20
2 例目(09-21) 当方は push していないのに origin に含まれていた 12:23:27 → 12:23:42=15 秒・--contains=origin/master・%an 3/3 同名
再現 ①git add a.txt; git commit 他方が stage 済みの b.txt も乗る 2 files(3/3)
再現 ②git commit --only -- a.txt a.txt だけ 1 file(3/3)・b.txt は stage に残る
制限の門 予定内/別 dir/同 dir の別ファイル/--dir 明示/.bak/リポの外 exit 0/1/1/0/1/2

2 例とも、commit の前に git status -sb か git diff --cached --name-only を読んでいれば他方の変更は表示されていたはずです(当時は読んでいないので推論)。

今日から入れる 3 段

  1. 隔離——セッションごとに git worktree add で working tree と index を分ける。これが第一選択で、以下は分けられない日の話。
  2. 制限——commit に乗るものを機械で絞る。git commit --only -- <path> を使い、さらに commit 前に「stage に予定外のパスが在れば赤」の門を置く。当方の門は staged_path_gate.py --check <自分のパス…>=git diff --cached --name-only -z を取り、引数のパス(完全一致・ディレクトリは --dir で明示)と比べて 1 本でも予定外なら exit 1、git が失敗したら exit 2。
  3. 監査——git add -A を打たない。commit の前後で git status -sb と git diff --cached --name-only を読む。push していないはずの commit が origin に居るかは git branch -r --contains <sha>。

チェックの最初の版にあった穴 2 つ

この門は書いた日のうちに外部の精査で 2 か所直しています。1 つ目、予定のパスを .git/ の中の 1 ファイルに保存していた=同じ作業コピーを共有する他方が上書きできる(「共有が危ない」という記事の道具が共有されていた)。2 つ目、先頭一致だったので同じディレクトリの別ファイル(docs/other.md・docs/mine.md.bak)が通っていた。予定は毎回引数で渡し、ファイルは完全一致を既定にして、毒 6 本で exit 0/1/1/0/1/2 を確かめました。

もう 1 つ。1 例目の件数を最初は手で書いていて、CSV から数え直したら 2 か所違っていました。本文の数は全部 CSV 由来です。

言えないこと

他方も同じ運用者の別セッションで、第三者ではありません。門が止めるのは stage の巻き込みだけで、同じファイルを他方が上書きするのは止められない(そこは worktree の領域)。「防げた」とは書きません。最小再現は「他方が stage だけ」の型で、1 例目の「他方が commit まで進めた」型とは向きが違い、再現しているのは index の共有そのものです。worktree に分けたあとに残る問題(deploy・共有 remote・生成物の未コミット)は数えていません。

再現の器と門は https://github.com/sumitsuke/staged-path-gate に置きました(MIT)。

AI の利用について

2 例を踏んだのは AI セッション自身で、git の写し・分類・再現の器・門・この下書きも AI(Claude Code)が作っています。数字は git の出力から写し、パスは匿名 ID に落とし、原本は非公開の箱に SHA256 つきで置いています。

関連


Sumitsuke は、AI や外注で作ったものの点検と修理、業務自動化、検証を受託しています。AI に任せた作業の「何が起きたか」を git と数で検収する設計は → https://sumitsuke.jp/works/verification/


この記事は Zenn にも同じ内容を掲載しています。

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?