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