iOSのファイルアプリに直接Gitリポジトリをcloneする方法

iPhoneやiPadでGitHubのリポジトリをちょっと見たい、手元に置いておきたい、ということがたまにあります。iOSにはGitクライアントのアプリもいくつかありますが、Linuxエミュレータの「iSH」を使うと普通にgit cloneコマンドでファイルアプリのフォルダに直接cloneできたので、その手順を備忘録として書いておきます。

iSHとは

iSHはiOS上でAlpine Linuxのシェルを動かせるアプリです。App Storeから無料でインストールできます。x86のユーザーモードエミュレーションで動いているのでそれなりに遅いですが、apkでパッケージを入れて普通にコマンドが使えます。

ポイントは、iSHにはmount -t iosという独自のマウント機能があって、iOSのファイルアプリ上の任意のフォルダをLinux側のディレクトリとしてマウントできることです。これを使うとiSH内で作ったファイルがそのままファイルアプリから見えるようになります。

手順

1. iSHをインストールしてgitを入れる

App StoreからiSHをインストールして起動し、まずパッケージ一覧を更新してgitを入れます。

apk update
apk add git

2. ファイルアプリのフォルダをマウントする

マウント先のディレクトリを作ってから、mount -t iosでマウントします。デバイス名の部分(.)はダミーなので何でも構いません。

mkdir -p /mnt/files
mount -t ios . /mnt/files

コマンドを実行するとiOSのフォルダ選択画面が出てくるので、cloneしたい場所のフォルダ(例えば「このiPhone内」や「iCloud Drive」の中に作ったフォルダ)を選びます。選んだフォルダが/mnt/filesとしてマウントされます。

cd /mnt/files
ls

で中身が見えていればOKです。

3. git cloneする

あとは普通にcloneするだけです。

cd /mnt/files
git clone https://github.com/ユーザー名/リポジトリ名.git

終わったらファイルアプリを開くと、選んだフォルダの中にリポジトリのフォルダができています。あとはファイルアプリ対応のエディタアプリなどから直接開けます。

公開リポジトリならこれだけで終わりです。プライベートリポジトリの場合は認証が必要なので次の項を参照してください。

SSHでGitHubに接続する

プライベートリポジトリをcloneしたりpushしたりするには認証が必要です。HTTPSの場合はGitHubのパスワードではなくPersonal Access Tokenが必要で毎回入力するのも面倒なので、SSH鍵で接続するのがおすすめです。

なお、PCでよく使うgh auth loginでのログインはiSHでは使えません。GitHub CLI(gh)はiSHの環境では動かないので、SSH鍵を手動で作ってGitHubに登録する方法でいきます。

1. opensshをインストールする

iSHのAlpineにはデフォルトでSSHクライアントが入っていないので、apkで入れます。

apk add openssh

2. SSH鍵を作る

ssh-keygen -t ed25519 -C "メールアドレス"

保存先やパスフレーズを聞かれるのでそのままEnterで進めると、~/.ssh/id_ed25519(秘密鍵)と~/.ssh/id_ed25519.pub(公開鍵)ができます。

3. 公開鍵をGitHubに登録する

公開鍵の中身を表示してコピーします。

cat ~/.ssh/id_ed25519.pub

iSHの画面で長押しするとテキストを選択してコピーできるので、ssh-ed25519から始まる1行をコピーして、GitHubの Settings → SSH and GPG keys → New SSH key に貼り付けて登録します。

4. SSHのconfigを編集する

GitHubに接続するときに使う鍵を指定するために、~/.ssh/configを作ります。iSHにはGUIのエディタがないのでviで編集します。

vi ~/.ssh/config

viが開いたらiキーで入力モードにして、以下を書きます。

Host github.com
  HostName github.com
  User git
  IdentityFile ~/.ssh/id_ed25519

書き終わったらEscキーでコマンドモードに戻り、:wqと入力してEnterで保存して終了します。

パーミッションが緩いとSSHに怒られるので、念のため絞っておきます。

chmod 700 ~/.ssh
chmod 600 ~/.ssh/config ~/.ssh/id_ed25519

5. 接続を確認する

ssh -T git@github.com

初回は接続してよいか聞かれるのでyesと答えます。Hi ユーザー名! You've successfully authenticated...と出れば成功です。

6. gitのユーザー情報を設定する

commitするなら名前とメールアドレスも設定しておきます。

git config --global user.name "名前"
git config --global user.email "メールアドレス"

~/.gitconfigを直接いじりたい場合は、これもvi ~/.gitconfigで編集します。

7. SSHのURLでcloneする

あとはHTTPSではなくSSHのURLでcloneすればOKです。

cd /mnt/files
git clone git@github.com:ユーザー名/リポジトリ名.git

注意点

マウントはiSHを終了しても外れない

mount -t iosでのマウントはiSHアプリを終了しても保持されます。次に起動したときも/mnt/filesにそのままアクセスできるので、毎回フォルダを選び直す必要はありません。マウントを外したいときはumount /mnt/filesで解除できます。

速度はかなり遅い

エミュレーションな上に、iosマウント越しのファイルアクセスはさらに遅いです。大きいリポジトリをcloneするとかなり時間がかかるので、履歴がいらないなら--depth 1をつけることをおすすめします。

git clone --depth 1 https://github.com/ユーザー名/リポジトリ名.git

新しめのiSHではmount -t ios-unsafeというオプションもあり、こちらのほうが速いです(名前の通り安全性と引き換えなので、ファイルの同時アクセスには注意)。

iCloud Driveのフォルダは注意

iCloud Drive上のフォルダにcloneすると.gitフォルダの中の大量の小さいファイルも全部同期対象になります。同期が終わるまで他の端末で中途半端な状態に見えたり、ダウンロードされていないファイルがあってgitコマンドがエラーになったりするので、できれば「このiPhone内」の方にcloneしたほうが無難です。

別のやり方:iSH自身のフォルダをファイルアプリから開く

実はiSHのファイルシステム自体がファイルアプリの「場所」として表示されます。なのでマウントせずにiSHのホームディレクトリにcloneして、ファイルアプリ側からiSHのフォルダを開く、という逆のやり方もできます。

cd ~
git clone https://github.com/ユーザー名/リポジトリ名.git

こちらのほうがcloneは速いです。ただしiSHをアンインストールすると全部消えるので、長く残しておきたいものはやはりファイルアプリ側にマウントしてcloneするか、あとでコピーしておくのがいいと思います。

自分の使い方:Spotifyのローカルファイルをgitで管理する

あまりいい方法ではないと思いますが、自分はSpotifyのローカルファイル(Spotifyで配信されていない音源)をgitリポジトリで管理していて、それをiPhoneのSpotifyフォルダに直接cloneしています。

iPhoneのSpotifyアプリにローカルファイルを入れるには、ファイルアプリの「このiPhone内」にある「Spotify」フォルダに音声ファイルを置く必要があります。普段はPCからケーブルでつないで転送するところですが、mount -t iosでこのSpotifyフォルダをマウントしてしまえば、iSHから直接git cloneやgit pullで音源を持ってこられます。

mkdir -p ~/ios/spotify
mount -t ios . ~/ios/spotify   # フォルダ選択で「このiPhone内」→「Spotify」を選ぶ
cd ~/ios/spotify
git clone --depth 1 git@github.com:ユーザー名/music.git

Spotifyフォルダの直下ではなく、その中のmusicフォルダとしてcloneしています。Spotifyはサブフォルダの中の音源も拾ってくれるので、Spotifyフォルダ直下に.gitを置くより見た目がすっきりします。

PC側で音源を追加してpushしたら、iPhone側でiSHを開いてgit pullするだけで同期できるのでケーブルいらずです。

ただ、音声ファイルのようなバイナリをgitで管理するのはリポジトリが肥大化する一方で履歴の意味もほぼないですし、速度も遅いので、本来はクラウドストレージなどで同期するのが素直だと思います。gitに慣れているから使っているだけ、くらいに思ってください。

まとめ

  • iSHを入れてapk add git
  • mount -t ios . /mnt/filesでファイルアプリのフォルダをマウント
  • マウント先でgit clone
  • プライベートリポジトリはapk add opensshで鍵を作ってSSH接続(ghは使えない、設定ファイルはviで編集)

これだけでiPhoneやiPadのファイルアプリに直接リポジトリを置けます。速度が遅いのが難点ですが、マウントはiSHを終了しても残るので、一度設定してしまえばあとはPCと同じ感覚でgit pullやgit pushができて便利でした。