GitHub リポジトリのバックアップと移行

GitHub の有料プランは利用しているプライベートリポジトリの数によって料金が変わってきます。使わなくなったリポジトリは、ローカルや自分のサーバにバックアップして削除してしまうのが賢く使うコツです。

以下に GitHub のリポジトリをバックアップして、自分のサーバ上にリポジトリを移行して開発を続ける方法を紹介します。

1. バックアップ

バックアップするだけで再利用しないのならば、以下のコマンドだけでOKです。このディレクトリを適宜 zip などで圧縮して保存しておけば良いでしょう。

$ git clone --mirror git@github.com:weboo/project.git
$ zip -r project.git.zip project.git

2. 自分のサーバで開発を続ける

リポジトリを自分のサーバに移行して開発を続けるには、1.でバックアップしたファイルをサーバにコピーして展開した後に git --bare init コマンドを実行します。

$ unzip project.git.zip
$ cd project.git
$ git --bare init

3. 開発用PCで git clone

開発用のPCで git clone するのは特に変わったことはありません。2.で作成した新リポジトリのパスに注意して clone するだけです。これで、GitHubでのコミットログやブランチを維持したまま今まで通りに開発を続けられます。

$ git clone user@example.com:repos/project.git

※example.com サーバの /home/user/repos/project.git に展開した場合

もし、cloneし直さずに既に存在するワーキングディレクトリをそのまま利用したい場合は、以下のようにしてリモートリポジトリを変更します。

$ git remote set-url origin user@example.com:repos/project.git
$ git remote -v
origin  user@example.com:repos/project.git (fetch)
origin  user@example.com:repos/project.git (push)

以上でバックアップ&移行は完了です。これで安心して GitHub から不要になったリポジトリを削除することができますね。

もしくは、プライベートリポジトリが無料で作り放題の BitBucket ならブラウザ上から必要な項目を入力するだけで簡単に移行できるので、いっそのこと BitBucket に完全移行しちゃうというのもお勧めです。

NSUserDefaults と NSKeyedArchiver と KeyChain の速度比較

ちょっと気になったので調べてみた。

使ったのはこんなデータ

NSDictionary *data = @{
    @"spam": @"Lorem ipsum dolor sit amet, consectetur adipiscing elit.",
    @"egg" : @123456,
    @"ham" : [NSDate date],
};

このデータを実機(iPhone5)で1,000回読み書きした時の時間をそれぞれ計測した結果がこれ。まあ予想通りというか KeyChain が一番遅い。

KeyChain はセキュアなデータを保存するためのもので、永続化のためにカジュアルに利用するべきではない。NSUserDefaults の read が速いのは繰り返し読む場合にメモリに載ってるからかな。普通は繰り返し読み込むデータは何度もファイルから読み出したりはしないので、ArchiveToFileにキャッシュする機能を付ければその差は無視できそう。

読み書きする部分のコードはこちら。KeyChain に関しては、LUKeychainAccessというライブラリを利用した。NSUserDefaults のように簡単に使えてセキュアに保存できるのでとても便利。自分はこれを API Token の保存に利用している。

- (void)writeUserDefaults
{
    NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
    [userDefaults setObject:self.data forKey:@"data"];
    [userDefaults synchronize];
}

- (void)readUserDefaults
{
    NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
    self.data = [userDefaults objectForKey:@"data"];
}

- (void)writeArchiveToFile
{
    [NSKeyedArchiver archiveRootObject:self.data toFile:pathToArchive];
}

- (void)readArchiveToFile
{
    self.data = [NSKeyedUnarchiver unarchiveObjectWithFile:pathToArchive];
}

- (void)writeKeyChain
{
    [[LUKeychainAccess standardKeychainAccess] setObject:self.data forKey:@"data"];
}

- (void)readKeyChain
{
    self.data = [[LUKeychainAccess standardKeychainAccess] objectForKey:@"data"];
}