/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar
0.5.1 by John Arbash Meinel
Just an initial working step.
1
#!/usr/bin/env python
2
"""\
3
Just some work for generating a changeset.
4
"""
5
6
import bzrlib, bzrlib.errors
7
8
def _canonicalize_revision(branch, revision=None):
9
    """Turn some sort of revision information into a single
10
    set of from-to revision ids.
11
0.5.3 by John Arbash Meinel
Added a couple more bits
12
    A revision id can be None if there is no associated revison.
13
14
    :return: (old, new)
0.5.1 by John Arbash Meinel
Just an initial working step.
15
    """
16
    # This is a little clumsy because revision parsing may return
17
    # a single entry, or a list
18
    if revision is None:
19
        old, new = None, None
20
    elif isinstance(revision, (list, tuple)):
21
        if len(revision) == 0:
22
            old, new = None, None
23
        elif len(revision) == 1:
24
            old = revision[0]
25
            new = None
26
        elif len(revision) == 2:
27
            old = revision[0]
28
            new = revision[1]
29
        else:
30
            raise bzrlib.errors.BzrCommandError('revision can be'
31
                    ' at most 2 entries.')
32
    else:
33
        old = revision
34
        new = None
35
36
    if new is not None:
37
        new = branch.lookup_revision(new)
0.5.3 by John Arbash Meinel
Added a couple more bits
38
    if old is None:
39
        old = branch.last_patch()
0.5.1 by John Arbash Meinel
Just an initial working step.
40
    else:
0.5.3 by John Arbash Meinel
Added a couple more bits
41
        old = branch.lookup_revision(old)
0.5.1 by John Arbash Meinel
Just an initial working step.
42
43
    return old, new
44
45
def _get_trees(branch, revisions):
46
    """Get the old and new trees based on revision.
47
    """
48
    if revisions[0] is None:
49
        old_tree = branch.basis_tree()
50
    else:
51
        old_tree = branch.revision_tree(revisions[0])
52
53
    if revisions[1] is None:
54
        new_tree = branch.working_tree()
55
    else:
56
        new_tree = branch.revision_tree(revisions[1])
57
    return old_tree, new_tree
58
59
def _fake_working_revision(branch):
60
    """Fake a Revision object for the working tree."""
61
    from bzrlib.revision import Revision
62
    import time
63
    from bzrlib.osutils import local_time_offset, \
64
            username
65
66
    precursor = branch.last_patch()
67
    precursor_sha1 = branch.get_revision_sha1(precursor)
68
69
    return Revision(timestamp=time.time(),
70
            timezone=local_time_offset(),
71
            committer=username(),
72
            precursor=precursor,
73
            precursor_sha1=precursor_sha1)
74
75
76
class MetaInfoHeader(object):
77
    """Maintain all of the header information about this
78
    changeset.
79
    """
80
81
    def __init__(self, branch, revisions, delta):
82
        self.branch = branch
83
        self.delta = delta
84
        self._get_revision_list(revisions)
85
86
    def _get_revision_list(self, revisions):
87
        """This generates the list of all revisions from->to.
88
        """
89
        old_revno = None
90
        new_revno = None
91
        rh = self.branch.revision_history()
92
        for revno, rev in enumerate(rh):
93
            if rev == revisions[0]:
94
                old_revno = revno
95
            if rev == revisions[1]:
96
                new_revno = revno
97
0.5.3 by John Arbash Meinel
Added a couple more bits
98
        self.revision_list = []
0.5.1 by John Arbash Meinel
Just an initial working step.
99
        if old_revno is None:
0.5.3 by John Arbash Meinel
Added a couple more bits
100
            self.base_revision = None
101
            old_revno = 1
102
        else:
103
            self.base_revision = self.branch.get_revision(rh[old_revno])
0.5.1 by John Arbash Meinel
Just an initial working step.
104
        if new_revno is not None:
0.5.3 by John Arbash Meinel
Added a couple more bits
105
            for rev_id in rh[old_revno+1:new_revno+1]:
0.5.1 by John Arbash Meinel
Just an initial working step.
106
                self.revision_list.append(self.branch.get_revision(rev_id))
107
        else:
0.5.3 by John Arbash Meinel
Added a couple more bits
108
            for rev_id in rh[old_revno+1:]:
0.5.1 by John Arbash Meinel
Just an initial working step.
109
                self.revision_list.append(self.branch.get_revision(rev_id))
110
            self.revision_list.append(_fake_working_revision(self.branch))
111
112
    def write_meta_info(self, to_file):
113
        """Write out the meta-info portion to the supplied file."""
114
        from bzrlib.osutils import username
0.5.3 by John Arbash Meinel
Added a couple more bits
115
        def write(txt, key=None):
116
            if key:
117
                to_file.write('# ' + key + ': ' + txt + '\n')
118
            else:
119
                to_file.write('# ' + txt + '\n')
120
0.5.4 by John Arbash Meinel
Added printout of file ids, need directory ids
121
        write('Bazaar-NG (bzr) changeset v0.0.5')
122
        write('This changeset can be applied with bzr apply-changeset')
123
        write('')
124
0.5.3 by John Arbash Meinel
Added a couple more bits
125
        write(username(), key='committer')
126
127
        if self.base_revision:
128
            write(self.base_revision.revision_id, key='precursor')
129
130
        first = True
131
        for rev in self.revision_list:
132
            if rev.revision_id is not None:
133
                if first:
134
                    write(rev.revision_id, key='revisions')
135
                    first = False
136
                else:
0.5.4 by John Arbash Meinel
Added printout of file ids, need directory ids
137
                    write(' '*11 + rev.revision_id)
138
139
        if self.revision_list[-1].revision_id is None:
140
            final_tree = self.branch.working_tree()
141
        else:
142
            final_tree = self.branch.revision_tree(
143
                    self.revision_list[-1])
144
145
        class _write_file(object):
146
            first = True
147
            def __call__(self, info):
148
                if self.first:
149
                    self.first = False
150
                    to_file.write('# file ids: ')
151
                else:
152
                    to_file.write('#           ')
153
                to_file.write(info[0].encode('utf-8'))
154
                to_file.write('\t')
155
                to_file.write(info[1].encode('utf-8'))
156
                inv = final_tree.inventory[info[1]]
157
                if inv.parent_id:
158
                    to_file.write('\t')
159
                    to_file.write(inv.parent_id)
160
                to_file.write('\n')
161
        write_file = _write_file()
162
163
        for info in self.delta.removed:
164
            if info[2] == 'file':
165
                write_file(info)
166
        for info in self.delta.added:
167
            if info[2] == 'file':
168
                write_file(info)
169
        for info in self.delta.renamed:
170
            if info[3] == 'file':
171
                write_file(info[1:2])
172
        for info in self.delta.modified:
173
            if info[2] == 'file':
174
                write_file(info)
0.5.1 by John Arbash Meinel
Just an initial working step.
175
176
177
def show_changeset(branch, revision=None, specific_files=None,
178
        external_diff_options=None, to_file=None):
179
    from bzrlib.diff import compare_trees
180
181
    if to_file is None:
182
        import sys
183
        to_file = sys.stdout
184
    revisions = _canonicalize_revision(branch, revision)
185
186
    old_tree, new_tree = _get_trees(branch, revisions)
187
188
    delta = compare_trees(old_tree, new_tree, want_unchanged=False,
189
                          specific_files=specific_files)
190
191
    meta = MetaInfoHeader(branch, revisions, delta)
192
    meta.write_meta_info(to_file)
193
194