Subversion Command-Line Wrapper (svn)
The `svn` library by dsoprea is an intuitive Python wrapper for the Subversion (SVN) command-line client, compatible with Python 2.7 and 3.3+. It provides a lightweight interface for common SVN operations such as listing, getting info, logging, checking out, exporting, adding, committing, updating, and diffing. The library itself wraps the `svn` command-line executable, which must be installed separately on the system. The current version is 1.0.1, with its last release in February 2020.
Common errors
-
ImportError: No module named svn.core
cause This error often occurs when attempting to use features of the `pysvn` library (SWIG bindings) while having installed the `svn` (command-line wrapper) package. The `svn` package does not expose a `svn.core` module.fixIf you intend to use the command-line wrapper, do not import `svn.core`. Instead, use `import svn.local` or `import svn.remote`. If you genuinely need the `pysvn` SWIG bindings, ensure it is installed correctly and manage potential conflicts with the `svn` package. -
pysvn.ClientError exception with the value 'client in use on another thread'
cause The underlying Subversion client (whether the `pysvn` SWIG bindings or the `svn` command-line tool being shelled out to) is generally not thread-safe. Concurrent access from multiple threads to the same client instance can cause this error.fixAvoid using a single `svn.local.LocalClient` or `svn.remote.RemoteClient` instance across multiple threads simultaneously. Instantiate a new client object for each thread or ensure thread-safe access (e.g., using locks) if you must share a client.
Warnings
- breaking The `diff` implementation was re-written in version 1.0, making it backwards-incompatible. If your application relies on the older `diff` output, you must pin your dependency to version `0.3.46` or earlier.
- gotcha The Python `svn` library is a wrapper around the Subversion command-line client. The `svn` executable must be installed on the system where the Python code runs and be accessible in the system's PATH.
- gotcha From version 1.0 onwards, exceptions related to SVN repository issues are raised as `svn.exception.SvnException`, replacing `ValueError`.
Install
-
pip install svn
Imports
- LocalClient
import svn.local client = svn.local.LocalClient('/path/to/working/copy') - RemoteClient
import svn.remote client = svn.remote.RemoteClient('https://repo.local/svn') - SvnException
from svn.exception import ValueError
from svn.exception import SvnException
- Client
import svn client = svn.Client()
import svn.local client = svn.local.LocalClient(...)
- svn.core
import svn.core
Quickstart
import svn.remote
import os
# Example: Checkout a remote repository
# Replace with your actual repository URL and desired local path
repo_url = os.environ.get('SVN_REPO_URL', 'https://example.com/svn/myproject/trunk')
local_path = os.environ.get('SVN_LOCAL_PATH', '/tmp/myproject_working_copy')
if not os.path.exists(local_path):
print(f"Checking out '{repo_url}' to '{local_path}'...")
try:
r = svn.remote.RemoteClient(repo_url)
# For repositories requiring credentials:
# r = svn.remote.RemoteClient(repo_url, username='myuser', password='mypassword')
r.checkout(local_path)
print("Checkout successful.")
# Example: Get info about the checked out working copy
local_client = svn.local.LocalClient(local_path)
info = local_client.info()
print("\nWorking copy info:")
for key, value in info.items():
print(f" {key}: {value}")
except svn.exception.SvnException as e:
print(f"SVN Error: {e}")
except Exception as e:
print(f"An unexpected error occurred: {e}")
else:
print(f"'{local_path}' already exists. Skipping checkout.")
print("You can use svn.local.LocalClient to interact with it.")