0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

gitレポジトリ内の任意リビジョンのファイルを取り出すピュアJSライブラリとWebサーバ `weboverlay`

Last updated at Posted at 2021-12-27

開発作業中にローカルの git レポジトリ内の古いファイルを参照したいことがあります。
過去のブランチに git switch するのは少し面倒だし、間違えて作業中のファイルを失うことも。
そこで、任意リビジョンの任意ファイルを参照できる Node.js のライブラリや Web サーバを書いてみました。

weboverlay を使えばサーバ1つで、任意のブランチ・コミットにアクセスできるので、たとえば、ブラウザの2つのタブで master ブランチと develop ブランチのウェブサイトを同時に開いて比較することもできます。

(1) JS ライブラリ git-cat-file

標準 git コマンドの git cat-file -p 等の機能をピュア JavaScript (TypeScript) で実装したのが git-cat-file になります。

.git ディレクトリのパス
② ブランチ名やコミットID
③ ファイルのパス

の3点を指定すると、そのファイルのバイナリデータを Buffer で取り出せます。

const {openLocalRepo} = require("git-cat-file");

async function catFile(revision, path) {
  const repo = openLocalRepo("path/to/repository/.git");
  const commit = await repo.getCommit(revision);
  const file = await commit.getFile(path);
  process.stdout.write(file.data);
}

catFile("HEAD", "path/to/file.txt");

git レポジトリの形式としては、非圧縮の loose と git gc で圧縮された packed 形式の両方に対応しています。

(2) Express ミドルウェア serve-static-git

Express.js で静的ファイルを公開するときの app.use(express.static("htdocs")) のミドルウェアの実装 serve-static と同様に、git レポジトリ内に格納された静的ファイルを提供する Express ミドルウェアが serve-static-git になります。

ローカルファイルシステム上の静的ファイルを提供するとき:

const express = require("express");
const app = express();

app.use(express.static("htdocs"));

app.listen(3000);

git レポジトリ内から静的ファイルを提供するとき:

const express = require("express");
const {serveStaticGit} = require("serve-static-git");
const app = express();

app.use(serveStaticGit({
  repo: "path/to/repository/.git",
  root: "htdocs",
}));

app.listen(3000);

raw.githubusercontent.com ではパスでリビジョン(git ブランチ名やコミット ID)を指定するのに対して、
serve-static-git ではリクエストヘッダ Host: の冒頭(サブドメイン名・ホスト名)でリビジョンを指定するため、
絶対パスで記述しているリンクも参照できます。
いまの Chrome 等のモダンブラウザでは xxxx.localhost 形式で任意のホスト名を指定できます。

(例1) main レポジトリ内の htdocs/index.html ファイルを取り出すとき
http://main.localhost:3000/index.html

(例2) develop レポジトリ内の htdocs/css/style.css ファイルを取り出すとき
http://develop.localhost:3000/css/style.css

ただし、hotfix/xxxfeature/xxxrelease/xxx のような記号の入るブランチやタグは、リクエストのホスト名に指定できないため代わりにコミット ID で指定するか、または 210.refs.ts を参考にして refs オプションでリビジョンを指定する定義を指定する必要があります。

(例3) curl で明示的にリクエストヘッダ host: を指定する例:

curl -s -H 'host: feature/xxx' http://localhost:3000/index.html

(例4) リクエストヘッダ x-refs: で指定する例:(※要・refsオプション)

curl -s -H 'x-refs: feature/xxx' http://localhost:3000/index.html

指定したブランチが存在しなかった場合は、HEAD にフォールバックします。
なお、提供できるのは静的ファイルのみです。動的な API などは提供できません。

(3) CLI ワンライナー Web サーバ weboverlay

最後に紹介するのは、ワンライナーで Web サーバを構築できる weboverlay になります。
自前で git-cat-fileserve-static-git を使うコードを書かずに、CLI でサーバを起動できます。

# インストール
npm install weboverlay

# サーバを起動する
node_modules/.bin/weboverlay --port=3000 path/to/repository/.git:htdocs

# Chrome 等でアクセスする
open http://main.localhost:3000/index.html

# curl でアクセスする
curl -s -H 'Host: main' http://localhost:3000/index.html
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?