~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/diff.py

  • Committer: Canonical.com Patch Queue Manager
  • Date: 2006-02-22 07:59:56 UTC
  • mfrom: (1553.5.33 bzr.mbp.locks)
  • Revision ID: pqm@pqm.ubuntu.com-20060222075956-fb281c427e571da6
add LockDir and related fixes

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.delta import compare_trees
 
18
from bzrlib.errors import BzrError
17
19
from bzrlib.trace import mutter
18
 
from bzrlib.errors import BzrError
19
 
from bzrlib.delta import compare_trees
20
20
 
21
21
# TODO: Rather than building a changeset object, we should probably
22
22
# invoke callbacks on an object.  That object can either accumulate a
23
23
# list, write them out directly, etc etc.
24
24
 
25
 
def internal_diff(old_label, oldlines, new_label, newlines, to_file):
 
25
def internal_diff(old_filename, oldlines, new_filename, newlines, to_file):
26
26
    import difflib
27
27
    
28
28
    # FIXME: difflib is wrong if there is no trailing newline.
42
42
        return
43
43
 
44
44
    ud = difflib.unified_diff(oldlines, newlines,
45
 
                              fromfile=old_label, tofile=new_label)
 
45
                              fromfile=old_filename+'\t', 
 
46
                              tofile=new_filename+'\t')
46
47
 
47
48
    ud = list(ud)
48
49
    # work-around for difflib being too smart for its own good
62
63
    print >>to_file
63
64
 
64
65
 
65
 
def external_diff(old_label, oldlines, new_label, newlines, to_file,
 
66
def external_diff(old_filename, oldlines, new_filename, newlines, to_file,
66
67
                  diff_opts):
67
68
    """Display a diff by calling out to the external diff program."""
68
69
    import sys
97
98
        if not diff_opts:
98
99
            diff_opts = []
99
100
        diffcmd = ['diff',
100
 
                   '--label', old_label,
 
101
                   '--label', old_filename+'\t',
101
102
                   oldtmpf.name,
102
 
                   '--label', new_label,
 
103
                   '--label', new_filename+'\t',
103
104
                   newtmpf.name]
104
105
 
105
106
        # diff only allows one style to be specified; they don't override.
141
142
        newtmpf.close()
142
143
 
143
144
def show_diff(b, from_spec, specific_files, external_diff_options=None,
144
 
              revision2=None, output=None):
 
145
              revision2=None, output=None, b2=None):
145
146
    """Shortcut for showing the diff to the working tree.
146
147
 
147
148
    b
158
159
        output = sys.stdout
159
160
 
160
161
    if from_spec is None:
161
 
        old_tree = b.basis_tree()
 
162
        old_tree = b.bzrdir.open_workingtree()
 
163
        if b2 is None:
 
164
            old_tree = old_tree = old_tree.basis_tree()
162
165
    else:
163
 
        old_tree = b.revision_tree(from_spec.in_history(b).rev_id)
 
166
        old_tree = b.repository.revision_tree(from_spec.in_history(b).rev_id)
164
167
 
165
168
    if revision2 is None:
166
 
        new_tree = b.working_tree()
 
169
        if b2 is None:
 
170
            new_tree = b.bzrdir.open_workingtree()
 
171
        else:
 
172
            new_tree = b2.bzrdir.open_workingtree()
167
173
    else:
168
 
        new_tree = b.revision_tree(revision2.in_history(b).rev_id)
 
174
        new_tree = b.repository.revision_tree(revision2.in_history(b).rev_id)
169
175
 
170
 
    show_diff_trees(old_tree, new_tree, output, specific_files,
171
 
                    external_diff_options)
 
176
    return show_diff_trees(old_tree, new_tree, output, specific_files,
 
177
                           external_diff_options)
172
178
 
173
179
 
174
180
 
183
189
        If set, use an external GNU diff and pass these options.
184
190
    """
185
191
 
 
192
    old_tree.lock_read()
 
193
    try:
 
194
        new_tree.lock_read()
 
195
        try:
 
196
            return _show_diff_trees(old_tree, new_tree, to_file,
 
197
                                    specific_files, external_diff_options)
 
198
        finally:
 
199
            new_tree.unlock()
 
200
    finally:
 
201
        old_tree.unlock()
 
202
 
 
203
 
 
204
def _show_diff_trees(old_tree, new_tree, to_file,
 
205
                     specific_files, external_diff_options):
 
206
 
186
207
    # TODO: Options to control putting on a prefix or suffix, perhaps as a format string
187
208
    old_label = ''
188
209
    new_label = ''
207
228
    delta = compare_trees(old_tree, new_tree, want_unchanged=False,
208
229
                          specific_files=specific_files)
209
230
 
 
231
    has_changes = 0
210
232
    for path, file_id, kind in delta.removed:
 
233
        has_changes = 1
211
234
        print >>to_file, '=== removed %s %r' % (kind, path)
212
235
        old_tree.inventory[file_id].diff(diff_file, old_label + path, old_tree,
213
236
                                         DEVNULL, None, None, to_file)
214
237
    for path, file_id, kind in delta.added:
 
238
        has_changes = 1
215
239
        print >>to_file, '=== added %s %r' % (kind, path)
216
240
        new_tree.inventory[file_id].diff(diff_file, new_label + path, new_tree,
217
241
                                         DEVNULL, None, None, to_file, 
218
242
                                         reverse=True)
219
243
    for (old_path, new_path, file_id, kind,
220
244
         text_modified, meta_modified) in delta.renamed:
 
245
        has_changes = 1
221
246
        prop_str = get_prop_change(meta_modified)
222
247
        print >>to_file, '=== renamed %s %r => %r%s' % (
223
248
                          kind, old_path, new_path, prop_str)
225
250
                                    new_label, new_path, new_tree,
226
251
                                    text_modified, kind, to_file, diff_file)
227
252
    for path, file_id, kind, text_modified, meta_modified in delta.modified:
 
253
        has_changes = 1
228
254
        prop_str = get_prop_change(meta_modified)
229
255
        print >>to_file, '=== modified %s %r%s' % (kind, path, prop_str)
230
256
        if text_modified:
231
257
            _maybe_diff_file_or_symlink(old_label, path, old_tree, file_id,
232
258
                                        new_label, path, new_tree,
233
259
                                        True, kind, to_file, diff_file)
 
260
    return has_changes
234
261
    
235
262
 
236
263
def get_prop_change(meta_modified):