error: <your repository> did not send all necessary objects
GitHub 上の俺様リポジトリの CI/CD(GitHub Actions)で、パッチが当たったのでローカルをアップデートしようと git pull --rebase
したところ、"error: <リポジトリ名> did not send all necessary objects
" エラーが出始めました。
$ git pull --rebase
remote: Enumerating objects: 5, done.
remote: Counting objects: 100% (3/3), done.
remote: Total 5 (delta 2), reused 2 (delta 2), pack-reused 2 (from 1)
Unpacking objects: 100% (5/5), 2.46 KiB | 2.46 MiB/s, done.
fatal: bad object refs/remotes/origin/HEAD 2
error: https://github.com/KEINOS/go-argonize.git did not send all necessary objects
落ち着いてエラーを読んでみると、"fatal: bad object refs/remotes/origin/HEAD 2
" とあります。どうやらリモートにはないオブジェクトがローカルのリポジトリにあり、それが bad object
なようです。
動作環境
$ sw_vers
ProductName: macOS
ProductVersion: 12.7.6
BuildVersion: 21H1320
$ git version
git version 2.47.0
$ gh version
gh version 2.60.1 (2024-10-25)
https://github.com/cli/cli/releases/tag/v2.60.1
エラーの理由
.git/refs/remots/origin/
内に、リモートにはない git オブジェクトが格納されており同期に不統合が発生した。今回は HEAD 2
オブジェクト。
原因
bird
プロセスによる iCloud Drive の同期と、git pull
によるリポジトリの同期タイミングが重なってしまい、番号付きのコピーができてしまった(この場合 HEAD
のコピーである HEAD 2
)。
対処法
- 指定されたファイルを削除する
(ここでは.git
内にある.git/refs/remotes/origin/HEAD 2
のオプジェクト)
$ cd .git/refs/remotes/origin/
$ # HEADのコピーができていることに注目
$ ls -lah
total 24
drwxr-xr-x@ 4 admin staff 128B 11 12 08:51 .
drwxr-xr-x@ 3 admin staff 96B 11 4 11:04 ..
-rw-r--r-- 1 admin staff 30B 10 16 03:11 HEAD
-rw-r--r--@ 1 admin staff 30B 10 13 15:08 HEAD 2
$ rm -f "HEAD 2"
$ ls
HEAD
$ cd ../../../..
$ git pull --rebase
Updating 14e8244..055ca0e
Fast-forward
go.mod | 4 ++--
go.sum | 8 ++++----
2 files changed, 6 insertions(+), 6 deletions(-)
$ echo $?
0
$ # 👍
再発防止対策と所感
iCloud の同期息切れでコピペピピック
iCloud Drive って同期に失敗すると連番付きのコピーを作ることが、まれに多くあります。競合コピーってやつです。
例えば README.md
の同期中に変更すると README 2.md
を勝手に作ったり、同期中にファイル・ロックがかかったりする場合です。
通常は目に見える範囲で作成されるため git status
などで気付くのですが、今回は .git
ディレクトリ内だったので気づき辛かったです。
あっちょんぶりけ
再発防止対策の考察
そもそも同期対象から外す
ネットを調べると、結局のところ「そもそもローカル・リポジトリを iCloud Drive に同期させる方が悪い」という意見が大半のようです。「必要ならリモートからクローンすれば良いだけ」という至極まっとうな考えです。
しかし、GitHub などに置く前だったり、ローカルだけで git でバージョン管理したい場合も多くあります。「GitHub のプライベート・リポジトリを使えよ。無料版でも制限数はないんだから」という声も聞こえてきそうです。
ただ、.gitignore
で除外している大量のデータがあるリポジトリも多いため、これらのプレシャスなデータも含めて iCloud Drive に保存したいのです。だって、iCloud Drive の容量が 1 TB もあるし(都合のいいサイズの契約がない)。
iCloud を一時的に止める
次点で多い意見が「iCloud を止めておき、一連の操作・作業が終わったら再開する」というものでした。
まぁ、そうですよね。おそらく、それが一番無難な方法でしょう。でも、ぶっちゃけ面倒臭い。
2台ある Mac(MBP と Mac mini)で一番同期したいのがローカルのリポジトリなので、高い iCloud Drive の容量を月々払っているんだから、なんとかならないかしら。