Posted at

skeletonリポジトリを継続的に適用するgitサブコマンド git-skel


はじめに

ここで言うskeletonリポジトリとは、何かのプロジェクトを始めるときに、定型的に必要なディレクトリやスクリプト、テンプレートの類いを格納したリポジトリです。GitHub上でもskeletonで検索するとたくさん見つかります。

こういったリポジトリを使う際は、最初にcloneしてoriginを自分のリポジトリに書き換えたり、あるいは単にファイルコピーしたりすると思いますが、元のskeletonリポジトリの更新に追従するのは結構厄介な問題です。

gitの機能を使うならpull先を変えたりcherry-pickで変更を取り込むことは可能ですが、簡単にできるという感じでもありません。

そこで外部のskeletonリポジトリを簡単に取り込めるgitのサブコマンドを作りました。

実装言語はRustです。

https://github.com/dalance/git-skel/


インストール

Linux/macOS/Windows向けのバイナリはReleasesからダウンロードするか、

Rustがインストール済みでcargoコマンドが使える方は以下でインストールできます。

$ cargo install git-skel


使い方

ディレクトリ作成、gitリポジトリ作成、skeleton適用して最後に適用前に状態の戻すまでの流れをデモ画像にしてみました。


基本的なフロー

skeletonリポジトリ(http://example.com/skeleton.git)をプロジェクトリポジトリ(http://example.com/project.git)に適用する場合を例に説明します。

初回は適用したいリポジトリにてgit skel initを実行します。

$ git clone http://example.com/project.git

$ cd project
$ git skel init http://example.com/skeleton.git

すると、skeletonリポジトリの内容がプロジェクトリポジトリのリポジトリルートに展開されます。

また、そのURLとその時のリビジョンを.gitskel.tomlに書き込みます。

展開結果に問題なければ展開されたファイルを追加してコミットしてください。

skeletonリポジトリに更新があった場合は

$ cd project

$ git skel update

で取り込めます。

これもgit diffなどで確認して問題なければコミットです。

このようにgit-skelはファイル操作しかしないので、実際にコミットする、しないはユーザー判断になっています。

また、ファイル操作の結果、何かが失われる可能性がある場合はデフォルトではなにもしません。

例えば、あるファイルが変更されて未コミットのとき、そのファイルをgit-skelコマンドが上書きしそうなら、上書きせずに中断します。オプション(--force)で強制も可能です。


.gitskelignore

このコマンドの対象にしたくないファイルは.gitskelignoreで指定することができます。フォーマットは.gitignoreと同じです。

このファイルはskeletonリポジトリとプロジェクトリポジトリの両方に置くことができます。

skeletonリポジトリに置く場合は、例えばREADME.mdLICENSEなどskeletonリポジトリそのものについてのファイルや、説明用のサンプルファイルなどを指定するといいと思います。

プロジェクトリポジトリに置く場合は、そのプロジェクト用にカスタマイズしたファイルを指定することで、更新による上書きを防ぐことができます。


branch/tag

skeletonリポジトリの特定のブランチやタグに追従するよう設定することもできます。

$ cd project

$ git skel branch branch1
$ git skel tag tag1

git skel branchgit skel tagコマンドを実行すると、そのブランチ・タグの内容を取り込んで.gitskel.tomlを更新します。

また、それ以降git skel updateを実行した場合、追従するよう設定したブランチ・タグの最新に追従します。


クリーンアップ

プロジェクトリポジトリからskeletonリポジトリの内容を取り除きたい場合はgit skel cleanが使えます。

$ cd project

$ git skel clean

これでプロジェクトリポジトリに展開されたskeletonリポジトリの内容を全て削除したうえで.gitskel.tomlも削除します。