1
# Copyright (C) 2006 Canonical Ltd
2
# Authors: Robert Collins <robert.collins@canonical.com>
4
# This program is free software; you can redistribute it and/or modify
5
# it under the terms of the GNU General Public License as published by
6
# the Free Software Foundation; either version 2 of the License, or
7
# (at your option) any later version.
9
# This program is distributed in the hope that it will be useful,
10
# but WITHOUT ANY WARRANTY; without even the implied warranty of
11
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
# GNU General Public License for more details.
14
# You should have received a copy of the GNU General Public License
15
# along with this program; if not, write to the Free Software
16
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19
"""A GIT branch and repository format implementation for bzr."""
22
from StringIO import StringIO
25
import stgit.git as git
35
from bzrlib.decorators import *
38
import bzrlib.errors as errors
39
import bzrlib.repository
40
from bzrlib.revision import Revision
43
class GitInventory(object):
45
def __init__(self, revision_id):
47
self.root = GitEntry('', 'directory', revision_id)
48
self.entries[''] = self.root
50
def __getitem__(self, key):
51
return self.entries[key]
53
def iter_entries(self):
54
return iter(sorted(self.entries.items()))
56
def iter_entries_by_dir(self):
57
return self.iter_entries()
60
return len(self.entries)
63
class GitEntry(object):
65
def __init__(self, path, kind, revision, text_sha1=None, executable=False,
70
self.executable = executable
71
self.name = osutils.basename(path)
75
self.parent_id = osutils.dirname(path)
76
self.revision = revision
77
self.symlink_target = None
78
self.text_sha1 = text_sha1
82
return "GitEntry(%r, %r, %r, %r)" % (self.path, self.kind,
83
self.revision, self.parent_id)
86
class GitModel(object):
87
"""API that follows GIT model closely"""
89
def __init__(self, git_dir):
90
self.git_dir = git_dir
92
def git_command(self, command, args):
93
args = ' '.join("'%s'" % arg for arg in args)
94
return 'git --git-dir=%s %s %s' % (self.git_dir, command, args)
96
def git_lines(self, command, args):
97
return stgit.git._output_lines(self.git_command(command, args))
99
def git_line(self, command, args):
100
return stgit.git._output_one_line(self.git_command(command, args))
102
def cat_file(self, type, object_id, pretty=False):
108
args.append(object_id)
109
return self.git_lines('cat-file', args)
111
def rev_list(self, heads, max_count=None, header=False):
113
if max_count is not None:
114
args.append('--max-count=%d' % max_count)
115
if header is not False:
116
args.append('--header')
121
return self.git_lines('rev-list', args)
123
def rev_parse(self, git_id):
124
args = ['--verify', git_id]
125
return self.git_line('rev-parse', args)
128
return self.rev_parse('HEAD')
130
def ancestor_lines(self, revisions):
132
for line in self.rev_list(revisions, header=True):
133
if line.startswith('\x00'):
135
revision_lines = [line[1:].decode('latin-1')]
137
revision_lines.append(line.decode('latin-1'))
138
assert revision_lines == ['']
140
def get_inventory(self, tree_id):
141
for line in self.cat_file('tree', tree_id, True):
142
sections = line.split(' ', 2)
143
obj_id, name = sections[2].split('\t', 1)
144
name = name.rstrip('\n')
145
if name.startswith('"'):
146
name = name[1:-1].decode('string_escape').decode('utf-8')
147
yield (sections[0], sections[1], obj_id, name)
150
class cmd_test_git(commands.Command):
153
from bzrlib.tests import selftest
156
from bzrlib.plugins.git import tests
157
return tests.test_suite()