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