ブラウザIDEでGitHub同期を実践する方法

ブラウザIDEはセットアップをなくすのが得意です。しかし、その次の段階、つまり作業をブラウザプロファイルの外に永続的な場所へ置くことになると、話は別です。そこで通常はターミナルが登場します。git init、remote add、commit、push。ブラウザIDEのGitHub同期はこの流れをパネル一つにまとめますが、魔法でも完全なGitクライアントでもありません。ブラウザストレージにあるプロジェクトとGitHubにあるリポジトリをつなぐ、焦点を絞った橋です。この記事では、GB Coderでその橋がどう動くか、何がアップロードされるか、競合やトークンをどう扱うか、そしてデスクトップのGitワークフローが今も適している場面を説明します。

1. ブラウザIDEにGitHubが必要な理由

ブラウザ上のプロジェクトが便利なのは、フォルダもランタイムもインストールも不要だからです。その同じ性質が弱点になります。プロジェクトはブラウザプロファイルの中にあり、クリーンアップツールで消えたり、端末の紛失とともに失われたり、別のコンピュータに移ったときに置き去りにされたりします。ZIPを書き出せばコピーは作れますが、ZIPは履歴も共有リモートもないスナップショットです。GitHubは不足している層を提供します。端末の外にあるリポジトリ、コミット履歴、共同作業の場、そしてCIやデプロイの自然な供給元です。これによりブラウザIDEの役割が変わります。使い捨てのメモ帳ではなく、小さなプロジェクトを書き、見直し、引き渡す場所になります。この流れは、Chromebook、学校の実習室、Gitをインストールできないロックダウンされた社用ノートPCで特に役立ちます。後からデスクトップのリポジトリへ移す可能性がある簡単なプロトタイプにも向いています。最初の草稿はブラウザが担い、GitHubがそれを永続化します。

2. 同期ができること、できないこと

GB CoderにはGitHubの操作が3つあります。Push、New repo、Pullです。Pushは現在のプロジェクトを既存のリポジトリとブランチへ書き込みます。New repoは接続中のGitHubアカウントにリポジトリを作成し、プロジェクトを最初の内容としてコミットします。Pullはブランチを読み、テキストファイルをエディタへインポートします。すべてのリクエストはブラウザからapi.github.comへ直接送られ、LadeStackのサーバーが間に立ってトークンを保持することはありません。この狭い範囲は意図的です。このパネルはGitコマンドラインの代替ではありません。rebase、マージコンフリクトの解決、サブモジュール、Git LFS、署名付きコミット、フック、複数のリモートは提供しません。コミットグラフ全体も表示しません。複雑なリポジトリではこれらの制限が重要になります。静的なページ、Reactのプロトタイプ、教材、小さなユーティリティといった一般的なブラウザプロジェクトでは、3つの操作がタブの外で本当に必要な部分をカバーします。

3. 適切なスコープのトークンを作成する

GitHub同期はパスワードでもGB Coderのアカウントでもなく、パーソナルアクセストークンを使います。クラシックトークンにはrepoスコープが必要です。fine-grainedトークンにはContentsの読み取りと書き込み権限が必要で、単一のリポジトリに限定できます。狭いほうが安全な既定値です。トークンが漏れても、被害は到達できるプロジェクトに限定されます。接続画面はGitHubのトークンページへのリンクを示し、両方の選択肢を説明します。トークンを貼り付け、端末に記憶するかどうかを選び、Connectを押します。GB Coderはアカウントとリポジトリ一覧を取得して検証し、サインイン中のログイン名と残りのAPIレート制限を表示します。Pushまたはリポジトリ作成を確定するまで、リポジトリには何も書き込まれません。トークンはパスワードのように扱ってください。issue、チャット、スクリーンショットに貼り付けず、不要になったらGitHubで失効させます。有効期限があり、1つのリポジトリだけにアクセスできるトークンは、この流れに妥当な妥協点です。

4. 最初のPushで実際に送られるもの

Pushタブでは、リポジトリ、ブランチ、コミットメッセージ、そしてプロジェクトに存在しないファイルを削除するかどうかのオプションを指定します。何かがブラウザを出る前に、パネルはファイル数と合計サイズを表示します。アップロードはエディタのタブをそのまま吐き出すわけではないので、このプレビューは役に立ちます。GB CoderはZIP書き出しやデプロイと同じアーカイブビルダーを使います。シンプルなHTML/CSS/JavaScriptプロジェクトはindex.html、style.css、script.js、READMEになります。ReactまたはVueプロジェクトは、index.html、package.json、vite.config.js、.gitignore、README、src/以下のソースファイルというVite形式のリポジトリになります。依存関係のフォルダやビルド出力は含まれません。コミットメッセージは編集でき、既定値は「Update from GB Coder」です。存在しないファイルを削除するオプションは既定でオフです。リポジトリを現在のプロジェクトと完全に一致させたい場合だけオンにしてください。ローカルに存在しないリモートファイルが削除されるためです。最初のPushでは、意図的に別ブランチを作りたい場合を除き、リポジトリの既定ブランチを選びます。

5. アトミックコミットと変更なしファイルのスキップ

素朴なブラウザ同期は1ファイルずつコミットします。すると履歴が煩雑になり、途中でリクエストが失敗するとリポジトリが半端に更新されたままになります。GB Coderは代わりにGitHubのGit Data APIを使います。blobをアップロードし、ブランチの現在のツリーの上にツリーを構築し、1つのコミットを作成してブランチ参照を移動します。その結果、Pushごとに1つのアトミックなコミットができ、削除オプションによる削除も含まれます。2つ目の最適化は地味ですが同じくらい重要です。Gitはファイル内容をSHA-1ハッシュで識別し、ブラウザはWebCryptoでそのハッシュをローカル計算できます。GB Coderはアップロード前にローカルファイルと対象ツリーを比較します。変更のないファイルはAPI呼び出しを消費せず、何も変わっていないPushは空のコミットを作らず「already up to date」を返します。これにより履歴が読みやすく保たれ、APIの予算を本当の変更のために残せます。小さなプロジェクトでは差は見えませんが、数十ファイルのプロジェクトでは、きれいな同期と遅くて騒がしい同期の差になります。

6. ブラウザを離れずにリポジトリを作成する

New repoタブは接続中のアカウントにリポジトリを作成します。名前と任意の説明を入力し、公開か非公開を選び、GitHubがREADMEでリポジトリを初期化するかどうかを決めます。空のリポジトリには最初のPushの土台となるブランチの先端がないため、初期化は既定でオンです。GB Coderはそのシードコミットを使い、READMEをプロジェクト自身のファイルで置き換え、最初のコミットを記録します。初期化をオフにすると、ルートコミットと既定ブランチの参照を自分で作成します。作成後は新しいリポジトリと既定ブランチが次のPush用に選択されるので、二度目の設定は不要です。アイデアから非公開でバージョン管理されたリポジトリへの最短経路です。授業の課題、非公開にしたいクライアント向けデモ、CIサービスのURLが必要なプロトタイプに向いています。リポジトリはトークンを所有するGitHubアカウントに属し、LadeStackのものではありません。作成後はGitHubで管理、移管、削除できます。

7. リポジトリをエディタへ戻す

Pullは帰りの旅です。リポジトリのURLまたはowner/nameの組を入力し、ブランチを選ぶと、GB Coderがブランチツリーを読みます。エディタで意味のある形で開けるテキストファイル、つまりソースコード、JSON、Markdown、設定、SVGなどをインポートします。node_modules、dist、build、.git、.next、coverageディレクトリはスキップします。Pullは200ファイル、1ファイル512KBまでに制限されています。どちらかの上限を超えると、パネルは黙って捨てずに、何ファイルが除外されたかを表示します。改行コードは正規化されるので、Windowsで作成したファイルが全行変更されたように見えることはありません。インポートしたファイルがすぐにプロジェクトを上書きすることはありません。ZIPインポートと同じレビューと適用の流れを通るため、変更を確定する前に検出された構造を確認でき、後から元に戻せます。したがってPullは、別の端末で作業を続ける、編集前にリポジトリを確認する、ブラウザストレージが消えた後にプロジェクトを復元するといった用途に向いています。これはインポートでありマージではありません。現在のプロジェクトとブランチが分岐している場合は、結果を慎重に確認してください。

8. 競合、レート制限、正直な失敗モード

最も重要な安全特性は、編集中にリモートブランチが進んだときに何が起こるかです。GB Coderはブランチ参照をforce無効で更新します。その間に誰かがPushしていた場合、GitHubは更新を拒否し、パネルはその人の作業を黙って破棄せず競合を報告します。解決はあえて手動です。最新のブランチをプロジェクトにPullし、ファイルを確認してから再度Pushするか、本格的なマージのためにデスクトップのGitクライアントへ移ります。その他の失敗は、メッセージに基づいて行動できるよう分類されます。期限切れのトークンは認証エラーとなり、再接続を求めます。レート制限ではGitHubのクォータがいつリセットされるかを表示します。APIは認証済みユーザーに1時間5,000リクエストを許可し、Pullはファイルごとに1リクエストを消費します。存在しないリポジトリやブランチはnot-foundエラーになります。リクエストは60秒でタイムアウトし、長い操作はパネルからキャンセルできます。これらの細部は華やかではありませんが、信頼できる同期ツールと、曖昧な失敗をするツールの差になります。

9. トークンの安全性:既定ではセッションのみ

トークンは価値の高い認証情報です。書き込み権限を持つGitHubトークンは、到達できるすべてのリポジトリを変更できます。GB Coderは貼り付けたトークンを既定でモジュールスコープのマップに保持します。つまりタブを閉じると消え、localStorageには書き込まれません。「Remember on this device」オプションは明示的なオプトインです。有効にし、ページがセキュアコンテキストであれば、トークンは保存前にインストールごとのランダムな鍵でAES-GCMにより封印されます。これにより、ブラウザプロファイルのバックアップ、同期されたプロファイル、共有マシン、開発者ツールのスクリーンショット、サポートバンドル内でトークンが読める状態になることを防ぎます。同じオリジンで実行できるスクリプトには防御できません。そのスクリプトは同じストレージモジュールを呼べるからです。ブラウザだけで完結する設計では完全には解決できません。したがって実務上の制御はスコープ、有効期限、失効です。必要なリポジトリに限定したfine-grainedトークンを使い、有効期限を設定し、作業が終わったらGitHubでトークンを削除します。GitHubの通信はブラウザからapi.github.comへ直接送られ、LadeStackが認証情報を保持する必要はありません。ブラウザストレージは依然としてバックアップではないので、リポジトリは端末外のコピーとしても合理的です。

10. このワークフローが十分な場合とそうでない場合

GitHub同期は、ブラウザプロジェクトの大部分には十分です。静的サイト、ReactやVueのプロトタイプ、授業の演習、小さな社内ツール、リモートとデプロイ元が必要なデモなどです。Gitをインストールせずにバージョン管理をしたい個人開発者、再現可能な引き渡しが必要な教師、ターミナルがないマシンで作業する人に向いています。サブモジュールを含むモノレポ、Git LFSに依存するリポジトリ、署名付きコミットや詳細なコミット履歴のレビューが必要なチーム、フックと複数のリモートに基づくリリース流程には十分ではありません。それらはデスクトップGitの仕事であり、そうでないふりをするとブラウザの流れが悪くなります。有用なのはハイブリッドなパターンです。最初のプレビューがすぐ得られるのでブラウザで始めます。残す価値のある形になったらPushします。ネイティブツール、より深いデバッガ、完全なGitワークフローが必要になったら、同じリポジトリをデスクトップで開きます。ブラウザに戻るときはGitHub経由で変更をPullします。ファイルは通常のソースファイルなので、引き渡しは移行ではなくバージョン管理です。ブラウザ側を試すには、/app/projectsのProjects Dashboardを開き、プロジェクトを作成し、GitHub syncを開いて最初のコミットをPushしてください。完全なセットアップと機能リファレンスはドキュメントにあります。