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