Git foreign data wrapper
This is unreleased software made to scratch a very specific itch. The intention is to polish this into production grade code with support for qual pushdown support.
The name "ekorre" is Swedish for squirrel, since squirrels like Git are good at jumping between branches.
This repository also contains a CloudNativePG image-volume extension image
definition under containers/ekorre. The GitHub Actions
workflow publishes multi-architecture images for PostgreSQL 18 on Debian
trixie to ghcr.io/sxd/ekorre whenever main is updated.
Use the extension image together with a matching CloudNativePG PostgreSQL image. For the current build, that means:
- PostgreSQL image:
ghcr.io/cloudnative-pg/postgresql:18-minimal-trixie - Extension image:
ghcr.io/sxd/ekorre:1.0.0-18-trixie
The PostgreSQL major version and Debian distribution must match between the cluster image and the extension image.
Image volume extensions require PostgreSQL 18 or later. They also require
Kubernetes 1.35 or later, or Kubernetes 1.33/1.34 with the ImageVolume
feature gate enabled.
Example Cluster manifest:
apiVersion: postgresql.cnpg.io/v1
kind: Cluster
metadata:
name: cluster-ekorre
spec:
imageName: ghcr.io/cloudnative-pg/postgresql:18-minimal-trixie
instances: 1
storage:
size: 1Gi
postgresql:
extensions:
- name: ekorre
image:
reference: ghcr.io/sxd/ekorre:1.0.0-18-trixie
ld_library_path:
- systemIf you want the cluster to come up already configured against the upstream
PostgreSQL Git repository, the best fit is bootstrap.initdb.postInitApplicationSQL
because it can create the extension and import the foreign schema in one pass:
apiVersion: postgresql.cnpg.io/v1
kind: Cluster
metadata:
name: cluster-ekorre
spec:
imageName: ghcr.io/cloudnative-pg/postgresql:18-minimal-trixie
instances: 1
storage:
size: 1Gi
bootstrap:
initdb:
database: app
owner: app
postInitApplicationSQL:
- CREATE EXTENSION IF NOT EXISTS ekorre;
- CREATE SERVER git_server FOREIGN DATA WRAPPER ekorre OPTIONS (owner 'app');
- |
IMPORT FOREIGN SCHEMA git
FROM SERVER git_server
INTO public
OPTIONS (
repo_url 'https://github.com/postgres/postgres.git',
branches 'master, REL_14_STABLE, REL_15_STABLE, REL_16_STABLE, REL_17_STABLE, REL_18_STABLE',
root_branch 'master',
include_diff 'false',
max_commits '2000'
);
- CREATE OR REPLACE VIEW public.git_log AS SELECT * FROM public.git_log_master;
- ALTER VIEW public.git_log OWNER TO app;
postgresql:
extensions:
- name: ekorre
image:
reference: ghcr.io/sxd/ekorre:1.0.0-18-trixie
ld_library_path:
- systemAs of April 12, 2026, https://github.com/postgres/postgres.git still uses
master as its default branch.
The owner 'app' option on CREATE SERVER tells ekorre to assign imported
foreign tables to app during IMPORT FOREIGN SCHEMA. You can also provide
owner 'app' directly in the IMPORT FOREIGN SCHEMA ... OPTIONS (...) list
if you want a per-import override. The helper git_log view is separate from
the FDW import, so the example still alters that view owner explicitly.
If you only want declarative extension installation and will manage the FDW
objects yourself later, use the CloudNativePG Database resource:
apiVersion: postgresql.cnpg.io/v1
kind: Database
metadata:
name: cluster-ekorre-app
spec:
name: app
owner: app
cluster:
name: cluster-ekorre
extensions:
- name: ekorre
version: "1.0.0"If you manage schema setup manually instead of using the Database resource,
connect to the database after the cluster is running and execute:
CREATE EXTENSION ekorre;The extension image contains only the extension artifacts, required runtime
libraries, and bundled license files. License texts are available under
/licenses/ inside the mounted image volume.
CREATE EXTENSION ekorre;
CREATE SERVER git_server FOREIGN DATA WRAPPER ekorre;
IMPORT FOREIGN SCHEMA git
FROM SERVER git_server
INTO public
OPTIONS (
repopath '/path/to/gitrepo',
branches 'branch_name, feature_branch',
root_branch 'branch_name',
include_diff 'false',
max_commits '2000'
);
SELECT * FROM git_log_branch_name;
SELECT * FROM git_log_feature_branch;Remote public repositories can be imported with repo_url instead of
repopath:
IMPORT FOREIGN SCHEMA git
FROM SERVER git_server
INTO public
OPTIONS (
repo_url 'https://github.com/postgres/postgres.git',
branch 'master'
);Use include_diff 'false' to skip per-commit diffstats during scans.
Use max_commits to cap branch history for faster interactive exploration.
Set max_commits '0' for an unlimited scan.
repo_url accepts public http://, https://, git://, and file://
repositories only. The first scan creates a persistent bare mirror under
$PGDATA/ekorre-mirror-cache; later scans use the cached mirror immediately
and trigger a background refresh in a detached process.
The helper bootstrap script also creates git_log_all, which adds a branch
column and keeps only commits unique to non-master branches.