17
17
from bzrlib.delta import compare_trees
 
18
18
from bzrlib.errors import BzrError
 
19
19
import bzrlib.errors as errors
 
20
 
from bzrlib.patiencediff import SequenceMatcher, unified_diff
 
 
20
from bzrlib.patiencediff import unified_diff
 
 
21
import bzrlib.patiencediff
 
21
22
from bzrlib.symbol_versioning import *
 
22
23
from bzrlib.textfile import check_text_lines
 
23
24
from bzrlib.trace import mutter
 
25
27
# TODO: Rather than building a changeset object, we should probably
 
26
28
# invoke callbacks on an object.  That object can either accumulate a
 
27
29
# list, write them out directly, etc etc.
 
29
31
def internal_diff(old_filename, oldlines, new_filename, newlines, to_file,
 
30
 
                  allow_binary=False, sequence_matcher=None):
 
 
32
                  allow_binary=False, sequence_matcher=None,
 
 
33
                  path_encoding='utf8'):
 
31
34
    # FIXME: difflib is wrong if there is no trailing newline.
 
32
35
    # The syntax used by patch seems to be "\ No newline at
 
33
36
    # end of file" following the last diff line from that
 
 
49
52
        check_text_lines(newlines)
 
51
54
    if sequence_matcher is None:
 
52
 
        sequence_matcher = SequenceMatcher
 
 
55
        sequence_matcher = bzrlib.patiencediff.PatienceSequenceMatcher
 
53
56
    ud = unified_diff(oldlines, newlines,
 
54
 
                      fromfile=old_filename+'\t', 
 
55
 
                      tofile=new_filename+'\t',
 
 
57
                      fromfile=old_filename.encode(path_encoding)+'\t', 
 
 
58
                      tofile=new_filename.encode(path_encoding)+'\t',
 
56
59
                      sequencematcher=sequence_matcher)
 
 
289
292
    for path, file_id, kind in delta.removed:
 
291
 
        print >>to_file, '=== removed %s %r' % (kind, path)
 
 
294
        print >>to_file, '=== removed %s %r' % (kind, path.encode('utf8'))
 
292
295
        old_tree.inventory[file_id].diff(diff_file, old_label + path, old_tree,
 
293
296
                                         DEVNULL, None, None, to_file)
 
294
297
    for path, file_id, kind in delta.added:
 
296
 
        print >>to_file, '=== added %s %r' % (kind, path)
 
 
299
        print >>to_file, '=== added %s %r' % (kind, path.encode('utf8'))
 
297
300
        new_tree.inventory[file_id].diff(diff_file, new_label + path, new_tree,
 
298
301
                                         DEVNULL, None, None, to_file, 
 
 
303
306
        prop_str = get_prop_change(meta_modified)
 
304
307
        print >>to_file, '=== renamed %s %r => %r%s' % (
 
305
 
                    kind, old_path, new_path, prop_str)
 
 
308
                    kind, old_path.encode('utf8'),
 
 
309
                    new_path.encode('utf8'), prop_str)
 
306
310
        _maybe_diff_file_or_symlink(old_label, old_path, old_tree, file_id,
 
307
311
                                    new_label, new_path, new_tree,
 
308
312
                                    text_modified, kind, to_file, diff_file)
 
309
313
    for path, file_id, kind, text_modified, meta_modified in delta.modified:
 
311
315
        prop_str = get_prop_change(meta_modified)
 
312
 
        print >>to_file, '=== modified %s %r%s' % (kind, path, prop_str)
 
 
316
        print >>to_file, '=== modified %s %r%s' % (kind, path.encode('utf8'), prop_str)
 
313
317
        if text_modified:
 
314
318
            _maybe_diff_file_or_symlink(old_label, path, old_tree, file_id,
 
315
319
                                        new_label, path, new_tree,