A PostgreSQL-native Git implementation.
Status markers — every entry below carries one.
- ✅ Implemented: exported by
sql/functions/*.sqlorsql/pgit-*.sql, and does the work in the database.⚠️ Partial: exported and callable, but a named part of it is a placeholder. The note says which part.- 🧭 Planned / Aspirational: mentioned for roadmap completeness, not exported as a callable function.
- ✅ Repository initialization (
init_repository) - ✅ File staging (
stage_file,unstage_file) - ✅ Commit creation (
commit_index) - ✅ Commit history and status (
get_log,get_decorated_log,get_status,get_formatted_status) - ✅ Branch management (
create_branch,list_branches,checkout_branch) - ✅ Diff operations (
diff_text,diff_blobs,diff_commits) - ✅ Reset operations (
reset_soft,reset_mixed,reset_file) - ✅ Tag operations (
create_tag,list_tags) - ✅ Merge conflict detection (
can_auto_merge,detect_conflicts) ⚠️ Merge (find_merge_base,can_fast_forward,merge_branches) — fast-forward only;merge_branchesraisesOnly fast-forward merges are currently supportedon a divergent history⚠️ Remote operations (add_remote,fetch_remote,pull,clone,push) —pushresolves the ref and raises a notice; it does not transfer objects to the remote
- ✅ Stash management (
stash_save,stash_pop) - ✅ Worktree support (
add_worktree) - ✅ Commit notes (
add_note) - ✅ Blame tracking (
blame) - ✅ Bisect debugging (
bisect_start,bisect_good,bisect_bad,bisect_reset) - ✅ Cherry-pick and revert (
cherry_pick,revert) - ✅ Grep functionality (
grep) - ✅ Submodule support (
submodule_add,submodule_update,submodule_update_recursive) - ✅ Sparse checkout for large repositories (
sparse_checkout_set,sparse_checkout_add,is_path_in_sparse_checkout,get_tree_files) - ✅ Reuse recorded resolution / rerere (
record_resolution,find_resolution,clear_rerere_cache) - ✅ Tree-level merge (
merge_trees) - ✅ Whatchanged view (
whatchanged) - ✅ Repository diagnostics (
collect_diagnostics,get_diagnostic_report) - ✅ Object replacement (
replace,get_replaced_hash,remove_replace,list_replace) - ✅ Pack refs optimization (
pack_refs,unpack_refs,verify_packed_refs) - ✅ Repack support (
repack,unpack) - ✅ Bundles (
create_bundle,unbundle) - ✅ HTTPS transport and credential storage (
store_credentials,http_fetch) — the only feature that needsplpython3u ⚠️ Archive creation (create_archive) — walks the tree and concatenates blob contents, but the tar/zip headers are placeholders, so the result is not a valid archive fortar/unzip⚠️ GPG signature verification (add_gpg_key,sign_commit,verify_commit,sign_tag,verify_tag,verify_all_tags) — stores signatures and enforces key trust levels, but performs no cryptographic verification: any stored signature is reported valid⚠️ Instaweb interface (generate_repo_view,start_instaweb,stop_instaweb) — renders repository HTML and records the listener config, but starts no web server;start_instawebreturns the URL it would serve on
- ✅ Schema migration helpers (
get_current_schema_version,run_migration) - ✅ Garbage collection (
gc) - ✅ Repository integrity checks (
verify_integrity) - ✅ Index maintenance / optimization (
optimize_indexes) - 🧭 Reflog
- 🧭 File system check (beyond what
verify_integritycovers)
- ✅ Tree/index plumbing (
create_tree_from_index) - ✅ Object and history plumbing (
cat_file,hash_object,ls_tree,rev_list,merge_base)
The pg_git.control file provides PostgreSQL with metadata about the
extension and instructs it to load sql/pg_git--0.5.0.sql when the
extension is created. Both the control file and the SQL script are
installed by make install. The install script is generated from the
modular fragments under sql/schema/, sql/functions/ and sql/pgit-*.sql
(run make to regenerate it); editing it by hand is not recommended.
Schema name: the extension installs its objects into the
pggitschema (e.g.pggit.init_repository(...)). PostgreSQL reserves thepg_prefix for system schemas, so the schema cannot be namedpg_giteven though the extension itself is calledpg_git.
- PostgreSQL 12+
- PL/pgSQL (
plpgsql) pgcryptopg_trgm
All of these are trusted or built in, so pg_git installs on managed
PostgreSQL (RDS, Cloud SQL, Supabase, Neon) as well as on self-hosted servers.
pg_gitplpython3u
Why HTTPS is a separate extension:
pggit.http_fetchis defined inLANGUAGE plpython3u, which is untrusted — it requires superuser and is not offered by managed PostgreSQL providers. Listing it inpg_git'srequiresmade the whole extension uninstallable there, so the HTTPS transport ships aspg_git_httpsinstead. Everything else inpg_gitis unaffected; install the companion only if you need HTTPS remotes.
make && make install
# Core extension. CASCADE auto-installs pgcrypto and pg_trgm.
CREATE EXTENSION pg_git CASCADE;
# Optional: HTTPS transport. Needs plpython3u, so it requires a self-hosted
# server (or any provider that offers plpython3u).
CREATE EXTENSION pg_git_https CASCADE;
# Alternatively, from the command line:
# psql -d yourdb -c "CREATE EXTENSION pg_git CASCADE;"ALTER EXTENSION pg_git UPDATE;The 0.4.0 -> 0.5.0 step releases pggit.credentials, pggit.store_credentials
and pggit.http_fetch from pg_git without dropping them, so stored
credentials are preserved. If you use HTTPS remotes, follow it with
CREATE EXTENSION pg_git_https; to bring those objects back under extension
management. If you do not, drop the three leftovers — the SQL is spelled out at
the top of sql/pg_git--0.4.0--0.5.0.sql.
Test suites are split by speed and external dependencies:
test-core(default): deterministic SQL tests for local logic. Expected runtime: ~10-30 seconds in Docker on a modern laptop. Prerequisites: running PostgreSQL test database.test-integration(opt-in): HTTPS transport checks intest/sql/https_fetch_test.sql. Expected runtime: ~30-90 seconds depending on network/container startup. Prerequisites: setRUN_INTEGRATION=1;plpython3uavailable so the test can installpg_git_https. The test serves its own endpoints on loopback, so no outbound network is needed.test-performance(opt-in): GC performance regression checks intest/sql/gc_performance_test.sql. Expected runtime: ~1-5+ minutes depending on machine load. Prerequisites: setRUN_PERF=1; stable CPU/IO for consistent measurements.test-all: runstest-coreand then conditionally runs integration/performance suites when their flags are enabled.
In CI, test-core runs on every push and pull request. The HTTPS integration
suite additionally runs on any pull request that touches an HTTPS file, so
changes to the transport are exercised before they land rather than at the next
weekly run. The performance suite stays on the weekly schedule (and
workflow_dispatch), since it is slow and sensitive to runner load.
# Fast default suite (also what `make test` runs)
make test-core
# Explicitly include HTTPS/integration tests
RUN_INTEGRATION=1 make test-integration
# Explicitly include performance tests
RUN_PERF=1 make test-performance
# Run everything (slow suites run only when flags are set)
RUN_INTEGRATION=1 RUN_PERF=1 make test-allUsing Docker:
# Start the development environment
docker-compose up -d
# Access psql console
docker-compose exec db psql -U postgres -d pg_git_dev
# Run tests (includes the same preflight checks as local runs)
docker-compose run --rm test
-- Initialize repository
SELECT pggit.init_repository('my_repository', '/path/to/repo');
-- Clone repository
SELECT pggit.clone('https://github.com/org/repo.git', 'local_name', '/path');
-- Stage / unstage files
SELECT pggit.stage_file(1, 'file.txt', 'content'::bytea);
SELECT pggit.unstage_file(1, 'file.txt');
-- Commit
SELECT pggit.commit_index(1, 'author', 'Your commit message here');
-- Branch creation and checkout
SELECT pggit.create_branch(1, 'feature');
SELECT pggit.checkout_branch(1, 'feature');
-- Merge Branch
SELECT pggit.merge_branches(1, 'feature', 'main');
-- Remote operations with HTTPS (requires: CREATE EXTENSION pg_git_https)
-- Set encryption key for storing credentials
ALTER SYSTEM SET pggit.credential_key = 'my_secret';
SELECT pg_reload_conf();
SELECT pggit.store_credentials(1, 'github.com', 'username', 'token');
-- `http_fetch` uses Python to perform the actual HTTPS request
-- Garbage collection
SELECT * FROM pggit.gc(1);
-- Integrity verification
SELECT * FROM pggit.verify_integrity(1);
-- Index optimization
SELECT * FROM pggit.optimize_indexes(1);
-- View history
SELECT * FROM pggit.get_log(1);
-- Tagging
SELECT pggit.create_tag(1, 'v1.0.0');
SELECT * FROM pggit.list_tags(1);Current: pg_git 0.5.0, pg_git_https 0.1.0
See LICENSE for the full text of the PostgreSQL License.