Skip to main content

Polarion SVN CLI (svncli)

CI Python 3.10+ License: MIT

CLI tool for syncing files with Polarion's SVN repository when direct SVN access is not available — such as on PolarionX or other hosted environments.

Supports macOS, Linux, and Windows.

Why?

Some Polarion deployments don't expose direct SVN access. You can browse and manage individual files through the web UI, but there's no built-in way to recursively upload folders, sync changes, or automate file management. svncli fills that gap.

Installation

pip install svncli

For interactive browser login (optional):

pip install "svncli[interactive]"
playwright install chromium

From source

git clone https://github.com/pupca/svncli.git
cd svncli
pip install -e ".[dev]"

Quick start

1. Authenticate

Pick one of these methods:

# Auto-extract cookies from Chrome (requires being logged in via browser)
svncli login https://your-server.example.com

# Interactive login — opens a browser window (works with SSO/MFA)
svncli login -i https://your-server.example.com

# Manual cookie — paste from browser DevTools
svncli login --cookie "JSESSIONID=ABC123; X-CSRF-Token=DEF456" https://your-server.example.com

All methods save the session to ~/.svncli/cookies.json — you only need to log in once per server. After that, all commands just work.

2. Browse

svncli ls https://your-server.example.com:MyProject/trunk
svncli ls -r https://your-server.example.com:MyProject/trunk   # recursive

3. Copy files

# Upload
svncli cp ./report.pdf https://your-server.example.com:MyProject/trunk/docs/report.pdf

# Download
svncli cp https://your-server.example.com:MyProject/trunk/docs/report.pdf ./report.pdf

# Copy a whole folder
svncli cp -r ./local-folder https://your-server.example.com:MyProject/trunk/folder

4. Sync

# Push local changes to remote
svncli sync ./src https://your-server.example.com:MyProject/trunk/src

# Pull remote changes to local
svncli sync https://your-server.example.com:MyProject/trunk/src ./src

# Preview what would change
svncli sync -n ./src https://your-server.example.com:MyProject/trunk/src

# Delete remote files not present locally
svncli sync --delete --force ./src https://your-server.example.com:MyProject/trunk/src

5. Cross-server operations

Copy or sync files directly between two Polarion servers — no manual download/upload needed:

# Copy a folder from one server to another
svncli cp -r https://server1.com:Project/src https://server2.com:Project/src

# Sync between servers (only transfers changed files)
svncli sync https://server1.com:Project/src https://server2.com:Project/src

# Preview cross-server sync
svncli sync -n https://server1.com:Project/src https://server2.com:Project/src

This works by downloading from the source server to a temp directory, then uploading to the destination. Each server authenticates independently — run svncli login for each one.

Python API

svncli can be used as a Python library:

from svncli import PolarionSVNClient

client = PolarionSVNClient(verify_ssl=False)

# Authenticate (saved to ~/.svncli/cookies.json)
client.login("https://server.com")                            # auto-extract from Chrome
client.login("https://server.com", browser="edge")            # specific browser
client.login("https://server.com", cookie="JSESSIONID=...")   # manual cookie
client.login("https://server.com", interactive=True)           # opens browser window

# List files
items = client.ls("https://server.com:Project/trunk")
for item in items:
    print(f"{item.name}  {item.size} bytes  r{item.revision}")

# Copy a single file
client.cp("./report.pdf", "https://server.com:Project/docs/report.pdf")   # upload
client.cp("https://server.com:Project/docs/report.pdf", "./report.pdf")   # download

# Copy a directory recursively
actions = client.cp_r("./src", "https://server.com:Project/trunk/src")

# Sync with options
actions = client.sync("./src", "https://server.com:Project/trunk/src",
    delete=True,                     # remove remote files not in local
    exclude=["*.log", ".git/*"],     # exclude patterns
    dry_run=True,                    # preview only, don't execute
)

# Inspect what happened
from svncli import SyncOp
uploaded = [a for a in actions if a.op == SyncOp.UPLOAD]
skipped = [a for a in actions if a.op == SyncOp.SKIP]

# Cross-server sync
client.login("https://other-server.com")
client.sync("https://server.com:Project/src", "https://other-server.com:Project/src")

# Create / delete
client.mkdir("https://server.com:Project/new-folder")   # returns True
client.rm("https://server.com:Project/old-file.txt")     # returns True

Path format

Remote paths include the server URL followed by : and the repository path:

https://server.example.com:RepoName/folder/path

Local paths start with /, ./, or ~/:

./local-folder
/absolute/path
~/home-relative

Commands

Command Description
svncli ls <remote> List remote directory (-r for recursive)
svncli cp <src> <dst> Copy files (local↔remote or remote↔remote with -r)
svncli sync <src> <dst> Sync files between local and remote
svncli rm <remote> Delete a remote file or folder
svncli mb <remote> Create a remote directory
svncli login <server> Authenticate and save session cookies
svncli logout [server] Remove saved session cookies

Global options

--no-verify-ssl    Disable SSL certificate verification
--timeout SECONDS  HTTP request timeout (default: 60)
-v, --verbose      Verbose output
--version          Show version

Sync options

-n, --dry-run      Show what would change without doing it
--delete           Remove destination files not present in source
--force            Skip confirmation prompt for deletions
--exclude PATTERN  Exclude files matching glob pattern (repeatable)

Authentication

Each server has its own saved session. svncli resolves cookies per server in this order:

  1. --cookie flag
  2. Saved cookies from ~/.svncli/cookies.json (from a previous svncli login)
  3. Auto-extraction from browser cookie store (Chrome, Firefox, Edge, Safari, etc.)

Automatic cookie extraction

By default, svncli reads cookies from your Chrome cookie store. This requires that you've already logged into Polarion in Chrome. To use a different browser:

svncli login --browser firefox https://your-server.com
svncli login --browser edge https://your-server.com    # common on Windows

Supported browsers: chrome, firefox, edge, brave, opera, chromium, vivaldi, safari, librewolf, arc.

Interactive login

For environments where automatic cookie extraction doesn't work (e.g., remote servers, locked-down browsers):

svncli login -i https://your-server.com

This opens a Chromium window. Log in normally (including SSO/MFA), then close the window. Cookies are saved automatically.

Requires the interactive extra: pip install "svncli[interactive]" and playwright install chromium.

Manual cookie extraction

If neither automatic nor interactive login works, you can extract cookies manually from your browser:

  1. Open your Polarion server in Chrome/Firefox
  2. Log in normally
  3. Open Developer Tools (F12 or Cmd+Option+I)
  4. Go to the Network tab
  5. Navigate to any page on the Polarion server (e.g. refresh the page)
  6. Click on any request to the server
  7. In the Headers section, find the Cookie request header
  8. Copy the entire cookie value string (e.g. JSESSIONID=ABC123; X-CSRF-Token=DEF456; ...)

Then save it with svncli login:

svncli login --cookie "JSESSIONID=ABC123; X-CSRF-Token=DEF456" https://your-server.com

After this, all commands to that server will use the saved session automatically.

Tip: In Chrome, you can also right-click a request in the Network tab → Copy → Copy as cURL, then extract the cookie value from the -b or --cookie flag in the copied command.

How sync works

svncli tracks sync state in manifest files stored in ~/.svncli/manifests/. On each sync:

  1. First sync — compares by file size; uploads/downloads differences
  2. Subsequent syncs — uses SVN revision numbers + local file SHA-256 hashes:
    • Local file unchanged + remote revision unchanged → skip (fast, no hashing needed)
    • Local file changed → upload
    • Remote revision changed, local unchanged → skip (remote is newer)
    • New local file → upload
    • New remote file → download (in download direction)

The manifest enables efficient incremental syncs without downloading remote files to compare.

Corporate environments

For servers with self-signed or corporate CA certificates:

svncli --no-verify-ssl ls MyProject

Development

git clone https://github.com/pupca/svncli.git
cd svncli
python -m venv .venv
source .venv/bin/activate
pip install -e ".[dev]"

# Run unit tests (no server needed)
pytest tests/test_sync.py tests/test_client.py tests/test_models.py tests/test_util.py -v

# Run full suite including E2E (requires access to two Polarion servers)
export SVNCLI_SERVER_A="https://your-server.example.com"
export SVNCLI_ROOT_A="ProjectRoot"
export SVNCLI_SERVER_B="https://your-other-server.example.com"
export SVNCLI_ROOT_B="OtherProjectRoot"
pytest tests/ -v --cov=svncli --cov-report=html

# Run E2E with one server only (cross-server tests will be skipped)
export SVNCLI_SERVER_A="https://your-server.example.com"
export SVNCLI_ROOT_A="ProjectRoot"
pytest tests/ -v

License

MIT

Metadata

Release files for svncli 1.0.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for svncli 1.0.0
File Size Uploaded
svncli-1.0.0.tar.gz 40.8 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for svncli 1.0.0
File Interpreter ABI Platform
svncli-1.0.0-py3-none-any.whl Python 3 none any Details

Total release size: 68.1 kB

Release files / svncli-1.0.0.tar.gz

Download URL svncli-1.0.0.tar.gz
Size 40.8 kB
Tags Source
SHA-256 checksum
How to use checksums
d192388e37cb2e98318c09749d6a83fa901922e2ebf406a08df0eee909e03ed8
BLAKE2b-256 checksum
How to use checksums
89532c4a920509f9d08cd2f4dd8d53444b79e85a9aa13bf1da0d50be5ec2a295
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.7

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.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Mar 18, 2026.

Transparency log

Release files / svncli-1.0.0-py3-none-any.whl

Download URL svncli-1.0.0-py3-none-any.whl
Size 27.3 kB
Tags Python 3
SHA-256 checksum
How to use checksums
c93475dfb56c99dd9d33c671d7fe45233cf8f92f0599748697c192e22189d242
BLAKE2b-256 checksum
How to use checksums
da640747caa227aef1495b307069def3910e52c89d036ef3834fda8ebcd8a9e6
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.7

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.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Mar 18, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

1.0.0 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page