git-sync-filtered
A thin wrapper around git-filter-repo for syncing filtered commits from a private repository to a public repository.
Overview
git-sync-filtered clones a private repository, filters it to only include specified paths using git-filter-repo, and pushes the result to a public repository's sync branch. This enables maintaining a public subset of a private repository while preserving commit history.
Installation
uv (recommended)
uv tool install git-sync-filtered
pip
pip install git-sync-filtered
uvx (run without installing)
uvx git-sync-filtered \
--private git@github.com:org/private.git \
--public git@github.com:org/public.git \
--keep src \
--keep docs
GitHub Actions
You can use this workflow to sync from your private repo to a public repo when the private repo receives a push.
In your private repository, create .github/workflows/sync.yaml:
name: Sync to Public Repo
on:
push:
branches:
- main
jobs:
sync:
uses: Merge-42/git-sync-filtered/.github/workflows/sync.yaml@v0.1.5
with:
private_repo: ${{ github.repositoryUrl }}
public_repo: git@github.com:org/public.git
keep: src docs
merge: true
secrets:
GH_TOKEN: ${{ secrets.GH_PAT }}
Required secrets:
GH_PAT- A GitHub Personal Access Token withreposcope (for pushing to the public repo)
Available inputs:
| Input | Description | Default |
|---|---|---|
private_repo |
Private repository URL | Required |
public_repo |
Public repository URL | Required |
keep |
Space-separated paths to keep | - |
keep_from_file |
File containing paths to keep | - |
sync_branch |
Sync branch name | upstream/sync |
main_branch |
Main branch name | main |
private_branch |
Private branch to sync from | main |
merge |
Merge into main after sync | false |
force |
Force push | false |
dry_run |
Dry run mode | false |
Usage
git-sync-filtered \
--private git@github.com:org/private.git \
--public git@github.com:org/public.git \
--keep src \
--keep docs
Using a paths file
Create a file with paths to keep (one per line, lines starting with # are comments):
src
docs
README.md
git-sync-filtered \
--private git@github.com:org/private.git \
--public git@github.com:org/public.git \
--keep-from-file paths.txt
Options
| Option | Description | Default |
|---|---|---|
--private |
Private repo path or URL | Required |
--public |
Public repo path or URL | Required |
--keep |
Paths to keep (specify multiple) | Required |
--keep-from-file |
File containing paths to keep | - |
--sync-branch |
Sync branch name | upstream/sync |
--main-branch |
Main branch name | main |
--private-branch |
Private branch to sync from | main |
--dry-run |
Show what would happen without making changes | false |
--merge |
Merge into main branch after sync | false |
--force |
Force push | false |
How It Works
- Clones the private repository
- Runs git-filter-repo to filter to only the specified paths
- Pushes filtered commits to the public repository's sync branch
- Optionally merges the sync branch into main
The sync branch can then be merged into main manually or with --merge.
Workflow
flowchart LR
A[Private Repo<br/>private-branch] -->|clone & filter| B[git-sync-filtered]
B -->|push| C[Public Repo<br/>sync-branch]
C -->|"merge<br/>(manual or with --merge)"| D[Public Repo<br/>main-branch]
Requirements
- Python 3.10+
- git >= 2.36.0
Sponsored by Merge 42
Metadata
Release files for git-sync-filtered 0.1.5
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| git_sync_filtered-0.1.5.tar.gz | 9.6 kB | Without provenance | Details for git_sync_filtered-0.1.5.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| git_sync_filtered-0.1.5-py3-none-any.whl | Python 3 | none | any | Details for git_sync_filtered-0.1.5-py3-none-any.whl |
Total release size: 19.4 kB
Release files / git_sync_filtered-0.1.5.tar.gz
| Download URL | git_sync_filtered-0.1.5.tar.gz |
|---|---|
| Size | 9.6 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
854bc2c8e6169505828009dd58875621631f3d9023da312f805910cc7ee83060
|
|
BLAKE2b-256 checksum How to use checksums |
c7696abe9461f83d4ce98a59bfa7340273c3b910f52505c901f026f11e2f0d3f
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.10.7 {"installer":{"name":"uv","version":"0.10.7","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|
Release files / git_sync_filtered-0.1.5-py3-none-any.whl
| Download URL | git_sync_filtered-0.1.5-py3-none-any.whl |
|---|---|
| Size | 9.8 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
7d86c91cf45d4c190e19b7419b064d724646c2fa443f9882f18b612f0b394ba4
|
|
BLAKE2b-256 checksum How to use checksums |
1b17fcd7ce77ba613a27dae98a5d3ca6c1c1098540ed26f63b26d96abf1322f7
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.10.7 {"installer":{"name":"uv","version":"0.10.7","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|
Security for git-sync-filtered 0.1.5
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.