数理的手法を使いやすくするためのソフトウェア開発

科学技術計算とデータサイエンスについて

iCloud / Google Drive と git を一緒に使うとリポジトリがおかしくなることがある?

自宅で文書ファイルやソースコードをバージョン管理、バックアップしたり、複数PCで同期させるための 方法を検討しています。 初めは、iCloud あるいは Google Drive にgitリモートリポジトリを置くのが手軽で良いのかも、 と思っていたのですが、危険もあるようです。

1. 背景:iCloud / Google Drive のファイル共有機能は便利だが、バージョン管理機能は貧弱

複数のPCやデバイスの間でファイルを共有するために、 iCloud Drive や Google Driveを私は使っていて、この機能については特に不満はありません。

しかし、git のようなバージョン管理ができないのが残念です。 iCloudファイル復元できるだけであり、Google Driveでは、バージョンを遡るくらいのことはできますが、 下書き用のブランチと、メンテナンス用のブランチを切り替えることはできません。

2. 手法:iCloud / Google Drive を gitリモートリポジトリとして使うのは簡単

そこで、これらのクラウドストレージをgitとともに使う方法を調べてみると、意外と簡単にできることがわかりました。

How to Add iCloud as a Git Repo | MacStadium Blog

Using GIT with Google Drive – a Tutorial

iCloud Drive についてもGoogle Driveについても、やり方は同じで、次の2ステップです。

(1) クラウドストレージ上に git リモートリポジトリを作成
$ mkdir ${CLOUD_STORAGE}/gitRepo/
$ git init --bare ${CLOUD_STORAGE}/gitRepo/your_project.git

ここで、${CLOUD_STORAGE} には、 クラウドストレージに同期させているディレクトリの名前を指定します。

例えば、macOS (ver. 12.4) で Document フォルダを iCloud Drive と同期させている時には、 ${CLOUD_STORAGE} として ~/Library/Mobile\ Documents/com~apple~CloudDocs/を指定すれば良いです。 また、 "Google Drive for Desktop"をインストールして、ローカルなHDDの /Volumes/GoogleDrive/マイドライブ/ ディレクトリを Google Driveと同期させている時には、 そのディレクトリ名を指定すれば良いです。

(2) 作成したリモートリポジトリにローカルプロトコルでアクセスできるように設定

すでに、リモートリポジトリ your_project.gitに対応する、 ローカルリポジトリがあるときには、次のようにします。

$ cd ${YOUR_PROJECT_DIR}
$ git remote add origin ${CLOUD_STORAGE}/gitRepo/your_project.git

ここで、${YOUR_PROJECT_DIR}はローカルリポジトリディレクトリ名です。

そして、git remote add originでは、 リモートリポジトリのURLとしてディレクトリパスを指定します。 (普通は URLをhttps:// ...ssh:// ...のように指定しますが、 同じ計算機のなかにリモートリポジトリがあるときにはディレクトリパスを指定して、 gitはローカルプロトコルでリモートリポジトリにアクセスするようにします。 そして、クラウドストレージ上のリモートリポジトリは、 同じ計算機のなかにあるかのように扱えるので、ディレクトリパスを指定するのです。)

これによって、git push origin mastergit pull origin masterなどは、 クラウドストレージ上のリモートリポジトリに対して行われるようになります。

ちなみに、リモートリポジトリ your_project.gitからローカルリポジトリを複製する時には、次のようにします。

$ git clone ${CLOUD_STORAGE}/gitRepo/your_project.git

3. 考察:クラウドストレージとgitを混ぜるとトラブルが生じるのか?

3.1 iCloud Drive + git の危険性は否定できない

しかし、よくよく調べてみると、iCloud Drive をgit とともに使ってみてトラブルが生じた(余計なファイルやディレクトリが現れた)という報告が見つかりました。

iCloud管理下のフォルダでgitリポジトリをクローン ⇄ rm -rf 繰り返したら、覚えのないファイルが生成されつづけて困った話 - 自分にやさしく学ぶプログラミング

Xcode 11 + project with git + iClo… | Apple Developer Forums

iCloud Driveは何でもかんでも同期されるわけじゃないのね|nnamm.work

3.1.1 トラブルの原因は、iCloudのファイル同期とgitのファイル更新が衝突することがあるから

そして、トラブルシューティングのアドバイスを求める質問に対して、 クラウドストレージとgitを混ぜて使うのは勧められない、と答えている人がいました。

macos - ICloud Drive Desktop Sync vs. Git - deleted files reappear and duplicates with number suffixes - Stack Overflow

Short Answer: Keep your repository folders outside of your iCloud Drive-synced folders, and you should be fine. To be safe, do not combine VCS and file-syncing services together for the same directories/files. Use Github/GitLab/Bitbucket/etc. for synced access and centralised safekeeping.

...
Even Longer Answer: ... In the particular case of the 'iCloud Drive + git' pair, we have a deadly combination: git is very fast at make sweeping changes to entire directory structures, and iCloud Drive is notoriously bad at detecting what has actually changed correctly - and is also very slow at syncing. This means that as git goes about switching branches and updating your working tree, iCloud Drive is likely to wrongly detect that files have changed, when they haven't. It will then tag these files for syncing. But because it is extremely slow at syncing, by the time it's halfway making its first duplicate copies, you might have already made another git change to your repository - which will cause you to now have 'file 3', and then 'file 4' and so on.

Hopefully this might change in the future, but in the meantime, the safest solution is to simply NOT keep your version-controlled repositories in any folder that is automatically synced. In this particular case, if you keep your repositories on any folder that is not 'Documents' or 'Desktop' - and not watched by iCloud Drive - then you should not have an issue with git.

上記回答のなかでは、トラブルが起こるメカニズムも説明されています。 私はiCloud やgitの内部動作に詳しくはないのですが、説明されているようなメカニズムなら、 gitリポジトリ内部のファイル更新と iCloudのファイル更新検知が協調動作しないために、 報告されているように妙なファイルやディレクトリがiCloudによって作られることもありえる、 と思えます。

3.1.2 iCloudがうまく同期できないファイルやフォルダがある

あと、 Appleは「iCloudに appフォルダを入れるべきでない」と公式に注意していて、 .gitは appフォルダのようなものだから、gitリポジトリiCloudに入れるべきではない、という意見もありました。

github - Can Git and iCloud Drive be effectively used together? - Stack Overflow

No, they shouldn’t be used together.

* Apple says “You shouldn’t store app folders, libraries, or .tmp files in iCloud Drive.” .git is an app folder.

ただ、なぜ .gitディレクトリが appフォルダのようなものと見なせるのかは、この投稿に書かれていませんでした。

3.2 Google Drive + git のトラブルは回避可能?

ただ、Google Drive + git については、 iCloud Drive + git のような、確かなトラブル報告は見つかりませんでした。 また、私が Google Drive + Colab + git を一緒に使っていたとき、 別にトラブルには遭遇しませんでした。

それでも、Google Driveをgitと混ぜて使うことの質問に対して、 混ぜて使うのは勧められない、と答えている人はいました。

git - Can I push/pull directly from my google drive online? - Stack Overflow

No, you can't. ...I would also suggest against Google drive/Dropbox based solutions, and go for a git hosting solution instead. ...

... you can put the bare repository inside your local Google Drive/Dropbox folder and work with that, however, there are caveats. The cloud services have their own systems for merging conflicts, and that doesn't really work with git. ...

しかし、 Using GIT with Google Drive – a Tutorial

There is one major caveat that you should know about (not a show stopper, but important to have control over). On some Windows machines, Google Drive can have trouble to synch all the Git files in one go. There’s a simple solution, you just shut down Google Drive and restart it again. It then re-synchs and the remaining files get synched. It’s important to not forget to check this after each git push since otherwise you can mess up the git project files on Google Drive and you’d be left with a mess.

のように、Windows PCでは Google Drive + git でトラブルが起こることが知られているものの、 その回避策はあるようです。

また、

Git + Google Drive = Simple Git Host | by Laura Taylor | Medium

When sharing the Git repository, collaborators should coordinate ‘push’ and ‘pull’ operations to avoid sync conflicts which could leave the Git repository in an unstable state.

のように、Google Drive上のリモートリポジトリを操作する時には、 リモートリポジトリの更新とGoogle Driveのファイル同期が衝突しないように、 複数のpush やpushの操作が重ならないように気をつけるべきで、 さもないと、リポジトリが不安定な状態に陥るようです。

4. どうするか: gitホスティングサービスの無料プライベートリポジトリ

クラウドストレージとgitを混ぜて使うのは、安全なのでしょうか、危険なのでしょうか? 調べてみると意見が分かれるようです。 iCloudについては、トラブルに遭遇したことがないという人はいますが、 トラブル事例を見る限り危険性は否定できないと思います。 そして、gitリポジトリのなかに余計なファイルやディレクトリが勝手に作られるというトラブルは、 かなり重大に思えます。 他方で、Google Driveについては確かなトラブル報告が見つからなかったので、 注意すればトラブルを回避できるのかもしれませんが、不安は残ります。

なので、安全性と確実性をとるなら、 クラウドあるいはオンプレミスのgitホスティングサービスのほうが良いのかもしれません。

GitHub: Where the world builds software · GitHub

Bitbucket | Git solution for teams using Jira

The One DevOps Platform | GitLab

Mac miniで始める「GitLab」入門! | ai-lab

ただ、オンプレミスのGitLabサーバーを構築するのは、 クラウドストレージとgitを混ぜて使うより、はるかに手間がかかるので、悩ましいところです。 しかし、今や、GitLab.com と Bitbucket.org だけでなく、 GitHub.com でも、無料でプライベートリポジトリを作れる ので、 非公開のソースやドキュメントを扱いたい場合でも、 これらのgitホスティングサービスを利用する方がよさそうです。

(それでも、 盗まれたOAuthユーザートークンでGitHubリポジトリからデータ奪う攻撃発生 | TECH+ のようなことが起きているので、重要度の高いgitリモートリポジトリは自宅内のPCに置いて、 外部インターネットからアクセスされないようにしておこうと思います。)