Git と OneDrive 等のクラウドストレージを併用する

Pocket

ブログに書きたいネタとか雑多なメモを管理する際、Git によるバージョン管理と、クラウドストレージによる同期を併用したくなる。

具体的には、こんなことがしたい:

  • コミットに至らないメモ書きの段階では、クラウドストレージで同期させたい
    • ついでにそのメモ書きは、タブレット等の複数の端末から更新したい
  • ブログで記事を公開してからの差分を Git で管理

プライベートのリモートリポジトリ代わりに、ベアリポジトリを OneDrive に共有する話は見たことある (これ とか これ) のだが、私がやりたいこととはちょっと違うんだよな。
そもそも、 Microsoft 買収後に GitHub で無制限にプライベートリポジトリ作れるようになったので、 Git リポジトリの共有自体は GitHub とかで良いので。

以前、ローカルリポジトリをまるごと OneDrive で共有させてみたのだが、複数の端末で編集すると同期の競合が発生しまくってしまった。
特に .\.git ディレクトリ内でコンフリクトすると後処理が面倒くさすぎる。

どうにかならんもんか。

.\.git ディレクトリだけ同期除外

先に答えを言ってしまうと、クラウドストレージでの同期で特定のディレクトリの同期を除外させれば良い。

.\.git ディレクトリ内のコンフリクトが面倒なら、 .\.git ディレクトリだけ同期を除外させればいじゃない… という精神だ。

ただ、 OneDrive では一筋縄ではいかなかったので、少々トリッキーな方法を採っている。

そのやり方を、 Windows 上の OneDrive を例に紹介する。

1つ目の端末

既に OneDrive で管理しているフォルダを、 Git 管理させる方法。

  1. 同期させたいディレクトリのルート直下に .\.git フォルダを手動で新規作成する
  2. OneDrive の設定から、 アカウント → フォルダの選択 から、 .\.git フォルダーを同期の対象外にする

    • ローカルから .\.git フォルダが消える
  3. git init する
    • .\.git 隠しフォルダが再作成される
  4. 適当に Git のコミットしたり、 remote の追加・プッシュしたりする

この結果、 Git のリポジトリやステージングのデータを除く、ワーキングツリーのファイルだけをクラウドストレージで同期できる。

難点なのが、 OneDrive 上で「同期の問題」として以下のエラーが出続けることだ。

この名前のファイルまたはフォルダーが、同じ場所にあります。
両方のバージョンを残すには、この PCまたはオンラインのどちらかでこのアイテムの名前を変更してください。両方のアイテムが同じ場合は、この PCにあるバージョンを削除するとオンラインのバージョンをダウンロードできます。

なお、エラーが出ていても同期はされる。

2つ目の端末

上記と同様、 OneDrive でワーキングツリーを同期させつつ、 .\.git ディレクトリは同期させないフォルダを、別のマシンに構築する方法。

  1. 一旦、対象ディレクトリを「このデバイス上で常に保持する」を実行して、ファイルをローカルにおいておく

  2. OneDrive の設定から、 アカウント → フォルダの選択 から、 .\.git フォルダーを同期の対象外にする

    • 1つ目の端末の設定で、既に空の .\.git フォルダが存在しているはず
    • 設定後ローカルから .\.git フォルダが消える
  3. 同期を一時停止

  4. clone の替わりに fetch と reset を使い、ワーキングツリーはそのままリポジトリだけ更新する

    $ git init
    $ git remote add origin git@github.com:username/reponame.git
    $ git fetch origin master
    $ git reset origin/master
  5. 同期を再開させる

リポジトリの同期

片方で push した後もう一方で pull しようとしても、先に OneDrive の同期によってワーキングツリーのファイルが更新されてしまっているので、 pull がエラーになってしまう。

こればかりはどうしようもないので、2つ目の端末のセットアップと同様、以下のように ワークツリーを維持したまま、 リポジトリとステージングを (--mixed オプション相当で) リセットしてやれば良い。

$ git fetch origin master
$ git reset origin/master

こんな感じで、期待していた環境が整った。

Android からは Jota+ あたりを使って OneDrive 上のファイルを直接更新したりしながら活用している。

【参考】: OneDrive で特定のファイル名パターンのファイルをアップロードから除外する方法

ちなみに、グループポリシーやレジストリをいじることで、「特定の種類のファイルをアップロードから除外」する事ができる (OneDrive ポリシーを使用して同期設定を制御する - SharePoint in Microsoft 365 | Microsoft Learn)。

が、残念ながらフォルダに対してはこの機能が働かないので、上記の用途を満たさない。

参考までに、やり方だけ下記に示しておく。

レジストリを弄る場合:

  1. HKLM\SOFTWARE\Policies\Microsoft\OneDrive\ の下に EnableODIgnoreListFromGPO というキーを作る
  2. その中に「除外したいファイル名」を名前と値の両方に持った、文字列値(複数可)を入れる
  3. PC を再起動する

グループポリシーを使う場合:

  1. 「グループ ポリシーの編集」を使える状態にする
    • Windows の Pro エディション以上なら標準で入っている。 Home エディションなら、ググって調べて。
  2. C:\Users\N2633\AppData\Local\Microsoft\OneDrive\<ビルド番号>\adm\ 内の以下のファイルをコピーする
    • .\OneDrive.admxC:\Windows\PolicyDefinitions\
    • .\ja\OneDrive.adml を C:\Windows\PolicyDefinitions\ja-JP\
  3. Win+R で gpedit.msc を入力し「ローカル グループ ポリシー エディター」を立ち上げる
  4. [コンピューターの構成] → [管理用テンプレート] → [OneDrive] → [特定の種類のファイルをアップロードから除外] を選択
  5. 構成を有効にして、キーワード一覧に除外したいファイル名(アスタリスク可)を設定する

コメントを残す

メールアドレスが公開されることはありません。

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください