Added: incubator/bloodhound/vendor/trac/current/tracopt/versioncontrol/svn/tests/svn_fs.py URL: http://svn.apache.org/viewvc/incubator/bloodhound/vendor/trac/current/tracopt/versioncontrol/svn/tests/svn_fs.py?rev=1398858&view=auto ============================================================================== --- incubator/bloodhound/vendor/trac/current/tracopt/versioncontrol/svn/tests/svn_fs.py (added) +++ incubator/bloodhound/vendor/trac/current/tracopt/versioncontrol/svn/tests/svn_fs.py Tue Oct 16 15:55:00 2012 @@ -0,0 +1,916 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C)2005-2009 Edgewall Software +# Copyright (C) 2005 Christopher Lenz <cml...@gmx.de> +# All rights reserved. +# +# This software is licensed as described in the file COPYING, which +# you should have received as part of this distribution. The terms +# are also available at http://trac.edgewall.org/wiki/TracLicense. +# +# This software consists of voluntary contributions made by many +# individuals. For the exact contribution history, see the revision +# history and logs, available at http://trac.edgewall.org/log/. +# +# Author: Christopher Lenz <cml...@gmx.de> + +from datetime import datetime +import new +import os.path +import stat +import shutil +import tempfile +import unittest + +from StringIO import StringIO + +try: + from svn import core, repos + has_svn = True +except ImportError: + has_svn = False + +from trac.test import EnvironmentStub, TestSetup +from trac.core import TracError +from trac.resource import Resource, resource_exists +from trac.util.concurrency import get_thread_id +from trac.util.datefmt import utc +from trac.versioncontrol import DbRepositoryProvider, Changeset, Node, \ + NoSuchChangeset +from tracopt.versioncontrol.svn import svn_fs + +REPOS_PATH = os.path.join(tempfile.gettempdir(), 'trac-svnrepos') +REPOS_NAME = 'repo' + +HEAD = 22 +TETE = 21 + + +class SubversionRepositoryTestSetup(TestSetup): + + def setUp(self): + dumpfile = open(os.path.join(os.path.split(__file__)[0], + 'svnrepos.dump')) + + svn_fs._import_svn() + core.apr_initialize() + pool = core.svn_pool_create(None) + dumpstream = None + try: + if os.path.exists(REPOS_PATH): + print 'trouble ahead with db/rep-cache.db... see #8278' + r = repos.svn_repos_create(REPOS_PATH, '', '', None, None, pool) + if hasattr(repos, 'svn_repos_load_fs2'): + repos.svn_repos_load_fs2(r, dumpfile, StringIO(), + repos.svn_repos_load_uuid_default, '', + 0, 0, None, pool) + else: + dumpstream = core.svn_stream_from_aprfile(dumpfile, pool) + repos.svn_repos_load_fs(r, dumpstream, None, + repos.svn_repos_load_uuid_default, '', + None, None, pool) + finally: + if dumpstream: + core.svn_stream_close(dumpstream) + core.svn_pool_destroy(pool) + core.apr_terminate() + + def tearDown(self): + repos.svn_repos_delete(REPOS_PATH) + + +# -- Re-usable test mixins + +class NormalTests(object): + + def test_resource_exists(self): + repos = Resource('repository', REPOS_NAME) + self.assertEqual(True, resource_exists(self.env, repos)) + self.assertEqual(False, resource_exists(self.env, repos(id='xxx'))) + node = repos.child('source', u'tête') + self.assertEqual(True, resource_exists(self.env, node)) + self.assertEqual(False, resource_exists(self.env, node(id='xxx'))) + cset = repos.child('changeset', HEAD) + self.assertEqual(True, resource_exists(self.env, cset)) + self.assertEqual(False, resource_exists(self.env, cset(id=123456))) + + def test_repos_normalize_path(self): + self.assertEqual('/', self.repos.normalize_path('/')) + self.assertEqual('/', self.repos.normalize_path('')) + self.assertEqual('/', self.repos.normalize_path(None)) + self.assertEqual(u'tête', self.repos.normalize_path(u'tête')) + self.assertEqual(u'tête', self.repos.normalize_path(u'/tête')) + self.assertEqual(u'tête', self.repos.normalize_path(u'tête/')) + self.assertEqual(u'tête', self.repos.normalize_path(u'/tête/')) + + def test_repos_normalize_rev(self): + self.assertEqual(HEAD, self.repos.normalize_rev('latest')) + self.assertEqual(HEAD, self.repos.normalize_rev('head')) + self.assertEqual(HEAD, self.repos.normalize_rev('')) + self.assertRaises(NoSuchChangeset, + self.repos.normalize_rev, 'something else') + self.assertEqual(HEAD, self.repos.normalize_rev(None)) + self.assertEqual(11, self.repos.normalize_rev('11')) + self.assertEqual(11, self.repos.normalize_rev(11)) + + def test_rev_navigation(self): + self.assertEqual(1, self.repos.oldest_rev) + self.assertEqual(None, self.repos.previous_rev(0)) + self.assertEqual(None, self.repos.previous_rev(1)) + self.assertEqual(HEAD, self.repos.youngest_rev) + self.assertEqual(6, self.repos.next_rev(5)) + self.assertEqual(7, self.repos.next_rev(6)) + # ... + self.assertEqual(None, self.repos.next_rev(HEAD)) + self.assertRaises(NoSuchChangeset, self.repos.normalize_rev, HEAD + 1) + + def test_rev_path_navigation(self): + self.assertEqual(1, self.repos.oldest_rev) + self.assertEqual(None, self.repos.previous_rev(0, u'tête')) + self.assertEqual(None, self.repos.previous_rev(1, u'tête')) + self.assertEqual(HEAD, self.repos.youngest_rev) + self.assertEqual(6, self.repos.next_rev(5, u'tête')) + self.assertEqual(13, self.repos.next_rev(6, u'tête')) + # ... + self.assertEqual(None, self.repos.next_rev(HEAD, u'tête')) + # test accentuated characters + self.assertEqual(None, + self.repos.previous_rev(17, u'tête/R\xe9sum\xe9.txt')) + self.assertEqual(17, self.repos.next_rev(16, u'tête/R\xe9sum\xe9.txt')) + + def test_has_node(self): + self.assertEqual(False, self.repos.has_node(u'/tête/dir1', 3)) + self.assertEqual(True, self.repos.has_node(u'/tête/dir1', 4)) + self.assertEqual(True, self.repos.has_node(u'/tête/dir1')) + + def test_get_node(self): + node = self.repos.get_node(u'/tête') + self.assertEqual(u'tête', node.name) + self.assertEqual(u'/tête', node.path) + self.assertEqual(Node.DIRECTORY, node.kind) + self.assertEqual(HEAD, node.rev) + self.assertEqual(TETE, node.created_rev) + self.assertEqual(datetime(2007, 4, 30, 17, 45, 26, 234375, utc), + node.last_modified) + node = self.repos.get_node(u'/tête/README.txt') + self.assertEqual('README.txt', node.name) + self.assertEqual(u'/tête/README.txt', node.path) + self.assertEqual(Node.FILE, node.kind) + self.assertEqual(HEAD, node.rev) + self.assertEqual(3, node.created_rev) + self.assertEqual(datetime(2005, 4, 1, 13, 24, 58, 234643, utc), + node.last_modified) + + def test_get_node_specific_rev(self): + node = self.repos.get_node(u'/tête', 1) + self.assertEqual(u'tête', node.name) + self.assertEqual(u'/tête', node.path) + self.assertEqual(Node.DIRECTORY, node.kind) + self.assertEqual(1, node.rev) + self.assertEqual(datetime(2005, 4, 1, 10, 0, 52, 353248, utc), + node.last_modified) + node = self.repos.get_node(u'/tête/README.txt', 2) + self.assertEqual('README.txt', node.name) + self.assertEqual(u'/tête/README.txt', node.path) + self.assertEqual(Node.FILE, node.kind) + self.assertEqual(2, node.rev) + self.assertEqual(datetime(2005, 4, 1, 13, 12, 18, 216267, utc), + node.last_modified) + + def test_get_dir_entries(self): + node = self.repos.get_node(u'/tête') + entries = node.get_entries() + self.assertEqual('dir1', entries.next().name) + self.assertEqual('mpp_proc', entries.next().name) + self.assertEqual('v2', entries.next().name) + self.assertEqual('README3.txt', entries.next().name) + self.assertEqual(u'R\xe9sum\xe9.txt', entries.next().name) + self.assertEqual('README.txt', entries.next().name) + self.assertRaises(StopIteration, entries.next) + + def test_get_file_entries(self): + node = self.repos.get_node(u'/tête/README.txt') + entries = node.get_entries() + self.assertRaises(StopIteration, entries.next) + + def test_get_dir_content(self): + node = self.repos.get_node(u'/tête') + self.assertEqual(None, node.content_length) + self.assertEqual(None, node.content_type) + self.assertEqual(None, node.get_content()) + + def test_get_file_content(self): + node = self.repos.get_node(u'/tête/README.txt') + self.assertEqual(8, node.content_length) + self.assertEqual('text/plain', node.content_type) + self.assertEqual('A test.\n', node.get_content().read()) + + def test_get_dir_properties(self): + f = self.repos.get_node(u'/tête') + props = f.get_properties() + self.assertEqual(1, len(props)) + + def test_get_file_properties(self): + f = self.repos.get_node(u'/tête/README.txt') + props = f.get_properties() + self.assertEqual('native', props['svn:eol-style']) + self.assertEqual('text/plain', props['svn:mime-type']) + + def test_created_path_rev(self): + node = self.repos.get_node(u'/tête/README3.txt', 15) + self.assertEqual(15, node.rev) + self.assertEqual(u'/tête/README3.txt', node.path) + self.assertEqual(14, node.created_rev) + self.assertEqual(u'tête/README3.txt', node.created_path) + + def test_created_path_rev_parent_copy(self): + node = self.repos.get_node('/tags/v1/README.txt', 15) + self.assertEqual(15, node.rev) + self.assertEqual('/tags/v1/README.txt', node.path) + self.assertEqual(3, node.created_rev) + self.assertEqual(u'tête/README.txt', node.created_path) + + # Revision Log / node history + + def test_get_node_history(self): + node = self.repos.get_node(u'/tête/README3.txt') + history = node.get_history() + self.assertEqual((u'tête/README3.txt', 14, 'copy'), history.next()) + self.assertEqual((u'tête/README2.txt', 6, 'copy'), history.next()) + self.assertEqual((u'tête/README.txt', 3, 'edit'), history.next()) + self.assertEqual((u'tête/README.txt', 2, 'add'), history.next()) + self.assertRaises(StopIteration, history.next) + + def test_get_node_history_limit(self): + node = self.repos.get_node(u'/tête/README3.txt') + history = node.get_history(2) + self.assertEqual((u'tête/README3.txt', 14, 'copy'), history.next()) + self.assertEqual((u'tête/README2.txt', 6, 'copy'), history.next()) + self.assertRaises(StopIteration, history.next) + + def test_get_node_history_follow_copy(self): + node = self.repos.get_node('/tags/v1/README.txt') + history = node.get_history() + self.assertEqual(('tags/v1/README.txt', 7, 'copy'), history.next()) + self.assertEqual((u'tête/README.txt', 3, 'edit'), history.next()) + self.assertEqual((u'tête/README.txt', 2, 'add'), history.next()) + self.assertRaises(StopIteration, history.next) + + def test_get_copy_ancestry(self): + node = self.repos.get_node('/tags/v1/README.txt') + ancestry = node.get_copy_ancestry() + self.assertEqual([(u'tête/README.txt', 6)], ancestry) + for path, rev in ancestry: + self.repos.get_node(path, rev) # shouldn't raise NoSuchNode + + node = self.repos.get_node(u'/tête/README3.txt') + ancestry = node.get_copy_ancestry() + self.assertEqual([(u'tête/README2.txt', 13), + (u'tête/README.txt', 3)], ancestry) + for path, rev in ancestry: + self.repos.get_node(path, rev) # shouldn't raise NoSuchNode + + node = self.repos.get_node('/branches/v1x') + ancestry = node.get_copy_ancestry() + self.assertEqual([(u'tags/v1.1', 11), + (u'branches/v1x', 9), + (u'tags/v1', 7), + (u'tête', 6)], ancestry) + for path, rev in ancestry: + self.repos.get_node(path, rev) # shouldn't raise NoSuchNode + + def test_get_copy_ancestry_for_move(self): + node = self.repos.get_node(u'/tête/dir1/dir2', 5) + ancestry = node.get_copy_ancestry() + self.assertEqual([(u'tête/dir2', 4)], ancestry) + for path, rev in ancestry: + self.repos.get_node(path, rev) # shouldn't raise NoSuchNode + + def test_get_branch_origin(self): + node = self.repos.get_node('/tags/v1/README.txt') + self.assertEqual(7, node.get_branch_origin()) + node = self.repos.get_node(u'/tête/README3.txt') + self.assertEqual(14, node.get_branch_origin()) + node = self.repos.get_node('/branches/v1x') + self.assertEqual(12, node.get_branch_origin()) + node = self.repos.get_node(u'/tête/dir1/dir2', 5) + self.assertEqual(5, node.get_branch_origin()) + + # Revision Log / path history + + def test_get_path_history(self): + history = self.repos.get_path_history(u'/tête/README2.txt', None) + self.assertEqual((u'tête/README2.txt', 14, 'delete'), history.next()) + self.assertEqual((u'tête/README2.txt', 6, 'copy'), history.next()) + self.assertEqual((u'tête/README.txt', 3, 'unknown'), history.next()) + self.assertRaises(StopIteration, history.next) + + def test_get_path_history_copied_file(self): + history = self.repos.get_path_history('/tags/v1/README.txt', None) + self.assertEqual(('tags/v1/README.txt', 7, 'copy'), history.next()) + self.assertEqual((u'tête/README.txt', 3, 'unknown'), history.next()) + self.assertRaises(StopIteration, history.next) + + def test_get_path_history_copied_dir(self): + history = self.repos.get_path_history('/branches/v1x', None) + self.assertEqual(('branches/v1x', 12, 'copy'), history.next()) + self.assertEqual(('tags/v1.1', 10, 'unknown'), history.next()) + self.assertEqual(('branches/v1x', 11, 'delete'), history.next()) + self.assertEqual(('branches/v1x', 9, 'edit'), history.next()) + self.assertEqual(('branches/v1x', 8, 'copy'), history.next()) + self.assertEqual(('tags/v1', 7, 'unknown'), history.next()) + self.assertRaises(StopIteration, history.next) + + # Diffs + + def _cmp_diff(self, expected, got): + if expected[0]: + old = self.repos.get_node(*expected[0]) + self.assertEqual((old.path, old.rev), (got[0].path, got[0].rev)) + if expected[1]: + new = self.repos.get_node(*expected[1]) + self.assertEqual((new.path, new.rev), (got[1].path, got[1].rev)) + self.assertEqual(expected[2], (got[2], got[3])) + + def test_diff_file_different_revs(self): + diffs = self.repos.get_changes(u'tête/README.txt', 2, + u'tête/README.txt', 3) + self._cmp_diff(((u'tête/README.txt', 2), + (u'tête/README.txt', 3), + (Node.FILE, Changeset.EDIT)), diffs.next()) + self.assertRaises(StopIteration, diffs.next) + + def test_diff_file_different_files(self): + diffs = self.repos.get_changes('branches/v1x/README.txt', 12, + 'branches/v1x/README2.txt', 12) + self._cmp_diff((('branches/v1x/README.txt', 12), + ('branches/v1x/README2.txt', 12), + (Node.FILE, Changeset.EDIT)), diffs.next()) + self.assertRaises(StopIteration, diffs.next) + + def test_diff_file_no_change(self): + diffs = self.repos.get_changes(u'tête/README.txt', 7, + 'tags/v1/README.txt', 7) + self.assertRaises(StopIteration, diffs.next) + + def test_diff_dir_different_revs(self): + diffs = self.repos.get_changes(u'tête', 4, u'tête', 8) + self._cmp_diff((None, (u'tête/README2.txt', 8), + (Node.FILE, Changeset.ADD)), diffs.next()) + self._cmp_diff((None, (u'tête/dir1/dir2', 8), + (Node.DIRECTORY, Changeset.ADD)), diffs.next()) + self._cmp_diff((None, (u'tête/dir1/dir3', 8), + (Node.DIRECTORY, Changeset.ADD)), diffs.next()) + self._cmp_diff(((u'tête/dir2', 4), None, + (Node.DIRECTORY, Changeset.DELETE)), diffs.next()) + self._cmp_diff(((u'tête/dir3', 4), None, + (Node.DIRECTORY, Changeset.DELETE)), diffs.next()) + self.assertRaises(StopIteration, diffs.next) + + def test_diff_dir_different_dirs(self): + diffs = self.repos.get_changes(u'tête', 1, 'branches/v1x', 12) + self._cmp_diff((None, ('branches/v1x/README.txt', 12), + (Node.FILE, Changeset.ADD)), diffs.next()) + self._cmp_diff((None, ('branches/v1x/README2.txt', 12), + (Node.FILE, Changeset.ADD)), diffs.next()) + self._cmp_diff((None, ('branches/v1x/dir1', 12), + (Node.DIRECTORY, Changeset.ADD)), diffs.next()) + self._cmp_diff((None, ('branches/v1x/dir1/dir2', 12), + (Node.DIRECTORY, Changeset.ADD)), diffs.next()) + self._cmp_diff((None, ('branches/v1x/dir1/dir3', 12), + (Node.DIRECTORY, Changeset.ADD)), diffs.next()) + self.assertRaises(StopIteration, diffs.next) + + def test_diff_dir_no_change(self): + diffs = self.repos.get_changes(u'tête', 7, + 'tags/v1', 7) + self.assertRaises(StopIteration, diffs.next) + + # Changesets + + def test_changeset_repos_creation(self): + chgset = self.repos.get_changeset(0) + self.assertEqual(0, chgset.rev) + self.assertEqual('', chgset.message) + self.assertEqual('', chgset.author) + self.assertEqual(datetime(2005, 4, 1, 9, 57, 41, 312767, utc), + chgset.date) + self.assertRaises(StopIteration, chgset.get_changes().next) + + def test_changeset_added_dirs(self): + chgset = self.repos.get_changeset(1) + self.assertEqual(1, chgset.rev) + self.assertEqual('Initial directory layout.', chgset.message) + self.assertEqual('john', chgset.author) + self.assertEqual(datetime(2005, 4, 1, 10, 0, 52, 353248, utc), + chgset.date) + + changes = chgset.get_changes() + self.assertEqual(('branches', Node.DIRECTORY, Changeset.ADD, None, -1), + changes.next()) + self.assertEqual(('tags', Node.DIRECTORY, Changeset.ADD, None, -1), + changes.next()) + self.assertEqual((u'tête', Node.DIRECTORY, Changeset.ADD, None, -1), + changes.next()) + self.assertRaises(StopIteration, changes.next) + + def test_changeset_file_edit(self): + chgset = self.repos.get_changeset(3) + self.assertEqual(3, chgset.rev) + self.assertEqual('Fixed README.\n', chgset.message) + self.assertEqual('kate', chgset.author) + self.assertEqual(datetime(2005, 4, 1, 13, 24, 58, 234643, utc), + chgset.date) + + changes = chgset.get_changes() + self.assertEqual((u'tête/README.txt', Node.FILE, Changeset.EDIT, + u'tête/README.txt', 2), changes.next()) + self.assertRaises(StopIteration, changes.next) + + def test_changeset_dir_moves(self): + chgset = self.repos.get_changeset(5) + self.assertEqual(5, chgset.rev) + self.assertEqual('Moved directories.', chgset.message) + self.assertEqual('kate', chgset.author) + self.assertEqual(datetime(2005, 4, 1, 16, 25, 39, 658099, utc), + chgset.date) + + changes = chgset.get_changes() + self.assertEqual((u'tête/dir1/dir2', Node.DIRECTORY, Changeset.MOVE, + u'tête/dir2', 4), changes.next()) + self.assertEqual((u'tête/dir1/dir3', Node.DIRECTORY, Changeset.MOVE, + u'tête/dir3', 4), changes.next()) + self.assertRaises(StopIteration, changes.next) + + def test_changeset_file_copy(self): + chgset = self.repos.get_changeset(6) + self.assertEqual(6, chgset.rev) + self.assertEqual('More things to read', chgset.message) + self.assertEqual('john', chgset.author) + self.assertEqual(datetime(2005, 4, 1, 18, 56, 46, 985846, utc), + chgset.date) + + changes = chgset.get_changes() + self.assertEqual((u'tête/README2.txt', Node.FILE, Changeset.COPY, + u'tête/README.txt', 3), changes.next()) + self.assertRaises(StopIteration, changes.next) + + def test_changeset_root_propset(self): + chgset = self.repos.get_changeset(13) + self.assertEqual(13, chgset.rev) + self.assertEqual('Setting property on the repository_dir root', + chgset.message) + changes = chgset.get_changes() + self.assertEqual(('/', Node.DIRECTORY, Changeset.EDIT, '/', 12), + changes.next()) + self.assertEqual((u'tête', Node.DIRECTORY, Changeset.EDIT, u'tête', 6), + changes.next()) + self.assertRaises(StopIteration, changes.next) + + def test_changeset_base_path_rev(self): + chgset = self.repos.get_changeset(9) + self.assertEqual(9, chgset.rev) + changes = chgset.get_changes() + self.assertEqual(('branches/v1x/README.txt', Node.FILE, + Changeset.EDIT, u'tête/README.txt', 3), + changes.next()) + self.assertRaises(StopIteration, changes.next) + + def test_changeset_rename_and_edit(self): + chgset = self.repos.get_changeset(14) + self.assertEqual(14, chgset.rev) + changes = chgset.get_changes() + self.assertEqual((u'tête/README3.txt', Node.FILE, + Changeset.MOVE, u'tête/README2.txt', 13), + changes.next()) + self.assertRaises(StopIteration, changes.next) + + def test_changeset_edit_after_wc2wc_copy__original_deleted(self): + chgset = self.repos.get_changeset(16) + self.assertEqual(16, chgset.rev) + changes = chgset.get_changes() + self.assertEqual(('branches/v2', Node.DIRECTORY, Changeset.COPY, + 'tags/v1.1', 14), + changes.next()) + self.assertEqual(('branches/v2/README2.txt', Node.FILE, + Changeset.EDIT, u'tête/README2.txt', 6), + changes.next()) + self.assertRaises(StopIteration, changes.next) + + def test_fancy_rename_double_delete(self): + chgset = self.repos.get_changeset(19) + self.assertEqual(19, chgset.rev) + changes = chgset.get_changes() + self.assertEqual((u'tête/mpp_proc', Node.DIRECTORY, + Changeset.MOVE, u'tête/Xprimary_proc', 18), + changes.next()) + self.assertEqual((u'tête/mpp_proc/Xprimary_pkg.vhd', + Node.FILE, Changeset.DELETE, + u'tête/Xprimary_proc/Xprimary_pkg.vhd', 18), + changes.next()) + self.assertEqual((u'tête/mpp_proc/Xprimary_proc', Node.DIRECTORY, + Changeset.COPY, u'tête/Xprimary_proc', 18), + changes.next()) + self.assertEqual((u'tête/mpp_proc/Xprimary_proc/Xprimary_pkg.vhd', + Node.FILE, Changeset.DELETE, + u'tête/Xprimary_proc/Xprimary_pkg.vhd', 18), + changes.next()) + self.assertRaises(StopIteration, changes.next) + + def test_copy_with_deletions_below_copy(self): + """Regression test for #4900.""" + chgset = self.repos.get_changeset(22) + self.assertEqual(22, chgset.rev) + changes = chgset.get_changes() + self.assertEqual((u'branches/v3', 'dir', 'copy', + u'tête', 21), changes.next()) + self.assertEqual((u'branches/v3/dir1', 'dir', 'delete', + u'tête/dir1', 21), changes.next()) + self.assertEqual((u'branches/v3/mpp_proc', 'dir', 'delete', + u'tête/mpp_proc', 21), changes.next()) + self.assertEqual((u'branches/v3/v2', 'dir', 'delete', + u'tête/v2', 21), changes.next()) + self.assertRaises(StopIteration, changes.next) + + def test_changeset_utf_8(self): + chgset = self.repos.get_changeset(20) + self.assertEqual(20, chgset.rev) + self.assertEqual(u'Chez moi ça marche\n', chgset.message) + self.assertEqual(u'Jonas Borgström', chgset.author) + + + +class ScopedTests(object): + + def test_repos_normalize_path(self): + self.assertEqual('/', self.repos.normalize_path('/')) + self.assertEqual('/', self.repos.normalize_path('')) + self.assertEqual('/', self.repos.normalize_path(None)) + self.assertEqual('dir1', self.repos.normalize_path('dir1')) + self.assertEqual('dir1', self.repos.normalize_path('/dir1')) + self.assertEqual('dir1', self.repos.normalize_path('dir1/')) + self.assertEqual('dir1', self.repos.normalize_path('/dir1/')) + + def test_repos_normalize_rev(self): + self.assertEqual(TETE, self.repos.normalize_rev('latest')) + self.assertEqual(TETE, self.repos.normalize_rev('head')) + self.assertEqual(TETE, self.repos.normalize_rev('')) + self.assertEqual(TETE, self.repos.normalize_rev(None)) + self.assertEqual(5, self.repos.normalize_rev('5')) + self.assertEqual(5, self.repos.normalize_rev(5)) + + def test_rev_navigation(self): + self.assertEqual(1, self.repos.oldest_rev) + self.assertEqual(None, self.repos.previous_rev(0)) + self.assertEqual(1, self.repos.previous_rev(2)) + self.assertEqual(TETE, self.repos.youngest_rev) + self.assertEqual(2, self.repos.next_rev(1)) + self.assertEqual(3, self.repos.next_rev(2)) + # ... + self.assertEqual(None, self.repos.next_rev(TETE)) + + def test_has_node(self): + self.assertEqual(False, self.repos.has_node('/dir1', 3)) + self.assertEqual(True, self.repos.has_node('/dir1', 4)) + + def test_get_node(self): + node = self.repos.get_node('/dir1') + self.assertEqual('dir1', node.name) + self.assertEqual('/dir1', node.path) + self.assertEqual(Node.DIRECTORY, node.kind) + self.assertEqual(TETE, node.rev) + self.assertEqual(5, node.created_rev) + self.assertEqual(datetime(2005, 4, 1, 16, 25, 39, 658099, utc), + node.last_modified) + node = self.repos.get_node('/README.txt') + self.assertEqual('README.txt', node.name) + self.assertEqual('/README.txt', node.path) + self.assertEqual(Node.FILE, node.kind) + self.assertEqual(TETE, node.rev) + self.assertEqual(3, node.created_rev) + self.assertEqual(datetime(2005, 4, 1, 13, 24, 58, 234643, utc), + node.last_modified) + + def test_get_node_specific_rev(self): + node = self.repos.get_node('/dir1', 4) + self.assertEqual('dir1', node.name) + self.assertEqual('/dir1', node.path) + self.assertEqual(Node.DIRECTORY, node.kind) + self.assertEqual(4, node.rev) + self.assertEqual(datetime(2005, 4, 1, 15, 42, 35, 450595, utc), + node.last_modified) + node = self.repos.get_node('/README.txt', 2) + self.assertEqual('README.txt', node.name) + self.assertEqual('/README.txt', node.path) + self.assertEqual(Node.FILE, node.kind) + self.assertEqual(2, node.rev) + self.assertEqual(datetime(2005, 4, 1, 13, 12, 18, 216267, utc), + node.last_modified) + + def test_get_dir_entries(self): + node = self.repos.get_node('/') + entries = node.get_entries() + self.assertEqual('dir1', entries.next().name) + self.assertEqual('mpp_proc', entries.next().name) + self.assertEqual('v2', entries.next().name) + self.assertEqual('README3.txt', entries.next().name) + self.assertEqual(u'R\xe9sum\xe9.txt', entries.next().name) + self.assertEqual('README.txt', entries.next().name) + self.assertRaises(StopIteration, entries.next) + + def test_get_file_entries(self): + node = self.repos.get_node('/README.txt') + entries = node.get_entries() + self.assertRaises(StopIteration, entries.next) + + def test_get_dir_content(self): + node = self.repos.get_node('/dir1') + self.assertEqual(None, node.content_length) + self.assertEqual(None, node.content_type) + self.assertEqual(None, node.get_content()) + + def test_get_file_content(self): + node = self.repos.get_node('/README.txt') + self.assertEqual(8, node.content_length) + self.assertEqual('text/plain', node.content_type) + self.assertEqual('A test.\n', node.get_content().read()) + + def test_get_dir_properties(self): + f = self.repos.get_node('/dir1') + props = f.get_properties() + self.assertEqual(0, len(props)) + + def test_get_file_properties(self): + f = self.repos.get_node('/README.txt') + props = f.get_properties() + self.assertEqual('native', props['svn:eol-style']) + self.assertEqual('text/plain', props['svn:mime-type']) + + # Revision Log / node history + + def test_get_history_scope(self): + """Regression test for #9504""" + node = self.repos.get_node('/') + history = list(node.get_history()) + self.assertEqual(('/', 1, 'add'), history[-1]) + initial_cset = self.repos.get_changeset(history[-1][1]) + self.assertEqual(1, initial_cset.rev) + + def test_get_node_history(self): + node = self.repos.get_node('/README3.txt') + history = node.get_history() + self.assertEqual(('README3.txt', 14, 'copy'), history.next()) + self.assertEqual(('README2.txt', 6, 'copy'), history.next()) + self.assertEqual(('README.txt', 3, 'edit'), history.next()) + self.assertEqual(('README.txt', 2, 'add'), history.next()) + self.assertRaises(StopIteration, history.next) + + def test_get_node_history_follow_copy(self): + node = self.repos.get_node('dir1/dir3', ) + history = node.get_history() + self.assertEqual(('dir1/dir3', 5, 'copy'), history.next()) + self.assertEqual(('dir3', 4, 'add'), history.next()) + self.assertRaises(StopIteration, history.next) + + def test_get_copy_ancestry(self): + node = self.repos.get_node(u'/README3.txt') + ancestry = node.get_copy_ancestry() + self.assertEqual([(u'README2.txt', 13), + (u'README.txt', 3)], ancestry) + for path, rev in ancestry: + self.repos.get_node(path, rev) # shouldn't raise NoSuchNode + + def test_get_copy_ancestry_for_move(self): + node = self.repos.get_node(u'/dir1/dir2', 5) + ancestry = node.get_copy_ancestry() + self.assertEqual([(u'dir2', 4)], ancestry) + for path, rev in ancestry: + self.repos.get_node(path, rev) # shouldn't raise NoSuchNode + + def test_get_branch_origin(self): + node = self.repos.get_node(u'/README3.txt') + self.assertEqual(14, node.get_branch_origin()) + node = self.repos.get_node(u'/dir1/dir2', 5) + self.assertEqual(5, node.get_branch_origin()) + + # Revision Log / path history + + def test_get_path_history(self): + history = self.repos.get_path_history('dir3', None) + self.assertEqual(('dir3', 5, 'delete'), history.next()) + self.assertEqual(('dir3', 4, 'add'), history.next()) + self.assertRaises(StopIteration, history.next) + + def test_get_path_history_copied_file(self): + history = self.repos.get_path_history('README3.txt', None) + self.assertEqual(('README3.txt', 14, 'copy'), history.next()) + self.assertEqual(('README2.txt', 6, 'unknown'), history.next()) + self.assertRaises(StopIteration, history.next) + + def test_get_path_history_copied_dir(self): + history = self.repos.get_path_history('dir1/dir3', None) + self.assertEqual(('dir1/dir3', 5, 'copy'), history.next()) + self.assertEqual(('dir3', 4, 'unknown'), history.next()) + self.assertRaises(StopIteration, history.next) + + def test_changeset_repos_creation(self): + chgset = self.repos.get_changeset(0) + self.assertEqual(0, chgset.rev) + self.assertEqual('', chgset.message) + self.assertEqual('', chgset.author) + self.assertEqual(datetime(2005, 4, 1, 9, 57, 41, 312767, utc), + chgset.date) + self.assertRaises(StopIteration, chgset.get_changes().next) + + def test_changeset_added_dirs(self): + chgset = self.repos.get_changeset(4) + self.assertEqual(4, chgset.rev) + self.assertEqual('More directories.', chgset.message) + self.assertEqual('john', chgset.author) + self.assertEqual(datetime(2005, 4, 1, 15, 42, 35, 450595, utc), + chgset.date) + + changes = chgset.get_changes() + self.assertEqual(('dir1', Node.DIRECTORY, 'add', None, -1), + changes.next()) + self.assertEqual(('dir2', Node.DIRECTORY, 'add', None, -1), + changes.next()) + self.assertEqual(('dir3', Node.DIRECTORY, 'add', None, -1), + changes.next()) + self.assertRaises(StopIteration, changes.next) + + def test_changeset_file_edit(self): + chgset = self.repos.get_changeset(3) + self.assertEqual(3, chgset.rev) + self.assertEqual('Fixed README.\n', chgset.message) + self.assertEqual('kate', chgset.author) + self.assertEqual(datetime(2005, 4, 1, 13, 24, 58, 234643, utc), + chgset.date) + + changes = chgset.get_changes() + self.assertEqual(('README.txt', Node.FILE, Changeset.EDIT, + 'README.txt', 2), changes.next()) + self.assertRaises(StopIteration, changes.next) + + def test_changeset_dir_moves(self): + chgset = self.repos.get_changeset(5) + self.assertEqual(5, chgset.rev) + self.assertEqual('Moved directories.', chgset.message) + self.assertEqual('kate', chgset.author) + self.assertEqual(datetime(2005, 4, 1, 16, 25, 39, 658099, utc), + chgset.date) + + changes = chgset.get_changes() + self.assertEqual(('dir1/dir2', Node.DIRECTORY, Changeset.MOVE, + 'dir2', 4), changes.next()) + self.assertEqual(('dir1/dir3', Node.DIRECTORY, Changeset.MOVE, + 'dir3', 4), changes.next()) + self.assertRaises(StopIteration, changes.next) + + def test_changeset_file_copy(self): + chgset = self.repos.get_changeset(6) + self.assertEqual(6, chgset.rev) + self.assertEqual('More things to read', chgset.message) + self.assertEqual('john', chgset.author) + self.assertEqual(datetime(2005, 4, 1, 18, 56, 46, 985846, utc), + chgset.date) + + changes = chgset.get_changes() + self.assertEqual(('README2.txt', Node.FILE, Changeset.COPY, + 'README.txt', 3), changes.next()) + self.assertRaises(StopIteration, changes.next) + + def test_changeset_root_propset(self): + chgset = self.repos.get_changeset(13) + self.assertEqual(13, chgset.rev) + self.assertEqual('Setting property on the repository_dir root', + chgset.message) + changes = chgset.get_changes() + self.assertEqual(('/', Node.DIRECTORY, Changeset.EDIT, '/', 6), + changes.next()) + self.assertRaises(StopIteration, changes.next) + + def test_changeset_copy_from_outside_and_delete(self): + chgset = self.repos.get_changeset(21) + self.assertEqual(21, chgset.rev) + self.assertEqual('copy from outside of the scope + delete', + chgset.message) + changes = chgset.get_changes() + self.assertEqual(('v2', Node.DIRECTORY, Changeset.ADD, None, -1), + changes.next()) + self.assertEqual(('v2/README2.txt', Node.FILE, Changeset.DELETE, + None, -1), changes.next()) + self.assertEqual(('v2/dir1', Node.DIRECTORY, Changeset.DELETE, + None, -1), changes.next()) + self.assertRaises(StopIteration, changes.next) + + +class RecentPathScopedTests(object): + + def test_rev_navigation(self): + self.assertEqual(False, self.repos.has_node('/', 1)) + self.assertEqual(False, self.repos.has_node('/', 2)) + self.assertEqual(False, self.repos.has_node('/', 3)) + self.assertEqual(True, self.repos.has_node('/', 4)) + # We can't make this work anymore because of #5213. + # self.assertEqual(4, self.repos.oldest_rev) + self.assertEqual(1, self.repos.oldest_rev) # should really be 4... + self.assertEqual(None, self.repos.previous_rev(4)) + + +class NonSelfContainedScopedTests(object): + + def test_mixed_changeset(self): + chgset = self.repos.get_changeset(7) + self.assertEqual(7, chgset.rev) + changes = chgset.get_changes() + self.assertEqual(('/', Node.DIRECTORY, Changeset.ADD, None, -1), + changes.next()) + self.assertRaises(TracError, lambda: self.repos.get_node(None, 6)) + + +class AnotherNonSelfContainedScopedTests(object): + + def test_mixed_changeset_with_edit(self): + chgset = self.repos.get_changeset(9) + self.assertEqual(9, chgset.rev) + changes = chgset.get_changes() + self.assertEqual(('v1x/README.txt', Node.FILE, Changeset.EDIT, + 'v1x/README.txt', 8), + changes.next()) + + +# -- Test cases for SubversionRepository + +class SubversionRepositoryTestCase(unittest.TestCase): + + def setUp(self): + self.env = EnvironmentStub() + repositories = self.env.config['repositories'] + DbRepositoryProvider(self.env).add_repository(REPOS_NAME, self.path, + 'direct-svnfs') + self.repos = self.env.get_repository(REPOS_NAME) + + def tearDown(self): + self.env.reset_db() + # needed to avoid issue with 'WindowsError: The process cannot access + # the file ... being used by another process: ...\rep-cache.db' + self.env.shutdown(get_thread_id()) + + +# -- Test cases for SvnCachedRepository + +class SvnCachedRepositoryTestCase(unittest.TestCase): + + def setUp(self): + self.env = EnvironmentStub() + DbRepositoryProvider(self.env).add_repository(REPOS_NAME, self.path, + 'svn') + self.repos = self.env.get_repository(REPOS_NAME) + self.repos.sync() + + def tearDown(self): + self.env.reset_db() + self.repos.close() + self.repos = None + + +def suite(): + suite = unittest.TestSuite() + if has_svn: + tests = [(NormalTests, ''), + (ScopedTests, u'/tête'), + (RecentPathScopedTests, u'/tête/dir1'), + (NonSelfContainedScopedTests, '/tags/v1'), + (AnotherNonSelfContainedScopedTests, '/branches'), + ] + skipped = { + 'SvnCachedRepositoryNormalTests': [ + 'test_changeset_repos_creation', + ], + 'SvnCachedRepositoryScopedTests': [ + 'test_changeset_repos_creation', + 'test_rev_navigation', + ], + } + for test, scope in tests: + tc = new.classobj('SubversionRepository' + test.__name__, + (SubversionRepositoryTestCase, test), + {'path': REPOS_PATH + scope}) + suite.addTest(unittest.makeSuite( + tc, 'test', suiteClass=SubversionRepositoryTestSetup)) + tc = new.classobj('SvnCachedRepository' + test.__name__, + (SvnCachedRepositoryTestCase, test), + {'path': REPOS_PATH + scope}) + for skip in skipped.get(tc.__name__, []): + setattr(tc, skip, lambda self: None) # no skip, so we cheat... + suite.addTest(unittest.makeSuite( + tc, 'test', suiteClass=SubversionRepositoryTestSetup)) + else: + print("SKIP: tracopt/versioncontrol/svn/tests/svn_fs.py (no svn " + "bindings)") + return suite + +if __name__ == '__main__': + runner = unittest.TextTestRunner() + runner.run(suite())
Propchange: incubator/bloodhound/vendor/trac/current/tracopt/versioncontrol/svn/tests/svn_fs.py ------------------------------------------------------------------------------ svn:eol-style = native Added: incubator/bloodhound/vendor/trac/current/tracopt/versioncontrol/svn/tests/svnrepos.dump URL: http://svn.apache.org/viewvc/incubator/bloodhound/vendor/trac/current/tracopt/versioncontrol/svn/tests/svnrepos.dump?rev=1398858&view=auto ============================================================================== --- incubator/bloodhound/vendor/trac/current/tracopt/versioncontrol/svn/tests/svnrepos.dump (added) +++ incubator/bloodhound/vendor/trac/current/tracopt/versioncontrol/svn/tests/svnrepos.dump Tue Oct 16 15:55:00 2012 @@ -0,0 +1,748 @@ +SVN-fs-dump-format-version: 2 + +UUID: 92ea810a-adf3-0310-b540-bef912dcf5ba + +Revision-number: 0 +Prop-content-length: 56 +Content-length: 56 + +K 8 +svn:date +V 27 +2005-04-01T09:57:41.312767Z +PROPS-END + +Revision-number: 1 +Prop-content-length: 124 +Content-length: 124 + +K 7 +svn:log +V 25 +Initial directory layout. +K 10 +svn:author +V 4 +john +K 8 +svn:date +V 27 +2005-04-01T10:00:52.353248Z +PROPS-END + +Node-path: branches +Node-kind: dir +Node-action: add +Prop-content-length: 10 +Content-length: 10 + +PROPS-END + + +Node-path: tags +Node-kind: dir +Node-action: add +Prop-content-length: 10 +Content-length: 10 + +PROPS-END + + +Node-path: tête +Node-kind: dir +Node-action: add +Prop-content-length: 10 +Content-length: 10 + +PROPS-END + + +Revision-number: 2 +Prop-content-length: 112 +Content-length: 112 + +K 7 +svn:log +V 13 +Added README. +K 10 +svn:author +V 4 +john +K 8 +svn:date +V 27 +2005-04-01T13:12:18.216267Z +PROPS-END + +Node-path: tête/README.txt +Node-kind: file +Node-action: add +Prop-content-length: 10 +Text-content-length: 8 +Text-content-md5: a0691c0f61f52683bcb05da98fe028c8 +Text-content-sha1: 59ccaf31a075b2a2fe64f83ca05e2694d692d4fc +Content-length: 18 + +PROPS-END +A text. + + +Revision-number: 3 +Prop-content-length: 113 +Content-length: 113 + +K 7 +svn:log +V 14 +Fixed README. + +K 10 +svn:author +V 4 +kate +K 8 +svn:date +V 27 +2005-04-01T13:24:58.234643Z +PROPS-END + +Node-path: tête/README.txt +Node-kind: file +Node-action: change +Prop-content-length: 75 +Text-content-length: 8 +Text-content-md5: eaf1c95c78c9f848636d357788bd4a4c +Text-content-sha1: 6aade8dde7d1b86b451b5d5f044a8ddcbab6b448 +Content-length: 83 + +K 13 +svn:mime-type +V 10 +text/plain +K 13 +svn:eol-style +V 6 +native +PROPS-END +A test. + + +Revision-number: 4 +Prop-content-length: 116 +Content-length: 116 + +K 7 +svn:log +V 17 +More directories. +K 10 +svn:author +V 4 +john +K 8 +svn:date +V 27 +2005-04-01T15:42:35.450595Z +PROPS-END + +Node-path: tête/dir1 +Node-kind: dir +Node-action: add +Prop-content-length: 10 +Content-length: 10 + +PROPS-END + + +Node-path: tête/dir2 +Node-kind: dir +Node-action: add +Prop-content-length: 10 +Content-length: 10 + +PROPS-END + + +Node-path: tête/dir3 +Node-kind: dir +Node-action: add +Prop-content-length: 10 +Content-length: 10 + +PROPS-END + + +Revision-number: 5 +Prop-content-length: 117 +Content-length: 117 + +K 7 +svn:log +V 18 +Moved directories. +K 10 +svn:author +V 4 +kate +K 8 +svn:date +V 27 +2005-04-01T16:25:39.658099Z +PROPS-END + +Node-path: tête/dir1/dir2 +Node-kind: dir +Node-action: add +Node-copyfrom-rev: 4 +Node-copyfrom-path: tête/dir2 + + +Node-path: tête/dir1/dir3 +Node-kind: dir +Node-action: add +Node-copyfrom-rev: 4 +Node-copyfrom-path: tête/dir3 + + +Node-path: tête/dir2 +Node-action: delete + + +Node-path: tête/dir3 +Node-action: delete + + +Revision-number: 6 +Prop-content-length: 118 +Content-length: 118 + +K 7 +svn:log +V 19 +More things to read +K 10 +svn:author +V 4 +john +K 8 +svn:date +V 27 +2005-04-01T18:56:46.985846Z +PROPS-END + +Node-path: tête/README2.txt +Node-kind: file +Node-action: add +Node-copyfrom-rev: 3 +Node-copyfrom-path: tête/README.txt +Text-copy-source-md5: eaf1c95c78c9f848636d357788bd4a4c +Text-copy-source-sha1: 6aade8dde7d1b86b451b5d5f044a8ddcbab6b448 + + +Revision-number: 7 +Prop-content-length: 151 +Content-length: 151 + +K 7 +svn:log +V 42 +test the tag operation (copy of directory) +K 10 +svn:author +V 13 +Administrator +K 8 +svn:date +V 27 +2005-04-14T15:06:20.717616Z +PROPS-END + +Node-path: tags/v1 +Node-kind: dir +Node-action: add +Node-copyfrom-rev: 6 +Node-copyfrom-path: tête + + +Revision-number: 8 +Prop-content-length: 124 +Content-length: 124 + +K 7 +svn:log +V 15 +Fix stuff in v1 +K 10 +svn:author +V 13 +Administrator +K 8 +svn:date +V 27 +2005-04-22T08:57:33.499643Z +PROPS-END + +Node-path: branches/v1x +Node-kind: dir +Node-action: add +Node-copyfrom-rev: 7 +Node-copyfrom-path: tags/v1 + + +Revision-number: 9 +Prop-content-length: 127 +Content-length: 127 + +K 7 +svn:log +V 18 +Now that's the fix +K 10 +svn:author +V 13 +Administrator +K 8 +svn:date +V 27 +2005-04-22T08:59:24.308979Z +PROPS-END + +Node-path: branches/v1x/README.txt +Node-kind: file +Node-action: change +Text-content-length: 16 +Text-content-md5: 02bcabffffd16fe0fc250f08cad95e0c +Text-content-sha1: 0828324174b10cc867b7255a84a8155cf89e1b8b +Content-length: 16 + +This is a test. + + +Revision-number: 10 +Prop-content-length: 141 +Content-length: 141 + +K 7 +svn:log +V 32 +Tagging v1.1 from the fix branch +K 10 +svn:author +V 13 +Administrator +K 8 +svn:date +V 27 +2005-04-22T09:00:34.549980Z +PROPS-END + +Node-path: tags/v1.1 +Node-kind: dir +Node-action: add +Node-copyfrom-rev: 9 +Node-copyfrom-path: branches/v1x + + +Revision-number: 11 +Prop-content-length: 191 +Content-length: 191 + +K 7 +svn:log +V 82 +''(a few months later)'' We don't need the fix branch anymore, 1.1 is super-stable +K 10 +svn:author +V 13 +Administrator +K 8 +svn:date +V 27 +2005-04-22T09:01:38.361737Z +PROPS-END + +Node-path: branches/v1x +Node-action: delete + + +Revision-number: 12 +Prop-content-length: 166 +Content-length: 166 + +K 7 +svn:log +V 57 +''(a few years later)'' Argh... v1.1 was buggy, after all +K 10 +svn:author +V 13 +Administrator +K 8 +svn:date +V 27 +2005-04-22T09:06:37.011174Z +PROPS-END + +Node-path: branches/v1x +Node-kind: dir +Node-action: add +Node-copyfrom-rev: 11 +Node-copyfrom-path: tags/v1.1 + + +Revision-number: 13 +Prop-content-length: 143 +Content-length: 143 + +K 7 +svn:log +V 43 +Setting property on the repository_dir root +K 10 +svn:author +V 5 +cboos +K 8 +svn:date +V 27 +2005-11-17T15:13:16.197772Z +PROPS-END + +Node-path: +Node-kind: dir +Node-action: change +Prop-content-length: 37 +Content-length: 37 + +K 10 +svn:ignore +V 6 +*.pyc + +PROPS-END + + +Node-path: tête +Node-kind: dir +Node-action: change +Prop-content-length: 37 +Content-length: 37 + +K 10 +svn:ignore +V 6 +*.pyc + +PROPS-END + + +Revision-number: 14 +Prop-content-length: 119 +Content-length: 119 + +K 7 +svn:log +V 19 +Testing rename+edit +K 10 +svn:author +V 5 +cboos +K 8 +svn:date +V 27 +2005-11-30T08:47:03.467814Z +PROPS-END + +Node-path: tête/README3.txt +Node-kind: file +Node-action: add +Node-copyfrom-rev: 13 +Node-copyfrom-path: tête/README2.txt +Text-copy-source-md5: eaf1c95c78c9f848636d357788bd4a4c +Text-copy-source-sha1: 6aade8dde7d1b86b451b5d5f044a8ddcbab6b448 +Text-content-length: 42 +Text-content-md5: 211b820b566541dd49a1283d6476d89f +Text-content-sha1: 7e9f46800519d6ae305f44cc07bd7568be3c9d5c +Content-length: 42 + +A test of svn move, followed by a change. + + +Node-path: tête/README2.txt +Node-action: delete + + +Revision-number: 15 +Prop-content-length: 162 +Content-length: 162 + +K 7 +svn:log +V 62 +Removing original file, just before committing the wc->wc copy +K 10 +svn:author +V 5 +cboos +K 8 +svn:date +V 27 +2005-12-06T12:47:36.271020Z +PROPS-END + +Node-path: tags/v1.1/README2.txt +Node-action: delete + + +Revision-number: 16 +Prop-content-length: 138 +Content-length: 138 + +K 7 +svn:log +V 38 +Committing wc->wc copy + local changes +K 10 +svn:author +V 5 +cboos +K 8 +svn:date +V 27 +2005-12-06T12:47:51.122376Z +PROPS-END + +Node-path: branches/v2 +Node-kind: dir +Node-action: add +Node-copyfrom-rev: 14 +Node-copyfrom-path: tags/v1.1 + + +Node-path: branches/v2/README2.txt +Node-kind: file +Node-action: change +Text-content-length: 47 +Text-content-md5: 9b7bad978c6ad159f939c3db2038cbb1 +Text-content-sha1: 4a475c10d832c28f9a9798477885c48146c0bc18 +Content-length: 47 + +A test + local modifications after wc->wc copy + + +Revision-number: 17 +Prop-content-length: 139 +Content-length: 139 + +K 7 +svn:log +V 39 +Test des caractères accentués (cp437) +K 10 +svn:author +V 5 +cboos +K 8 +svn:date +V 27 +2006-03-31T12:30:25.421875Z +PROPS-END + +Node-path: tête/Résumé.txt +Node-kind: file +Node-action: add +Prop-content-length: 10 +Text-content-length: 13 +Text-content-md5: 858e52306ecdfcb6f6eadb50d6f9086b +Text-content-sha1: f4802e1b42e6256148438ce62d9b95ba671c23f8 +Content-length: 23 + +PROPS-END +En résumé ... + +Revision-number: 18 +Prop-content-length: 124 +Content-length: 124 + +K 7 +svn:log +V 24 +Prepare for fancy rename +K 10 +svn:author +V 5 +cboos +K 8 +svn:date +V 27 +2006-09-27T10:40:38.671875Z +PROPS-END + +Node-path: tête/Xprimary_proc +Node-kind: dir +Node-action: add +Prop-content-length: 10 +Content-length: 10 + +PROPS-END + + +Node-path: tête/Xprimary_proc/Xprimary_pkg.vhd +Node-kind: file +Node-action: add +Prop-content-length: 10 +Text-content-length: 5 +Text-content-md5: 2debfdcf79f03e4a65a667d21ef9de14 +Text-content-sha1: 4c49b08e9b258e0e5867d76ce583c159597b6857 +Content-length: 15 + +PROPS-END +TEST + + +Revision-number: 19 +Prop-content-length: 145 +Content-length: 145 + +K 7 +svn:log +V 45 +Fancy copy+rename resulting in double delete. +K 10 +svn:author +V 5 +cboos +K 8 +svn:date +V 27 +2006-09-27T10:41:27.484375Z +PROPS-END + +Node-path: tête/mpp_proc +Node-kind: dir +Node-action: add +Node-copyfrom-rev: 18 +Node-copyfrom-path: tête/Xprimary_proc + + +Node-path: tête/mpp_proc/Xprimary_proc +Node-kind: dir +Node-action: add +Node-copyfrom-rev: 18 +Node-copyfrom-path: tête/Xprimary_proc + + +Node-path: tête/mpp_proc/Xprimary_proc/Xprimary_pkg.vhd +Node-action: delete + + +Node-path: tête/mpp_proc/Xprimary_pkg.vhd +Node-action: delete + + +Node-path: tête/Xprimary_proc +Node-action: delete + + +Revision-number: 20 +Prop-content-length: 132 +Content-length: 132 + +K 7 +svn:log +V 20 +Chez moi ça marche + +K 10 +svn:author +V 16 +Jonas Borgström +K 8 +svn:date +V 27 +2006-12-04T10:47:24.015625Z +PROPS-END + +Node-path: tête/Résumé.txt +Node-kind: file +Node-action: change +Text-content-length: 25 +Text-content-md5: c3744e0035c756a17fdf6dbbdd5719f0 +Text-content-sha1: f7453fe6bac18f7dc717295a30331297ff05ae14 +Content-length: 25 + +En résumé ... ça marche. + + +Revision-number: 21 +Prop-content-length: 139 +Content-length: 139 + +K 7 +svn:log +V 39 +copy from outside of the scope + delete +K 10 +svn:author +V 5 +cboos +K 8 +svn:date +V 27 +2007-04-30T17:45:26.234375Z +PROPS-END + +Node-path: tête/v2 +Node-kind: dir +Node-action: add +Node-copyfrom-rev: 20 +Node-copyfrom-path: branches/v2 + + +Node-path: tête/v2/dir1 +Node-action: delete + + +Node-path: tête/v2/README2.txt +Node-action: delete + + +Revision-number: 22 +Prop-content-length: 130 +Content-length: 130 + +K 7 +svn:log +V 30 +test delete after copy (#4900) +K 10 +svn:author +V 5 +cboos +K 8 +svn:date +V 27 +2010-02-26T14:48:19.377000Z +PROPS-END + +Node-path: branches/v3 +Node-kind: dir +Node-action: add +Node-copyfrom-rev: 21 +Node-copyfrom-path: tête + + +Node-path: branches/v3/v2 +Node-action: delete + + +Node-path: branches/v3/dir1 +Node-action: delete + + +Node-path: branches/v3/mpp_proc +Node-action: delete + +