/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

Viewing changes to breezy/bisect.py

  • Committer: Jelmer Vernooij
  • Date: 2017-07-23 22:06:41 UTC
  • mfrom: (6738 trunk)
  • mto: This revision was merged to the branch mainline in revision 6739.
  • Revision ID: jelmer@jelmer.uk-20170723220641-69eczax9bmv8d6kk
Merge trunk, address review comments.

Show diffs side-by-side

added added

removed removed

Lines of Context:
16
16
 
17
17
"""bisect command implementations."""
18
18
 
 
19
from __future__ import absolute_import
 
20
 
19
21
import sys
20
22
from .controldir import ControlDir
21
23
from . import revision as _mod_revision
22
24
from .commands import Command
23
 
from .errors import CommandError
 
25
from .errors import BzrCommandError
24
26
from .option import Option
25
27
from .trace import note
26
28
 
44
46
    def _save(self):
45
47
        """Save the current revision."""
46
48
        self._controldir.control_transport.put_bytes(
47
 
            self._filename, self._revid + b"\n")
 
49
            self._filename, self._revid + "\n")
48
50
 
49
51
    def get_current_revid(self):
50
52
        """Return the current revision id."""
52
54
 
53
55
    def get_current_revno(self):
54
56
        """Return the current revision number as a tuple."""
55
 
        return self._branch.revision_id_to_dotted_revno(self._revid)
 
57
        revdict = self._branch.get_revision_id_to_revno_map()
 
58
        return revdict[self.get_current_revid()]
56
59
 
57
60
    def get_parent_revids(self):
58
61
        """Return the IDs of the current revision's predecessors."""
59
62
        repo = self._branch.repository
60
 
        with repo.lock_read():
61
 
            retval = repo.get_parent_map([self._revid]).get(self._revid, None)
 
63
        repo.lock_read()
 
64
        retval = repo.get_parent_map([self._revid]).get(self._revid, None)
 
65
        repo.unlock()
62
66
        return retval
63
67
 
64
68
    def is_merge_point(self):
65
69
        """Is the current revision a merge point?"""
66
70
        return len(self.get_parent_revids()) > 1
67
71
 
68
 
    def show_rev_log(self, outf):
 
72
    def show_rev_log(self, out = sys.stdout):
69
73
        """Write the current revision's log entry to a file."""
70
74
        rev = self._branch.repository.get_revision(self._revid)
71
75
        revno = ".".join([str(x) for x in self.get_current_revno()])
72
 
        outf.write("On revision %s (%s):\n%s\n" % (revno, rev.revision_id,
73
 
                                                   rev.message))
 
76
        out.write("On revision %s (%s):\n%s\n" % (revno, rev.revision_id,
 
77
                                                  rev.message))
74
78
 
75
79
    def switch(self, revid):
76
80
        """Switch the current revision to the given revid."""
120
124
        if not self._branch:
121
125
            self._branch = self._controldir.open_branch()
122
126
 
123
 
    def _find_range_and_middle(self, branch_last_rev=None):
 
127
    def _find_range_and_middle(self, branch_last_rev = None):
124
128
        """Find the current revision range, and the midpoint."""
125
129
        self._load_tree()
126
130
        self._middle_revid = None
131
135
            last_revid = branch_last_rev
132
136
 
133
137
        repo = self._branch.repository
134
 
        with repo.lock_read():
 
138
        repo.lock_read()
 
139
        try:
135
140
            graph = repo.get_graph()
136
 
            rev_sequence = graph.iter_lefthand_ancestry(
137
 
                last_revid, (_mod_revision.NULL_REVISION,))
 
141
            rev_sequence = graph.iter_lefthand_ancestry(last_revid,
 
142
                (_mod_revision.NULL_REVISION,))
138
143
            high_revid = None
139
144
            low_revid = None
140
145
            between_revs = []
158
163
                high_revid = last_revid
159
164
            if not low_revid:
160
165
                low_revid = self._branch.get_rev_id(1)
 
166
        finally:
 
167
            repo.unlock()
161
168
 
162
169
        # The spread must include the high revision, to bias
163
170
        # odd numbers of intervening revisions towards the high
167
174
        if spread < 2:
168
175
            middle_index = 0
169
176
        else:
170
 
            middle_index = (spread // 2) - 1
 
177
            middle_index = (spread / 2) - 1
171
178
 
172
179
        if len(between_revs) > 0:
173
180
            self._middle_revid = between_revs[middle_index]
180
187
    def _switch_wc_to_revno(self, revno, outf):
181
188
        """Move the working tree to the given revno."""
182
189
        self._current.switch(revno)
183
 
        self._current.show_rev_log(outf=outf)
 
190
        self._current.show_rev_log(out=outf)
184
191
 
185
192
    def _set_status(self, revid, status):
186
193
        """Set the bisect status for the given revid."""
201
208
            revlog = self._open_for_read()
202
209
            for line in revlog:
203
210
                (revid, status) = line.split()
204
 
                self._items.append((revid, status.decode('ascii')))
 
211
                self._items.append((revid, status))
205
212
 
206
213
    def save(self):
207
214
        """Save the bisection log."""
208
 
        contents = b''.join(
209
 
            (b"%s %s\n" % (revid, status.encode('ascii')))
 
215
        contents = ''.join(
 
216
            ("%s %s\n" % (revid, status))
210
217
            for (revid, status) in self._items)
211
218
        if self._filename:
212
219
            self._controldir.control_transport.put_bytes(
233
240
 
234
241
    def get_parent_revids(self, revid):
235
242
        repo = self._branch.repository
236
 
        with repo.lock_read():
 
243
        repo.lock_read()
 
244
        try:
237
245
            retval = repo.get_parent_map([revid]).get(revid, None)
 
246
        finally:
 
247
            repo.unlock()
238
248
        return retval
239
249
 
240
250
    def bisect(self, outf):
242
252
        self._find_range_and_middle()
243
253
        # If we've found the "final" revision, check for a
244
254
        # merge point.
245
 
        while ((self._middle_revid == self._high_revid or
246
 
                self._middle_revid == self._low_revid) and
247
 
                self.is_merge_point(self._middle_revid)):
 
255
        while ((self._middle_revid == self._high_revid
 
256
                or self._middle_revid == self._low_revid)
 
257
                and self.is_merge_point(self._middle_revid)):
248
258
            for parent in self.get_parent_revids(self._middle_revid):
249
259
                if parent == self._low_revid:
250
260
                    continue
309
319
 
310
320
    takes_args = ['subcommand', 'args*']
311
321
    takes_options = [Option('output', short_name='o',
312
 
                            help='Write log to this file.', type=str),
 
322
                            help='Write log to this file.', type=unicode),
313
323
                     'revision', 'directory']
314
324
 
315
325
    def _check(self, controldir):
316
326
        """Check preconditions for most operations to work."""
317
327
        if not controldir.control_transport.has(BISECT_INFO_PATH):
318
 
            raise CommandError("No bisection in progress.")
 
328
            raise BzrCommandError("No bisection in progress.")
319
329
 
320
330
    def _set_state(self, controldir, revspec, state):
321
331
        """Set the state of the given revspec and bisecting.
324
334
        bisect_log = BisectLog(controldir)
325
335
        if bisect_log.is_done():
326
336
            note("No further bisection is possible.\n")
327
 
            bisect_log._current.show_rev_log(outf=self.outf)
 
337
            bisect_log._current.show_rev_log(self.outf)
328
338
            return True
329
339
 
330
340
        if revspec:
335
345
        bisect_log.save()
336
346
        return False
337
347
 
338
 
    def run(self, subcommand, args_list, directory='.', revision=None,
339
 
            output=None):
 
348
    def run(self, subcommand, args_list, directory='.', revision=None, output=None):
340
349
        """Handle the bisect command."""
341
350
 
342
351
        log_fn = None
345
354
        elif subcommand in ('replay', ) and args_list and len(args_list) == 1:
346
355
            log_fn = args_list[0]
347
356
        elif subcommand in ('move', ) and not revision:
348
 
            raise CommandError(
 
357
            raise BzrCommandError(
349
358
                "The 'bisect move' command requires a revision.")
350
359
        elif subcommand in ('run', ):
351
360
            run_script = args_list[0]
352
361
        elif args_list or revision:
353
 
            raise CommandError(
 
362
            raise BzrCommandError(
354
363
                "Improper arguments to bisect " + subcommand)
355
364
 
356
365
        controldir, _ = ControlDir.open_containing(directory)
373
382
        elif subcommand == "run":
374
383
            self.run_bisect(controldir, run_script)
375
384
        else:
376
 
            raise CommandError(
 
385
            raise BzrCommandError(
377
386
                "Unknown bisect command: " + subcommand)
378
387
 
379
388
    def reset(self, controldir):
397
406
        self._set_state(controldir, revspec, "yes")
398
407
 
399
408
    def no(self, controldir, revspec):
400
 
        """Mark a given revision as wrong."""
 
409
        """Mark that a given revision does not have the state we're looking for."""
401
410
        self._set_state(controldir, revspec, "no")
402
411
 
403
412
    def move(self, controldir, revspec):
404
413
        """Move to a different revision manually."""
405
414
        current = BisectCurrent(controldir)
406
415
        current.switch(revspec)
407
 
        current.show_rev_log(outf=self.outf)
 
416
        current.show_rev_log(out=self.outf)
408
417
 
409
418
    def log(self, controldir, filename):
410
419
        """Write the current bisect log to a file."""