/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

Viewing changes to gitlib/model.py

stgit dependency was removed already

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# Copyright (C) 2007 Canonical Ltd
 
2
#
 
3
# This program is free software; you can redistribute it and/or modify
 
4
# it under the terms of the GNU General Public License as published by
 
5
# the Free Software Foundation; either version 2 of the License, or
 
6
# (at your option) any later version.
 
7
#
 
8
# This program is distributed in the hope that it will be useful,
 
9
# but WITHOUT ANY WARRANTY; without even the implied warranty of
 
10
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
11
# GNU General Public License for more details.
 
12
#
 
13
# You should have received a copy of the GNU General Public License
 
14
# along with this program; if not, write to the Free Software
 
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
16
 
 
17
"""The model for interacting with the git process, etc."""
 
18
 
 
19
import os
 
20
import subprocess
 
21
 
 
22
from bzrlib.plugins.git.gitlib import errors
 
23
 
 
24
 
 
25
class GitModel(object):
 
26
    """API that follows GIT model closely"""
 
27
 
 
28
    def __init__(self, git_dir):
 
29
        self.git_dir = git_dir
 
30
 
 
31
    def git_command(self, command, args):
 
32
        return ['git', command] + args
 
33
 
 
34
    def git_lines(self, command, args):
 
35
        cmd = self.git_command(command, args)
 
36
        env = os.environ.copy()
 
37
        env['GIT_DIR'] = self.git_dir
 
38
        p = subprocess.Popen(cmd,
 
39
                             stdout=subprocess.PIPE,
 
40
                             stderr=subprocess.PIPE,
 
41
                             env=env)
 
42
        lines = p.stdout.readlines()
 
43
        if p.wait() != 0:
 
44
            raise errors.GitCommandError(cmd, p.returncode,
 
45
                                         p.stderr.read().strip())
 
46
        return lines
 
47
 
 
48
    def git_line(self, command, args):
 
49
        lines = self.git_lines(command, args)
 
50
        return lines[0]
 
51
 
 
52
    def cat_file(self, type, object_id, pretty=False):
 
53
        args = []
 
54
        if pretty:
 
55
            args.append('-p')
 
56
        else:
 
57
            args.append(type)
 
58
        args.append(object_id)
 
59
        return self.git_lines('cat-file', args)
 
60
 
 
61
    def rev_list(self, heads, max_count=None, header=False, parents=False):
 
62
        args = []
 
63
        if max_count is not None:
 
64
            args.append('--max-count=%d' % max_count)
 
65
        if header:
 
66
            args.append('--header')
 
67
        if parents:
 
68
            args.append('--parents')
 
69
        if heads is None:
 
70
            args.append('--all')
 
71
        else:
 
72
            args.extend(heads)
 
73
        return self.git_lines('rev-list', args)
 
74
 
 
75
    def rev_parse(self, git_id):
 
76
        args = ['--verify', git_id]
 
77
        return self.git_line('rev-parse', args).strip()
 
78
 
 
79
    def get_head(self):
 
80
        try:
 
81
            return self.rev_parse('HEAD')
 
82
        except errors.GitCommandError, e:
 
83
            # Most likely, this is a null branch, so treat it as such
 
84
            if e.stderr == 'fatal: Needed a single revision':
 
85
                return None
 
86
            raise
 
87
 
 
88
    def ancestry(self, revisions):
 
89
        ancestors = {}
 
90
        for line in self.rev_list(revisions, parents=True):
 
91
            entries = line.split()
 
92
            ancestors[entries[0]] = entries[1:]
 
93
        return ancestors
 
94
 
 
95
    def ancestor_lines(self, revisions):
 
96
        revision_lines = []
 
97
        for line in self.rev_list(revisions, header=True):
 
98
            if line.startswith('\x00'):
 
99
                yield revision_lines
 
100
                revision_lines = [line[1:].decode('latin-1')]
 
101
            else:
 
102
                revision_lines.append(line.decode('latin-1'))
 
103
        assert revision_lines == ['']
 
104
 
 
105
    def get_inventory(self, tree_id):
 
106
        for line in self.cat_file('tree', tree_id, True):
 
107
            sections = line.split(' ', 2)
 
108
            obj_id, name = sections[2].split('\t', 1)
 
109
            name = name.rstrip('\n')
 
110
            if name.startswith('"'):
 
111
                name = name[1:-1].decode('string_escape').decode('utf-8')
 
112
            yield (sections[0], sections[1], obj_id, name)