iCloud Drive 同期トラブルの落とし穴メモ
私は2台の Mac を行き来して作業していて、プロジェクトのフォルダはまるごと iCloud Drive に入れています。
この「2台運用」そのものの全体像や、雲マークを待つ・並行作業をしない、といった日々の運用ルールは 2台のMacをiCloudで行き来する運用 に書きました。環境や運用の話はそちらを読んでもらうとして、この記事は「同期そのものの技術的な落とし穴」に絞ります。
便利な仕組みなのですが、油断すると地味な事故を踏みます。私が実際に踏んで「これは記録しておかないと、また同じところでハマるな」と思ったものを、3つに絞って書いていきます。
落とし穴1: 「hoge 2.txt」型の重複コピーと、その二次災害
一番ひやっとしたのが、ファイルがいつの間にか二重になる現象です。
具体的には、ある日フォルダを覗くと「hoge 2.txt」のように、末尾に半角スペース+数字が付いたコピーが増えていることがあります。これは iCloud が「2台のあいだで食い違いが起きた」と判断したときに、片方を別名で残しておく動きだと理解しています(細かい仕様までは追えていません)。
厄介なのはここからです。コピーが「hoge 2.txt」として増えるということは、本来の「hoge.txt」のほうが中身を失っている、あるいは消えたように見えるケースがあるのです。私が踏んだのは、まさに本体が空っぽになって、新しいほうにだけ中身が入っている、という状態でした。
これ単体でも面倒なのですが、もっと怖いのは二次災害でした。
私のサイトは、ファイルが見つからないときに「とりあえずトップページを表示する」挙動をするホスティングに置いています。便利な反面、これが裏目に出ます。たとえば style.css が重複コピー側に逃げて本体が空になっても、配信側は「ファイルが無い」と正直にエラーを出さず、代わりにトップページのHTMLを返してしまうのです。
そうすると、ブラウザは「CSSのつもりで読み込んだものがHTMLだった」という状態になります。エラーにはならないので、パッと見では気づけません。見た目だけがなぜか崩れている、という分かりにくい壊れ方をします。CSSやJSがこっそり欠けても、ページ自体は200(正常)で返ってくるので、原因にたどり着くまで余計に時間がかかりました。
教訓は、「ファイルが無いときに別ページで代用する」設定のサイトでは、同期事故で中身が抜けた欠損を、エラーではなく見た目の崩れとして探さないといけない、ということです。重複コピーを見つけたら、本体側の中身が無事かを毎回セットで確認するようにしました。
落とし穴2: ファイルの最終更新時刻(mtime)は当てにならない
次に踏んだのが、ファイルの最終更新時刻にまつわるズレです。
ファイルには「最後に書き換えられたのはいつか」という時刻(よく mtime と呼ばれます)が記録されています。ふつうは「新しいほうが最新」と判断する目安になります。ところが iCloud Drive 配下では、この時刻が同期のタイミングで書き換わってしまうことがありました。実際に中身を編集していなくても、別端末に降りてくる過程で時刻が更新されたように見えるのです。
これに足をすくわれたのが、毎日決まった時間に動く自動処理の「生きているか/止まっているか」の判定でした。
その処理が最後に動いた時刻を、私は単純にファイルの更新時刻で見ていました。すると、本当は毎日ちゃんと動いていたのに「数日前から止まっている」と誤判定してしまったのです。原因は処理が止まったことではなく、iCloud の同期で時刻だけが新しくなったり、逆に古いまま残ったりしていたことでした。
ここから学んだのは、iCloud 配下のファイルでは「いつ更新されたか」を更新時刻で判断しない、という割り切りです。代わりに、その処理が残す履歴そのもの——私の場合は Git のコミット日付——を見るようにしました。コミット日付は、誰かが実際に変更を記録したときの時刻なので、iCloud の同期で勝手に動くことがありません。
「ファイルの時刻は嘘をつくことがあるので、本当の履歴は別のところで持つ」。これは iCloud に限らず覚えておくと良さそうな考え方だと感じています。
落とし穴3: 本体を守る「三重の保険」設計
落とし穴1と2をくぐったうえで行き着いたのが、そもそも本体を iCloud だけに預けない、という設計です。
iCloud Drive で持ち歩けるのは確かに便利です。でも、ここまで書いたとおり、同期は時々ファイルを別名で増やしたり、時刻をいじったりします。「iCloud にしか無い大事なファイル」が同期事故で壊れたら、もう取り返せません。
そこで私は、ソースコードや原稿の本体は Git で履歴管理し、そのGit 管理下のディレクトリ全体を、丸ごと iCloud に置く、という重ね方にしています。図にすると入れ子で、「Git で管理されているフォルダ」を「iCloud が同期する場所」に入れている、というイメージです。
この重ね方には、私が「三重の保険」と呼んでいる効きめがあります。
- 保険1: iCloud が同期事故を起こして本体が空になっても、Git に直前の中身が残っているので戻せる。
- 保険2: あとから「いつ・どこを変えたか」を Git の履歴でたどれるので、おかしくなった時点まで巻き戻して再現できる。
- 保険3: 2台の端末でズレが起きても、Git の差分として「どちらが何を変えたか」が目に見える。雲マークを眺めるよりずっと確実です。
ポイントは、iCloud と Git をどちらか選ぶものとして考えない、ということです。iCloud は「同じファイルパスで2台から開ける手軽さ」を、Git は「壊れても戻せる履歴」を担当する。役割が違うので、重ねて使うほど守りが厚くなる、という関係だと感じています。
ちなみに、この「Git 管理下のフォルダごと iCloud に置く」やり方は、私の環境でうまく回っている方法というだけです。同期のタイミングや道具の仕様によっては別の問題が出るかもしれないので、試すなら小さく始めて、様子を見ながら本格導入するのが安全だと思います。
まとめ
iCloud Drive にプロジェクトをまるごと置く運用は、私にとっては快適です。ただ、同期そのものには独特のクセがあって、
- 重複コピー(
hoge 2.txt型)が本体を空にして、しかも見た目の崩れとしてしか現れないことがある - ファイルの更新時刻は同期で書き換わるので、新旧の判断には使わない
- 本体は Git で履歴を持ち、そのフォルダごと iCloud に置いて二段に守る
このあたりを「そういうものだ」と知ったうえで付き合うと、ずいぶん事故が減りました。仕組みを完璧に把握しているわけではありませんが、踏んだ落とし穴を一つずつメモして潰していく、というのが今のところ私には合っています。
← 他の制作記を見る | トップ | お問い合わせ