/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 bzrlib/merge_directive.py

  • Committer: Aaron Bentley
  • Date: 2007-03-01 04:14:36 UTC
  • mto: (2323.6.9 0.15-integration)
  • mto: This revision was merged to the branch mainline in revision 2330.
  • Revision ID: aaron.bentley@utoronto.ca-20070301041436-cyfzmqrtau2qs4fk
Get MergeDirective.from_objects working

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
from StringIO import StringIO
 
2
 
 
3
from bzrlib import (
 
4
    branch as _mod_branch,
 
5
    diff,
 
6
    errors,
 
7
    revision as _mod_revision,
 
8
    rio,
 
9
    testament,
 
10
    )
 
11
from bzrlib.bundle import serializer as bundle_serializer
 
12
 
 
13
 
 
14
class MergeDirective(object):
 
15
 
 
16
    def __init__(self, revision_id, testament_sha1, time, timezone,
 
17
                 submit_location, patch=None, patch_type=None,
 
18
                 public_location=None):
 
19
        assert patch_type in (None, 'diff', 'bundle')
 
20
        if patch_type != 'bundle' and public_location is None:
 
21
            raise errors.NoMergeSource()
 
22
        if patch_type is not None and patch is None:
 
23
            raise errors.PatchMissing(patch_type)
 
24
        self.revision_id = revision_id
 
25
        self.testament_sha1 = testament_sha1
 
26
        self.time = time
 
27
        self.timezone = timezone
 
28
        self.submit_location = submit_location
 
29
        self.patch = patch
 
30
        self.patch_type = patch_type
 
31
        self.public_location = public_location
 
32
 
 
33
    @staticmethod
 
34
    def from_lines(lines):
 
35
        line_iter = iter(lines)
 
36
        stanza = rio.read_patch_stanza(line_iter)
 
37
        patch_lines = list(line_iter)
 
38
        if len(patch_lines) == 0:
 
39
            patch = None
 
40
        else:
 
41
            patch = ''.join(patch_lines)
 
42
        try:
 
43
            bundle_serializer.read_bundle(StringIO(patch))
 
44
        except errors.NotABundle:
 
45
            patch_type = 'diff'
 
46
        else:
 
47
            patch_type = 'bundle'
 
48
        time, timezone = bundle_serializer.unpack_highres_date(
 
49
            stanza.get('timestamp'))
 
50
        kwargs = {}
 
51
        for key in ('revision_id', 'testament_sha1', 'submit_location',
 
52
                    'public_location'):
 
53
            try:
 
54
                kwargs[key] = stanza.get(key)
 
55
            except KeyError:
 
56
                pass
 
57
        return MergeDirective(time=time, timezone=timezone,
 
58
                              patch_type=patch_type, patch=patch, **kwargs)
 
59
 
 
60
    def to_lines(self):
 
61
        timestamp = bundle_serializer.format_highres_date(self.time,
 
62
                                                          self.timezone)
 
63
        stanza = rio.Stanza(revision_id=self.revision_id, timestamp=timestamp,
 
64
                            submit_location=self.submit_location,
 
65
                            testament_sha1=self.testament_sha1)
 
66
        for key in ('public_location',):
 
67
            if self.__dict__[key] is not None:
 
68
                stanza.add(key, self.__dict__[key])
 
69
        lines = rio.to_patch_lines(stanza)
 
70
        lines.append('# \n')
 
71
        if self.patch is not None:
 
72
            lines.extend(self.patch.splitlines(True))
 
73
        return lines
 
74
 
 
75
    @classmethod
 
76
    def from_objects(klass, repository, revision_id, time, timezone,
 
77
                 submit_location, patch_type='bundle',
 
78
                 local_submit_location=None, public_branch=None):
 
79
        if public_branch is not None:
 
80
            public_location = public_branch.base
 
81
            if not public_branch.repository.has_revision(revision_id):
 
82
                raise errors.PublicBranchOutOfDate(public_location,
 
83
                                                   revision_id)
 
84
            else:
 
85
                public_location = None
 
86
        t = testament.StrictTestament3.from_revision(repository, revision_id)
 
87
        if patch_type is None:
 
88
            patch = None
 
89
        else:
 
90
            submit_branch = _mod_branch.Branch.open(submit_location)
 
91
            submit_revision_id = submit_branch.last_revision()
 
92
            repository.fetch(submit_branch.repository, submit_revision_id)
 
93
            ancestor_id = _mod_revision.common_ancestor(revision_id,
 
94
                                                        submit_revision_id,
 
95
                                                        repository)
 
96
            if patch_type == 'bundle':
 
97
                s = StringIO()
 
98
                bundle_serializer.write_bundle(repository, revision_id,
 
99
                                               ancestor_id, s)
 
100
                patch = s.getvalue()
 
101
            elif patch_type == 'diff':
 
102
                patch = klass._generate_diff(repository, revision_id,
 
103
                                             ancestor_id)
 
104
        return MergeDirective(revision_id, t.as_sha1(), time, timezone,
 
105
                              submit_location, patch, patch_type,
 
106
                              public_branch)
 
107
 
 
108
    @staticmethod
 
109
    def _generate_diff(repository, revision_id, ancestor_id):
 
110
        tree_1 = repository.revision_tree(ancestor_id)
 
111
        tree_2 = repository.revision_tree(revision_id)
 
112
        s = StringIO()
 
113
        diff.show_diff_trees(tree_1, tree_2, s)
 
114
        return s.getvalue()