/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar
0.436.2 by Jelmer Vernooij
Add stubs for testsuite, rebase-continue and rebase-abort commands.
1
# Copyright (C) 2006-2007 by Jelmer Vernooij
2
# 
3
# This program is free software; you can redistribute it and/or modify
4
# it under the terms of the GNU General Public License as published by
5
# the Free Software Foundation; either version 2 of the License, or
6
# (at your option) any later version.
7
#
8
# This program is distributed in the hope that it will be useful,
9
# but WITHOUT ANY WARRANTY; without even the implied warranty of
10
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11
# GNU General Public License for more details.
12
#
13
# You should have received a copy of the GNU General Public License
14
# along with this program; if not, write to the Free Software
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
0.436.16 by Jelmer Vernooij
Some more work on maptree.
16
"""Rebase."""
0.436.3 by Jelmer Vernooij
Fill in commands.
17
0.436.5 by Jelmer Vernooij
Import change_revision_parent from bzr-svn.
18
from bzrlib.config import Config
0.436.16 by Jelmer Vernooij
Some more work on maptree.
19
from bzrlib.errors import BzrError, NoSuchFile, UnknownFormatError
0.436.4 by Jelmer Vernooij
Add some tests.
20
from bzrlib.generate_ids import gen_revision_id
0.436.10 by Jelmer Vernooij
Add more agressive version of revert.
21
from bzrlib import osutils
0.436.9 by Jelmer Vernooij
Add rebase-todo command, fix rebase-continue.
22
from bzrlib.revision import NULL_REVISION
0.436.4 by Jelmer Vernooij
Add some tests.
23
from bzrlib.trace import mutter
0.436.5 by Jelmer Vernooij
Import change_revision_parent from bzr-svn.
24
import bzrlib.ui as ui
0.436.4 by Jelmer Vernooij
Add some tests.
25
0.436.17 by Jelmer Vernooij
Move maptree code to separate files.
26
from maptree import MapTree, map_file_ids
27
0.436.3 by Jelmer Vernooij
Fill in commands.
28
REBASE_PLAN_FILENAME = 'rebase-plan'
0.436.9 by Jelmer Vernooij
Add rebase-todo command, fix rebase-continue.
29
REBASE_CURRENT_REVID_FILENAME = 'rebase-current'
0.436.4 by Jelmer Vernooij
Add some tests.
30
REBASE_PLAN_VERSION = 1
0.436.27 by Jelmer Vernooij
Note revision property 'rebase-of', add explanation of use of pregenerated revision ids.
31
REVPROP_REBASE_OF = 'rebase-of'
0.436.3 by Jelmer Vernooij
Fill in commands.
32
33
def rebase_plan_exists(wt):
34
    """Check whether there is a rebase plan present.
35
36
    :param wt: Working tree for which to check.
37
    :return: boolean
38
    """
0.436.7 by Jelmer Vernooij
Add more test, make basic rebase work.
39
    try:
40
        return wt._control_files.get(REBASE_PLAN_FILENAME).read() != ''
41
    except NoSuchFile:
42
        return False
0.436.3 by Jelmer Vernooij
Fill in commands.
43
44
45
def read_rebase_plan(wt):
46
    """Read a rebase plan file.
47
48
    :param wt: Working Tree for which to write the plan.
0.436.4 by Jelmer Vernooij
Add some tests.
49
    :return: Tuple with last revision info and replace map.
0.436.3 by Jelmer Vernooij
Fill in commands.
50
    """
51
    text = wt._control_files.get(REBASE_PLAN_FILENAME).read()
52
    if text == '':
0.436.7 by Jelmer Vernooij
Add more test, make basic rebase work.
53
        raise NoSuchFile(REBASE_PLAN_FILENAME)
0.436.4 by Jelmer Vernooij
Add some tests.
54
    return unmarshall_rebase_plan(text)
55
56
57
def write_rebase_plan(wt, replace_map):
0.436.3 by Jelmer Vernooij
Fill in commands.
58
    """Write a rebase plan file.
59
60
    :param wt: Working Tree for which to write the plan.
0.436.4 by Jelmer Vernooij
Add some tests.
61
    :param replace_map: Replace map (old revid -> (new revid, new parents))
0.436.3 by Jelmer Vernooij
Fill in commands.
62
    """
0.436.7 by Jelmer Vernooij
Add more test, make basic rebase work.
63
    wt._control_files.put_utf8(REBASE_PLAN_FILENAME, 
64
            marshall_rebase_plan(wt.branch.last_revision_info(), replace_map))
0.436.3 by Jelmer Vernooij
Fill in commands.
65
66
67
def remove_rebase_plan(wt):
68
    """Remove a rebase plan file.
69
70
    :param wt: Working Tree for which to remove the plan.
71
    """
0.436.7 by Jelmer Vernooij
Add more test, make basic rebase work.
72
    wt._control_files.put_utf8(REBASE_PLAN_FILENAME, '')
0.436.3 by Jelmer Vernooij
Fill in commands.
73
74
0.436.4 by Jelmer Vernooij
Add some tests.
75
def marshall_rebase_plan(last_rev_info, replace_map):
0.436.3 by Jelmer Vernooij
Fill in commands.
76
    """Marshall a rebase plan.
77
78
    :param last_rev_info: Last revision info tuple.
0.436.4 by Jelmer Vernooij
Add some tests.
79
    :param replace_map: Replace map (old revid -> (new revid, new parents))
0.436.3 by Jelmer Vernooij
Fill in commands.
80
    :return: string
81
    """
0.436.4 by Jelmer Vernooij
Add some tests.
82
    ret = "# Bazaar rebase plan %d\n" % REBASE_PLAN_VERSION
83
    ret += "%d %s\n" % last_rev_info
84
    for oldrev in replace_map:
85
        (newrev, newparents) = replace_map[oldrev]
86
        ret += "%s %s" % (oldrev, newrev) + \
87
            "".join([" %s" % p for p in newparents]) + "\n"
88
    return ret
89
90
91
def unmarshall_rebase_plan(text):
0.436.3 by Jelmer Vernooij
Fill in commands.
92
    """Unmarshall a rebase plan.
93
94
    :param text: Text to parse
0.436.4 by Jelmer Vernooij
Add some tests.
95
    :return: Tuple with last revision info, replace map.
0.436.3 by Jelmer Vernooij
Fill in commands.
96
    """
0.436.4 by Jelmer Vernooij
Add some tests.
97
    lines = text.split('\n')
98
    # Make sure header is there
99
    if lines[0] != "# Bazaar rebase plan %d" % REBASE_PLAN_VERSION:
100
        raise UnknownFormatError(lines[0])
101
102
    pts = lines[1].split(" ", 1)
103
    last_revision_info = (int(pts[0]), pts[1])
104
    replace_map = {}
105
    for l in lines[2:]:
106
        if l == "":
107
            # Skip empty lines
108
            continue
109
        pts = l.split(" ")
110
        replace_map[pts[0]] = (pts[1], pts[2:])
111
    return (last_revision_info, replace_map)
112
0.436.6 by Jelmer Vernooij
Add somewhat more complex plan generation function, rebase implementation.
113
114
def regenerate_default_revid(rev):
115
    return gen_revision_id(rev.committer, rev.timestamp)
116
117
118
def generate_simple_plan(repository, history, start_revid, onto_revid, 
119
                         generate_revid=regenerate_default_revid):
0.436.3 by Jelmer Vernooij
Fill in commands.
120
    """Create a simple rebase plan that replays history based 
0.436.6 by Jelmer Vernooij
Add somewhat more complex plan generation function, rebase implementation.
121
    on one revision being replayed on top of another.
0.436.3 by Jelmer Vernooij
Fill in commands.
122
0.436.6 by Jelmer Vernooij
Add somewhat more complex plan generation function, rebase implementation.
123
    :param repository: Repository
124
    :param history: Revision history
125
    :param start_revid: Id of revision at which to start replaying
126
    :param onto_revid: Id of revision on top of which to replay
127
    :param generate_revid: Function for generating new revision ids
0.436.3 by Jelmer Vernooij
Fill in commands.
128
0.436.4 by Jelmer Vernooij
Add some tests.
129
    :return: replace map
0.436.3 by Jelmer Vernooij
Fill in commands.
130
    """
0.436.6 by Jelmer Vernooij
Add somewhat more complex plan generation function, rebase implementation.
131
    assert start_revid in history
132
    assert repository.has_revision(start_revid)
133
    assert repository.has_revision(onto_revid)
134
    replace_map = {}
135
    i = history.index(start_revid)
136
    new_parent = onto_revid
137
    for oldrevid in history[i:]: 
138
        rev = repository.get_revision(oldrevid)
139
        parents = rev.parent_ids
140
        assert len(parents) == 0 or \
141
                parents[0] == history[history.index(oldrevid)-1]
142
        parents[0] = new_parent
143
        newrevid = generate_revid(rev)
144
        assert newrevid != oldrevid
145
        replace_map[oldrevid] = (newrevid, parents)
146
        new_parent = newrevid
147
    return replace_map
148
149
0.436.31 by Jelmer Vernooij
Refactor generate_transpose_plan() to not take a repository object but
150
def generate_transpose_plan(graph, renames, get_parents, generate_revid):
151
    """Create a rebase plan that replaces a bunch of revisions
152
    in a revision graph.
0.436.6 by Jelmer Vernooij
Add somewhat more complex plan generation function, rebase implementation.
153
154
    :param graph: Revision graph in which to operate
155
    :param renames: Renames of revision
0.436.31 by Jelmer Vernooij
Refactor generate_transpose_plan() to not take a repository object but
156
    :param get_parents: Function for determining parents
0.436.6 by Jelmer Vernooij
Add somewhat more complex plan generation function, rebase implementation.
157
    :param generate_revid: Function for creating new revision ids
158
    """
159
    replace_map = {}
160
    todo = []
0.436.13 by Jelmer Vernooij
Add progress bar, some optimizations. Make merge type configurable.
161
    children = {}
162
    for r in graph:
163
        if not children.has_key(r):
164
            children[r] = []
165
        for p in graph[r]:
166
            if not children.has_key(p):
167
                children[p] = []
168
            children[p].append(r)
169
0.436.31 by Jelmer Vernooij
Refactor generate_transpose_plan() to not take a repository object but
170
    # todo contains a list of revisions that need to 
171
    # be rewritten
172
    for r in renames:
173
        replace_map[r] = (renames[r], get_parents(renames[r]))
174
        todo.append(r)
175
0.436.13 by Jelmer Vernooij
Add progress bar, some optimizations. Make merge type configurable.
176
    total = len(todo)
177
    processed = set()
178
    i = 0
179
    pb = ui.ui_factory.nested_progress_bar()
180
    try:
181
        while len(todo) > 0:
182
            r = todo.pop()
183
            i += 1
184
            pb.update('determining dependencies', i, total)
185
            # Add entry for them in replace_map
186
            for c in children[r]:
187
                if c in renames:
188
                    continue
189
                if replace_map.has_key(c):
190
                    parents = replace_map[c][1]
191
                else:
0.436.31 by Jelmer Vernooij
Refactor generate_transpose_plan() to not take a repository object but
192
                    parents = graph[c]
0.436.13 by Jelmer Vernooij
Add progress bar, some optimizations. Make merge type configurable.
193
                # replace r in parents with replace_map[r][0]
194
                if not replace_map[r][0] in parents:
195
                    parents[parents.index(r)] = replace_map[r][0]
0.436.31 by Jelmer Vernooij
Refactor generate_transpose_plan() to not take a repository object but
196
                replace_map[c] = (generate_revid(c), parents)
197
                assert replace_map[c][0] != c
0.436.13 by Jelmer Vernooij
Add progress bar, some optimizations. Make merge type configurable.
198
            processed.add(r)
199
            # Add them to todo[]
0.436.15 by Jelmer Vernooij
Fix inverse bug - needs tests.
200
            todo.extend(filter(lambda x: not x in processed, children[r]))
0.436.13 by Jelmer Vernooij
Add progress bar, some optimizations. Make merge type configurable.
201
    finally:
202
        pb.finished()
0.436.6 by Jelmer Vernooij
Add somewhat more complex plan generation function, rebase implementation.
203
0.436.31 by Jelmer Vernooij
Refactor generate_transpose_plan() to not take a repository object but
204
    # Remove items from the map that already exist
205
    for revid in renames:
206
        if replace_map.has_key(revid):
207
            del replace_map[revid]
208
0.436.6 by Jelmer Vernooij
Add somewhat more complex plan generation function, rebase implementation.
209
    return replace_map
210
211
0.436.9 by Jelmer Vernooij
Add rebase-todo command, fix rebase-continue.
212
def rebase_todo(repository, replace_map):
213
    """Figure out what revisions still need to be rebased.
214
215
    :param repository: Repository that contains the revisions
216
    :param replace_map: Replace map
217
    """
218
    for revid in replace_map:
219
        if not repository.has_revision(replace_map[revid][0]):
220
            yield revid
221
222
0.436.6 by Jelmer Vernooij
Add somewhat more complex plan generation function, rebase implementation.
223
def rebase(repository, replace_map, replay_fn):
0.436.5 by Jelmer Vernooij
Import change_revision_parent from bzr-svn.
224
    """Rebase a working tree according to the specified map.
225
0.436.6 by Jelmer Vernooij
Add somewhat more complex plan generation function, rebase implementation.
226
    :param repository: Repository that contains the revisions
0.436.5 by Jelmer Vernooij
Import change_revision_parent from bzr-svn.
227
    :param replace_map: Dictionary with revisions to (optionally) rewrite
0.436.6 by Jelmer Vernooij
Add somewhat more complex plan generation function, rebase implementation.
228
    :param merge_fn: Function for replaying a revision
0.436.5 by Jelmer Vernooij
Import change_revision_parent from bzr-svn.
229
    """
0.436.9 by Jelmer Vernooij
Add rebase-todo command, fix rebase-continue.
230
    todo = list(rebase_todo(repository, replace_map))
0.436.6 by Jelmer Vernooij
Add somewhat more complex plan generation function, rebase implementation.
231
    dependencies = {}
232
233
    # Figure out the dependencies
234
    for revid in todo:
235
        for p in replace_map[revid][1]:
236
            if repository.has_revision(p):
237
                continue
238
            if not dependencies.has_key(p):
239
                dependencies[p] = []
240
            dependencies[p].append(revid)
241
242
    pb = ui.ui_factory.nested_progress_bar()
0.436.22 by Jelmer Vernooij
Try to improve the progress bar a bit.
243
    total = len(todo)
0.436.6 by Jelmer Vernooij
Add somewhat more complex plan generation function, rebase implementation.
244
    i = 0
245
    try:
246
        while len(todo) > 0:
0.436.22 by Jelmer Vernooij
Try to improve the progress bar a bit.
247
            pb.update('rebase revisions', i, total)
0.436.6 by Jelmer Vernooij
Add somewhat more complex plan generation function, rebase implementation.
248
            i += 1
249
            revid = todo.pop()
250
            (newrevid, newparents) = replace_map[revid]
0.436.19 by Jelmer Vernooij
- Add blackbox tests
251
            if filter(repository.has_revision, newparents) != newparents:
0.436.6 by Jelmer Vernooij
Add somewhat more complex plan generation function, rebase implementation.
252
                # Not all parents present yet, avoid for now
253
                continue
254
            if repository.has_revision(newrevid):
255
                # Was already converted, no need to worry about it again
256
                continue
257
            replay_fn(repository, revid, newrevid, newparents)
258
            assert repository.has_revision(newrevid)
0.436.32 by Jelmer Vernooij
Properly detect invalid snapshot replays.
259
            assert repository.revision_parents(newrevid) == newparents, \
260
                   "expected parents %r, got %r" % (newparents, 
261
                           repository.revision_parents(newrevid))
0.436.6 by Jelmer Vernooij
Add somewhat more complex plan generation function, rebase implementation.
262
            if dependencies.has_key(newrevid):
263
                todo.extend(dependencies[newrevid])
264
                del dependencies[newrevid]
265
    finally:
266
        pb.finished()
267
        
0.436.19 by Jelmer Vernooij
- Add blackbox tests
268
    #assert all(map(repository.has_revision, 
269
    #           [replace_map[r][0] for r in replace_map]))
0.436.16 by Jelmer Vernooij
Some more work on maptree.
270
0.436.32 by Jelmer Vernooij
Properly detect invalid snapshot replays.
271
272
0.436.7 by Jelmer Vernooij
Add more test, make basic rebase work.
273
def replay_snapshot(repository, oldrevid, newrevid, new_parents):
0.436.32 by Jelmer Vernooij
Properly detect invalid snapshot replays.
274
    """Replay a commit by simply commiting the same snapshot with different 
275
    parents.
0.436.5 by Jelmer Vernooij
Import change_revision_parent from bzr-svn.
276
277
    :param repository: Repository in which the revision is present.
278
    :param oldrevid: Revision id of the revision to copy.
279
    :param newrevid: Revision id of the revision to create.
280
    :param new_parents: Revision ids of the new parent revisions.
281
    """
282
    assert isinstance(new_parents, list)
0.436.16 by Jelmer Vernooij
Some more work on maptree.
283
    mutter('creating copy %r of %r with new parents %r' % 
284
                               (newrevid, oldrevid, new_parents))
0.436.5 by Jelmer Vernooij
Import change_revision_parent from bzr-svn.
285
    oldrev = repository.get_revision(oldrevid)
286
0.436.7 by Jelmer Vernooij
Add more test, make basic rebase work.
287
    revprops = dict(oldrev.properties)
0.436.27 by Jelmer Vernooij
Note revision property 'rebase-of', add explanation of use of pregenerated revision ids.
288
    revprops[REVPROP_REBASE_OF] = oldrevid
0.436.7 by Jelmer Vernooij
Add more test, make basic rebase work.
289
0.436.5 by Jelmer Vernooij
Import change_revision_parent from bzr-svn.
290
    builder = repository.get_commit_builder(branch=None, parents=new_parents, 
291
                                  config=Config(),
292
                                  committer=oldrev.committer,
293
                                  timestamp=oldrev.timestamp,
294
                                  timezone=oldrev.timezone,
0.436.7 by Jelmer Vernooij
Add more test, make basic rebase work.
295
                                  revprops=revprops,
0.436.5 by Jelmer Vernooij
Import change_revision_parent from bzr-svn.
296
                                  revision_id=newrevid)
297
298
    # Check what new_ie.file_id should be
299
    # use old and new parent inventories to generate new_id map
0.436.16 by Jelmer Vernooij
Some more work on maptree.
300
    fileid_map = map_file_ids(repository, oldrev.parent_ids, new_parents)
301
    oldtree = MapTree(repository.revision_tree(oldrevid), fileid_map)
302
    total = len(oldtree.inventory)
0.436.5 by Jelmer Vernooij
Import change_revision_parent from bzr-svn.
303
    pb = ui.ui_factory.nested_progress_bar()
0.436.7 by Jelmer Vernooij
Add more test, make basic rebase work.
304
    i = 0
0.436.5 by Jelmer Vernooij
Import change_revision_parent from bzr-svn.
305
    try:
0.436.14 by Jelmer Vernooij
More speed optimizations, deal with already created revisions.
306
        parent_invs = map(repository.get_revision_inventory, new_parents)
0.436.7 by Jelmer Vernooij
Add more test, make basic rebase work.
307
        transact = repository.get_transaction()
0.436.16 by Jelmer Vernooij
Some more work on maptree.
308
        for path, ie in oldtree.inventory.iter_entries():
0.436.5 by Jelmer Vernooij
Import change_revision_parent from bzr-svn.
309
            pb.update('upgrading file', i, total)
0.436.32 by Jelmer Vernooij
Properly detect invalid snapshot replays.
310
            # Either this file was modified last in this revision
311
            if ie.revision == oldrevid:
312
                ie = ie.copy()
313
                ie.revision = None
314
            else:
315
                # Other it should already have had this version in one of the parents
316
                if len(filter(lambda inv: ie.file_id in inv and inv[ie.file_id].revision == ie.revision, parent_invs)) == 0:
317
                    raise ReplaySnapshotFailed("Revision %r for file %r doesn't appear in any parent invs" % (ie.revision, ie.file_id))
0.436.5 by Jelmer Vernooij
Import change_revision_parent from bzr-svn.
318
            i += 1
0.436.32 by Jelmer Vernooij
Properly detect invalid snapshot replays.
319
            builder.record_entry_contents(ie, parent_invs, path, oldtree)
0.436.5 by Jelmer Vernooij
Import change_revision_parent from bzr-svn.
320
    finally:
321
        pb.finished()
322
323
    builder.finish_inventory()
324
    return builder.commit(oldrev.message)
325
326
0.436.9 by Jelmer Vernooij
Add rebase-todo command, fix rebase-continue.
327
def commit_rebase(wt, oldrev, newrevid):
328
    """Commit a rebase.
329
    
330
    :param wt: Mutable tree with the changes.
331
    :param oldrev: Revision info of new revision to commit.
332
    :param newrevid: New revision id."""
333
    assert oldrev.revision_id != newrevid
334
    revprops = dict(oldrev.properties)
0.436.27 by Jelmer Vernooij
Note revision property 'rebase-of', add explanation of use of pregenerated revision ids.
335
    revprops[REVPROP_REBASE_OF] = oldrev.revision_id
0.436.9 by Jelmer Vernooij
Add rebase-todo command, fix rebase-continue.
336
    wt.commit(message=oldrev.message, timestamp=oldrev.timestamp, timezone=oldrev.timezone,
337
              revprops=revprops, rev_id=newrevid)
338
    write_active_rebase_revid(wt, None)
339
340
0.436.7 by Jelmer Vernooij
Add more test, make basic rebase work.
341
def replay_delta_workingtree(wt, oldrevid, newrevid, newparents, map_ids=False,
342
        merge_type=None):
343
    """Replay a commit in a working tree, with a different base.
344
345
    :param wt: Working tree in which to do the replays.
346
    :param oldrevid: Old revision id
347
    :param newrevid: New revision id
348
    :param newparents: New parent revision ids
349
    :param map_ids: Whether to map file ids from the rebased revision using 
350
        the old and new parent tree file ids.
351
    """
352
    repository = wt.branch.repository
353
    if merge_type is None:
354
        from bzrlib.merge import Merge3Merger
355
        merge_type = Merge3Merger
356
    oldrev = wt.branch.repository.get_revision(oldrevid)
357
    # Make sure there are no conflicts or pending merges/changes 
358
    # in the working tree
359
    if wt.changes_from(wt.basis_tree()).has_changed():
360
        raise BzrError("Working tree has uncommitted changes.")
0.436.10 by Jelmer Vernooij
Add more agressive version of revert.
361
    complete_revert(wt, newparents)
0.436.8 by Jelmer Vernooij
Couple more minor fixes.
362
    assert not wt.changes_from(wt.basis_tree()).has_changed()
0.436.7 by Jelmer Vernooij
Add more test, make basic rebase work.
363
364
    oldtree = repository.revision_tree(oldrevid)
365
    basetree = repository.revision_tree(oldrev.parent_ids[0])
366
    if map_ids:
0.436.16 by Jelmer Vernooij
Some more work on maptree.
367
        fileid_map = map_file_ids(repository, oldrev.parent_ids, new_parents)
368
        oldtree = MapTree(repository, oldtree, fileid_map)
369
        basetree = MapTree(repository, basetree, fileid_map)
0.436.7 by Jelmer Vernooij
Add more test, make basic rebase work.
370
0.436.9 by Jelmer Vernooij
Add rebase-todo command, fix rebase-continue.
371
    write_active_rebase_revid(wt, oldrevid)
0.436.7 by Jelmer Vernooij
Add more test, make basic rebase work.
372
    merge = merge_type(working_tree=wt, this_tree=wt, 
373
            base_tree=basetree,
374
            other_tree=oldtree)
375
0.436.9 by Jelmer Vernooij
Add rebase-todo command, fix rebase-continue.
376
    commit_rebase(wt, oldrev, newrevid)
0.436.8 by Jelmer Vernooij
Couple more minor fixes.
377
0.436.10 by Jelmer Vernooij
Add more agressive version of revert.
378
0.436.13 by Jelmer Vernooij
Add progress bar, some optimizations. Make merge type configurable.
379
def workingtree_replay(wt, map_ids=False, merge_type=None):
0.436.6 by Jelmer Vernooij
Add somewhat more complex plan generation function, rebase implementation.
380
    """Returns a function that can replay revisions in wt.
381
382
    :param wt: Working tree in which to do the replays.
0.436.7 by Jelmer Vernooij
Add more test, make basic rebase work.
383
    :param map_ids: Whether to try to map between file ids (False for path-based merge)
0.436.6 by Jelmer Vernooij
Add somewhat more complex plan generation function, rebase implementation.
384
    """
385
    def replay(repository, oldrevid, newrevid, newparents):
0.436.7 by Jelmer Vernooij
Add more test, make basic rebase work.
386
        assert wt.branch.repository == repository
0.436.16 by Jelmer Vernooij
Some more work on maptree.
387
        return replay_delta_workingtree(wt, oldrevid, newrevid, newparents, 
388
                                        merge_type=merge_type)
0.436.6 by Jelmer Vernooij
Add somewhat more complex plan generation function, rebase implementation.
389
    return replay
0.436.7 by Jelmer Vernooij
Add more test, make basic rebase work.
390
0.436.9 by Jelmer Vernooij
Add rebase-todo command, fix rebase-continue.
391
392
def write_active_rebase_revid(wt, revid):
0.436.16 by Jelmer Vernooij
Some more work on maptree.
393
    """Write the id of the revision that is currently being rebased. 
394
395
    :param wt: Working Tree that is being used for the rebase.
396
    :param revid: Revision id to write
397
    """
0.436.9 by Jelmer Vernooij
Add rebase-todo command, fix rebase-continue.
398
    if revid is None:
399
        revid = NULL_REVISION
400
    wt._control_files.put_utf8(REBASE_CURRENT_REVID_FILENAME, revid)
401
0.436.10 by Jelmer Vernooij
Add more agressive version of revert.
402
0.436.9 by Jelmer Vernooij
Add rebase-todo command, fix rebase-continue.
403
def read_active_rebase_revid(wt):
0.436.16 by Jelmer Vernooij
Some more work on maptree.
404
    """Read the id of the revision that is currently being rebased.
405
406
    :param wt: Working Tree that is being used for the rebase.
407
    :return: Id of the revision that is being rebased.
408
    """
0.436.9 by Jelmer Vernooij
Add rebase-todo command, fix rebase-continue.
409
    try:
410
        text = wt._control_files.get(REBASE_CURRENT_REVID_FILENAME).read().rstrip("\n")
411
        if text == NULL_REVISION:
412
            return None
413
        return text
414
    except NoSuchFile:
415
        return None
0.436.10 by Jelmer Vernooij
Add more agressive version of revert.
416
417
418
def complete_revert(wt, newparents):
0.436.16 by Jelmer Vernooij
Some more work on maptree.
419
    """Simple helper that reverts to specified new parents and makes sure none 
420
    of the extra files are left around.
421
422
    :param wt: Working tree to use for rebase
423
    :param newparents: New parents of the working tree
0.436.10 by Jelmer Vernooij
Add more agressive version of revert.
424
    """
425
    newtree = wt.branch.repository.revision_tree(newparents[0])
426
    delta = wt.changes_from(newtree)
427
    wt.branch.generate_revision_history(newparents[0])
428
    wt.set_parent_ids(newparents)
429
    for (f, _, _) in delta.added:
430
        abs_path = wt.abspath(f)
431
        if osutils.lexists(abs_path):
432
            osutils.delete_any(abs_path)
433
    wt.revert([], old_tree=newtree, backups=False)
0.436.32 by Jelmer Vernooij
Properly detect invalid snapshot replays.
434
435
436
class ReplaySnapshotFailed(BzrError):
437
    _fmt = """Replaying the snapshot failed: %(message)s."""
438
439
    def __init__(self, message):
440
        BzrError.__init__(self)
441
        self.message = message