/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 bzrlib/annotate.py

  • Committer: Vincent Ladeuil
  • Date: 2012-01-18 14:09:19 UTC
  • mto: This revision was merged to the branch mainline in revision 6468.
  • Revision ID: v.ladeuil+lp@free.fr-20120118140919-rlvdrhpc0nq1lbwi
Change set/remove to require a lock for the branch config files.

This means that tests (or any plugin for that matter) do not requires an
explicit lock on the branch anymore to change a single option. This also
means the optimisation becomes "opt-in" and as such won't be as
spectacular as it may be and/or harder to get right (nothing fails
anymore).

This reduces the diff by ~300 lines.

Code/tests that were updating more than one config option is still taking
a lock to at least avoid some IOs and demonstrate the benefits through
the decreased number of hpss calls.

The duplication between BranchStack and BranchOnlyStack will be removed
once the same sharing is in place for local config files, at which point
the Stack class itself may be able to host the changes.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Canonical Ltd
 
1
# Copyright (C) 2005-2010 Canonical Ltd
2
2
#
3
3
# This program is free software; you can redistribute it and/or modify
4
4
# it under the terms of the GNU General Public License as published by
16
16
 
17
17
"""File annotate based on weave storage"""
18
18
 
 
19
from __future__ import absolute_import
 
20
 
19
21
# TODO: Choice of more or less verbose formats:
20
22
#
21
23
# interposed: show more details between blocks of modified lines
28
30
import sys
29
31
import time
30
32
 
 
33
from bzrlib.lazy_import import lazy_import
 
34
lazy_import(globals(), """
 
35
from bzrlib import (
 
36
    patiencediff,
 
37
    tsort,
 
38
    )
 
39
""")
31
40
from bzrlib import (
32
41
    errors,
33
42
    osutils,
34
 
    patiencediff,
35
 
    tsort,
36
43
    )
37
44
from bzrlib.config import extract_email_address
38
45
from bzrlib.repository import _strip_NULL_ghosts
39
 
from bzrlib.revision import CURRENT_REVISION, Revision
40
 
 
41
 
 
 
46
from bzrlib.revision import (
 
47
    CURRENT_REVISION,
 
48
    Revision,
 
49
    )
 
50
from bzrlib.symbol_versioning import (
 
51
    deprecated_function,
 
52
    deprecated_in,
 
53
    )
 
54
 
 
55
 
 
56
@deprecated_function(deprecated_in((2, 4, 0)))
42
57
def annotate_file(branch, rev_id, file_id, verbose=False, full=False,
43
58
                  to_file=None, show_ids=False):
44
59
    """Annotate file_id at revision rev_id in branch.
55
70
        used.
56
71
    :param show_ids: Show revision ids in the annotation output.
57
72
    """
58
 
    if to_file is None:
59
 
        to_file = sys.stdout
60
 
 
61
 
    # Handle the show_ids case
62
 
    annotations = _annotations(branch.repository, file_id, rev_id)
63
 
    if show_ids:
64
 
        return _show_id_annotations(annotations, to_file, full)
65
 
 
66
 
    # Calculate the lengths of the various columns
67
 
    annotation = list(_expand_annotations(annotations, branch))
68
 
    _print_annotations(annotation, verbose, to_file, full)
 
73
    tree = branch.repository.revision_tree(rev_id)
 
74
    annotate_file_tree(tree, file_id, to_file, verbose=verbose,
 
75
        full=full, show_ids=show_ids, branch=branch)
69
76
 
70
77
 
71
78
def annotate_file_tree(tree, file_id, to_file, verbose=False, full=False,
72
 
    show_ids=False):
 
79
    show_ids=False, branch=None):
73
80
    """Annotate file_id in a tree.
74
81
 
75
82
    The tree should already be read_locked() when annotate_file_tree is called.
81
88
        reasonable text width.
82
89
    :param full: XXXX Not sure what this does.
83
90
    :param show_ids: Show revision ids in the annotation output.
 
91
    :param branch: Branch to use for revision revno lookups
84
92
    """
85
 
    rev_id = tree.last_revision()
86
 
    branch = tree.branch
 
93
    if branch is None:
 
94
        branch = tree.branch
 
95
    if to_file is None:
 
96
        to_file = sys.stdout
87
97
 
88
98
    # Handle the show_ids case
89
99
    annotations = list(tree.annotate_iter(file_id))
90
100
    if show_ids:
91
101
        return _show_id_annotations(annotations, to_file, full)
92
102
 
93
 
    # Create a virtual revision to represent the current tree state.
94
 
    # Should get some more pending commit attributes, like pending tags,
95
 
    # bugfixes etc.
96
 
    current_rev = Revision(CURRENT_REVISION)
97
 
    current_rev.parent_ids = tree.get_parent_ids()
98
 
    current_rev.committer = tree.branch.get_config().username()
99
 
    current_rev.message = "?"
100
 
    current_rev.timestamp = round(time.time(), 3)
101
 
    current_rev.timezone = osutils.local_time_offset()
102
 
    annotation = list(_expand_annotations(annotations, tree.branch,
 
103
    if not getattr(tree, "get_revision_id", False):
 
104
        # Create a virtual revision to represent the current tree state.
 
105
        # Should get some more pending commit attributes, like pending tags,
 
106
        # bugfixes etc.
 
107
        current_rev = Revision(CURRENT_REVISION)
 
108
        current_rev.parent_ids = tree.get_parent_ids()
 
109
        try:
 
110
            current_rev.committer = branch.get_config_stack().get('email')
 
111
        except errors.NoWhoami:
 
112
            current_rev.committer = 'local user'
 
113
        current_rev.message = "?"
 
114
        current_rev.timestamp = round(time.time(), 3)
 
115
        current_rev.timezone = osutils.local_time_offset()
 
116
    else:
 
117
        current_rev = None
 
118
    annotation = list(_expand_annotations(annotations, branch,
103
119
        current_rev))
104
120
    _print_annotations(annotation, verbose, to_file, full)
105
121
 
165
181
    return
166
182
 
167
183
 
168
 
def _annotations(repo, file_id, rev_id):
169
 
    """Return the list of (origin_revision_id, line_text) for a revision of a file in a repository."""
170
 
    annotations = repo.texts.annotate((file_id, rev_id))
171
 
    #
172
 
    return [(key[-1], line) for (key, line) in annotations]
173
 
 
174
 
 
175
184
def _expand_annotations(annotations, branch, current_rev=None):
176
185
    """Expand a file's annotations into command line UI ready tuples.
177
186
 
184
193
    """
185
194
    repository = branch.repository
186
195
    if current_rev is not None:
187
 
        # This can probably become a function on MutableTree, get_revno_map there,
188
 
        # or something.
 
196
        # This can probably become a function on MutableTree, get_revno_map
 
197
        # there, or something.
189
198
        last_revision = current_rev.revision_id
190
199
        # XXX: Partially Cloned from branch, uses the old_get_graph, eep.
191
200
        # XXX: The main difficulty is that we need to inject a single new node
312
321
 
313
322
 
314
323
def _get_matching_blocks(old, new):
315
 
    matcher = patiencediff.PatienceSequenceMatcher(None,
316
 
        old, new)
 
324
    matcher = patiencediff.PatienceSequenceMatcher(None, old, new)
317
325
    return matcher.get_matching_blocks()
318
326
 
319
327