{"id":28757133,"url":"https://github.com/matthieu-foucault/postgit","last_synced_at":"2025-10-10T06:33:14.091Z","repository":{"id":63434570,"uuid":"567027379","full_name":"matthieu-foucault/postgit","owner":"matthieu-foucault","description":"Integrate declarative PostgreSQL schema migrations with Git","archived":false,"fork":false,"pushed_at":"2022-12-15T20:58:08.000Z","size":87,"stargazers_count":8,"open_issues_count":2,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-06-17T03:09:55.549Z","etag":null,"topics":["declarative-migrations","git","migra","migration-automation","postgresql","rust"],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/matthieu-foucault.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2022-11-16T23:09:49.000Z","updated_at":"2024-03-19T14:16:28.000Z","dependencies_parsed_at":"2023-01-29T04:30:27.104Z","dependency_job_id":null,"html_url":"https://github.com/matthieu-foucault/postgit","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/matthieu-foucault/postgit","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/matthieu-foucault%2Fpostgit","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/matthieu-foucault%2Fpostgit/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/matthieu-foucault%2Fpostgit/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/matthieu-foucault%2Fpostgit/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/matthieu-foucault","download_url":"https://codeload.github.com/matthieu-foucault/postgit/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/matthieu-foucault%2Fpostgit/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":279002962,"owners_count":26083489,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-10-10T02:00:06.843Z","response_time":62,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["declarative-migrations","git","migra","migration-automation","postgresql","rust"],"created_at":"2025-06-17T03:09:54.927Z","updated_at":"2025-10-10T06:33:14.075Z","avatar_url":"https://github.com/matthieu-foucault.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# PostGit\n\nThe goal of PostGit is to integrate PostgreSQL schema diffing tools (e.g. `migra`) with Git to provide a modern development experience for PostgreSQL schemas.\n\nThis is a proof-of-concept, which started as my Hackathon Onboarding Project with [Commit](https://commit.dev/). Contributors are welcome.\n\n## Concept\n\nThe goal of PostGit is to enable PostgreSQL schema developers to write clean, refactorable SQL code which does not rely on a list of ordered migration files and does not require developers to write idempotent scripts.\n\nBy leveraging a schema diffing tool, the `postgit push` command generates a migration script between two committed schemas and applies the migration to a target database.\n\n## Usage\n\n### Diff command\n\nPrints the migration between two committed SQL files\n\n`postgit diff [OPTIONS] --from \u003cFROM\u003e --to \u003cTO\u003e \u003cPATH\u003e`\n\nArguments:\n`\u003cPATH\u003e` Path to the schema file or directory, relative to the repo root\n\nOptions:\n\n- `-r`, `--repo-path \u003cREPO_PATH\u003e` Path to the root of the git repository `[default: .]`\n\n- `-f`, `--from \u003cFROM\u003e` Git commit where the source schema can be found\n- `-t`, `--to \u003cTO\u003e` Git commit where the target schema can be found\n- `--source-path \u003cSOURCE_PATH\u003e` Path to the source schema at the source ref, if different from the target path\n\n### Push command\n\nApplies the migration between two committed SQL files onto the target database\n\n`postgit push [OPTIONS] --from \u003cFROM\u003e --to \u003cTO\u003e \u003cPATH\u003e`\n\nArguments:\n`\u003cPATH\u003e` Path to the schema file or directory, relative to the repo root\n\nOptions:\n\n- `-r`, `--repo-path \u003cREPO_PATH\u003e` Path to the root of the git repository `[default: .]`\n\n- `-f`, `--from \u003cFROM\u003e` Git commit where the source schema can be found\n- `-t`, `--to \u003cTO\u003e` Git commit where the target schema can be found\n- `--source-path \u003cSOURCE_PATH\u003e` Path to the source schema at the source ref, if different from the target path\n\n### Watch command\n\nWatches a directory and applies the migrations to the target database\n\nUsage: `postgit watch \u003cPATH\u003e`\n\nArguments:\n`\u003cPATH\u003e` Path to the directory to watch\n\n### Configuration\n\nThe behaviour of PostGit can be configured through a combination of configuration file and command line arguments.\n\n#### PostgreSQL config\n\nPostGit relies on three databases:\n\n- a diff engine source and a target where the respective schemas are deployed for the `diff` command. Those databases should only be used by PostGit as they are dropped and recreated every time\n- a target database where the migrations from the `push` and `watch` commands are applied\n\nA local `postgit.toml` file can be used to define the PostgreSQL connection parameters. The default configuration is equivalent to the following\n\n```toml\n[diff_engine]\n\n[diff_engine.source]\ndbname='postgit_diff_source'\nhost='localhost'\nport=5432\nuser='postgres'\n\n[diff_engine.target]\ndbname='postgit_diff_target'\nhost='localhost'\nport=5432\nuser='postgres'\n\n[target]\ndbname='postgres'\nhost='localhost'\nport=5432\nuser='postgres'\n```\n\nPostGit supports the following [`libpq` environment variables](https://www.postgresql.org/docs/current/libpq-envars.html) for all three databases (the `postgit.toml` file takes precedence over env variables): `PGHOST`, `PGUSER`, `PGPORT`.\n\nThe `PGDATABASE` env variable can be used to specify the `target` database name.\n\n#### Diff engine\n\nPostGit relies on customisable external CLI tools to perform the schema diffing.\n\nThe current default schema diffing tool is [`migra`](https://github.com/djrobstep/migra), which can be installed by running `pip install migra psycopg2-binary`.\n\nThe diff tool can be configured with the `diff_engine.command` configuration option. The custom command must use two postgresql connection strings for the source and target databases as the positional arguments `$1` and `$2`, respectively.\n\nFor instance, to use migra, the `config.toml` would contain the following (the default behaviour is equivalent to this configuration):\n\n```toml\n[diff_engine]\ncommand='migra --unsafe $1 $2'\n```\n\nUsing the [CLI version of `pgAdmin4`](https://supabase.com/blog/supabase-cli#choosing-the-best-diff-tool) can be done with\n\n```toml\n[diff_engine]\ncommand='docker run --network=host supabase/pgadmin-schema-diff $1 $2'\n```\n\n## SQL files management\n\nAs your database schema grows, you will most likely want to split your SQL code into multiple files.\nTo allow you to load multiple files in the desired order, PostGit supports:\n\n- loading files in lexicographic path order\n- a custom `-- import` syntax\n\n### Lexicographic path order (e.g. using numbered prefixes)\n\nYou can rely on file naming to define the file loading order, e.g., given the following file hierarchy\n\n- `schema/`\n  - `001_dir/`\n    - `001_file_a.sql`\n    - `002_file_b.sql`\n  - `002_file_c.sql`\n  - `003_dir/`\n    - `001_file_d.sql`\n    - `002_file_e.sql`\n\nThe files will be imported in the \"a,b,c,d,e\" order.\n\n### `--import` syntax\n\n`schema/schema.sql`\n\n```sql\ncreate schema my_app;\n```\n\n`schema/user.sql`\n\n```sql\n-- import schema/schema.sql\n\ncreate table my_app.user (\n  id int primary key generated always as identity,\n  given_name text not null,\n  family_name text,\n  email text not null\n);\n```\n\n**Import file resolution**:\n\n- Paths starting with `./` or `../` are resolved relatively to the file's directory\n- Other paths are resolved from the repository root\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmatthieu-foucault%2Fpostgit","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmatthieu-foucault%2Fpostgit","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmatthieu-foucault%2Fpostgit/lists"}