33
from .lazy_import import lazy_import
33
from bzrlib.lazy_import import lazy_import
34
34
lazy_import(globals(), """
47
extract_email_address,
49
from .repository import _strip_NULL_ghosts
50
from .revision import (
44
from bzrlib.config import extract_email_address
45
from bzrlib.repository import _strip_NULL_ghosts
46
from bzrlib.revision import (
56
def annotate_file_tree(tree, path, to_file, verbose=False, full=False,
57
show_ids=False, branch=None, file_id=None):
52
def annotate_file_tree(tree, file_id, to_file, verbose=False, full=False,
53
show_ids=False, branch=None):
58
54
"""Annotate file_id in a tree.
60
56
The tree should already be read_locked() when annotate_file_tree is called.
62
58
:param tree: The tree to look for revision numbers and history from.
63
:param path: The path to annotate
59
:param file_id: The file_id to annotate.
64
60
:param to_file: The file to output the annotation to.
65
61
:param verbose: Show all details rather than truncating to ensure
66
62
reasonable text width.
67
63
:param full: XXXX Not sure what this does.
68
64
:param show_ids: Show revision ids in the annotation output.
69
:param file_id: The file_id to annotate (must match file path)
70
65
:param branch: Branch to use for revision revno lookups
75
70
to_file = sys.stdout
77
72
# Handle the show_ids case
78
annotations = list(tree.annotate_iter(path, file_id))
73
annotations = list(tree.annotate_iter(file_id))
80
75
return _show_id_annotations(annotations, to_file, full)
87
82
current_rev.parent_ids = tree.get_parent_ids()
89
84
current_rev.committer = branch.get_config_stack().get('email')
85
except errors.NoWhoami:
91
86
current_rev.committer = 'local user'
92
87
current_rev.message = "?"
93
88
current_rev.timestamp = round(time.time(), 3)
120
115
# Output the annotations
117
encoding = getattr(to_file, 'encoding', None) or \
118
osutils.get_terminal_encoding()
122
119
for (revno_str, author, date_str, line_rev_id, text) in annotation:
124
121
anno = '%-*s %-*s %8s ' % (max_revno_len, revno_str,
129
126
anno = "%-*s %-7s " % (max_revno_len, revno_str, author[:7])
130
127
if anno.lstrip() == "" and full:
132
# GZ 2017-05-21: Writing both unicode annotation and bytes from file
133
# which the given to_file must cope with.
131
except UnicodeEncodeError:
132
# cmd_annotate should be passing in an 'exact' object, which means
133
# we have a direct handle to sys.stdout or equivalent. It may not
134
# be able to handle the exact Unicode characters, but 'annotate' is
135
# a user function (non-scripting), so shouldn't die because of
136
# unrepresentable annotation characters. So encode using 'replace',
137
# and write them again.
138
to_file.write(anno.encode(encoding, 'replace'))
135
139
to_file.write('| %s\n' % (text,))
193
197
revision_id_to_revno[CURRENT_REVISION] = (
194
198
"%d?" % (branch.revno() + 1),)
195
199
revisions[CURRENT_REVISION] = current_rev
198
repository.iter_revisions(revision_ids)
199
if entry[1] is not None)
200
revision_ids = [o for o in revision_ids if
201
repository.has_revision(o)]
202
revisions.update((r.revision_id, r) for r in
203
repository.get_revisions(revision_ids))
200
204
for origin, text in annotations:
201
205
text = text.rstrip('\r\n')
202
206
if origin == last_origin:
203
(revno_str, author, date_str) = ('', '', '')
207
(revno_str, author, date_str) = ('','','')
205
209
last_origin = origin
206
210
if origin not in revisions:
207
(revno_str, author, date_str) = ('?', '?', '?')
211
(revno_str, author, date_str) = ('?','?','?')
209
213
revno_str = '.'.join(str(i) for i in
210
214
revision_id_to_revno[origin])
217
221
author = rev.get_apparent_authors()[0]
219
223
author = extract_email_address(author)
220
except NoEmailInUsername:
224
except errors.NoEmailInUsername:
221
225
pass # use the whole name
222
226
yield (revno_str, author, date_str, origin, text)
344
348
output_extend = output_lines.extend
345
349
output_append = output_lines.append
346
350
# We need to see if any of the unannotated lines match
347
plain_right_subset = [l for a, l in right_lines[start_right:end_right]]
351
plain_right_subset = [l for a,l in right_lines[start_right:end_right]]
348
352
plain_child_subset = plain_child_lines[start_child:end_child]
349
353
match_blocks = _get_matching_blocks(plain_right_subset, plain_child_subset)
355
359
if child_idx > last_child_idx:
356
360
output_extend(child_lines[start_child + last_child_idx
357
361
:start_child + child_idx])
358
for offset in range(match_len):
362
for offset in xrange(match_len):
359
363
left = child_lines[start_child+child_idx+offset]
360
364
right = right_lines[start_right+right_idx+offset]
361
365
if left[0] == right[0]:
373
377
heads = heads_provider.heads((left[0], right[0]))
374
378
if len(heads) == 1:
375
output_append((next(iter(heads)), left[1]))
379
output_append((iter(heads).next(), left[1]))
377
381
# Both claim different origins, get a stable result.
378
382
# If the result is not stable, there is a risk a
438
from breezy._annotator_pyx import Annotator
439
except ImportError as e:
442
from bzrlib._annotator_pyx import Annotator
443
except ImportError, e:
440
444
osutils.failed_to_load_extension(e)
441
from breezy._annotator_py import Annotator
445
from bzrlib._annotator_py import Annotator