.. _quickstart: Quickstart ========== Say you don't want to install ``vcs`` or just want to begin with really fast tutorial? Not a problem, just follow sections below. Prepare ------- We will try to show you how you can use ``vcs`` directly on repository. But hey, ``vcs`` is maintained within git `repository `_ already, so why not use it? Simply run following commands in your shell .. code-block:: bash cd /tmp git clone git://github.com/codeinn/vcs.git cd vcs Now run your python interpreter of choice:: $ python >>> .. note:: You may of course put your clone of ``vcs`` wherever you like but running python shell *inside* of it would allow you to use just cloned version of ``vcs``. Take the shortcut ----------------- There is no need to import everything from ``vcs`` - in fact, all you'd need is to import ``get_repo``, at least for now. Then, simply initialize repository object by providing it's type and path. .. code-block:: python >>> import vcs >>> # create repository representation at current dir >>> repo = vcs.get_repo(path='') .. note:: In above example we didn't specify scm. We can provide as second argument to the ``get_repo`` function, i.e. ``get_repo('', 'hg')``. Basics ------ Let's ask repo about the content... .. code-block:: python >>> root = repo.get_changeset().get_node('') >>> print root.nodes # prints nodes of the RootNode [, , , # ... (chopped) >>> >>> # get 10th changeset >>> chset = repo.get_changeset(10) >>> print chset >>> >>> # any backend would return latest changeset if revision is not given >>> tip = repo.get_changeset() >>> tip == repo.get_changeset('tip') # for git/mercurial backend 'tip' is allowed True >>> tip == repo.get_changeset(None) # any backend allow revision to be None (default) True >>> tip.raw_id == repo.revisions[-1] True >>> >>> # Iterate repository >>> for cs in repo: ... print cs ... ... >>> >>> >>> ... Walking ------- Now let's ask for nodes at revision faebbb751cc36c137127c50f57bcdb5f1c540013 (https://github.com/codeinn/vcs/commit/faebbb751cc36c137127c50f57bcdb5f1c540013) .. code-block:: python >>> chset = repo.get_changeset('faebbb751cc36c137127c50f57bcdb5f1c540013') >>> root = chset.root >>> print root.dirs [, , ] .. note:: :ref:`api-nodes` are objects representing files and directories within the repository revision. .. code-block:: python >>> # Fetch vcs directory >>> vcs = repo.get_changeset('faebbb751cc36c137127c50f57bcdb5f1c540013').get_node('vcs') >>> print vcs.dirs [, , ] >>> backends_node = vcs.dirs[0] >>> print backends_node.nodes [, , , ] >>> print '\n'.join(backends_node.files[0].content.splitlines()[:4]) # -*- coding: utf-8 -*- """ vcs.backends ~~~~~~~~~~~~ Getting meta data ----------------- Make ``vcs`` show us some meta information Tags and branches ~~~~~~~~~~~~~~~~~ .. code-block:: python >>> print repo.branches OrderedDict([('master', 'fe568b4081755c12abf6ba673ba777fc02a415f3')]) >>> for tag, raw_id in repo.tags.items(): ... print tag.rjust(10), '|', raw_id ... v0.1.9 | 341d28f0eec5ddf0b6b77871e13c2bbd6bec685c v0.1.8 | 74ebce002c088b8a5ecf40073db09375515ecd68 v0.1.7 | 4d78bf73b5c22c82b68f902f138f7881b4fffa2c v0.1.6 | 0205cb3f44223fb3099d12a77a69c81b798772d9 v0.1.5 | 6c0ce52b229aa978889e91b38777f800e85f330b v0.1.4 | 7d735150934cd7645ac3051903add952390324a5 v0.1.3 | 5a3a8fb005554692b16e21dee62bf02667d8dc3e v0.1.2 | 0ba5f8a4660034ff25c0cac2a5baabf5d2791d63 v0.1.11 | c60f01b77c42dce653d6b1d3b04689862c261929 v0.1.10 | 10cddef6b794696066fb346434014f0a56810218 v0.1.1 | e6ea6d16e2f26250124a1f4b4fe37a912f9d86a0 Give me a file, finally! ~~~~~~~~~~~~~~~~~~~~~~~~ .. code-block:: python >>> import vcs >>> repo = vcs.get_repo('') >>> chset = repo.get_changeset('faebbb751cc36c137127c50f57bcdb5f1c540013') >>> root = chset.get_node('') >>> backends = root.get_node('vcs/backends') >>> backends.files [, , , ] >>> f = backends.get_node('hg.py') >>> f.name 'hg.py' >>> f.path 'vcs/backends/hg.py' >>> f.size 28549 >>> f.last_changeset >>> f.last_changeset.date datetime.datetime(2011, 2, 28, 23, 23, 5) >>> f.last_changeset.message u'fixed bug in get_changeset when 0 or None was passed' >>> f.last_changeset.author u'marcinkuzminski ' >>> f.mimetype 'text/x-python' >>> # Following would raise exception unless you have pygments installed >>> f.lexer >>> f.lexer_alias # shortcut to get first of lexers' available aliases 'python' >>> # wanna go back? why? oh, whatever... >>> f.parent >>> >>> # is it cached? Hell yeah... >>> f is f.parent.get_node('hg.py') is chset.get_node('vcs/backends/hg.py') True How about history? ~~~~~~~~~~~~~~~~~~ It is possible to retrieve changesets for which file node has been changed and this is pretty damn simple. Let's say we want to see history of the file located at ``vcs/nodes.py``. .. code-block:: python >>> f = repo.get_changeset().get_node('vcs/nodes.py') >>> for cs in f.history: ... print cs ... Note that ``history`` attribute is computed lazily and returned list is reversed - changesets are retrieved from most recent to oldest. Show me the difference! ~~~~~~~~~~~~~~~~~~~~~~~ Here we present naive implementation of diff table for the given file node located at ``vcs/nodes.py``. First we have to get the node from repository. After that we retrieve last changeset for which the file has been modified and we create a html file using `difflib`_. .. code-block:: python >>> new = repo.get_changeset(repo.tags['v0.1.11']) >>> old = repo.get_changeset(repo.tags['v0.1.10']) >>> f_old = old.get_node('vcs/nodes.py') >>> f_new = new.get_node('vcs/nodes.py') >>> f_old = repo.get_changeset(81).get_node(f.path) >>> out = open('/tmp/out.html', 'w') >>> from difflib import HtmlDiff >>> hd = HtmlDiff(tabsize=4) >>> diffs = hd.make_file(f_new.content.split('\n'), f_old.content.split('\n')) >>> out.write(diffs) >>> out.close() Now open file at ``/tmp/out.html`` in your favorite browser. .. _difflib: http://docs.python.org/library/difflib.html