/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar
0.436.25 by Jelmer Vernooij
Add setup.py.
1
# Copyright (C) 2007 by Jelmer Vernooij <jelmer@samba.org>
0.436.2 by Jelmer Vernooij
Add stubs for testsuite, rebase-continue and rebase-abort commands.
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.25 by Jelmer Vernooij
Add setup.py.
16
"""Rebase support.
17
18
The Bazaar rebase plugin adds support for rebasing branches to Bazaar.
19
It adds the command 'rebase' to Bazaar. When conflicts occur when replaying
20
patches, the user can resolve the conflict and continue the rebase using the
21
'rebase-continue' command or abort using the 'rebase-abort' command.
22
"""
0.436.1 by Jelmer Vernooij
Add framework for git-rebase plugin.
23
0.436.4 by Jelmer Vernooij
Add some tests.
24
from bzrlib.commands import Command, Option, display_command, register_command
0.436.16 by Jelmer Vernooij
Some more work on maptree.
25
from bzrlib.errors import (BzrCommandError, ConflictsInTree, NoSuchFile, 
0.436.51 by Jelmer Vernooij
Give proper warning when there is no common base.
26
                           UnrelatedBranches, NoSuchRevision)
0.436.49 by Jelmer Vernooij
Fix locking.
27
from bzrlib.trace import info, warning
0.436.1 by Jelmer Vernooij
Add framework for git-rebase plugin.
28
0.436.49 by Jelmer Vernooij
Fix locking.
29
version_info = (0, 2, 0, 'dev', 0)
30
if version_info[3] == 'final':
31
    version_string = '%d.%d.%d' % version_info[:3]
32
else:
33
    version_string = '%d.%d.%d%s%d' % version_info
34
__version__ = version_string
0.436.25 by Jelmer Vernooij
Add setup.py.
35
__author__ = 'Jelmer Vernooij <jelmer@samba.org>'
36
0.436.49 by Jelmer Vernooij
Fix locking.
37
min_compatible_bzr_version = (0, 92)
38
39
def check_bzrlib_version(desired):
40
    """Check that bzrlib is compatible.
41
42
    If version is < all compatible version, assume incompatible.
43
    """
44
    import bzrlib
45
    bzrlib_version = bzrlib.version_info[:2]
46
    if bzrlib.version_info[3] == 'dev':
47
        return
48
    if bzrlib_version < desired:
49
        warning('Installed bzr version %s is too old to be used with bzr-rebase'
50
                ' %s.' % (bzrlib.__version__, __version__))
51
        # Not using BzrNewError, because it may not exist.
52
        raise Exception, ('Version mismatch', desired)
53
54
55
check_bzrlib_version(min_compatible_bzr_version)
56
0.436.43 by Jelmer Vernooij
Factor out common revid code - maybe some of this can use aaron's common ancestor code instead?
57
def find_last_common_revid(revhistory1, revhistory2):
58
    for revid in reversed(revhistory1):
59
        if revid in revhistory2:
60
            return revid
61
62
    raise UnrelatedBranches()
63
64
0.436.1 by Jelmer Vernooij
Add framework for git-rebase plugin.
65
class cmd_rebase(Command):
66
    """Re-base a branch.
67
0.437.5 by James Westby
Add some help text to the rebase command.
68
    Rebasing is the process of taking a branch and modifying the history so
69
    that it appears to start from a different point. This can be useful
70
    to clean up the history before submitting your changes. The tree at the
71
    end of the process will be the same as if you had merged the other branch,
72
    but the history will be different.
73
74
    The command takes the location of another branch on to which the branch in
75
    the current working directory will be rebased. If a branch is not specified
76
    then the parent branch is used, and this is usually the desired result.
77
78
    The first step identifies the revisions that are in the current branch that
79
    are not in the parent branch. The current branch is then set to be at the
80
    same revision as the target branch, and each revision is replayed on top
81
    of the branch. At the end of the process it will appear as though your
82
    current branch was branched off the current last revision of the target.
83
84
    Each revision that is replayed may cause conflicts in the tree. If this
85
    happens the command will stop and allow you to fix them up. Resolve the
86
    commits as you would for a merge, and then run 'bzr resolve' to marked
87
    them as resolved. Once you have resolved all the conflicts you should
88
    run 'bzr rebase-continue' to continue the rebase operation.
89
90
    If conflicts are encountered and you decide that you do not wish to continue
91
    you can run 'bzr rebase-abort'.
92
93
    The '--onto' option allows you to specify a different revision in the
94
    target branch to start at when replaying the revisions. This means that
95
    you can change the point at which the current branch will appear to be
96
    branched from when the operation completes.
0.436.1 by Jelmer Vernooij
Add framework for git-rebase plugin.
97
    """
0.436.7 by Jelmer Vernooij
Add more test, make basic rebase work.
98
    takes_args = ['upstream_location?']
0.436.19 by Jelmer Vernooij
- Add blackbox tests
99
    takes_options = ['revision', 'merge-type', 'verbose',
0.436.29 by Jelmer Vernooij
Add --dry-run option to rebase command.
100
        Option('dry-run',
101
               help="Show what would be done, but don't actually do anything."),
102
        Option('onto', help='Different revision to replay onto.',
103
               type=str)]
0.436.1 by Jelmer Vernooij
Add framework for git-rebase plugin.
104
    
105
    @display_command
0.436.16 by Jelmer Vernooij
Some more work on maptree.
106
    def run(self, upstream_location=None, onto=None, revision=None, 
0.436.29 by Jelmer Vernooij
Add --dry-run option to rebase command.
107
            merge_type=None, verbose=False, dry_run=False):
0.436.7 by Jelmer Vernooij
Add more test, make basic rebase work.
108
        from bzrlib.branch import Branch
109
        from bzrlib.revisionspec import RevisionSpec
110
        from bzrlib.workingtree import WorkingTree
0.436.16 by Jelmer Vernooij
Some more work on maptree.
111
        from rebase import (generate_simple_plan, rebase, rebase_plan_exists, 
112
                            read_rebase_plan, remove_rebase_plan, 
0.437.4 by James Westby
Import rebase_todo as it is needed for --verbose.
113
                            workingtree_replay, write_rebase_plan,
0.436.39 by Jelmer Vernooij
Some more refactoring, add test that demonstrates #126743.
114
                            regenerate_default_revid,
0.437.4 by James Westby
Import rebase_todo as it is needed for --verbose.
115
                            rebase_todo)
0.436.51 by Jelmer Vernooij
Give proper warning when there is no common base.
116
        wt = WorkingTree.open(".")
0.436.7 by Jelmer Vernooij
Add more test, make basic rebase work.
117
        wt.lock_write()
118
        if upstream_location is None:
119
            upstream_location = wt.branch.get_parent()
0.438.3 by Jelmer Vernooij
Add stop_revid argumen to generate_simple_plan.
120
            info("Rebasing on %s" % upstream_location)
0.436.3 by Jelmer Vernooij
Fill in commands.
121
        upstream = Branch.open(upstream_location)
0.436.7 by Jelmer Vernooij
Add more test, make basic rebase work.
122
        upstream_repository = upstream.repository
123
        upstream_revision = upstream.last_revision()
0.436.3 by Jelmer Vernooij
Fill in commands.
124
        try:
125
            # Abort if there already is a plan file
126
            if rebase_plan_exists(wt):
127
                raise BzrCommandError("A rebase operation was interrupted. Continue using 'bzr rebase-continue' or abort using 'bzr rebase-abort'")
128
0.436.43 by Jelmer Vernooij
Factor out common revid code - maybe some of this can use aaron's common ancestor code instead?
129
            start_revid = None
130
            stop_revid = None
131
            if revision is not None:
132
                if len(revision) == 1:
133
                    if revision[0] is not None:
134
                        stop_revid = revision[0].in_history(wt.branch).rev_id
135
                elif len(revision) == 2:
136
                    if revision[0] is not None:
137
                        start_revid = revision[0].in_history(wt.branch).rev_id
138
                    if revision[1] is not None:
139
                        stop_revid = revision[1].in_history(wt.branch).rev_id
140
                else:
141
                    raise BzrCommandError(
142
                        "--revision takes only one or two arguments")
143
0.436.3 by Jelmer Vernooij
Fill in commands.
144
            # Pull required revisions
0.436.29 by Jelmer Vernooij
Add --dry-run option to rebase command.
145
            wt.branch.repository.fetch(upstream_repository, upstream_revision)
0.436.3 by Jelmer Vernooij
Fill in commands.
146
            if onto is None:
147
                onto = upstream.last_revision()
0.436.7 by Jelmer Vernooij
Add more test, make basic rebase work.
148
            else:
0.437.2 by James Westby
Lookup the onto revision in the upstream branch.
149
                rev_spec = RevisionSpec.from_string(onto)
150
                onto = rev_spec.in_history(upstream).rev_id
0.436.7 by Jelmer Vernooij
Add more test, make basic rebase work.
151
152
            wt.branch.repository.fetch(upstream_repository, onto)
153
0.436.43 by Jelmer Vernooij
Factor out common revid code - maybe some of this can use aaron's common ancestor code instead?
154
            if stop_revid is not None:
155
                wt.branch.generate_revision_history(stop_revid)
0.436.7 by Jelmer Vernooij
Add more test, make basic rebase work.
156
            revhistory = wt.branch.revision_history()
0.436.43 by Jelmer Vernooij
Factor out common revid code - maybe some of this can use aaron's common ancestor code instead?
157
158
            if start_revid is None:
159
                common_revid = find_last_common_revid(revhistory, 
160
                                                 upstream.revision_history())
161
                if common_revid == upstream.last_revision():
162
                    raise BzrCommandError("Already rebased on %s" % upstream)
0.436.51 by Jelmer Vernooij
Give proper warning when there is no common base.
163
                try:
164
                    start_revid = wt.branch.get_rev_id(
165
                            wt.branch.revision_id_to_revno(common_revid)+1)
166
                except NoSuchRevision:
167
                    raise BzrCommandError("No common revision, please specify --revision")
0.436.12 by Jelmer Vernooij
Give sane error when branch is already rebased.
168
0.436.3 by Jelmer Vernooij
Fill in commands.
169
            # Create plan
0.436.4 by Jelmer Vernooij
Add some tests.
170
            replace_map = generate_simple_plan(
0.436.43 by Jelmer Vernooij
Factor out common revid code - maybe some of this can use aaron's common ancestor code instead?
171
                    revhistory, start_revid, stop_revid, onto,
0.438.1 by Jelmer Vernooij
Split out function for determining rebase base.
172
                    wt.branch.repository.get_ancestry(onto),
0.436.39 by Jelmer Vernooij
Some more refactoring, add test that demonstrates #126743.
173
                    wt.branch.repository.revision_parents,
174
                    lambda revid: regenerate_default_revid(wt.branch.repository, revid)
175
                    )
0.436.3 by Jelmer Vernooij
Fill in commands.
176
0.436.19 by Jelmer Vernooij
- Add blackbox tests
177
            if verbose:
0.436.29 by Jelmer Vernooij
Add --dry-run option to rebase command.
178
                todo = list(rebase_todo(wt.branch.repository, replace_map))
179
                info('%d revisions will be rebased:' % len(todo))
180
                for revid in todo:
181
                    info("%s" % revid)
182
183
            if not dry_run:
184
                # Write plan file
185
                write_rebase_plan(wt, replace_map)
186
187
                # Start executing plan
188
                try:
189
                    rebase(wt.branch.repository, replace_map, 
190
                           workingtree_replay(wt, merge_type=merge_type))
191
                except ConflictsInTree:
192
                    raise BzrCommandError("A conflict occurred replaying a commit. Resolve the conflict and run 'bzr rebase-continue' or run 'bzr rebase-abort'.")
193
                # Remove plan file
194
                remove_rebase_plan(wt)
0.436.3 by Jelmer Vernooij
Fill in commands.
195
        finally:
196
            wt.unlock()
0.436.2 by Jelmer Vernooij
Add stubs for testsuite, rebase-continue and rebase-abort commands.
197
0.436.12 by Jelmer Vernooij
Give sane error when branch is already rebased.
198
0.436.2 by Jelmer Vernooij
Add stubs for testsuite, rebase-continue and rebase-abort commands.
199
class cmd_rebase_abort(Command):
200
    """Abort an interrupted rebase
201
202
    """
203
    
204
    @display_command
205
    def run(self):
0.436.10 by Jelmer Vernooij
Add more agressive version of revert.
206
        from rebase import read_rebase_plan, remove_rebase_plan, complete_revert
0.436.7 by Jelmer Vernooij
Add more test, make basic rebase work.
207
        from bzrlib.workingtree import WorkingTree
0.436.2 by Jelmer Vernooij
Add stubs for testsuite, rebase-continue and rebase-abort commands.
208
        wt = WorkingTree.open('.')
0.436.7 by Jelmer Vernooij
Add more test, make basic rebase work.
209
        wt.lock_write()
0.436.3 by Jelmer Vernooij
Fill in commands.
210
        try:
211
            # Read plan file and set last revision
0.436.9 by Jelmer Vernooij
Add rebase-todo command, fix rebase-continue.
212
            try:
213
                last_rev_info = read_rebase_plan(wt)[0]
214
            except NoSuchFile:
215
                raise BzrCommandError("No rebase to abort")
0.436.10 by Jelmer Vernooij
Add more agressive version of revert.
216
            complete_revert(wt, [last_rev_info[1]])
0.436.7 by Jelmer Vernooij
Add more test, make basic rebase work.
217
            remove_rebase_plan(wt)
0.436.3 by Jelmer Vernooij
Fill in commands.
218
        finally:
219
            wt.unlock()
0.436.2 by Jelmer Vernooij
Add stubs for testsuite, rebase-continue and rebase-abort commands.
220
221
222
class cmd_rebase_continue(Command):
223
    """Continue an interrupted rebase after resolving conflicts
224
225
    """
0.436.13 by Jelmer Vernooij
Add progress bar, some optimizations. Make merge type configurable.
226
    takes_options = ['merge-type']
0.436.2 by Jelmer Vernooij
Add stubs for testsuite, rebase-continue and rebase-abort commands.
227
    
228
    @display_command
0.436.13 by Jelmer Vernooij
Add progress bar, some optimizations. Make merge type configurable.
229
    def run(self, merge_type=None):
0.436.16 by Jelmer Vernooij
Some more work on maptree.
230
        from rebase import (commit_rebase, rebase, rebase_plan_exists, 
231
                            read_rebase_plan, read_active_rebase_revid, 
232
                            remove_rebase_plan, workingtree_replay)
0.436.7 by Jelmer Vernooij
Add more test, make basic rebase work.
233
        from bzrlib.workingtree import WorkingTree
0.436.2 by Jelmer Vernooij
Add stubs for testsuite, rebase-continue and rebase-abort commands.
234
        wt = WorkingTree.open('.')
0.436.7 by Jelmer Vernooij
Add more test, make basic rebase work.
235
        wt.lock_write()
0.436.3 by Jelmer Vernooij
Fill in commands.
236
        try:
237
            # Abort if there are any conflicts
238
            if len(wt.conflicts()) != 0:
0.437.3 by James Westby
Provide a hint in the conflicts present message to rebase-continue.
239
                raise BzrCommandError("There are still conflicts present. "
240
                                      "Resolve the conflicts and then run "
241
                                      "'bzr resolve' and try again.")
0.436.3 by Jelmer Vernooij
Fill in commands.
242
            # Read plan file
0.436.9 by Jelmer Vernooij
Add rebase-todo command, fix rebase-continue.
243
            try:
244
                replace_map = read_rebase_plan(wt)[1]
245
            except NoSuchFile:
246
                raise BzrCommandError("No rebase to continue")
247
            oldrevid = read_active_rebase_revid(wt)
248
            if oldrevid is not None:
249
                oldrev = wt.branch.repository.get_revision(oldrevid)
250
                commit_rebase(wt, oldrev, replace_map[oldrevid][0])
0.436.3 by Jelmer Vernooij
Fill in commands.
251
            try:
252
                # Start executing plan from current Branch.last_revision()
0.436.16 by Jelmer Vernooij
Some more work on maptree.
253
                rebase(wt.branch.repository, replace_map, 
254
                        workingtree_replay(wt, merge_type=merge_type))
0.436.8 by Jelmer Vernooij
Couple more minor fixes.
255
            except ConflictsInTree:
256
                raise BzrCommandError("A conflict occurred replaying a commit. Resolve the conflict and run 'bzr rebase-continue' or run 'bzr rebase-abort'.")
0.436.3 by Jelmer Vernooij
Fill in commands.
257
            # Remove plan file  
258
            remove_rebase_plan(wt)
259
        finally:
260
            wt.unlock()
0.436.2 by Jelmer Vernooij
Add stubs for testsuite, rebase-continue and rebase-abort commands.
261
262
0.436.9 by Jelmer Vernooij
Add rebase-todo command, fix rebase-continue.
263
class cmd_rebase_todo(Command):
0.436.16 by Jelmer Vernooij
Some more work on maptree.
264
    """Print list of revisions that still need to be replayed as part of the 
265
    current rebase operation.
0.436.9 by Jelmer Vernooij
Add rebase-todo command, fix rebase-continue.
266
267
    """
268
    
269
    def run(self):
0.436.16 by Jelmer Vernooij
Some more work on maptree.
270
        from rebase import (rebase_todo, read_rebase_plan, 
271
                            read_active_rebase_revid)
0.436.9 by Jelmer Vernooij
Add rebase-todo command, fix rebase-continue.
272
        from bzrlib.workingtree import WorkingTree
273
        wt = WorkingTree.open('.')
274
        wt.lock_read()
275
        try:
276
            try:
277
                replace_map = read_rebase_plan(wt)[1]
278
            except NoSuchFile:
0.436.16 by Jelmer Vernooij
Some more work on maptree.
279
                raise BzrCommandError("No rebase in progress")
0.436.9 by Jelmer Vernooij
Add rebase-todo command, fix rebase-continue.
280
            currentrevid = read_active_rebase_revid(wt)
281
            if currentrevid is not None:
282
                info("Currently replaying: %s" % currentrevid)
283
            for revid in rebase_todo(wt.branch.repository, replace_map):
284
                info("%s -> %s" % (revid, replace_map[revid][0]))
285
        finally:
286
            wt.unlock()
287
0.436.48 by Jelmer Vernooij
Add replay command.
288
class cmd_replay(Command):
289
    """Replay a commit on top of a different branch.
290
291
    """
292
    
293
    takes_options = ['revision', 'merge-type']
294
    takes_args = ['location']
295
296
    def run(self, location, revision=None, merge_type=None):
297
        from bzrlib.branch import Branch
298
        from bzrlib.workingtree import WorkingTree
299
        from rebase import regenerate_default_revid, workingtree_replay
300
301
        from_branch = Branch.open(location)
302
303
        if revision is not None:
304
            if len(revision) == 1:
305
                if revision[0] is not None:
306
                    revid = revision[0].in_history(from_branch).rev_id
307
                else:
308
                    raise BzrCommandError("--revision takes only one argument")
309
        else:
310
            raise BzrCommandError("--revision is mandatory")
311
312
        wt = WorkingTree.open(".")
313
        wt.lock_write()
314
        try:
315
            wt.branch.repository.fetch(from_branch.repository, revid)
316
            newrevid = regenerate_default_revid(wt.branch.repository, revid)
0.436.51 by Jelmer Vernooij
Give proper warning when there is no common base.
317
            replay_delta_workingtree(wt, revid, newrevid, [wt.last_revision()],
318
                                     merge_type=merge_type)
0.436.48 by Jelmer Vernooij
Add replay command.
319
        finally:
320
            wt.unlock()
321
322
323
for cmd in [cmd_replay, cmd_rebase, cmd_rebase_abort, cmd_rebase_continue, 
324
            cmd_rebase_todo]:
325
    register_command(cmd)
326
0.436.4 by Jelmer Vernooij
Add some tests.
327
0.436.2 by Jelmer Vernooij
Add stubs for testsuite, rebase-continue and rebase-abort commands.
328
def test_suite():
329
    from unittest import TestSuite
330
    from bzrlib.tests import TestUtil
331
332
    loader = TestUtil.TestLoader()
333
    suite = TestSuite()
0.436.19 by Jelmer Vernooij
- Add blackbox tests
334
    testmod_names = ['test_blackbox', 'test_rebase', 'test_maptree']
0.436.16 by Jelmer Vernooij
Some more work on maptree.
335
    suite.addTest(loader.loadTestsFromModuleNames(
336
                              ["%s.%s" % (__name__, i) for i in testmod_names]))
0.436.2 by Jelmer Vernooij
Add stubs for testsuite, rebase-continue and rebase-abort commands.
337
338
    return suite
0.436.1 by Jelmer Vernooij
Add framework for git-rebase plugin.
339