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