/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.103 by John Arbash Meinel
Updated to having a changeset specific message.
187
            message=None,
0.5.82 by John Arbash Meinel
Lots of changes, changing separators, updating tests, updated ChangesetTree to include text_ids
188
            base_label = 'orig', target_label = 'mod'):
0.5.5 by John Arbash Meinel
Updated to now include the diffs
189
        """
190
        :param full_remove: Include the full-text for a delete
191
        :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.
192
0.5.5 by John Arbash Meinel
Updated to now include the diffs
193
        """
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.
194
        self.base_branch = base_branch
195
        self.base_rev_id = base_rev_id
196
        self.base_tree = base_tree
0.5.78 by John Arbash Meinel
Working on test cases, starting with the empty project issues.
197
        if self.base_rev_id is not None:
198
            self.base_revision = self.base_branch.get_revision(self.base_rev_id)
199
        else:
200
            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.
201
202
        self.target_branch = target_branch
203
        self.target_rev_id = target_rev_id
204
        self.target_tree = target_tree
205
0.5.1 by John Arbash Meinel
Just an initial working step.
206
        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.
207
208
        self.starting_rev_id = starting_rev_id
209
0.5.5 by John Arbash Meinel
Updated to now include the diffs
210
        self.full_remove=full_remove
211
        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.
212
213
        self.base_label = base_label
0.5.71 by John Arbash Meinel
Cleaning up code for latest bzr.
214
        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.
215
0.5.7 by John Arbash Meinel
Added a bunch more information about changesets. Can now read back in all of the meta information.
216
        self.to_file = None
0.5.55 by John Arbash Meinel
Lots of updates. Using a minimized annotations for changesets.
217
        #self.revno = None
218
        #self.parent_revno = None
219
220
        # These are entries in the header.
221
        # They will be repeated in the footer,
222
        # only if they have changed
223
        self.date = None
224
        self.committer = None
0.5.103 by John Arbash Meinel
Updated to having a changeset specific message.
225
        self.message = 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.
226
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.
227
        self._get_revision_list()
0.5.1 by John Arbash Meinel
Just an initial working step.
228
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.
229
    def _get_revision_list(self):
0.5.1 by John Arbash Meinel
Just an initial working step.
230
        """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.
231
        It fills out the internal self.revision_list with Revision
232
        entries which should be in the changeset.
0.5.1 by John Arbash Meinel
Just an initial working step.
233
        """
0.5.71 by John Arbash Meinel
Cleaning up code for latest bzr.
234
        if self.starting_rev_id is None:
235
            self.starting_rev_id = _find_best_base(self.target_branch,
236
                    self.target_rev_id,
237
                    self.base_branch, self.base_rev_id)
238
239
        rev_id_list = _create_ancestry_to_rev(self.target_branch,
240
                self.starting_rev_id, self.target_rev_id)
0.5.73 by John Arbash Meinel
Some fixups for gen_changeset.
241
242
        assert rev_id_list[-1] == self.starting_rev_id
243
        # The last entry should be starting_rev_id which should
244
        # exist in both base and target, so we don't need to
245
        # include it in the changeset
246
        rev_id_list.pop()
0.5.71 by John Arbash Meinel
Cleaning up code for latest bzr.
247
        rev_id_list.reverse()
248
249
        self.revision_list = [self.target_branch.get_revision(rid) 
250
                                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.
251
0.5.87 by John Arbash Meinel
Handling international characters, added more test cases.
252
    def _write(self, txt, key=None, encode=True, indent=1):
253
        from common import encode as _encode
254
        if encode:
255
            def write(txt):
256
                self.to_file.write(_encode(txt))
257
        else:
258
            def write(txt):
259
                self.to_file.write(txt)
260
        if indent > 0:
261
            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.
262
        if key:
0.5.87 by John Arbash Meinel
Handling international characters, added more test cases.
263
            if txt:
264
                write('%s: %s\n' % (key, txt))
265
            else:
266
                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.
267
        else:
0.5.87 by John Arbash Meinel
Handling international characters, added more test cases.
268
            write('%s\n' % (txt,))
0.5.1 by John Arbash Meinel
Just an initial working step.
269
270
    def write_meta_info(self, to_file):
0.5.5 by John Arbash Meinel
Updated to now include the diffs
271
        """Write out the meta-info portion to the supplied file.
272
273
        :param to_file: Write out the meta information to the supplied
274
                        file
275
        """
0.5.7 by John Arbash Meinel
Added a bunch more information about changesets. Can now read back in all of the meta information.
276
        self.to_file = to_file
277
278
        self._write_header()
279
        self._write_diffs()
280
        self._write_footer()
281
282
    def _write_header(self):
283
        """Write the stuff that comes before the patches."""
0.5.81 by John Arbash Meinel
Cleaning up from pychecker.
284
        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.
285
        write = self._write
286
0.5.81 by John Arbash Meinel
Cleaning up from pychecker.
287
        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.
288
            write(line)
289
0.5.27 by John Arbash Meinel
Now capable of generating rollup changesets.
290
        # Print out the basic information about the 'target' revision
291
        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.
292
        write(rev.committer, key='committer')
0.5.55 by John Arbash Meinel
Lots of updates. Using a minimized annotations for changesets.
293
        self.committer = rev.committer
294
        self.date = format_highres_date(rev.timestamp, offset=rev.timezone)
295
        write(self.date, key='date')
0.5.103 by John Arbash Meinel
Updated to having a changeset specific message.
296
        if self.message is None:
297
            if rev.message is not None:
298
                self.message = rev.message
299
        if self.message:
0.5.87 by John Arbash Meinel
Handling international characters, added more test cases.
300
            write('', key='message')
0.5.103 by John Arbash Meinel
Updated to having a changeset specific message.
301
            for line in self.message.split('\n'):
0.5.87 by John Arbash Meinel
Handling international characters, added more test cases.
302
                write(txt=line, indent=4)
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
0.5.87 by John Arbash Meinel
Handling international characters, added more test cases.
304
        write('') # line with just '#'
305
        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.
306
307
    def _write_footer(self):
308
        """Write the stuff that comes after the patches.
309
310
        This is meant to be more meta-information, which people probably don't want
311
        to read, but which is required for proper bzr operation.
312
        """
313
        write = self._write
314
0.5.57 by John Arbash Meinel
Simplified the header, only output base if it is not the expected one.
315
        # 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)
316
        if len(self.revision_list[0].parents) == 0:
317
            assumed_base = None
318
        else:
319
            assumed_base = self.revision_list[0].parents[0].revision_id
320
        if (self.base_revision is not None 
321
                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.
322
            base = self.base_revision.revision_id
323
            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.
324
            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.
325
0.5.25 by John Arbash Meinel
Added some work to allow rollup revisions, and handling multiple parents.
326
        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.
327
328
    def _write_revisions(self):
329
        """Not used. Used for writing multiple revisions."""
0.5.87 by John Arbash Meinel
Handling international characters, added more test cases.
330
        from common import format_highres_date, encode
331
332
        write = self._write
0.5.55 by John Arbash Meinel
Lots of updates. Using a minimized annotations for changesets.
333
0.5.3 by John Arbash Meinel
Added a couple more bits
334
        for rev in self.revision_list:
0.5.25 by John Arbash Meinel
Added some work to allow rollup revisions, and handling multiple parents.
335
            rev_id = rev.revision_id
0.5.87 by John Arbash Meinel
Handling international characters, added more test cases.
336
            write(rev_id, key='revision')
337
            write(self.target_branch.get_revision_sha1(rev_id),
338
                    key = 'sha1', indent=4)
0.5.55 by John Arbash Meinel
Lots of updates. Using a minimized annotations for changesets.
339
            if rev.committer != self.committer:
0.5.87 by John Arbash Meinel
Handling international characters, added more test cases.
340
                write(rev.committer, key='committer', indent=4)
0.5.55 by John Arbash Meinel
Lots of updates. Using a minimized annotations for changesets.
341
            date = format_highres_date(rev.timestamp, rev.timezone)
342
            if date != self.date:
0.5.87 by John Arbash Meinel
Handling international characters, added more test cases.
343
                write(date, key='date', indent=4)
0.5.55 by John Arbash Meinel
Lots of updates. Using a minimized annotations for changesets.
344
            if rev.inventory_id != rev_id:
0.5.87 by John Arbash Meinel
Handling international characters, added more test cases.
345
                write(rev.inventory_id, key='inventory id', indent=4)
346
            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)
347
            if len(rev.parents) > 0:
0.5.87 by John Arbash Meinel
Handling international characters, added more test cases.
348
                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)
349
                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.
350
                    p_id = parent.revision_id
351
                    p_sha1 = parent.revision_sha1
352
                    if p_sha1 is None:
353
                        warning('Rev id {%s} parent {%s} missing sha hash.'
354
                                % (rev_id, p_id))
355
                        p_sha1 = self.target_branch.get_revision_sha1(p_id)
0.5.87 by John Arbash Meinel
Handling international characters, added more test cases.
356
                    write(p_id + '\t' + p_sha1, indent=7)
0.5.55 by John Arbash Meinel
Lots of updates. Using a minimized annotations for changesets.
357
            if rev.message and rev.message != self.message:
0.5.87 by John Arbash Meinel
Handling international characters, added more test cases.
358
                write('', key='message', indent=4)
0.5.55 by John Arbash Meinel
Lots of updates. Using a minimized annotations for changesets.
359
                for line in rev.message.split('\n'):
0.5.87 by John Arbash Meinel
Handling international characters, added more test cases.
360
                    write(line, indent=7)
0.5.25 by John Arbash Meinel
Added some work to allow rollup revisions, and handling multiple parents.
361
0.5.7 by John Arbash Meinel
Added a bunch more information about changesets. Can now read back in all of the meta information.
362
    def _write_diffs(self):
0.5.5 by John Arbash Meinel
Updated to now include the diffs
363
        """Write out the specific diffs"""
0.5.81 by John Arbash Meinel
Cleaning up from pychecker.
364
        from bzrlib.diff import internal_diff
0.5.87 by John Arbash Meinel
Handling international characters, added more test cases.
365
        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
366
        from os.path import join as pjoin
0.5.5 by John Arbash Meinel
Updated to now include the diffs
367
        DEVNULL = '/dev/null'
368
0.5.55 by John Arbash Meinel
Lots of updates. Using a minimized annotations for changesets.
369
        diff_file = internal_diff
370
        # Get the target tree so that we can check for
371
        # Appropriate text ids.
0.5.73 by John Arbash Meinel
Some fixups for gen_changeset.
372
        rev_id = self.target_rev_id
373
        tree = self.target_tree
0.5.55 by John Arbash Meinel
Lots of updates. Using a minimized annotations for changesets.
374
0.5.87 by John Arbash Meinel
Handling international characters, added more test cases.
375
        write = self._write
376
0.5.55 by John Arbash Meinel
Lots of updates. Using a minimized annotations for changesets.
377
0.5.81 by John Arbash Meinel
Cleaning up from pychecker.
378
        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.
379
            """This returns an empty string if guess_text_id == real_text_id.
380
            Otherwise it returns a string suitable for printing, indicating
381
            the file's id.
382
            """
0.5.81 by John Arbash Meinel
Cleaning up from pychecker.
383
            guess_id = guess_text_id(tree, file_id, rev_id,
384
                    kind, modified=modified)
0.5.55 by John Arbash Meinel
Lots of updates. Using a minimized annotations for changesets.
385
            real_id = tree.inventory[file_id].text_id
386
            if guess_id != real_id:
0.5.87 by John Arbash Meinel
Handling international characters, added more test cases.
387
                return ' // text-id:' + real_id
0.5.55 by John Arbash Meinel
Lots of updates. Using a minimized annotations for changesets.
388
            else:
389
                return ''
390
0.5.5 by John Arbash Meinel
Updated to now include the diffs
391
392
        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.
393
            # We don't care about text ids for removed files
0.5.100 by John Arbash Meinel
Switching from *** to ===
394
            write('=== removed %s %s' % (kind, path), indent=0)
0.5.5 by John Arbash Meinel
Updated to now include the diffs
395
            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
396
                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.
397
                          self.base_tree.get_file(file_id).readlines(),
0.5.5 by John Arbash Meinel
Updated to now include the diffs
398
                          DEVNULL, 
399
                          [],
0.5.7 by John Arbash Meinel
Added a bunch more information about changesets. Can now read back in all of the meta information.
400
                          self.to_file)
0.5.5 by John Arbash Meinel
Updated to now include the diffs
401
    
402
        for path, file_id, kind in self.delta.added:
0.5.100 by John Arbash Meinel
Switching from *** to ===
403
            write('=== added %s %s // file-id:%s%s' % (kind,
0.5.87 by John Arbash Meinel
Handling international characters, added more test cases.
404
                    path, file_id, get_text_id_str(file_id, kind)),
405
                    indent=0)
0.5.5 by John Arbash Meinel
Updated to now include the diffs
406
            if kind == 'file':
407
                diff_file(DEVNULL,
408
                          [],
0.5.82 by John Arbash Meinel
Lots of changes, changing separators, updating tests, updated ChangesetTree to include text_ids
409
                          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.
410
                          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.
411
                          self.to_file)
0.5.5 by John Arbash Meinel
Updated to now include the diffs
412
    
413
        for old_path, new_path, file_id, kind, text_modified in self.delta.renamed:
0.5.100 by John Arbash Meinel
Switching from *** to ===
414
            write('=== renamed %s %s // %s%s' % (kind,
0.5.87 by John Arbash Meinel
Handling international characters, added more test cases.
415
                    old_path, new_path,
416
                    get_text_id_str(file_id, kind, modified=text_modified)),
417
                    indent=0)
0.5.5 by John Arbash Meinel
Updated to now include the diffs
418
            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
419
                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.
420
                          self.base_tree.get_file(file_id).readlines(),
0.5.5 by John Arbash Meinel
Updated to now include the diffs
421
                          DEVNULL, 
422
                          [],
0.5.7 by John Arbash Meinel
Added a bunch more information about changesets. Can now read back in all of the meta information.
423
                          self.to_file)
0.5.5 by John Arbash Meinel
Updated to now include the diffs
424
                diff_file(DEVNULL,
425
                          [],
0.5.82 by John Arbash Meinel
Lots of changes, changing separators, updating tests, updated ChangesetTree to include text_ids
426
                          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.
427
                          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.
428
                          self.to_file)
0.5.5 by John Arbash Meinel
Updated to now include the diffs
429
            elif text_modified:
0.5.82 by John Arbash Meinel
Lots of changes, changing separators, updating tests, updated ChangesetTree to include text_ids
430
                    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.
431
                              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
432
                              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.
433
                              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.
434
                              self.to_file)
0.5.5 by John Arbash Meinel
Updated to now include the diffs
435
    
436
        for path, file_id, kind in self.delta.modified:
0.5.100 by John Arbash Meinel
Switching from *** to ===
437
            write('=== modified %s %s%s' % (kind,
0.5.87 by John Arbash Meinel
Handling international characters, added more test cases.
438
                    path, get_text_id_str(file_id, kind)),
439
                    indent=0)
0.5.5 by John Arbash Meinel
Updated to now include the diffs
440
            if kind == 'file':
0.5.82 by John Arbash Meinel
Lots of changes, changing separators, updating tests, updated ChangesetTree to include text_ids
441
                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.
442
                          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
443
                          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.
444
                          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.
445
                          self.to_file)
0.5.1 by John Arbash Meinel
Just an initial working step.
446
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.
447
def show_changeset(base_branch, base_rev_id,
448
        target_branch, target_rev_id,
449
        starting_rev_id = None,
0.5.103 by John Arbash Meinel
Updated to having a changeset specific message.
450
        to_file=None, include_full_diff=False,
451
        message=None):
0.5.1 by John Arbash Meinel
Just an initial working step.
452
    from bzrlib.diff import compare_trees
453
454
    if to_file is None:
455
        import sys
456
        to_file = sys.stdout
0.5.71 by John Arbash Meinel
Cleaning up code for latest bzr.
457
    base_tree = base_branch.revision_tree(base_rev_id)
458
    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.
459
460
    delta = compare_trees(base_tree, target_tree, want_unchanged=False)
461
462
    meta = MetaInfoHeader(base_branch, base_rev_id, base_tree,
463
            target_branch, target_rev_id, target_tree,
464
            delta,
465
            starting_rev_id=starting_rev_id,
0.5.103 by John Arbash Meinel
Updated to having a changeset specific message.
466
            full_rename=include_full_diff, full_remove=include_full_diff,
467
            message=message)
0.5.1 by John Arbash Meinel
Just an initial working step.
468
    meta.write_meta_info(to_file)
469