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