~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/diff.py

  • Committer: abentley
  • Date: 2006-04-20 23:47:53 UTC
  • mfrom: (1681 +trunk)
  • mto: This revision was merged to the branch mainline in revision 1683.
  • Revision ID: abentley@lappy-20060420234753-6a6874b76f09f86d
Merge bzr.dev

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# -*- coding: UTF-8 -*-
 
1
# Copyright (C) 2004, 2005, 2006 Canonical Ltd.
2
2
 
3
3
# This program is free software; you can redistribute it and/or modify
4
4
# it under the terms of the GNU General Public License as published by
16
16
 
17
17
from bzrlib.delta import compare_trees
18
18
from bzrlib.errors import BzrError
 
19
import bzrlib.errors as errors
19
20
from bzrlib.symbol_versioning import *
 
21
from bzrlib.textfile import check_text_lines
20
22
from bzrlib.trace import mutter
21
23
 
22
24
# TODO: Rather than building a changeset object, we should probably
23
25
# invoke callbacks on an object.  That object can either accumulate a
24
26
# list, write them out directly, etc etc.
25
27
 
26
 
def internal_diff(old_filename, oldlines, new_filename, newlines, to_file):
 
28
def internal_diff(old_filename, oldlines, new_filename, newlines, to_file,
 
29
                  allow_binary=False):
27
30
    import difflib
28
31
    
29
32
    # FIXME: difflib is wrong if there is no trailing newline.
41
44
    # both sequences are empty.
42
45
    if not oldlines and not newlines:
43
46
        return
 
47
    
 
48
    if allow_binary is False:
 
49
        check_text_lines(oldlines)
 
50
        check_text_lines(newlines)
44
51
 
45
52
    ud = difflib.unified_diff(oldlines, newlines,
46
53
                              fromfile=old_filename+'\t', 
235
242
    external_diff_options
236
243
        If set, use an external GNU diff and pass these options.
237
244
    """
238
 
 
239
245
    old_tree.lock_read()
240
246
    try:
241
247
        new_tree.lock_read()
264
270
    # TODO: Generation of pseudo-diffs for added/deleted files could
265
271
    # be usefully made into a much faster special case.
266
272
 
 
273
    _raise_if_doubly_unversioned(specific_files, old_tree, new_tree)
 
274
 
267
275
    if external_diff_options:
268
276
        assert isinstance(external_diff_options, basestring)
269
277
        opts = external_diff_options.split()
272
280
    else:
273
281
        diff_file = internal_diff
274
282
    
275
 
 
276
283
    delta = compare_trees(old_tree, new_tree, want_unchanged=False,
277
284
                          specific_files=specific_files)
278
285
 
306
313
            _maybe_diff_file_or_symlink(old_label, path, old_tree, file_id,
307
314
                                        new_label, path, new_tree,
308
315
                                        True, kind, to_file, diff_file)
 
316
 
309
317
    return has_changes
310
 
    
 
318
 
 
319
 
 
320
def _raise_if_doubly_unversioned(specific_files, old_tree, new_tree):
 
321
    """Complain if paths are not versioned in either tree."""
 
322
    if not specific_files:
 
323
        return
 
324
    old_unversioned = old_tree.filter_unversioned_files(specific_files)
 
325
    new_unversioned = new_tree.filter_unversioned_files(specific_files)
 
326
    unversioned = old_unversioned.intersection(new_unversioned)
 
327
    if unversioned:
 
328
        raise errors.PathsNotVersionedError(sorted(unversioned))
 
329
    
 
330
 
 
331
def _raise_if_nonexistent(paths, old_tree, new_tree):
 
332
    """Complain if paths are not in either inventory or tree.
 
333
 
 
334
    It's OK with the files exist in either tree's inventory, or 
 
335
    if they exist in the tree but are not versioned.
 
336
    
 
337
    This can be used by operations such as bzr status that can accept
 
338
    unknown or ignored files.
 
339
    """
 
340
    mutter("check paths: %r", paths)
 
341
    if not paths:
 
342
        return
 
343
    s = old_tree.filter_unversioned_files(paths)
 
344
    s = new_tree.filter_unversioned_files(s)
 
345
    s = [path for path in s if not new_tree.has_filename(path)]
 
346
    if s:
 
347
        raise errors.PathsDoNotExist(sorted(s))
 
348
 
311
349
 
312
350
def get_prop_change(meta_modified):
313
351
    if meta_modified: