svn


Namesvn JSON
Version 1.0.1 PyPI version JSON
download
home_pagehttps://github.com/dsoprea/PySvn
SummaryIntuitive Subversion wrapper.
upload_time2020-02-01 21:11:02
maintainer
docs_urlNone
authorDustin Oprea
requires_python
licenseGPL 2
keywords svn subversion
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI
coveralls test coverage No coveralls.
            [![Build_Status](https://travis-ci.org/dsoprea/PySvn.svg?branch=master)](https://travis-ci.org/dsoprea/PySvn)

[![Coverage_Status](https://coveralls.io/repos/github/dsoprea/PySvn/badge.svg?branch=master)](https://coveralls.io/github/dsoprea/PySvn?branch=master)


# Introduction

*svn* is a simple Subversion library for Python. I wrote it so that there could
be a lightweight and accessible library that was also available on *PyPI*. It is
compatible with both Python 2.7 and 3.3+.

The library wraps the `svn` commandline client, which should consequently be
installed on the local system.

Functions currently implemented:

- list
- info
- log
- checkout
- export
- cat
- diff
- diff_summary
- status
- add
- commit
- update
- cleanup

In addition, there is also an "admin" class (`svn.admin.Admin`) that provides a
`create` method with which to create repositories.

**You are more than welcome to submit pull-requests to add more support for
additional subcommands.**


# Usage

Usage is divided between two clients that either allow for access to a local
working-directory or a remote repository.

Both clients inherit a common set of methods that work with both local working-
directories and remote repositories.

`svn.utility.get_client` is provided for convenience. If you provide a location
that starts with a backslash, it will return a LocalClient instance. Otherwise,
it will return a RemoteClient instance.

You may pass `username` and `password` as optional arguments to both the
constructor and utility function.


## LocalClient

*LocalClient* allows access to a local working copy.


## RemoteClient

*RemoteClient* allows access to a remote repository.


## SvnException

*SvnException* is raised whenever there is an issue with the svn repository. We
are no longer supporting catching *ValueError*.


## checkout(path)

Checkout a remote repository:

```
import svn.remote

r = svn.remote.RemoteClient('https://repo.local/svn')
r.checkout('/tmp/working')
```


## Common Functionality

These methods are available on both clients.


### info(rel_path=None)

Get information about the directory.

```
import pprint

import svn.local

r = svn.local.LocalClient('/tmp/test_repo.co')
info = r.info()
pprint.pprint(info)

#{'commit#revision': 0,
# 'commit/author': None,
# 'commit/date': datetime.datetime(2015, 4, 24, 2, 53, 21, 874970, tzinfo=tzutc()),
# 'commit_author': None,
# 'commit_date': datetime.datetime(2015, 4, 24, 2, 53, 21, 874970, tzinfo=tzutc()),
# 'commit_revision': 0,
# 'entry#kind': 'dir',
# 'entry#path': '/tmp/test_repo.co',
# 'entry#revision': 0,
# 'entry_kind': 'dir',
# 'entry_path': '/tmp/test_repo.co',
# 'entry_revision': 0,
# 'relative_url': None,
# 'repository/root': 'file:///tmp/test_repo',
# 'repository/uuid': '7446d4e9-8846-46c0-858a-34a2a1739d1c',
# 'repository_root': 'file:///tmp/test_repo',
# 'repository_uuid': '7446d4e9-8846-46c0-858a-34a2a1739d1c',
# 'url': 'file:///tmp/test_repo',
# 'wc-info/depth': None,
# 'wc-info/schedule': None,
# 'wc-info/wcroot-abspath': None,
# 'wcinfo_depth': None,
# 'wcinfo_schedule': None,
# 'wcinfo_wcroot_abspath': None}
```

NOTE: The keys named with dashes, slashes, and hashes are considered
      obsolete, and only available for backwards compatibility. We
      have since moved to using only underscores to separate words.


### cat(rel_filepath)

Get file-data as string.

```
import svn.local

l = svn.local.LocalClient('/tmp/test_repo')
content = l.cat('test_file')
```


### log_default(timestamp_from_dt=None, timestamp_to_dt=None, limit=None, rel_filepath='', stop_on_copy=False, revision_from=None, revision_to=None, changelist=False)

Perform a log-listing that can be bounded by time or revision number and/or
take a maximum-count.

```
import svn.local

l = svn.local.LocalClient('/tmp/test_repo.co')

for e in l.log_default():
    print(e)

#LogEntry(date=datetime.datetime(2015, 4, 24, 3, 2, 39, 895975, tzinfo=tzutc()), msg='Added second file.', revision=2, author='dustin')
#LogEntry(date=datetime.datetime(2015, 4, 24, 2, 54, 2, 136170, tzinfo=tzutc()), msg='Initial commit.', revision=1, author='dustin')
```


### export(to_path, revision=None, force=False)

Checkout the tree without embedding an meta-information.

```
import svn.remote

r = svn.remote.RemoteClient('file:///tmp/test_repo')
r.export('/tmp/test_export')
```

We can also use `force` option to force the svn export.


### list(extended=False, rel_path=None)

Return either a flat-list of filenames or a list of objects describing even
more information about each.

```
import pprint

import svn.local

l = svn.local.LocalClient('/tmp/test_repo.co')

# Flat list.

entries = l.list()
for filename in entries:
    print(filename)

#aa
#bb

# Extended information.

entries = l.list(extended=True)
for entry in entries:
    pprint.pprint(entry)

#{'author': 'dustin',
# 'commit_revision': 1,
# 'date': datetime.datetime(2015, 4, 24, 2, 54, 2, 136170, tzinfo=tzutc()),
# 'is_directory': False,
# 'kind': 'file',
# 'name': 'aa',
# 'size': 0,
# 'timestamp': datetime.datetime(2015, 4, 24, 2, 54, 2, 136170, tzinfo=tzutc())}
#{'author': 'dustin',
# 'commit_revision': 2,
# 'date': datetime.datetime(2015, 4, 24, 3, 2, 39, 895975, tzinfo=tzutc()),
# 'is_directory': False,
# 'kind': 'file',
# 'name': 'bb',
# 'size': 0,
# 'timestamp': datetime.datetime(2015, 4, 24, 3, 2, 39, 895975, tzinfo=tzutc())}
```


### list_recursive(rel_path=None, yield_dirs=False, path_filter_cb=None)

List all entries at and beneath the root or given relative-path.

```
import pprint

import svn.local

l = svn.local.LocalClient('/tmp/test_repo.co')

for rel_path, e in l.list_recursive():
    print('')
    print('[' + rel_path + ']')
    print('')

    pprint.pprint(e)

#[]
#
#{'author': 'dustin',
# 'commit_revision': 1,
# 'date': datetime.datetime(2015, 4, 24, 2, 54, 2, 136170, tzinfo=tzutc()),
# 'is_directory': False,
# 'kind': 'file',
# 'name': 'aa',
# 'size': 0,
# 'timestamp': datetime.datetime(2015, 4, 24, 2, 54, 2, 136170, tzinfo=tzutc())}
#
#[]
#
#{'author': 'dustin',
# 'commit_revision': 2,
# 'date': datetime.datetime(2015, 4, 24, 3, 2, 39, 895975, tzinfo=tzutc()),
# 'is_directory': False,
# 'kind': 'file',
# 'name': 'bb',
# 'size': 0,
# 'timestamp': datetime.datetime(2015, 4, 24, 3, 2, 39, 895975, tzinfo=tzutc())}
#
#[dir1]
#
#{'author': 'dustin',
# 'commit_revision': 3,
# 'date': datetime.datetime(2015, 4, 24, 3, 25, 13, 479212, tzinfo=tzutc()),
# 'is_directory': False,
# 'kind': 'file',
# 'name': 'cc',
# 'size': 0,
# 'timestamp': datetime.datetime(2015, 4, 24, 3, 25, 13, 479212, tzinfo=tzutc())}
```


### diff_summary(start_revision,  end_revision)

A lower-level diff summary that doesn't actually provide the content
differences.

```
import svn.remote

l = svn.remote.RemoteClient('http://svn.apache.org/repos/asf')
print l.diff_summary(1760022, 1760023)

# [{'item': 'modified',
#  'kind': 'file',
#  'path': 'http://svn.apache.org/repos/asf/sling/trunk/pom.xml'},
# {'item': 'added',
#  'kind': 'file',
#  'path': 'http://svn.apache.org/repos/asf/sling/trunk/bundles/extensions/models/pom.xml'}]
```


### diff(start_revision,  end_revision)

Diffs between start and end revisions


# Notice of Diff Reimplementation in 1.0.0

There was a previous contribution to the diff implementation that has been
reported and confirmed to often throw an exception due to shoddy handling of
the file-paths in the output. It also made secondary shell calls and mixed both
text and XML output in the response. As a result of this, the decision has been
made to just reimplement it and reshape the output in a backwards-incompatible
way at the same time. If you need to stick to the older implementation, tie your
dependencies to the 0.3.46 release.
            

Raw data

            {
    "_id": null,
    "home_page": "https://github.com/dsoprea/PySvn",
    "name": "svn",
    "maintainer": "",
    "docs_url": null,
    "requires_python": "",
    "maintainer_email": "",
    "keywords": "svn subversion",
    "author": "Dustin Oprea",
    "author_email": "myselfasunder@gmail.com",
    "download_url": "https://files.pythonhosted.org/packages/2b/a5/a23ed647d0cbdac48de23d822581e273f087364c57e2cd1c3efc979e91f5/svn-1.0.1.tar.gz",
    "platform": "",
    "description": "[![Build_Status](https://travis-ci.org/dsoprea/PySvn.svg?branch=master)](https://travis-ci.org/dsoprea/PySvn)\n\n[![Coverage_Status](https://coveralls.io/repos/github/dsoprea/PySvn/badge.svg?branch=master)](https://coveralls.io/github/dsoprea/PySvn?branch=master)\n\n\n# Introduction\n\n*svn* is a simple Subversion library for Python. I wrote it so that there could\nbe a lightweight and accessible library that was also available on *PyPI*. It is\ncompatible with both Python 2.7 and 3.3+.\n\nThe library wraps the `svn` commandline client, which should consequently be\ninstalled on the local system.\n\nFunctions currently implemented:\n\n- list\n- info\n- log\n- checkout\n- export\n- cat\n- diff\n- diff_summary\n- status\n- add\n- commit\n- update\n- cleanup\n\nIn addition, there is also an \"admin\" class (`svn.admin.Admin`) that provides a\n`create` method with which to create repositories.\n\n**You are more than welcome to submit pull-requests to add more support for\nadditional subcommands.**\n\n\n# Usage\n\nUsage is divided between two clients that either allow for access to a local\nworking-directory or a remote repository.\n\nBoth clients inherit a common set of methods that work with both local working-\ndirectories and remote repositories.\n\n`svn.utility.get_client` is provided for convenience. If you provide a location\nthat starts with a backslash, it will return a LocalClient instance. Otherwise,\nit will return a RemoteClient instance.\n\nYou may pass `username` and `password` as optional arguments to both the\nconstructor and utility function.\n\n\n## LocalClient\n\n*LocalClient* allows access to a local working copy.\n\n\n## RemoteClient\n\n*RemoteClient* allows access to a remote repository.\n\n\n## SvnException\n\n*SvnException* is raised whenever there is an issue with the svn repository. We\nare no longer supporting catching *ValueError*.\n\n\n## checkout(path)\n\nCheckout a remote repository:\n\n```\nimport svn.remote\n\nr = svn.remote.RemoteClient('https://repo.local/svn')\nr.checkout('/tmp/working')\n```\n\n\n## Common Functionality\n\nThese methods are available on both clients.\n\n\n### info(rel_path=None)\n\nGet information about the directory.\n\n```\nimport pprint\n\nimport svn.local\n\nr = svn.local.LocalClient('/tmp/test_repo.co')\ninfo = r.info()\npprint.pprint(info)\n\n#{'commit#revision': 0,\n# 'commit/author': None,\n# 'commit/date': datetime.datetime(2015, 4, 24, 2, 53, 21, 874970, tzinfo=tzutc()),\n# 'commit_author': None,\n# 'commit_date': datetime.datetime(2015, 4, 24, 2, 53, 21, 874970, tzinfo=tzutc()),\n# 'commit_revision': 0,\n# 'entry#kind': 'dir',\n# 'entry#path': '/tmp/test_repo.co',\n# 'entry#revision': 0,\n# 'entry_kind': 'dir',\n# 'entry_path': '/tmp/test_repo.co',\n# 'entry_revision': 0,\n# 'relative_url': None,\n# 'repository/root': 'file:///tmp/test_repo',\n# 'repository/uuid': '7446d4e9-8846-46c0-858a-34a2a1739d1c',\n# 'repository_root': 'file:///tmp/test_repo',\n# 'repository_uuid': '7446d4e9-8846-46c0-858a-34a2a1739d1c',\n# 'url': 'file:///tmp/test_repo',\n# 'wc-info/depth': None,\n# 'wc-info/schedule': None,\n# 'wc-info/wcroot-abspath': None,\n# 'wcinfo_depth': None,\n# 'wcinfo_schedule': None,\n# 'wcinfo_wcroot_abspath': None}\n```\n\nNOTE: The keys named with dashes, slashes, and hashes are considered\n      obsolete, and only available for backwards compatibility. We\n      have since moved to using only underscores to separate words.\n\n\n### cat(rel_filepath)\n\nGet file-data as string.\n\n```\nimport svn.local\n\nl = svn.local.LocalClient('/tmp/test_repo')\ncontent = l.cat('test_file')\n```\n\n\n### log_default(timestamp_from_dt=None, timestamp_to_dt=None, limit=None, rel_filepath='', stop_on_copy=False, revision_from=None, revision_to=None, changelist=False)\n\nPerform a log-listing that can be bounded by time or revision number and/or\ntake a maximum-count.\n\n```\nimport svn.local\n\nl = svn.local.LocalClient('/tmp/test_repo.co')\n\nfor e in l.log_default():\n    print(e)\n\n#LogEntry(date=datetime.datetime(2015, 4, 24, 3, 2, 39, 895975, tzinfo=tzutc()), msg='Added second file.', revision=2, author='dustin')\n#LogEntry(date=datetime.datetime(2015, 4, 24, 2, 54, 2, 136170, tzinfo=tzutc()), msg='Initial commit.', revision=1, author='dustin')\n```\n\n\n### export(to_path, revision=None, force=False)\n\nCheckout the tree without embedding an meta-information.\n\n```\nimport svn.remote\n\nr = svn.remote.RemoteClient('file:///tmp/test_repo')\nr.export('/tmp/test_export')\n```\n\nWe can also use `force` option to force the svn export.\n\n\n### list(extended=False, rel_path=None)\n\nReturn either a flat-list of filenames or a list of objects describing even\nmore information about each.\n\n```\nimport pprint\n\nimport svn.local\n\nl = svn.local.LocalClient('/tmp/test_repo.co')\n\n# Flat list.\n\nentries = l.list()\nfor filename in entries:\n    print(filename)\n\n#aa\n#bb\n\n# Extended information.\n\nentries = l.list(extended=True)\nfor entry in entries:\n    pprint.pprint(entry)\n\n#{'author': 'dustin',\n# 'commit_revision': 1,\n# 'date': datetime.datetime(2015, 4, 24, 2, 54, 2, 136170, tzinfo=tzutc()),\n# 'is_directory': False,\n# 'kind': 'file',\n# 'name': 'aa',\n# 'size': 0,\n# 'timestamp': datetime.datetime(2015, 4, 24, 2, 54, 2, 136170, tzinfo=tzutc())}\n#{'author': 'dustin',\n# 'commit_revision': 2,\n# 'date': datetime.datetime(2015, 4, 24, 3, 2, 39, 895975, tzinfo=tzutc()),\n# 'is_directory': False,\n# 'kind': 'file',\n# 'name': 'bb',\n# 'size': 0,\n# 'timestamp': datetime.datetime(2015, 4, 24, 3, 2, 39, 895975, tzinfo=tzutc())}\n```\n\n\n### list_recursive(rel_path=None, yield_dirs=False, path_filter_cb=None)\n\nList all entries at and beneath the root or given relative-path.\n\n```\nimport pprint\n\nimport svn.local\n\nl = svn.local.LocalClient('/tmp/test_repo.co')\n\nfor rel_path, e in l.list_recursive():\n    print('')\n    print('[' + rel_path + ']')\n    print('')\n\n    pprint.pprint(e)\n\n#[]\n#\n#{'author': 'dustin',\n# 'commit_revision': 1,\n# 'date': datetime.datetime(2015, 4, 24, 2, 54, 2, 136170, tzinfo=tzutc()),\n# 'is_directory': False,\n# 'kind': 'file',\n# 'name': 'aa',\n# 'size': 0,\n# 'timestamp': datetime.datetime(2015, 4, 24, 2, 54, 2, 136170, tzinfo=tzutc())}\n#\n#[]\n#\n#{'author': 'dustin',\n# 'commit_revision': 2,\n# 'date': datetime.datetime(2015, 4, 24, 3, 2, 39, 895975, tzinfo=tzutc()),\n# 'is_directory': False,\n# 'kind': 'file',\n# 'name': 'bb',\n# 'size': 0,\n# 'timestamp': datetime.datetime(2015, 4, 24, 3, 2, 39, 895975, tzinfo=tzutc())}\n#\n#[dir1]\n#\n#{'author': 'dustin',\n# 'commit_revision': 3,\n# 'date': datetime.datetime(2015, 4, 24, 3, 25, 13, 479212, tzinfo=tzutc()),\n# 'is_directory': False,\n# 'kind': 'file',\n# 'name': 'cc',\n# 'size': 0,\n# 'timestamp': datetime.datetime(2015, 4, 24, 3, 25, 13, 479212, tzinfo=tzutc())}\n```\n\n\n### diff_summary(start_revision,  end_revision)\n\nA lower-level diff summary that doesn't actually provide the content\ndifferences.\n\n```\nimport svn.remote\n\nl = svn.remote.RemoteClient('http://svn.apache.org/repos/asf')\nprint l.diff_summary(1760022, 1760023)\n\n# [{'item': 'modified',\n#  'kind': 'file',\n#  'path': 'http://svn.apache.org/repos/asf/sling/trunk/pom.xml'},\n# {'item': 'added',\n#  'kind': 'file',\n#  'path': 'http://svn.apache.org/repos/asf/sling/trunk/bundles/extensions/models/pom.xml'}]\n```\n\n\n### diff(start_revision,  end_revision)\n\nDiffs between start and end revisions\n\n\n# Notice of Diff Reimplementation in 1.0.0\n\nThere was a previous contribution to the diff implementation that has been\nreported and confirmed to often throw an exception due to shoddy handling of\nthe file-paths in the output. It also made secondary shell calls and mixed both\ntext and XML output in the response. As a result of this, the decision has been\nmade to just reimplement it and reshape the output in a backwards-incompatible\nway at the same time. If you need to stick to the older implementation, tie your\ndependencies to the 0.3.46 release.",
    "bugtrack_url": null,
    "license": "GPL 2",
    "summary": "Intuitive Subversion wrapper.",
    "version": "1.0.1",
    "project_urls": {
        "Homepage": "https://github.com/dsoprea/PySvn"
    },
    "split_keywords": [
        "svn",
        "subversion"
    ],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "2ba5a23ed647d0cbdac48de23d822581e273f087364c57e2cd1c3efc979e91f5",
                "md5": "b88e1d57f14f027a58ce08f26ebf7f55",
                "sha256": "55f81f07853cc1d66d4800b0cfe2d3376ff02361a2b2361459dc22a0fab95247"
            },
            "downloads": -1,
            "filename": "svn-1.0.1.tar.gz",
            "has_sig": false,
            "md5_digest": "b88e1d57f14f027a58ce08f26ebf7f55",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": null,
            "size": 12814,
            "upload_time": "2020-02-01T21:11:02",
            "upload_time_iso_8601": "2020-02-01T21:11:02.626187Z",
            "url": "https://files.pythonhosted.org/packages/2b/a5/a23ed647d0cbdac48de23d822581e273f087364c57e2cd1c3efc979e91f5/svn-1.0.1.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2020-02-01 21:11:02",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "dsoprea",
    "github_project": "PySvn",
    "travis_ci": true,
    "coveralls": false,
    "github_actions": false,
    "requirements": [],
    "tox": true,
    "lcname": "svn"
}
        
Elapsed time: 4.58554s