Rev 19: More refactoring. Add some direct tests for GitModel. in http://bzr.arbash-meinel.com/plugins/git
John Arbash Meinel
john at arbash-meinel.com
Fri Nov 9 04:17:11 GMT 2007
At http://bzr.arbash-meinel.com/plugins/git
------------------------------------------------------------
revno: 19
revision-id:john at arbash-meinel.com-20071109041701-63ivdne9bip3f9fr
parent: john at arbash-meinel.com-20071108234431-voyj8yoshevk353j
committer: John Arbash Meinel <john at arbash-meinel.com>
branch nick: git
timestamp: Thu 2007-11-08 23:17:01 -0500
message:
More refactoring. Add some direct tests for GitModel.
added:
gitlib/errors.py errors.py-20071109041629-u1p6yfuljueipcv9-1
gitlib/model.py model.py-20071109031625-vi84303d1n5gnha1-1
tests/test_model.py test_model.py-20071109031625-vi84303d1n5gnha1-2
modified:
__init__.py __init__.py-20060715102359-vayyec84yioge4ok-1
gitlib/git_branch.py git_branch.py-20071108230535-su8dxk529f4uk9fx-2
gitlib/git_dir.py git_dir.py-20071108234408-ygidvy5hviixghsd-1
gitlib/git_repository.py git_repository.py-20071108234408-ygidvy5hviixghsd-2
tests/__init__.py __init__.py-20070202180350-njrb42t7fnv35d1k-2
tests/test_git_branch.py test_git_branch.py-20071108234408-ygidvy5hviixghsd-3
tests/test_git_dir.py test_git_dir.py-20071108234408-ygidvy5hviixghsd-4
tests/test_git_repository.py test_git_repository.-20071108234408-ygidvy5hviixghsd-5
-------------- next part --------------
=== added file 'gitlib/errors.py'
--- a/gitlib/errors.py 1970-01-01 00:00:00 +0000
+++ b/gitlib/errors.py 2007-11-09 04:17:01 +0000
@@ -0,0 +1,34 @@
+# Copyright (C) 2007 Canonical Ltd
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+"""A grouping of Exceptions for bzr-git"""
+
+from bzrlib import errors as bzr_errors
+
+
+class BzrGitError(bzr_errors.BzrError):
+ """The base-level exception for bzr-git errors."""
+
+
+class GitCommandError(BzrGitError):
+ """Raised when spawning 'git' does not return normally."""
+
+ _fmt = 'Command failed (%(returncode)s): command %(command)s\n%(stderr)s'
+
+ def __init__(self, command, returncode, stderr):
+ self.command = command
+ self.returncode = returncode
+ self.stderr = stderr
=== added file 'gitlib/model.py'
--- a/gitlib/model.py 1970-01-01 00:00:00 +0000
+++ b/gitlib/model.py 2007-11-09 04:17:01 +0000
@@ -0,0 +1,108 @@
+# Copyright (C) 2007 Canonical Ltd
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+"""The model for interacting with the git process, etc."""
+
+import subprocess
+
+from bzrlib.plugins.git.gitlib import errors
+
+
+class GitModel(object):
+ """API that follows GIT model closely"""
+
+ def __init__(self, git_dir):
+ self.git_dir = git_dir
+
+ def git_command(self, command, args):
+ return ['git', '--git-dir', self.git_dir, command] + args
+
+ def git_lines(self, command, args):
+ cmd = self.git_command(command, args)
+ p = subprocess.Popen(cmd,
+ stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE)
+ lines = p.stdout.readlines()
+ if p.wait() != 0:
+ raise errors.GitCommandError(cmd, p.returncode,
+ p.stderr.read().strip())
+ return lines
+
+ def git_line(self, command, args):
+ lines = self.git_lines(command, args)
+ return lines[0]
+
+ def cat_file(self, type, object_id, pretty=False):
+ args = []
+ if pretty:
+ args.append('-p')
+ else:
+ args.append(type)
+ args.append(object_id)
+ return self.git_lines('cat-file', args)
+
+ def rev_list(self, heads, max_count=None, header=False, parents=False):
+ args = []
+ if max_count is not None:
+ args.append('--max-count=%d' % max_count)
+ if header:
+ args.append('--header')
+ if parents:
+ args.append('--parents')
+ if heads is None:
+ args.append('--all')
+ else:
+ args.extend(heads)
+ return self.git_lines('rev-list', args)
+
+ def rev_parse(self, git_id):
+ args = ['--verify', git_id]
+ return self.git_line('rev-parse', args)
+
+ def get_head(self):
+ try:
+ return self.rev_parse('HEAD')
+ except errors.GitCommandError, e:
+ # Most likely, this is a null branch, so treat it as such
+ if e.stderr == 'fatal: Needed a single revision':
+ return None
+ raise
+
+ def ancestry(self, revisions):
+ ancestors = {}
+ for line in self.rev_list(revisions, parents=True):
+ entries = line.split()
+ ancestors[entries[0]] = entries[1:]
+ return ancestors
+
+ def ancestor_lines(self, revisions):
+ revision_lines = []
+ for line in self.rev_list(revisions, header=True):
+ if line.startswith('\x00'):
+ yield revision_lines
+ revision_lines = [line[1:].decode('latin-1')]
+ else:
+ revision_lines.append(line.decode('latin-1'))
+ assert revision_lines == ['']
+
+ def get_inventory(self, tree_id):
+ for line in self.cat_file('tree', tree_id, True):
+ sections = line.split(' ', 2)
+ obj_id, name = sections[2].split('\t', 1)
+ name = name.rstrip('\n')
+ if name.startswith('"'):
+ name = name[1:-1].decode('string_escape').decode('utf-8')
+ yield (sections[0], sections[1], obj_id, name)
=== added file 'tests/test_model.py'
--- a/tests/test_model.py 1970-01-01 00:00:00 +0000
+++ b/tests/test_model.py 2007-11-09 04:17:01 +0000
@@ -0,0 +1,60 @@
+# Copyright (C) 2007 Canonical Ltd
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+"""Test the model for interacting with the git process, etc."""
+
+from bzrlib.plugins.git import tests
+from bzrlib.plugins.git.gitlib import (
+ errors,
+ model,
+ )
+
+
+class TestModel(tests.TestCaseInTempDir):
+
+ def test_no_head(self):
+ tests.run_git('init')
+ themodel = model.GitModel('.git')
+ self.assertIs(None, themodel.get_head())
+
+ def test_no_repository(self):
+ themodel = model.GitModel('.git')
+ self.assertRaises(errors.GitCommandError, themodel.get_head)
+
+ def test_ancestors(self):
+ tests.run_git('init')
+ self.build_tree(['a'])
+ tests.run_git('add', 'a')
+ tests.run_git('commit', '-m', 'a')
+ tests.run_git('branch', 'foo')
+ self.build_tree_contents([('a', 'new a\n')])
+ tests.run_git('commit', '-a', '-m', 'new a')
+ tests.run_git('checkout', 'foo')
+ self.build_tree(['b'])
+ tests.run_git('add', 'b')
+ tests.run_git('commit', '-m', 'b')
+ tests.run_git('merge', 'master')
+
+ revisions = tests.run_git('rev-list', '--topo-order', 'HEAD')
+ revisions = revisions.splitlines()
+ graph = {revisions[0]:[revisions[2], revisions[1]],
+ revisions[1]:[revisions[3]],
+ revisions[2]:[revisions[3]],
+ revisions[3]:[],
+ }
+
+ themodel = model.GitModel('.git')
+ self.assertEqual(graph, themodel.ancestry([revisions[0]]))
=== modified file '__init__.py'
--- a/__init__.py 2007-11-08 23:44:31 +0000
+++ b/__init__.py 2007-11-09 04:17:01 +0000
@@ -18,140 +18,22 @@
"""A GIT branch and repository format implementation for bzr."""
-
-from StringIO import StringIO
-
-import stgit
-import stgit.git as git
-
from bzrlib import (
- commands,
- config,
- deprecated_graph,
- iterablefile,
- osutils,
- urlutils,
- )
-from bzrlib.decorators import *
-import bzrlib.branch
-import bzrlib.bzrdir
-import bzrlib.errors as errors
-import bzrlib.repository
-from bzrlib.revision import Revision
-
-
-class GitInventory(object):
-
- def __init__(self, revision_id):
- self.entries = {}
- self.root = GitEntry('', 'directory', revision_id)
- self.entries[''] = self.root
-
- def __getitem__(self, key):
- return self.entries[key]
-
- def iter_entries(self):
- return iter(sorted(self.entries.items()))
-
- def iter_entries_by_dir(self):
- return self.iter_entries()
-
- def __len__(self):
- return len(self.entries)
-
-
-class GitEntry(object):
-
- def __init__(self, path, kind, revision, text_sha1=None, executable=False,
- text_size=None):
- self.path = path
- self.file_id = path
- self.kind = kind
- self.executable = executable
- self.name = osutils.basename(path)
- if path == '':
- self.parent_id = None
- else:
- self.parent_id = osutils.dirname(path)
- self.revision = revision
- self.symlink_target = None
- self.text_sha1 = text_sha1
- self.text_size = None
-
- def __repr__(self):
- return "GitEntry(%r, %r, %r, %r)" % (self.path, self.kind,
- self.revision, self.parent_id)
-
-
-class GitModel(object):
- """API that follows GIT model closely"""
-
- def __init__(self, git_dir):
- self.git_dir = git_dir
-
- def git_command(self, command, args):
- args = ' '.join("'%s'" % arg for arg in args)
- return 'git --git-dir=%s %s %s' % (self.git_dir, command, args)
-
- def git_lines(self, command, args):
- return stgit.git._output_lines(self.git_command(command, args))
-
- def git_line(self, command, args):
- return stgit.git._output_one_line(self.git_command(command, args))
-
- def cat_file(self, type, object_id, pretty=False):
- args = []
- if pretty:
- args.append('-p')
- else:
- args.append(type)
- args.append(object_id)
- return self.git_lines('cat-file', args)
-
- def rev_list(self, heads, max_count=None, header=False):
- args = []
- if max_count is not None:
- args.append('--max-count=%d' % max_count)
- if header is not False:
- args.append('--header')
- if heads is None:
- args.append('--all')
- else:
- args.extend(heads)
- return self.git_lines('rev-list', args)
-
- def rev_parse(self, git_id):
- args = ['--verify', git_id]
- return self.git_line('rev-parse', args)
-
- def get_head(self):
- return self.rev_parse('HEAD')
-
- def ancestor_lines(self, revisions):
- revision_lines = []
- for line in self.rev_list(revisions, header=True):
- if line.startswith('\x00'):
- yield revision_lines
- revision_lines = [line[1:].decode('latin-1')]
- else:
- revision_lines.append(line.decode('latin-1'))
- assert revision_lines == ['']
-
- def get_inventory(self, tree_id):
- for line in self.cat_file('tree', tree_id, True):
- sections = line.split(' ', 2)
- obj_id, name = sections[2].split('\t', 1)
- name = name.rstrip('\n')
- if name.startswith('"'):
- name = name[1:-1].decode('string_escape').decode('utf-8')
- yield (sections[0], sections[1], obj_id, name)
-
-
-class cmd_test_git(commands.Command):
-
- def run(self):
- from bzrlib.tests import selftest
- selftest
+# branch,
+ bzrdir,
+# repository,
+ )
+
+bzrdir.format_registry.register_lazy('git',
+ 'bzrlib.plugins.git.gitlib.git_dir', 'GitDirFormat',
+ help='GIT - the stupid content tracker.',
+ native=False, hidden=True, experimental=True,
+ )
+
+# formats which have no format string are not discoverable
+# and not independently creatable, so are not registered.
+
+
def test_suite():
from bzrlib.plugins.git import tests
return tests.test_suite()
=== modified file 'gitlib/git_branch.py'
--- a/gitlib/git_branch.py 2007-11-08 23:44:31 +0000
+++ b/gitlib/git_branch.py 2007-11-09 04:17:01 +0000
@@ -19,6 +19,7 @@
from bzrlib import (
branch,
config,
+ revision,
)
from bzrlib.decorators import needs_read_lock
@@ -61,7 +62,10 @@
@needs_read_lock
def last_revision(self):
# perhaps should escape this ?
- return bzrrevid_from_git(self.repository.git.get_head())
+ head_git_id = self.repository._git.get_head()
+ if head_git_id is None:
+ return revision.NULL_REVISION
+ return ids.convert_revision_id_git_to_bzr(head_git_id)
@needs_read_lock
def revision_history(self):
@@ -92,7 +96,7 @@
def set_push_location(self, location):
"""See Branch.set_push_location."""
- self.get_config().set_user_option('push_location', location,
+ self.get_config().set_user_option('push_location', location,
local=True)
=== modified file 'gitlib/git_dir.py'
--- a/gitlib/git_dir.py 2007-11-08 23:44:31 +0000
+++ b/gitlib/git_dir.py 2007-11-09 04:17:01 +0000
@@ -16,17 +16,20 @@
"""An adapter between a Git control dir and a Bazaar BzrDir"""
+from bzrlib.lazy_import import lazy_import
from bzrlib import (
bzrdir,
- errors,
lockable_files,
urlutils,
)
+lazy_import(globals(), """
from bzrlib.plugins.git.gitlib import (
+ errors,
git_branch,
git_repository,
)
+""")
class GitLock(object):
@@ -66,7 +69,7 @@
return self.transport
if isinstance(branch_format, GitBzrDirFormat):
return self.transport
- raise errors.IncompatibleFormat(branch_format, self._format)
+ raise errors.bzr_errors.IncompatibleFormat(branch_format, self._format)
get_repository_transport = get_branch_transport
get_workingtree_transport = get_branch_transport
@@ -84,7 +87,7 @@
def open_workingtree(self):
loc = urlutils.unescape_for_display(self.root_transport.base, 'ascii')
- raise errors.NoWorkingTree(loc)
+ raise errors.bzr_errors.NoWorkingTree(loc)
class GitBzrDirFormat(bzrdir.BzrDirFormat):
@@ -105,7 +108,7 @@
url = url[len('readonly+'):]
path = urlutils.local_path_from_url(url)
if not transport.has('.git'):
- raise errors.NotBranchError(path=transport.base)
+ raise errors.bzr_errors.NotBranchError(path=transport.base)
lockfiles = GitLockableFiles(GitLock())
return GitDir(transport, lockfiles, self)
@@ -122,8 +125,8 @@
format.open(transport)
return format
except Exception, e:
- raise errors.NotBranchError(path=transport.base)
- raise errors.NotBranchError(path=transport.base)
+ raise errors.bzr_errors.NotBranchError(path=transport.base)
+ raise errors.bzr_errors.NotBranchError(path=transport.base)
bzrdir.BzrDirFormat.register_control_format(GitBzrDirFormat)
=== modified file 'gitlib/git_repository.py'
--- a/gitlib/git_repository.py 2007-11-08 23:44:31 +0000
+++ b/gitlib/git_repository.py 2007-11-09 04:17:01 +0000
@@ -17,12 +17,11 @@
"""An adapter between a Git Repository and a Bazaar Branch"""
from bzrlib import (
- errors,
repository,
urlutils,
)
-from bzrlib.plugins.git import GitModel
+from bzrlib.plugins.git.gitlib import model
class GitRepository(repository.Repository):
@@ -31,8 +30,8 @@
def __init__(self, gitdir, lockfiles):
self.bzrdir = gitdir
self.control_files = lockfiles
- gitdirectory = urlutils.local_path_from_url(gitdir.transport.base)
- self.git = GitModel(gitdirectory)
+ gitdirectory = gitdir.transport.local_abspath('.')
+ self._git = model.GitModel(gitdirectory)
self._revision_cache = {}
def _ancestor_revisions(self, revision_ids):
@@ -40,7 +39,7 @@
git_revisions = [gitrevid_from_bzr(r) for r in revision_ids]
else:
git_revisions = None
- for lines in self.git.ancestor_lines(git_revisions):
+ for lines in self._git.ancestor_lines(git_revisions):
yield self.parse_rev(lines)
def is_shared(self):
@@ -63,8 +62,8 @@
def get_revision(self, revision_id):
if revision_id in self._revision_cache:
return self._revision_cache[revision_id]
- raw = self.git.rev_list([gitrevid_from_bzr(revision_id)], max_count=1,
- header=True)
+ raw = self._git.rev_list([gitrevid_from_bzr(revision_id)], max_count=1,
+ header=True)
return self.parse_rev(raw)
def has_revision(self, revision_id):
@@ -112,7 +111,7 @@
result.inventory_sha1 = ""
result.timezone = timezone and int(timezone)
result.timestamp = float(timestamp)
- result.committer = committer
+ result.committer = committer
result.properties['git-tree-id'] = tree_id
return result
@@ -129,7 +128,7 @@
tree_id = revision.properties['git-tree-id']
type_map = {'blob': 'file', 'tree': 'directory' }
def get_inventory(tree_id, prefix):
- for perms, type, obj_id, name in self.git.get_inventory(tree_id):
+ for perms, type, obj_id, name in self._git.get_inventory(tree_id):
full_path = prefix + name
if type == 'blob':
text_sha1 = obj_id
@@ -153,11 +152,56 @@
self.inventory = repository.get_inventory(revision_id)
def get_file(self, file_id):
+ return iterablefile.IterableFile(self.get_file_lines(file_id))
+
+ def get_file_lines(self, file_id):
obj_id = self.inventory[file_id].text_sha1
- lines = self.repository.git.cat_file('blob', obj_id)
- return iterablefile.IterableFile(lines)
+ return self.repository._git.cat_file('blob', obj_id)
def is_executable(self, file_id):
return self.inventory[file_id].executable
+class GitInventory(object):
+
+ def __init__(self, revision_id):
+ self.entries = {}
+ self.root = GitEntry('', 'directory', revision_id)
+ self.entries[''] = self.root
+
+ def __getitem__(self, key):
+ return self.entries[key]
+
+ def iter_entries(self):
+ return iter(sorted(self.entries.items()))
+
+ def iter_entries_by_dir(self):
+ return self.iter_entries()
+
+ def __len__(self):
+ return len(self.entries)
+
+
+class GitEntry(object):
+
+ def __init__(self, path, kind, revision, text_sha1=None, executable=False,
+ text_size=None):
+ self.path = path
+ self.file_id = path
+ self.kind = kind
+ self.executable = executable
+ self.name = osutils.basename(path)
+ if path == '':
+ self.parent_id = None
+ else:
+ self.parent_id = osutils.dirname(path)
+ self.revision = revision
+ self.symlink_target = None
+ self.text_sha1 = text_sha1
+ self.text_size = None
+
+ def __repr__(self):
+ return "GitEntry(%r, %r, %r, %r)" % (self.path, self.kind,
+ self.revision, self.parent_id)
+
+
=== modified file 'tests/__init__.py'
--- a/tests/__init__.py 2007-11-08 23:44:31 +0000
+++ b/tests/__init__.py 2007-11-09 04:17:01 +0000
@@ -14,6 +14,10 @@
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+"""The basic test suite for bzr-git."""
+
+import subprocess
+
from bzrlib import (
tests,
trace,
@@ -27,7 +31,6 @@
class _GitCommandFeature(tests.Feature):
def _probe(self):
- import subprocess
try:
p = subprocess.Popen(['git', '--version'], stdout=subprocess.PIPE)
except IOError:
@@ -42,6 +45,18 @@
GitCommandFeature = _GitCommandFeature()
+def run_git(*args):
+ cmd = ['git'] + list(args)
+ p = subprocess.Popen(cmd,
+ stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE)
+ out, err = p.communicate()
+ if p.returncode != 0:
+ raise AssertionError('Bad return code: %d for %s:\n%s'
+ % (p.returncode, ' '.join(cmd), err))
+ return out
+
+
def test_suite():
loader = tests.TestLoader()
@@ -51,6 +66,7 @@
'test_git_branch',
'test_git_dir',
'test_git_repository',
+ 'test_model',
'test_ids',
]
testmod_names = ['%s.%s' % (__name__, t) for t in testmod_names]
=== modified file 'tests/test_git_branch.py'
--- a/tests/test_git_branch.py 2007-11-08 23:44:31 +0000
+++ b/tests/test_git_branch.py 2007-11-09 04:17:01 +0000
@@ -18,7 +18,7 @@
import subprocess
-from bzrlib import branch
+from bzrlib import branch, revision
from bzrlib.plugins.git import tests
from bzrlib.plugins.git.gitlib import git_branch
@@ -29,11 +29,15 @@
_test_needs_features = [tests.GitCommandFeature]
def test_open_existing(self):
- p = subprocess.Popen(['git', 'init'],
- stdout=subprocess.PIPE,
- stderr=subprocess.PIPE)
- p.communicate()
-
- gd = branch.Branch.open('.')
- self.assertIsInstance(gd, git_branch.GitBranch)
-
+ tests.run_git('init')
+
+ thebranch = branch.Branch.open('.')
+ self.assertIsInstance(thebranch, git_branch.GitBranch)
+
+ def test_last_revision_is_null(self):
+ tests.run_git('init')
+
+ thebranch = branch.Branch.open('.')
+ self.assertEqual(revision.NULL_REVISION, thebranch.last_revision())
+ self.assertEqual((0, revision.NULL_REVISION),
+ thebranch.last_revision_info())
=== modified file 'tests/test_git_dir.py'
--- a/tests/test_git_dir.py 2007-11-08 23:44:31 +0000
+++ b/tests/test_git_dir.py 2007-11-09 04:17:01 +0000
@@ -29,10 +29,7 @@
_test_needs_features = [tests.GitCommandFeature]
def test_open_existing(self):
- p = subprocess.Popen(['git', 'init'],
- stdout=subprocess.PIPE,
- stderr=subprocess.PIPE)
- p.communicate()
+ tests.run_git('init')
gd = bzrdir.BzrDir.open('.')
self.assertIsInstance(gd, git_dir.GitDir)
=== modified file 'tests/test_git_repository.py'
--- a/tests/test_git_repository.py 2007-11-08 23:44:31 +0000
+++ b/tests/test_git_repository.py 2007-11-09 04:17:01 +0000
@@ -21,7 +21,10 @@
from bzrlib import repository
from bzrlib.plugins.git import tests
-from bzrlib.plugins.git.gitlib import git_repository
+from bzrlib.plugins.git.gitlib import (
+ git_repository,
+ model,
+ )
class TestGitRepository(tests.TestCaseInTempDir):
@@ -29,10 +32,13 @@
_test_needs_features = [tests.GitCommandFeature]
def test_open_existing(self):
- p = subprocess.Popen(['git', 'init'],
- stdout=subprocess.PIPE,
- stderr=subprocess.PIPE)
- p.communicate()
-
- gd = repository.Repository.open('.')
- self.assertIsInstance(gd, git_repository.GitRepository)
+ tests.run_git('init')
+
+ repo = repository.Repository.open('.')
+ self.assertIsInstance(repo, git_repository.GitRepository)
+
+ def test_has_git_model(self):
+ tests.run_git('init')
+
+ repo = repository.Repository.open('.')
+ self.assertIsInstance(repo._git, model.GitModel)
More information about the bazaar-commits
mailing list