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
Revisions are returned in chronological order.
30
TODO: Perhaps some way to limit this to only particular revisions,
31
or to traverse a non-branch set of revisions?
33
TODO: If a directory is given, then by default look for all
34
changes under that directory.
39
for revision_id in branch.revision_history():
40
this_inv = branch.get_revision_inventory(revision_id)
41
if file_id in this_inv:
42
this_ie = this_inv[file_id]
43
this_path = this_inv.id2path(file_id)
45
this_ie = this_path = None
47
# now we know how it was last time, and how it is in this revision.
48
# are those two states effectively the same or not?
50
if not this_ie and not last_ie:
51
# not present in either
53
elif this_ie and not last_ie:
54
yield revno, revision_id, "added " + this_path
55
elif not this_ie and last_ie:
57
yield revno, revision_id, "deleted " + last_path
58
elif this_path != last_path:
59
yield revno, revision_id, ("renamed %s => %s" % (last_path, this_path))
60
elif (this_ie.text_size != last_ie.text_size
61
or this_ie.text_sha1 != last_ie.text_sha1):
62
yield revno, revision_id, "modified " + this_path
71
show_timezone='original',
75
"""Write out human-readable log of commits to this branch.
78
If true, list only the commits affecting the specified
79
file, rather than all commits.
82
'original' (committer's timezone),
83
'utc' (universal time), or
84
'local' (local user's timezone)
87
If true show added/changed/deleted/renamed files.
90
If true, show revision and file ids.
93
File to send log to; by default stdout.
95
from osutils import format_date
96
from errors import BzrCheckError
97
from diff import compare_inventories
98
from textui import show_status
99
from inventory import Inventory
106
file_id = branch.read_working_inventory().path2id(filename)
108
for revno, revid, why in find_touching_revisions(branch, file_id):
112
for i, revid in enumerate(branch.revision_history()):
115
branch._need_readlock()
118
prev_inv = Inventory()
119
for revno, revision_id in which_revs():
120
print >>to_file, '-' * 60
121
print >>to_file, 'revno:', revno
122
rev = branch.get_revision(revision_id)
124
print >>to_file, 'revision-id:', revision_id
125
print >>to_file, 'committer:', rev.committer
126
print >>to_file, 'timestamp: %s' % (format_date(rev.timestamp, rev.timezone or 0,
129
if revision_id != rev.revision_id:
130
raise BzrCheckError("retrieved wrong revision: %r"
131
% (revision_id, rev.revision_id))
133
print >>to_file, 'message:'
135
print >>to_file, ' (no message)'
137
for l in rev.message.split('\n'):
138
print >>to_file, ' ' + l
140
# Don't show a list of changed files if we were asked about
143
if verbose and not filename:
144
this_inv = branch.get_inventory(rev.inventory_id)
145
delta = compare_inventories(prev_inv, this_inv)
148
print >>to_file, 'removed files:'
149
for path, fid in delta.removed:
151
print >>to_file, ' %-30s %s' % (path, fid)
153
print >>to_file, ' ', path
155
print >>to_file, 'added files:'
156
for path, fid in delta.added:
158
print >>to_file, ' %-30s %s' % (path, fid)
160
print >>to_file, ' ' + path
162
print >>to_file, 'renamed files:'
163
for oldpath, newpath, fid in delta.renamed:
165
print >>to_file, ' %s => %s %s' % (oldpath, newpath, fid)
167
print >>to_file, ' %s => %s' % (oldpath, newpath)
169
print >>to_file, 'modified files:'
170
for path, fid in delta.modified:
172
print >>to_file, ' %-30s %s' % (path, fid)
174
print >>to_file, ' ' + path
178
precursor = revision_id