【git】`fatal: bad object refs/remotes/origin/HEAD 2` で pull できない【macOS】

## error: &lt;your repository&gt; did not send all necessary objects

GitHub 上の俺様リポジトリの CI/CD（GitHub Actions）で、パッチが当たったのでローカルをアップデートしようと `git pull --rebase` したところ、"`error: <リポジトリ名> did not send all necessary objects`" エラーが出始めました。

```shell-session
$ 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` なようです。

- 関連記事: [git pullをしたら`fatal: bad object refs/remotes/origin/main 2`と言われてしまった時の対処法](https://qiita.com/D_suke/items/56060e0dba9a0ec557a7) @ Qiita

<details><summary>動作環境</summary>

```shell-session
$ 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
```

</details>

## エラーの理由

`.git/refs/remots/origin/` 内に、リモートにはない [git オブジェクト](https://git-scm.com/book/ja/v2/Git%E3%81%AE%E5%86%85%E5%81%B4-Git%E3%82%AA%E3%83%96%E3%82%B8%E3%82%A7%E3%82%AF%E3%83%88)が格納されており同期に不統合が発生した。今回は `HEAD 2` オブジェクト。

## 原因

`bird` プロセスによる iCloud Drive の同期と、`git pull` によるリポジトリの同期タイミングが重なってしまい、番号付きのコピーができてしまった（この場合 `HEAD` のコピーである `HEAD 2`）。

## 対処法

- 指定されたファイルを削除する<br>（ここでは `.git` 内にある `.git/refs/remotes/origin/HEAD 2` のオプジェクト）

```shell-session
$ 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 の同期息切れでコピペピピック

<font color=darkorange>**iCloud Drive って同期に失敗すると連番付きのコピーを作る**</font>ことが、まれに多くあります。競合コピーってやつです。

例えば `README.md` の同期中に変更すると `README 2.md` を勝手に作ったり、同期中にファイル・ロックがかかったりする場合です。

通常は目に見える範囲で作成されるため `git status` などで気付くのですが、今回は `.git` ディレクトリ内だったので気づき辛かったです。

あっちょんぶりけ

### 再発防止対策の考察

#### そもそも同期対象から外す

ネットを調べると、結局のところ「そもそもローカル・リポジトリを iCloud Drive に同期させる方が悪い」という意見が大半のようです。「必要ならリモートからクローンすれば良いだけ」という至極まっとうな考えです。

しかし、GitHub などに置く前だったり、ローカルだけで git でバージョン管理したい場合も多くあります。「GitHub のプライベート・リポジトリを使えよ。[無料版でも制限数はない](https://github.blog/news-insights/product-news/new-year-new-github/)んだから」という声も聞こえてきそうです。

ただ、`.gitignore` で除外している大量のデータがあるリポジトリも多いため、これらのプレシャスなデータも含めて iCloud Drive に保存したいのです。だって、iCloud Drive の容量が 1 TB もあるし（都合のいいサイズの契約がない）。

#### iCloud を一時的に止める

次点で多い意見が「iCloud を止めておき、一連の操作・作業が終わったら再開する」というものでした。

まぁ、そうですよね。おそらく、それが一番無難な方法でしょう。でも、ぶっちゃけ面倒臭い。

2台ある Mac（MBP と Mac mini）で一番同期したいのがローカルのリポジトリなので、高い iCloud Drive の容量を月々払っているんだから、なんとかならないかしら。

<!--
iCloud Drive の同期を担うのが `bird` プロセスなので、コマンドから `bird` の一時停止と再開ができるなら「[`git hooks`](https://git-scm.com/book/ja/v2/Git-%E3%81%AE%E3%82%AB%E3%82%B9%E3%82%BF%E3%83%9E%E3%82%A4%E3%82%BA-Git-%E3%83%95%E3%83%83%E3%82%AF) と組み合わせればイケるんじゃね？」と思いました。

`/System/Library/LaunchAgents/com.apple.bird.plist` に

00>