Version Management¶
Portolan tracks data versions in versions.json, enabling git-like workflows for your geospatial data.
Quick Start¶
# Check what's changed since the last version
portolan status
# Create a new version after modifying files
portolan version bump my-collection 1.1.0 -m "Updated source data"
# View version history
portolan version list my-collection
Understanding Status¶
The portolan status command shows the state of your collections:
$ portolan status
→ Collection: demographics
→ Local version: 1.0.0
Remote version: (offline or not configured)
→
→ Modified files:
⚠ census-data.parquet (checksum changed)
→
→ Deleted files:
✗ old-data.parquet (missing from disk)
Status Categories¶
| Category | Meaning |
|---|---|
| Modified | File checksum differs from versions.json |
| Deleted | File in versions.json but missing from disk |
| Untracked | Data file on disk but not in versions.json |
Managed Files
STAC metadata files (collection.json, *.json items), README.md, and metadata.yaml are not shown as untracked. These are managed by Portolan separately from data versioning.
Sync State¶
When connected to a remote, status shows whether you're in sync:
- in_sync: Local and remote versions match
- ahead: Local has unpushed versions
- behind: Remote has versions you haven't pulled
- unknown: Remote not configured or offline
Use --offline to skip the remote check:
portolan status --offline
Creating Versions¶
Use portolan version bump to create a new version:
portolan version bump <collection> <version> [options]
Options¶
| Option | Description |
|---|---|
-m, --notes |
Version message (like a commit message) |
--breaking |
Mark as a breaking change |
-y, --yes |
Skip confirmation prompt |
--json |
JSON output for automation |
Examples¶
# Simple version bump with message
portolan version bump demographics 1.2.0 -m "Added 2024 census data"
# Breaking change (schema modified)
portolan version bump demographics 2.0.0 --breaking -m "Changed column names"
# Non-interactive (for CI/CD)
portolan version bump demographics 1.2.0 -y --json
Version Format¶
Versions must be valid semver strings:
- ✅
1.0.0,2.1.3,1.0.0-beta.1,1.0.0+build.123 - ❌
1.0,v1.0.0,latest,bad-version
Validation¶
The bump command validates:
- Semver format - Rejects invalid version strings
- Uniqueness - Rejects versions that already exist
Viewing History¶
Current Version¶
$ portolan version current demographics
→ demographics: 1.2.0 2026-05-06 10:30:00 — Added 2024 census data
3 asset(s)
All Versions¶
$ portolan version list demographics
→ Versions for 'demographics' (3 total):
→ 1.0.0 2026-01-15 08:00:00 — Initial release
census-data.parquet
→ 1.1.0 2026-03-20 14:30:00 — Updated boundaries
census-data.parquet
→ 1.2.0 2026-05-06 10:30:00 — Added 2024 census data
census-data.parquet
demographics-2024.parquet
JSON Output¶
All commands support --json for machine-readable output:
$ portolan status --json
{
"success": true,
"command": "status",
"data": {
"collections": [
{
"collection": "demographics",
"local_version": "1.2.0",
"remote_version": "1.2.0",
"sync_state": "in_sync",
"modified_files": [],
"untracked_files": [],
"deleted_files": []
}
]
}
}
Workflow Example¶
A typical workflow:
# 1. Check current state
portolan status
# 2. Make changes to your data files
# ... edit parquet files, add new files, etc.
# 3. Review what changed
portolan status
# 4. Create a new version
portolan version bump my-collection 1.3.0 -m "Monthly data update"
# 5. Push to remote
portolan push
What Gets Versioned?¶
Tracked in versions.json¶
- Data files (
.parquet,.tif,.csv, etc.) - Checksums (SHA256) for change detection
- File sizes and modification times
NOT Tracked (Managed Separately)¶
collection.json- STAC collection metadata*.jsonitem files - STAC item metadataREADME.md- Generated documentationmetadata.yaml- Human enrichment layerversions.json- The version file itself
These files are synced with portolan push but aren't versioned—they're derived from or supplement the data.
Portolan owns the bucket¶
Everything under the configured remote prefix belongs to Portolan. You supply credentials, an endpoint, and a bucket path; Portolan manages every file and the structure inside.
Editing the bucket with another tool is unsupported. Local state is the single
source of truth, and sync runs one direction. Portolan does not merge external
changes, so a remote edit either gets overwritten by the next push or leaves the
remote inconsistent with versions.json.
Two consequences worth planning around. Adopting an existing bucket means letting Portolan rewrite its layout, so point it at a fresh prefix when the current contents matter. Two people pushing from different local states will overwrite each other, because the newer push wins rather than merging.
The reasoning is consistency: a consumer reading the catalog gets files that match the manifest, and a CDN can cache them without worrying that they changed underneath it.
Drift is not detected yet
Portolan does not currently compare remote state against versions.json.
A file changed or deleted directly in the bucket goes unnoticed until
something downstream breaks. Treat the bucket as write-only through
portolan push.
See Also¶
- Configuration - Configure remote settings
- CLI Reference - Full command reference