1
# Copyright (C) 2005 Canonical Ltd
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.
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.
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
20
def find_touching_revisions(branch, file_id):
21
"""Yield a description of revisions which affect the file_id.
23
Each returned element is (revno, revision_id, description)
25
This is the list of revisions where the file is either added,
26
modified, renamed or deleted.
28
TODO: Perhaps some way to limit this to only particular revisions,
29
or to traverse a non-mainline set of revisions?
34
for revision_id in branch.revision_history():
35
this_inv = branch.get_revision_inventory(revision_id)
36
if file_id in this_inv:
37
this_ie = this_inv[file_id]
38
this_path = this_inv.id2path(file_id)
40
this_ie = this_path = None
42
# now we know how it was last time, and how it is in this revision.
43
# are those two states effectively the same or not?
45
if not this_ie and not last_ie:
46
# not present in either
48
elif this_ie and not last_ie:
49
yield revno, revision_id, "added " + this_path
50
elif not this_ie and last_ie:
52
yield revno, revision_id, "deleted " + last_path
53
elif this_path != last_path:
54
yield revno, revision_id, ("renamed %s => %s" % (last_path, this_path))
55
elif (this_ie.text_size != last_ie.text_size
56
or this_ie.text_sha1 != last_ie.text_sha1):
57
yield revno, revision_id, "modified " + this_path
66
show_timezone='original',
70
"""Write out human-readable log of commits to this branch.
73
If true, list only the commits affecting the specified
74
file, rather than all commits.
77
'original' (committer's timezone),
78
'utc' (universal time), or
79
'local' (local user's timezone)
82
If true show added/changed/deleted/renamed files.
85
If true, show revision and file ids.
88
File to send log to; by default stdout.
90
from osutils import format_date
91
from errors import BzrCheckError
92
from diff import compare_trees
93
from textui import show_status
100
file_id = branch.read_working_inventory().path2id(filename)
102
for revno, revid, why in find_touching_revisions(branch, file_id):
106
for i, revid in enumerate(branch.revision_history()):
109
branch._need_readlock()
112
from tree import EmptyTree
113
prev_tree = EmptyTree()
114
for revno, revision_id in which_revs():
115
print >>to_file, '-' * 60
116
print >>to_file, 'revno:', revno
117
rev = branch.get_revision(revision_id)
119
print >>to_file, 'revision-id:', revision_id
120
print >>to_file, 'committer:', rev.committer
121
print >>to_file, 'timestamp: %s' % (format_date(rev.timestamp, rev.timezone or 0,
124
if revision_id != rev.revision_id:
125
raise BzrCheckError("retrieved wrong revision: %r"
126
% (revision_id, rev.revision_id))
128
print >>to_file, 'message:'
130
print >>to_file, ' (no message)'
132
for l in rev.message.split('\n'):
133
print >>to_file, ' ' + l
135
# Don't show a list of changed files if we were asked about
139
this_tree = branch.revision_tree(revision_id)
140
delta = compare_trees(prev_tree, this_tree, want_unchanged=False)
141
delta.show(to_file, show_ids)
142
prev_tree = this_tree
144
precursor = revision_id