/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
0.5.87 by John Arbash Meinel
Handling international characters, added more test cases.
251
    def _write(self, txt, key=None, encode=True, indent=1):
252
        from common import encode as _encode
253
        if encode:
254
            def write(txt):
255
                self.to_file.write(_encode(txt))
256
        else:
257
            def write(txt):
258
                self.to_file.write(txt)
259
        if indent > 0:
260
            write('#' + (' ' * indent))
0.5.7 by John Arbash Meinel
Added a bunch more information about changesets. Can now read back in all of the meta information.
261
        if key:
0.5.87 by John Arbash Meinel
Handling international characters, added more test cases.
262
            if txt:
263
                write('%s: %s\n' % (key, txt))
264
            else:
265
                write('%s:\n' % key)
0.5.7 by John Arbash Meinel
Added a bunch more information about changesets. Can now read back in all of the meta information.
266
        else:
0.5.87 by John Arbash Meinel
Handling international characters, added more test cases.
267
            write('%s\n' % (txt,))
0.5.1 by John Arbash Meinel
Just an initial working step.
268
269
    def write_meta_info(self, to_file):
0.5.5 by John Arbash Meinel
Updated to now include the diffs
270
        """Write out the meta-info portion to the supplied file.
271
272
        :param to_file: Write out the meta information to the supplied
273
                        file
274
        """
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
        self.to_file = to_file
276
277
        self._write_header()
278
        self._write_diffs()
279
        self._write_footer()
280
281
    def _write_header(self):
282
        """Write the stuff that comes before the patches."""
0.5.81 by John Arbash Meinel
Cleaning up from pychecker.
283
        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.
284
        write = self._write
285
0.5.81 by John Arbash Meinel
Cleaning up from pychecker.
286
        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.
287
            write(line)
288
0.5.27 by John Arbash Meinel
Now capable of generating rollup changesets.
289
        # Print out the basic information about the 'target' revision
290
        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.
291
        write(rev.committer, key='committer')
0.5.55 by John Arbash Meinel
Lots of updates. Using a minimized annotations for changesets.
292
        self.committer = rev.committer
293
        self.date = format_highres_date(rev.timestamp, offset=rev.timezone)
294
        write(self.date, key='date')
0.5.17 by John Arbash Meinel
adding apply-changset, plus more meta information.
295
        if rev.message:
0.5.87 by John Arbash Meinel
Handling international characters, added more test cases.
296
            write('', key='message')
0.5.17 by John Arbash Meinel
adding apply-changset, plus more meta information.
297
            for line in rev.message.split('\n'):
0.5.87 by John Arbash Meinel
Handling international characters, added more test cases.
298
                write(txt=line, indent=4)
0.5.55 by John Arbash Meinel
Lots of updates. Using a minimized annotations for changesets.
299
            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.
300
0.5.87 by John Arbash Meinel
Handling international characters, added more test cases.
301
        write('') # line with just '#'
302
        write('', indent=0) # Empty line
0.5.7 by John Arbash Meinel
Added a bunch more information about changesets. Can now read back in all of the meta information.
303
304
    def _write_footer(self):
305
        """Write the stuff that comes after the patches.
306
307
        This is meant to be more meta-information, which people probably don't want
308
        to read, but which is required for proper bzr operation.
309
        """
310
        write = self._write
311
0.5.57 by John Arbash Meinel
Simplified the header, only output base if it is not the expected one.
312
        # 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)
313
        if len(self.revision_list[0].parents) == 0:
314
            assumed_base = None
315
        else:
316
            assumed_base = self.revision_list[0].parents[0].revision_id
317
        if (self.base_revision is not None 
318
                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.
319
            base = self.base_revision.revision_id
320
            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.
321
            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.
322
0.5.25 by John Arbash Meinel
Added some work to allow rollup revisions, and handling multiple parents.
323
        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.
324
325
    def _write_revisions(self):
326
        """Not used. Used for writing multiple revisions."""
0.5.87 by John Arbash Meinel
Handling international characters, added more test cases.
327
        from common import format_highres_date, encode
328
329
        write = self._write
0.5.55 by John Arbash Meinel
Lots of updates. Using a minimized annotations for changesets.
330
0.5.3 by John Arbash Meinel
Added a couple more bits
331
        for rev in self.revision_list:
0.5.25 by John Arbash Meinel
Added some work to allow rollup revisions, and handling multiple parents.
332
            rev_id = rev.revision_id
0.5.87 by John Arbash Meinel
Handling international characters, added more test cases.
333
            write(rev_id, key='revision')
334
            write(self.target_branch.get_revision_sha1(rev_id),
335
                    key = 'sha1', indent=4)
0.5.55 by John Arbash Meinel
Lots of updates. Using a minimized annotations for changesets.
336
            if rev.committer != self.committer:
0.5.87 by John Arbash Meinel
Handling international characters, added more test cases.
337
                write(rev.committer, key='committer', indent=4)
0.5.55 by John Arbash Meinel
Lots of updates. Using a minimized annotations for changesets.
338
            date = format_highres_date(rev.timestamp, rev.timezone)
339
            if date != self.date:
0.5.87 by John Arbash Meinel
Handling international characters, added more test cases.
340
                write(date, key='date', indent=4)
0.5.55 by John Arbash Meinel
Lots of updates. Using a minimized annotations for changesets.
341
            if rev.inventory_id != rev_id:
0.5.87 by John Arbash Meinel
Handling international characters, added more test cases.
342
                write(rev.inventory_id, key='inventory id', indent=4)
343
            write(rev.inventory_sha1, key='inventory sha1', indent=4)
0.5.59 by John Arbash Meinel
Several fixes for handling the case where you are doing a changeset against revno=0 (Null base)
344
            if len(rev.parents) > 0:
0.5.87 by John Arbash Meinel
Handling international characters, added more test cases.
345
                write(txt='', key='parents', indent=4)
0.5.59 by John Arbash Meinel
Several fixes for handling the case where you are doing a changeset against revno=0 (Null base)
346
                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.
347
                    p_id = parent.revision_id
348
                    p_sha1 = parent.revision_sha1
349
                    if p_sha1 is None:
350
                        warning('Rev id {%s} parent {%s} missing sha hash.'
351
                                % (rev_id, p_id))
352
                        p_sha1 = self.target_branch.get_revision_sha1(p_id)
0.5.87 by John Arbash Meinel
Handling international characters, added more test cases.
353
                    write(p_id + '\t' + p_sha1, indent=7)
0.5.55 by John Arbash Meinel
Lots of updates. Using a minimized annotations for changesets.
354
            if rev.message and rev.message != self.message:
0.5.87 by John Arbash Meinel
Handling international characters, added more test cases.
355
                write('', key='message', indent=4)
0.5.55 by John Arbash Meinel
Lots of updates. Using a minimized annotations for changesets.
356
                for line in rev.message.split('\n'):
0.5.87 by John Arbash Meinel
Handling international characters, added more test cases.
357
                    write(line, indent=7)
0.5.25 by John Arbash Meinel
Added some work to allow rollup revisions, and handling multiple parents.
358
0.5.7 by John Arbash Meinel
Added a bunch more information about changesets. Can now read back in all of the meta information.
359
    def _write_diffs(self):
0.5.5 by John Arbash Meinel
Updated to now include the diffs
360
        """Write out the specific diffs"""
0.5.81 by John Arbash Meinel
Cleaning up from pychecker.
361
        from bzrlib.diff import internal_diff
0.5.87 by John Arbash Meinel
Handling international characters, added more test cases.
362
        from common import guess_text_id
0.5.82 by John Arbash Meinel
Lots of changes, changing separators, updating tests, updated ChangesetTree to include text_ids
363
        from os.path import join as pjoin
0.5.5 by John Arbash Meinel
Updated to now include the diffs
364
        DEVNULL = '/dev/null'
365
0.5.55 by John Arbash Meinel
Lots of updates. Using a minimized annotations for changesets.
366
        diff_file = internal_diff
367
        # Get the target tree so that we can check for
368
        # Appropriate text ids.
0.5.73 by John Arbash Meinel
Some fixups for gen_changeset.
369
        rev_id = self.target_rev_id
370
        tree = self.target_tree
0.5.55 by John Arbash Meinel
Lots of updates. Using a minimized annotations for changesets.
371
0.5.87 by John Arbash Meinel
Handling international characters, added more test cases.
372
        write = self._write
373
0.5.55 by John Arbash Meinel
Lots of updates. Using a minimized annotations for changesets.
374
0.5.81 by John Arbash Meinel
Cleaning up from pychecker.
375
        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.
376
            """This returns an empty string if guess_text_id == real_text_id.
377
            Otherwise it returns a string suitable for printing, indicating
378
            the file's id.
379
            """
0.5.81 by John Arbash Meinel
Cleaning up from pychecker.
380
            guess_id = guess_text_id(tree, file_id, rev_id,
381
                    kind, modified=modified)
0.5.55 by John Arbash Meinel
Lots of updates. Using a minimized annotations for changesets.
382
            real_id = tree.inventory[file_id].text_id
383
            if guess_id != real_id:
0.5.87 by John Arbash Meinel
Handling international characters, added more test cases.
384
                return ' // text-id:' + real_id
0.5.55 by John Arbash Meinel
Lots of updates. Using a minimized annotations for changesets.
385
            else:
386
                return ''
387
0.5.5 by John Arbash Meinel
Updated to now include the diffs
388
389
        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.
390
            # We don't care about text ids for removed files
0.5.87 by John Arbash Meinel
Handling international characters, added more test cases.
391
            write('*** removed %s %s' % (kind, path), indent=0)
0.5.5 by John Arbash Meinel
Updated to now include the diffs
392
            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
393
                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.
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
    
399
        for path, file_id, kind in self.delta.added:
0.5.87 by John Arbash Meinel
Handling international characters, added more test cases.
400
            write('*** added %s %s // file-id:%s%s' % (kind,
401
                    path, file_id, get_text_id_str(file_id, kind)),
402
                    indent=0)
0.5.5 by John Arbash Meinel
Updated to now include the diffs
403
            if kind == 'file':
404
                diff_file(DEVNULL,
405
                          [],
0.5.82 by John Arbash Meinel
Lots of changes, changing separators, updating tests, updated ChangesetTree to include text_ids
406
                          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.
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 old_path, new_path, file_id, kind, text_modified in self.delta.renamed:
0.5.87 by John Arbash Meinel
Handling international characters, added more test cases.
411
            write('*** renamed %s %s // %s%s' % (kind,
412
                    old_path, new_path,
413
                    get_text_id_str(file_id, kind, modified=text_modified)),
414
                    indent=0)
0.5.5 by John Arbash Meinel
Updated to now include the diffs
415
            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
416
                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.
417
                          self.base_tree.get_file(file_id).readlines(),
0.5.5 by John Arbash Meinel
Updated to now include the diffs
418
                          DEVNULL, 
419
                          [],
0.5.7 by John Arbash Meinel
Added a bunch more information about changesets. Can now read back in all of the meta information.
420
                          self.to_file)
0.5.5 by John Arbash Meinel
Updated to now include the diffs
421
                diff_file(DEVNULL,
422
                          [],
0.5.82 by John Arbash Meinel
Lots of changes, changing separators, updating tests, updated ChangesetTree to include text_ids
423
                          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.
424
                          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.
425
                          self.to_file)
0.5.5 by John Arbash Meinel
Updated to now include the diffs
426
            elif text_modified:
0.5.82 by John Arbash Meinel
Lots of changes, changing separators, updating tests, updated ChangesetTree to include text_ids
427
                    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.
428
                              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
429
                              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.
430
                              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.
431
                              self.to_file)
0.5.5 by John Arbash Meinel
Updated to now include the diffs
432
    
433
        for path, file_id, kind in self.delta.modified:
0.5.87 by John Arbash Meinel
Handling international characters, added more test cases.
434
            write('*** modified %s %s%s' % (kind,
435
                    path, get_text_id_str(file_id, kind)),
436
                    indent=0)
0.5.5 by John Arbash Meinel
Updated to now include the diffs
437
            if kind == 'file':
0.5.82 by John Arbash Meinel
Lots of changes, changing separators, updating tests, updated ChangesetTree to include text_ids
438
                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.
439
                          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
440
                          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.
441
                          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.
442
                          self.to_file)
0.5.1 by John Arbash Meinel
Just an initial working step.
443
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.
444
def show_changeset(base_branch, base_rev_id,
445
        target_branch, target_rev_id,
446
        starting_rev_id = None,
447
        to_file=None, include_full_diff=False):
0.5.1 by John Arbash Meinel
Just an initial working step.
448
    from bzrlib.diff import compare_trees
449
450
    if to_file is None:
451
        import sys
452
        to_file = sys.stdout
0.5.71 by John Arbash Meinel
Cleaning up code for latest bzr.
453
    base_tree = base_branch.revision_tree(base_rev_id)
454
    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.
455
456
    delta = compare_trees(base_tree, target_tree, want_unchanged=False)
457
458
    meta = MetaInfoHeader(base_branch, base_rev_id, base_tree,
459
            target_branch, target_rev_id, target_tree,
460
            delta,
461
            starting_rev_id=starting_rev_id,
462
            full_rename=include_full_diff, full_remove=include_full_diff)
0.5.1 by John Arbash Meinel
Just an initial working step.
463
    meta.write_meta_info(to_file)
464