~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/delta.py

  • Committer: Aaron Bentley
  • Date: 2005-09-21 15:33:23 UTC
  • mto: (1185.1.37)
  • mto: This revision was merged to the branch mainline in revision 1390.
  • Revision ID: abentley@panoramicfeedback.com-20050921153323-5db674d572d7649d
Fixed bug in distance-from-root graph operation

Show diffs side-by-side

added added

removed removed

Lines of Context:
14
14
# along with this program; if not, write to the Free Software
15
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
16
16
 
17
 
from bzrlib.inventory import InventoryEntry
18
17
from bzrlib.trace import mutter
19
18
 
20
19
class TreeDelta(object):
27
26
    removed
28
27
        (path, id, kind)
29
28
    renamed
30
 
        (oldpath, newpath, id, kind, text_modified, meta_modified)
 
29
        (oldpath, newpath, id, kind, text_modified)
31
30
    modified
32
 
        (path, id, kind, text_modified, meta_modified)
 
31
        (path, id, kind)
33
32
    unchanged
34
33
        (path, id, kind)
35
34
 
36
35
    Each id is listed only once.
37
36
 
38
37
    Files that are both modified and renamed are listed only in
39
 
    renamed, with the text_modified flag true. The text_modified
40
 
    applies either to the the content of the file or the target of the
41
 
    symbolic link, depending of the kind of file.
 
38
    renamed, with the text_modified flag true.
42
39
 
43
40
    Files are only considered renamed if their name has changed or
44
41
    their parent directory has changed.  Renaming a directory
71
68
            self.modified, self.unchanged)
72
69
 
73
70
    def has_changed(self):
74
 
        return bool(self.modified
75
 
                    or self.added
76
 
                    or self.removed
77
 
                    or self.renamed)
 
71
        changes = len(self.added) + len(self.removed) + len(self.renamed)
 
72
        changes += len(self.modified) 
 
73
        return (changes != 0)
78
74
 
79
75
    def touches_file_id(self, file_id):
80
76
        """Return True if file_id is modified by this delta."""
90
86
 
91
87
    def show(self, to_file, show_ids=False, show_unchanged=False):
92
88
        def show_list(files):
93
 
            for item in files:
94
 
                path, fid, kind = item[:3]
95
 
 
 
89
            for path, fid, kind in files:
96
90
                if kind == 'directory':
97
91
                    path += '/'
98
92
                elif kind == 'symlink':
99
93
                    path += '@'
100
 
 
101
 
                if len(item) == 5 and item[4]:
102
 
                    path += '*'
103
 
 
 
94
                    
104
95
                if show_ids:
105
96
                    print >>to_file, '  %-30s %s' % (path, fid)
106
97
                else:
114
105
            print >>to_file, 'added:'
115
106
            show_list(self.added)
116
107
 
117
 
        extra_modified = []
118
 
 
119
108
        if self.renamed:
120
109
            print >>to_file, 'renamed:'
121
 
            for (oldpath, newpath, fid, kind,
122
 
                 text_modified, meta_modified) in self.renamed:
123
 
                if text_modified or meta_modified:
124
 
                    extra_modified.append((newpath, fid, kind,
125
 
                                           text_modified, meta_modified))
126
 
                if meta_modified:
127
 
                    newpath += '*'
 
110
            for oldpath, newpath, fid, kind, text_modified in self.renamed:
128
111
                if show_ids:
129
112
                    print >>to_file, '  %s => %s %s' % (oldpath, newpath, fid)
130
113
                else:
131
114
                    print >>to_file, '  %s => %s' % (oldpath, newpath)
132
115
                    
133
 
        if self.modified or extra_modified:
 
116
        if self.modified:
134
117
            print >>to_file, 'modified:'
135
118
            show_list(self.modified)
136
 
            show_list(extra_modified)
137
119
            
138
120
        if show_unchanged and self.unchanged:
139
121
            print >>to_file, 'unchanged:'
160
142
        files within them.
161
143
    """
162
144
 
163
 
    old_tree.lock_read()
164
 
    try:
165
 
        new_tree.lock_read()
166
 
        try:
167
 
            return _compare_trees(old_tree, new_tree, want_unchanged,
168
 
                                  specific_files)
169
 
        finally:
170
 
            new_tree.unlock()
171
 
    finally:
172
 
        old_tree.unlock()
173
 
 
174
 
 
175
 
def _compare_trees(old_tree, new_tree, want_unchanged, specific_files):
176
 
 
177
145
    from osutils import is_inside_any
178
146
    
179
147
    old_inv = old_tree.inventory
192
160
            kind = old_ie.kind
193
161
            assert kind == new_ie.kind
194
162
            
195
 
            assert kind in InventoryEntry.known_kinds, \
 
163
            assert kind in ('file', 'directory', 'symlink', 'root_directory'), \
196
164
                   'invalid file kind %r' % kind
197
165
 
198
166
            if kind == 'root_directory':
203
171
                    and not is_inside_any(specific_files, new_inv.id2path(file_id))):
204
172
                    continue
205
173
 
206
 
            # temporary hack until all entries are populated before clients 
207
 
            # get them
208
 
            old_path = old_inv.id2path(file_id)
209
 
            new_path = new_inv.id2path(file_id)
210
 
            old_ie._read_tree_state(old_path, old_tree)
211
 
            new_ie._read_tree_state(new_path, new_tree)
212
 
            text_modified, meta_modified = new_ie.detect_changes(old_ie)
 
174
            if kind == 'file':
 
175
                old_sha1 = old_tree.get_file_sha1(file_id)
 
176
                new_sha1 = new_tree.get_file_sha1(file_id)
 
177
                text_modified = (old_sha1 != new_sha1)
 
178
            else:
 
179
                ## mutter("no text to check for %r %r" % (file_id, kind))
 
180
                text_modified = False
213
181
 
214
182
            # TODO: Can possibly avoid calculating path strings if the
215
183
            # two files are unchanged and their names and parents are
218
186
            
219
187
            if (old_ie.name != new_ie.name
220
188
                or old_ie.parent_id != new_ie.parent_id):
221
 
                delta.renamed.append((old_path,
222
 
                                      new_path,
 
189
                delta.renamed.append((old_inv.id2path(file_id),
 
190
                                      new_inv.id2path(file_id),
223
191
                                      file_id, kind,
224
 
                                      text_modified, meta_modified))
225
 
            elif text_modified or meta_modified:
226
 
                delta.modified.append((new_path, file_id, kind,
227
 
                                       text_modified, meta_modified))
 
192
                                      text_modified))
 
193
            elif text_modified:
 
194
                delta.modified.append((new_inv.id2path(file_id), file_id, kind))
228
195
            elif want_unchanged:
229
 
                delta.unchanged.append((new_path, file_id, kind))
 
196
                delta.unchanged.append((new_inv.id2path(file_id), file_id, kind))
230
197
        else:
231
198
            kind = old_inv.get_file_kind(file_id)
232
199
            if kind == 'root_directory':
239
206
 
240
207
    mutter('start looking for new files')
241
208
    for file_id in new_inv:
242
 
        if file_id in old_inv or file_id not in new_tree:
 
209
        if file_id in old_inv:
243
210
            continue
244
211
        kind = new_inv.get_file_kind(file_id)
245
212
        if kind == 'root_directory':