/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
0.5.7 by John Arbash Meinel
Added a bunch more information about changesets. Can now read back in all of the meta information.
8
import common
9
10
from bzrlib.inventory import ROOT_ID
0.5.58 by John Arbash Meinel
Fixed a bug in the case that there are no revision committed yet.
11
from bzrlib.errors import BzrCommandError
0.5.7 by John Arbash Meinel
Added a bunch more information about changesets. Can now read back in all of the meta information.
12
0.5.5 by John Arbash Meinel
Updated to now include the diffs
13
try:
14
    set
15
except NameError:
16
    from sets import Set as set
17
0.5.1 by John Arbash Meinel
Just an initial working step.
18
def _fake_working_revision(branch):
0.5.7 by John Arbash Meinel
Added a bunch more information about changesets. Can now read back in all of the meta information.
19
    """Fake a Revision object for the working tree.
20
    
21
    This is for the future, to support changesets against the working tree.
22
    """
0.5.1 by John Arbash Meinel
Just an initial working step.
23
    from bzrlib.revision import Revision
24
    import time
25
    from bzrlib.osutils import local_time_offset, \
26
            username
27
28
    precursor = branch.last_patch()
29
    precursor_sha1 = branch.get_revision_sha1(precursor)
30
31
    return Revision(timestamp=time.time(),
32
            timezone=local_time_offset(),
33
            committer=username(),
34
            precursor=precursor,
35
            precursor_sha1=precursor_sha1)
36
0.5.71 by John Arbash Meinel
Cleaning up code for latest bzr.
37
def _get_revision_set(branch, target_rev_id=None):
0.5.68 by John Arbash Meinel
(broken), starting to change the syntax of the command to allow cset to take a base and a target.
38
    """Get the set of all revisions that are in the ancestry
39
    of this branch.
40
    """
41
    this_revs = set()
0.5.71 by John Arbash Meinel
Cleaning up code for latest bzr.
42
    if target_rev_id is None:
43
        to_search = [branch.last_patch()]
44
    else:
45
        to_search = [target_rev_id]
0.5.68 by John Arbash Meinel
(broken), starting to change the syntax of the command to allow cset to take a base and a target.
46
47
    while len(to_search) > 0:
48
        rev_id = to_search.pop(0)
49
        if rev_id in this_revs:
50
            continue
51
        this_revs.add(rev_id)
52
        rev = branch.get_revision(rev_id)
53
        for parent in rev.parents:
54
            if parent.revision_id not in this_revs:
55
                to_search.append(parent.revision_id)
56
    return this_revs
57
0.5.71 by John Arbash Meinel
Cleaning up code for latest bzr.
58
def _find_best_base(target_branch, target_rev_id, base_branch, base_rev_id):
0.5.68 by John Arbash Meinel
(broken), starting to change the syntax of the command to allow cset to take a base and a target.
59
    """Find the best base revision based on ancestry.
60
    All revisions should already be pulled into the local tree.
61
    """
0.5.71 by John Arbash Meinel
Cleaning up code for latest bzr.
62
    this_revs = _get_revision_set(target_branch, target_rev_id)
0.5.68 by John Arbash Meinel
(broken), starting to change the syntax of the command to allow cset to take a base and a target.
63
64
    # This does a breadth first search through history, looking for
65
    # something which matches
66
    checked = set()
0.5.71 by John Arbash Meinel
Cleaning up code for latest bzr.
67
    to_check = [base_rev_id]
0.5.68 by John Arbash Meinel
(broken), starting to change the syntax of the command to allow cset to take a base and a target.
68
    while len(to_check) > 0:
69
        # Removing the '0' would make this depth-first search
70
        rev_id = to_check.pop(0)
71
        if rev_id in checked:
72
            continue
73
        checked.add(rev_id)
74
        if rev_id in this_revs:
75
            return rev_id
76
0.5.71 by John Arbash Meinel
Cleaning up code for latest bzr.
77
        if rev_id in target_branch.revision_store:
78
            rev = target_branch.get_revision(rev_id)
79
        elif (rev_id in base_branch.revision_store):
80
            rev = base_branch.get_revision(rev_id)
0.5.68 by John Arbash Meinel
(broken), starting to change the syntax of the command to allow cset to take a base and a target.
81
        else:
82
            # Should we just continue here?
83
            warning('Could not find revision for rev: {%s}'
84
                    % rev_id)
85
            continue
86
87
88
        for parent in rev.parents:
89
            if parent.revision_id not in checked:
90
                to_check.append(parent.revision_id)
91
92
    return None
93
94
def _create_ancestry_to_rev(branch, ancestor_rev_id, this_rev_id):
95
    """Return a listing of revisions, which traces back from this_rev_id
96
    all the way back to the ancestor_rev_id.
97
    """
98
    # This is an optimization, when both target and base
99
    # exist in the revision history, we should already have
100
    # a valid listing of revision ancestry.
101
    rh = branch.revision_history()
102
    if ancestor_rev_id in rh and this_rev_id in rh:
103
        ancestor_idx = rh.index(ancestor_rev_id)
104
        this_rev_idx = rh.index(this_rev_id)
105
        if ancestor_idx > this_rev_idx:
106
            raise BzrCommandError('Revision {%s} is a child not an ancestor'
107
                    ' of {%s}' % (ancestor_rev_id, this_rev_id))
108
        rh_list = rh[ancestor_idx:this_rev_idx+1]
109
        rh_list.reverse()
110
        # return rh_list
111
112
    # I considered using depth-first search, as it is a little
113
    # bit less resource intensive, and it should favor generating
114
    # paths that are the same as revision_history
115
    # but since breadth-first-search is generally used
116
    # we will use that
117
    # 
118
    # WARNING: In the presence of merges, there are cases where
119
    # breadth first search will return a very different path
120
    # than revision_history or depth first search. Imaging the following:
121
    #
122
    # rh: A -> B -> C -> D -> E -> F
123
    #     |                        ^
124
    #     |                        |
125
    #     +--> Z ------------------+
126
    #
127
    # In this case, Starting with F, looking for A will return
128
    # A-F for a revision_history search, but breadth-first will
129
    # return A,Z,F since it is a much shorter path, and with
130
    # F merging Z, it looks like a shortcut.
131
    #
132
    # But since A-F seems to be the more "correct" history
133
    # for F, we might consider that revision_history should always
134
    # be consulted first, and if not found there, to use breadth
135
    # first search.
136
    checked_rev_ids = set()
137
138
    cur_trails = [[this_rev_id]]
139
    
140
    while len(cur_trails) > 0:
141
        cur_trail = cur_trails.pop(0)
142
        cur_rev_id = cur_trail[-1]
143
        if cur_rev_id in checked_rev_ids:
144
            continue
145
        checked_rev_ids.add(cur_rev_id)
146
147
        if cur_rev_id == ancestor_rev_id:
148
            return cur_trail
149
0.5.71 by John Arbash Meinel
Cleaning up code for latest bzr.
150
        if cur_rev_id in branch.revision_store:
151
            rev = branch.get_revision(cur_rev_id)
0.5.68 by John Arbash Meinel
(broken), starting to change the syntax of the command to allow cset to take a base and a target.
152
        else:
153
            # Should we just continue here?
154
            warning('Could not find revision for rev: {%s}, unable to'
0.5.71 by John Arbash Meinel
Cleaning up code for latest bzr.
155
                    ' trace ancestry.' % cur_rev_id)
0.5.68 by John Arbash Meinel
(broken), starting to change the syntax of the command to allow cset to take a base and a target.
156
            continue
157
158
        for parent in rev.parents:
0.5.71 by John Arbash Meinel
Cleaning up code for latest bzr.
159
            if parent.revision_id not in checked_rev_ids:
160
                cur_trails.append(cur_trail + [parent.revision_id])
0.5.68 by John Arbash Meinel
(broken), starting to change the syntax of the command to allow cset to take a base and a target.
161
162
    raise BzrCommandError('Revision id {%s} not an ancestor of {%s}'
163
            % (ancestor_rev_id, this_rev_id))
0.5.1 by John Arbash Meinel
Just an initial working step.
164
165
class MetaInfoHeader(object):
166
    """Maintain all of the header information about this
167
    changeset.
168
    """
169
0.5.68 by John Arbash Meinel
(broken), starting to change the syntax of the command to allow cset to take a base and a target.
170
    def __init__(self,
171
            base_branch, base_rev_id, base_tree,
172
            target_branch, target_rev_id, target_tree,
173
            delta,
174
            starting_rev_id=None,
175
            full_remove=False, full_rename=False,
176
            base_label = 'BASE', target_label = 'TARGET'):
0.5.5 by John Arbash Meinel
Updated to now include the diffs
177
        """
178
        :param full_remove: Include the full-text for a delete
179
        :param full_rename: Include an add+delete patch for a rename
0.5.25 by John Arbash Meinel
Added some work to allow rollup revisions, and handling multiple parents.
180
0.5.5 by John Arbash Meinel
Updated to now include the diffs
181
        """
0.5.68 by John Arbash Meinel
(broken), starting to change the syntax of the command to allow cset to take a base and a target.
182
        self.base_branch = base_branch
183
        self.base_rev_id = base_rev_id
184
        self.base_tree = base_tree
0.5.71 by John Arbash Meinel
Cleaning up code for latest bzr.
185
        self.base_revision = self.base_branch.get_revision(self.base_rev_id)
0.5.68 by John Arbash Meinel
(broken), starting to change the syntax of the command to allow cset to take a base and a target.
186
187
        self.target_branch = target_branch
188
        self.target_rev_id = target_rev_id
189
        self.target_tree = target_tree
190
0.5.1 by John Arbash Meinel
Just an initial working step.
191
        self.delta = delta
0.5.68 by John Arbash Meinel
(broken), starting to change the syntax of the command to allow cset to take a base and a target.
192
193
        self.starting_rev_id = starting_rev_id
194
0.5.5 by John Arbash Meinel
Updated to now include the diffs
195
        self.full_remove=full_remove
196
        self.full_rename=full_rename
0.5.68 by John Arbash Meinel
(broken), starting to change the syntax of the command to allow cset to take a base and a target.
197
198
        self.base_label = base_label
0.5.71 by John Arbash Meinel
Cleaning up code for latest bzr.
199
        self.target_label = target_label
0.5.68 by John Arbash Meinel
(broken), starting to change the syntax of the command to allow cset to take a base and a target.
200
0.5.7 by John Arbash Meinel
Added a bunch more information about changesets. Can now read back in all of the meta information.
201
        self.to_file = None
0.5.55 by John Arbash Meinel
Lots of updates. Using a minimized annotations for changesets.
202
        #self.revno = None
203
        #self.parent_revno = None
204
205
        # These are entries in the header.
206
        # They will be repeated in the footer,
207
        # only if they have changed
208
        self.date = None
209
        self.committer = None
210
        self.message = None
0.5.7 by John Arbash Meinel
Added a bunch more information about changesets. Can now read back in all of the meta information.
211
0.5.68 by John Arbash Meinel
(broken), starting to change the syntax of the command to allow cset to take a base and a target.
212
        self._get_revision_list()
0.5.1 by John Arbash Meinel
Just an initial working step.
213
0.5.68 by John Arbash Meinel
(broken), starting to change the syntax of the command to allow cset to take a base and a target.
214
    def _get_revision_list(self):
0.5.1 by John Arbash Meinel
Just an initial working step.
215
        """This generates the list of all revisions from->to.
0.5.68 by John Arbash Meinel
(broken), starting to change the syntax of the command to allow cset to take a base and a target.
216
        It fills out the internal self.revision_list with Revision
217
        entries which should be in the changeset.
0.5.1 by John Arbash Meinel
Just an initial working step.
218
        """
0.5.71 by John Arbash Meinel
Cleaning up code for latest bzr.
219
        if self.starting_rev_id is None:
220
            self.starting_rev_id = _find_best_base(self.target_branch,
221
                    self.target_rev_id,
222
                    self.base_branch, self.base_rev_id)
223
224
        rev_id_list = _create_ancestry_to_rev(self.target_branch,
225
                self.starting_rev_id, self.target_rev_id)
0.5.73 by John Arbash Meinel
Some fixups for gen_changeset.
226
227
        assert rev_id_list[-1] == self.starting_rev_id
228
        # The last entry should be starting_rev_id which should
229
        # exist in both base and target, so we don't need to
230
        # include it in the changeset
231
        rev_id_list.pop()
0.5.71 by John Arbash Meinel
Cleaning up code for latest bzr.
232
        rev_id_list.reverse()
233
234
        self.revision_list = [self.target_branch.get_revision(rid) 
235
                                for rid in rev_id_list]
0.5.7 by John Arbash Meinel
Added a bunch more information about changesets. Can now read back in all of the meta information.
236
237
    def _write(self, txt, key=None):
238
        if key:
0.5.17 by John Arbash Meinel
adding apply-changset, plus more meta information.
239
            self.to_file.write('# %s: %s\n' % (key, txt))
0.5.7 by John Arbash Meinel
Added a bunch more information about changesets. Can now read back in all of the meta information.
240
        else:
0.5.17 by John Arbash Meinel
adding apply-changset, plus more meta information.
241
            self.to_file.write('# %s\n' % (txt,))
0.5.1 by John Arbash Meinel
Just an initial working step.
242
243
    def write_meta_info(self, to_file):
0.5.5 by John Arbash Meinel
Updated to now include the diffs
244
        """Write out the meta-info portion to the supplied file.
245
246
        :param to_file: Write out the meta information to the supplied
247
                        file
248
        """
0.5.7 by John Arbash Meinel
Added a bunch more information about changesets. Can now read back in all of the meta information.
249
        self.to_file = to_file
250
251
        self._write_header()
252
        self._write_diffs()
253
        self._write_footer()
254
255
    def _write_header(self):
256
        """Write the stuff that comes before the patches."""
0.5.55 by John Arbash Meinel
Lots of updates. Using a minimized annotations for changesets.
257
        from bzrlib.osutils import username
258
        from common import format_highres_date
0.5.7 by John Arbash Meinel
Added a bunch more information about changesets. Can now read back in all of the meta information.
259
        write = self._write
260
261
        for line in common.get_header():
262
            write(line)
263
0.5.27 by John Arbash Meinel
Now capable of generating rollup changesets.
264
        # Print out the basic information about the 'target' revision
265
        rev = self.revision_list[-1]
0.5.7 by John Arbash Meinel
Added a bunch more information about changesets. Can now read back in all of the meta information.
266
        write(rev.committer, key='committer')
0.5.55 by John Arbash Meinel
Lots of updates. Using a minimized annotations for changesets.
267
        self.committer = rev.committer
268
        self.date = format_highres_date(rev.timestamp, offset=rev.timezone)
269
        write(self.date, key='date')
0.5.17 by John Arbash Meinel
adding apply-changset, plus more meta information.
270
        if rev.message:
271
            self.to_file.write('# message:\n')
272
            for line in rev.message.split('\n'):
273
                self.to_file.write('#    %s\n' % line)
0.5.55 by John Arbash Meinel
Lots of updates. Using a minimized annotations for changesets.
274
            self.message = rev.message
0.5.7 by John Arbash Meinel
Added a bunch more information about changesets. Can now read back in all of the meta information.
275
0.5.4 by John Arbash Meinel
Added printout of file ids, need directory ids
276
        write('')
0.5.7 by John Arbash Meinel
Added a bunch more information about changesets. Can now read back in all of the meta information.
277
        self.to_file.write('\n')
278
279
    def _write_footer(self):
280
        """Write the stuff that comes after the patches.
281
282
        This is meant to be more meta-information, which people probably don't want
283
        to read, but which is required for proper bzr operation.
284
        """
285
        write = self._write
286
0.5.57 by John Arbash Meinel
Simplified the header, only output base if it is not the expected one.
287
        # What should we print out for an Empty base revision?
0.5.59 by John Arbash Meinel
Several fixes for handling the case where you are doing a changeset against revno=0 (Null base)
288
        if len(self.revision_list[0].parents) == 0:
289
            assumed_base = None
290
        else:
291
            assumed_base = self.revision_list[0].parents[0].revision_id
292
        if (self.base_revision is not None 
293
                and self.base_revision.revision_id != assumed_base):
0.5.57 by John Arbash Meinel
Simplified the header, only output base if it is not the expected one.
294
            base = self.base_revision.revision_id
295
            write(base, key='base')
0.5.71 by John Arbash Meinel
Cleaning up code for latest bzr.
296
            write(self.target_branch.get_revision_sha1(base), key='base sha1')
0.5.17 by John Arbash Meinel
adding apply-changset, plus more meta information.
297
0.5.25 by John Arbash Meinel
Added some work to allow rollup revisions, and handling multiple parents.
298
        self._write_revisions()
0.5.7 by John Arbash Meinel
Added a bunch more information about changesets. Can now read back in all of the meta information.
299
300
    def _write_revisions(self):
301
        """Not used. Used for writing multiple revisions."""
0.5.55 by John Arbash Meinel
Lots of updates. Using a minimized annotations for changesets.
302
        from common import format_highres_date
303
0.5.3 by John Arbash Meinel
Added a couple more bits
304
        for rev in self.revision_list:
0.5.25 by John Arbash Meinel
Added some work to allow rollup revisions, and handling multiple parents.
305
            rev_id = rev.revision_id
306
            self.to_file.write('# revision: %s\n' % rev_id)
307
            self.to_file.write('#    sha1: %s\n' % 
0.5.71 by John Arbash Meinel
Cleaning up code for latest bzr.
308
                self.target_branch.get_revision_sha1(rev_id))
0.5.55 by John Arbash Meinel
Lots of updates. Using a minimized annotations for changesets.
309
            if rev.committer != self.committer:
310
                self.to_file.write('#    committer: %s\n' % rev.committer)
311
            date = format_highres_date(rev.timestamp, rev.timezone)
312
            if date != self.date:
313
                self.to_file.write('#    date: %s\n' % date)
314
            if rev.inventory_id != rev_id:
315
                self.to_file.write('#    inventory id: %s\n' % rev.inventory_id)
0.5.25 by John Arbash Meinel
Added some work to allow rollup revisions, and handling multiple parents.
316
            self.to_file.write('#    inventory sha1: %s\n' % rev.inventory_sha1)
0.5.59 by John Arbash Meinel
Several fixes for handling the case where you are doing a changeset against revno=0 (Null base)
317
            if len(rev.parents) > 0:
318
                self.to_file.write('#    parents:\n')
319
                for parent in rev.parents:
320
                    self.to_file.write('#       %s\t%s\n' % (
321
                        parent.revision_id,
322
                        parent.revision_sha1))
0.5.55 by John Arbash Meinel
Lots of updates. Using a minimized annotations for changesets.
323
            if rev.message and rev.message != self.message:
324
                self.to_file.write('#    message:\n')
325
                for line in rev.message.split('\n'):
326
                    self.to_file.write('#       %s\n' % line)
0.5.25 by John Arbash Meinel
Added some work to allow rollup revisions, and handling multiple parents.
327
0.5.7 by John Arbash Meinel
Added a bunch more information about changesets. Can now read back in all of the meta information.
328
    def _write_diffs(self):
0.5.5 by John Arbash Meinel
Updated to now include the diffs
329
        """Write out the specific diffs"""
330
        from bzrlib.diff import internal_diff, external_diff
0.5.55 by John Arbash Meinel
Lots of updates. Using a minimized annotations for changesets.
331
        from common import encode
0.5.5 by John Arbash Meinel
Updated to now include the diffs
332
        DEVNULL = '/dev/null'
333
0.5.55 by John Arbash Meinel
Lots of updates. Using a minimized annotations for changesets.
334
        diff_file = internal_diff
335
        # Get the target tree so that we can check for
336
        # Appropriate text ids.
0.5.73 by John Arbash Meinel
Some fixups for gen_changeset.
337
        rev_id = self.target_rev_id
338
        tree = self.target_tree
0.5.55 by John Arbash Meinel
Lots of updates. Using a minimized annotations for changesets.
339
340
341
        def get_text_id_str(file_id, modified=True):
342
            """This returns an empty string if guess_text_id == real_text_id.
343
            Otherwise it returns a string suitable for printing, indicating
344
            the file's id.
345
            """
346
            guess_id = common.guess_text_id(tree, file_id, rev_id,
347
                    modified=modified)
348
            real_id = tree.inventory[file_id].text_id
349
            if guess_id != real_id:
350
                return '\ttext-id:' + encode(real_id)
351
            else:
352
                return ''
353
0.5.5 by John Arbash Meinel
Updated to now include the diffs
354
355
        for path, file_id, kind in self.delta.removed:
0.5.55 by John Arbash Meinel
Lots of updates. Using a minimized annotations for changesets.
356
            # We don't care about text ids for removed files
357
            print >>self.to_file, '*** removed %s %s' % (kind,
358
                    encode(path))
0.5.5 by John Arbash Meinel
Updated to now include the diffs
359
            if kind == 'file' and self.full_remove:
0.5.71 by John Arbash Meinel
Cleaning up code for latest bzr.
360
                diff_file(self.base_label + path,
0.5.68 by John Arbash Meinel
(broken), starting to change the syntax of the command to allow cset to take a base and a target.
361
                          self.base_tree.get_file(file_id).readlines(),
0.5.5 by John Arbash Meinel
Updated to now include the diffs
362
                          DEVNULL, 
363
                          [],
0.5.7 by John Arbash Meinel
Added a bunch more information about changesets. Can now read back in all of the meta information.
364
                          self.to_file)
0.5.5 by John Arbash Meinel
Updated to now include the diffs
365
    
366
        for path, file_id, kind in self.delta.added:
0.5.55 by John Arbash Meinel
Lots of updates. Using a minimized annotations for changesets.
367
            print >>self.to_file, '*** added %s %s\tfile-id:%s%s' % (kind,
368
                    encode(path),
369
                    encode(file_id),
370
                    get_text_id_str(file_id))
0.5.5 by John Arbash Meinel
Updated to now include the diffs
371
            if kind == 'file':
372
                diff_file(DEVNULL,
373
                          [],
0.5.71 by John Arbash Meinel
Cleaning up code for latest bzr.
374
                          self.target_label + path,
0.5.68 by John Arbash Meinel
(broken), starting to change the syntax of the command to allow cset to take a base and a target.
375
                          self.target_tree.get_file(file_id).readlines(),
0.5.7 by John Arbash Meinel
Added a bunch more information about changesets. Can now read back in all of the meta information.
376
                          self.to_file)
0.5.5 by John Arbash Meinel
Updated to now include the diffs
377
    
378
        for old_path, new_path, file_id, kind, text_modified in self.delta.renamed:
0.5.55 by John Arbash Meinel
Lots of updates. Using a minimized annotations for changesets.
379
            print >>self.to_file, '*** renamed %s %s\t=> %s%s' % (kind,
380
                    encode(old_path), encode(new_path),
381
                    get_text_id_str(file_id, text_modified))
0.5.5 by John Arbash Meinel
Updated to now include the diffs
382
            if self.full_rename and kind == 'file':
0.5.71 by John Arbash Meinel
Cleaning up code for latest bzr.
383
                diff_file(self.base_label + old_path,
0.5.68 by John Arbash Meinel
(broken), starting to change the syntax of the command to allow cset to take a base and a target.
384
                          self.base_tree.get_file(file_id).readlines(),
0.5.5 by John Arbash Meinel
Updated to now include the diffs
385
                          DEVNULL, 
386
                          [],
0.5.7 by John Arbash Meinel
Added a bunch more information about changesets. Can now read back in all of the meta information.
387
                          self.to_file)
0.5.5 by John Arbash Meinel
Updated to now include the diffs
388
                diff_file(DEVNULL,
389
                          [],
0.5.71 by John Arbash Meinel
Cleaning up code for latest bzr.
390
                          self.target_label + new_path,
0.5.68 by John Arbash Meinel
(broken), starting to change the syntax of the command to allow cset to take a base and a target.
391
                          self.target_tree.get_file(file_id).readlines(),
0.5.7 by John Arbash Meinel
Added a bunch more information about changesets. Can now read back in all of the meta information.
392
                          self.to_file)
0.5.5 by John Arbash Meinel
Updated to now include the diffs
393
            elif text_modified:
0.5.71 by John Arbash Meinel
Cleaning up code for latest bzr.
394
                    diff_file(self.base_label + old_path,
0.5.68 by John Arbash Meinel
(broken), starting to change the syntax of the command to allow cset to take a base and a target.
395
                              self.base_tree.get_file(file_id).readlines(),
0.5.71 by John Arbash Meinel
Cleaning up code for latest bzr.
396
                              self.target_label + new_path,
0.5.68 by John Arbash Meinel
(broken), starting to change the syntax of the command to allow cset to take a base and a target.
397
                              self.target_tree.get_file(file_id).readlines(),
0.5.7 by John Arbash Meinel
Added a bunch more information about changesets. Can now read back in all of the meta information.
398
                              self.to_file)
0.5.5 by John Arbash Meinel
Updated to now include the diffs
399
    
400
        for path, file_id, kind in self.delta.modified:
0.5.55 by John Arbash Meinel
Lots of updates. Using a minimized annotations for changesets.
401
            print >>self.to_file, '*** modified %s %s%s' % (kind,
402
                    encode(path), get_text_id_str(file_id))
0.5.5 by John Arbash Meinel
Updated to now include the diffs
403
            if kind == 'file':
0.5.71 by John Arbash Meinel
Cleaning up code for latest bzr.
404
                diff_file(self.base_label + path,
0.5.68 by John Arbash Meinel
(broken), starting to change the syntax of the command to allow cset to take a base and a target.
405
                          self.base_tree.get_file(file_id).readlines(),
0.5.71 by John Arbash Meinel
Cleaning up code for latest bzr.
406
                          self.target_label + path,
0.5.68 by John Arbash Meinel
(broken), starting to change the syntax of the command to allow cset to take a base and a target.
407
                          self.target_tree.get_file(file_id).readlines(),
0.5.7 by John Arbash Meinel
Added a bunch more information about changesets. Can now read back in all of the meta information.
408
                          self.to_file)
0.5.1 by John Arbash Meinel
Just an initial working step.
409
0.5.68 by John Arbash Meinel
(broken), starting to change the syntax of the command to allow cset to take a base and a target.
410
def show_changeset(base_branch, base_rev_id,
411
        target_branch, target_rev_id,
412
        starting_rev_id = None,
413
        to_file=None, include_full_diff=False):
0.5.1 by John Arbash Meinel
Just an initial working step.
414
    from bzrlib.diff import compare_trees
415
416
    if to_file is None:
417
        import sys
418
        to_file = sys.stdout
0.5.71 by John Arbash Meinel
Cleaning up code for latest bzr.
419
    base_tree = base_branch.revision_tree(base_rev_id)
420
    target_tree = target_branch.revision_tree(target_rev_id)
0.5.68 by John Arbash Meinel
(broken), starting to change the syntax of the command to allow cset to take a base and a target.
421
422
    delta = compare_trees(base_tree, target_tree, want_unchanged=False)
423
424
    meta = MetaInfoHeader(base_branch, base_rev_id, base_tree,
425
            target_branch, target_rev_id, target_tree,
426
            delta,
427
            starting_rev_id=starting_rev_id,
428
            full_rename=include_full_diff, full_remove=include_full_diff)
0.5.1 by John Arbash Meinel
Just an initial working step.
429
    meta.write_meta_info(to_file)
430