Merge lp:~jelmer/brz/objects-1 into lp:brz

Proposed by Jelmer Vernooij
Status: Merged
Approved by: Jelmer Vernooij
Approved revision: no longer in the source branch.
Merge reported by: The Breezy Bot
Merged at revision: not available
Proposed branch: lp:~jelmer/brz/objects-1
Merge into: lp:brz
Prerequisite: lp:~jelmer/brz/objects
Diff against target: 1612 lines (+440/-407)
28 files modified
breezy/builtins.py (+8/-8)
breezy/bzr/_dirstate_helpers_pyx.pyx (+6/-3)
breezy/bzr/dirstate.py (+9/-9)
breezy/bzr/inventory.py (+3/-2)
breezy/bzr/inventorytree.py (+4/-5)
breezy/bzr/vf_repository.py (+30/-28)
breezy/bzr/workingtree.py (+9/-10)
breezy/commit.py (+16/-19)
breezy/delta.py (+31/-31)
breezy/diff.py (+13/-12)
breezy/git/commit.py (+29/-29)
breezy/git/object_store.py (+21/-22)
breezy/git/workingtree.py (+11/-12)
breezy/merge.py (+11/-11)
breezy/mutabletree.py (+1/-1)
breezy/plugins/fastimport/revision_store.py (+41/-36)
breezy/plugins/launchpad/lp_propose.py (+2/-3)
breezy/plugins/propose/launchpad.py (+2/-3)
breezy/rename_map.py (+13/-13)
breezy/shelf.py (+22/-23)
breezy/tests/per_intertree/test_compare.py (+76/-61)
breezy/tests/per_repository/test_check.py (+4/-2)
breezy/tests/per_repository/test_commit_builder.py (+6/-4)
breezy/tests/test__dirstate_helpers.py (+3/-6)
breezy/tests/test_commit.py (+17/-12)
breezy/tests/test_transform.py (+2/-3)
breezy/transform.py (+35/-34)
breezy/tree.py (+15/-5)
To merge this branch: bzr merge lp:~jelmer/brz/objects-1
Reviewer Review Type Date Requested Status
Martin Packman Approve
Review via email: mp+368859@code.launchpad.net

Commit message

Use the new attributes on TreeChange rather than indexing.

Description of the change

Use the new attributes on TreeChange rather than indexing.

To post a comment you must log in.
Revision history for this message
Martin Packman (gz) wrote :

Thanks! As discussed, probably makes sense to flatten this a bit more in future, but this is much more readable as is.

review: Approve
Revision history for this message
The Breezy Bot (the-breezy-bot) wrote :

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'breezy/builtins.py'
--- breezy/builtins.py 2019-06-02 03:11:13 +0000
+++ breezy/builtins.py 2019-06-15 17:35:57 +0000
@@ -1701,12 +1701,12 @@
1701 self.add_cleanup(old_tree.lock_read().unlock)1701 self.add_cleanup(old_tree.lock_read().unlock)
1702 renames = []1702 renames = []
1703 iterator = tree.iter_changes(old_tree, include_unchanged=True)1703 iterator = tree.iter_changes(old_tree, include_unchanged=True)
1704 for f, paths, c, v, p, n, k, e in iterator:1704 for change in iterator:
1705 if paths[0] == paths[1]:1705 if change.path[0] == change.path[1]:
1706 continue1706 continue
1707 if None in (paths):1707 if None in change.path:
1708 continue1708 continue
1709 renames.append(paths)1709 renames.append(change.path)
1710 renames.sort()1710 renames.sort()
1711 for old_name, new_name in renames:1711 for old_name, new_name in renames:
1712 self.outf.write("%s => %s\n" % (old_name, new_name))1712 self.outf.write("%s => %s\n" % (old_name, new_name))
@@ -1916,8 +1916,8 @@
1916 missing = []1916 missing = []
1917 for change in tree.iter_changes(tree.basis_tree()):1917 for change in tree.iter_changes(tree.basis_tree()):
1918 # Find paths in the working tree that have no kind:1918 # Find paths in the working tree that have no kind:
1919 if change[1][1] is not None and change[6][1] is None:1919 if change.path[1] is not None and change.kind[1] is None:
1920 missing.append(change[1][1])1920 missing.append(change.path[1])
1921 file_list = sorted(missing, reverse=True)1921 file_list = sorted(missing, reverse=True)
1922 file_deletion_strategy = 'keep'1922 file_deletion_strategy = 'keep'
1923 tree.remove(file_list, verbose=verbose, to_file=self.outf,1923 tree.remove(file_list, verbose=verbose, to_file=self.outf,
19241924
=== modified file 'breezy/bzr/_dirstate_helpers_pyx.pyx'
--- breezy/bzr/_dirstate_helpers_pyx.pyx 2019-06-15 01:02:49 +0000
+++ breezy/bzr/_dirstate_helpers_pyx.pyx 2019-06-15 17:35:57 +0000
@@ -1553,7 +1553,8 @@
1553 new_executable = bool(1553 new_executable = bool(
1554 stat.S_ISREG(self.root_dir_info[3].st_mode)1554 stat.S_ISREG(self.root_dir_info[3].st_mode)
1555 and stat.S_IEXEC & self.root_dir_info[3].st_mode)1555 and stat.S_IEXEC & self.root_dir_info[3].st_mode)
1556 return (None,1556 return TreeChange(
1557 None,
1557 (None, self.current_root_unicode),1558 (None, self.current_root_unicode),
1558 True,1559 True,
1559 (False, False),1560 (False, False),
@@ -1664,7 +1665,8 @@
1664 new_executable = bool(1665 new_executable = bool(
1665 stat.S_ISREG(current_path_info[3].st_mode)1666 stat.S_ISREG(current_path_info[3].st_mode)
1666 and stat.S_IEXEC & current_path_info[3].st_mode)1667 and stat.S_IEXEC & current_path_info[3].st_mode)
1667 return (None,1668 return TreeChange(
1669 None,
1668 (None, self.utf8_decode(current_path_info[0])[0]),1670 (None, self.utf8_decode(current_path_info[0])[0]),
1669 True,1671 True,
1670 (False, False),1672 (False, False),
@@ -1833,7 +1835,8 @@
1833 if changed is not None:1835 if changed is not None:
1834 raise AssertionError(1836 raise AssertionError(
1835 "result is not None: %r" % result)1837 "result is not None: %r" % result)
1836 result = (None,1838 result = TreeChange(
1839 None,
1837 (None, relpath_unicode),1840 (None, relpath_unicode),
1838 True,1841 True,
1839 (False, False),1842 (False, False),
18401843
=== modified file 'breezy/bzr/dirstate.py'
--- breezy/bzr/dirstate.py 2019-06-15 01:02:49 +0000
+++ breezy/bzr/dirstate.py 2019-06-15 17:35:57 +0000
@@ -4190,15 +4190,15 @@
4190 except UnicodeDecodeError:4190 except UnicodeDecodeError:
4191 raise errors.BadFilenameEncoding(4191 raise errors.BadFilenameEncoding(
4192 current_path_info[0], osutils._fs_enc)4192 current_path_info[0], osutils._fs_enc)
4193 yield (None,4193 yield TreeChange(
4194 (None, relpath_unicode),4194 None,
4195 True,4195 (None, relpath_unicode),
4196 (False, False),4196 True,
4197 (None, None),4197 (False, False),
4198 (None, utf8_decode(4198 (None, None),
4199 current_path_info[1])[0]),4199 (None, utf8_decode(current_path_info[1])[0]),
4200 (None, current_path_info[2]),4200 (None, current_path_info[2]),
4201 (None, new_executable))4201 (None, new_executable))
4202 # dont descend into this unversioned path if it is4202 # dont descend into this unversioned path if it is
4203 # a dir4203 # a dir
4204 if current_path_info[2] in ('directory'):4204 if current_path_info[2] in ('directory'):
42054205
=== modified file 'breezy/bzr/inventory.py'
--- breezy/bzr/inventory.py 2019-06-15 13:33:16 +0000
+++ breezy/bzr/inventory.py 2019-06-15 17:35:57 +0000
@@ -2104,8 +2104,9 @@
2104 # Could happen when only the revision changed for a directory2104 # Could happen when only the revision changed for a directory
2105 # for instance.2105 # for instance.
2106 continue2106 continue
2107 yield (file_id, (path_in_source, path_in_target), changed_content,2107 yield (
2108 versioned, parent, name, kind, executable)2108 file_id, (path_in_source, path_in_target), changed_content,
2109 versioned, parent, name, kind, executable)
21092110
2110 def __len__(self):2111 def __len__(self):
2111 """Return the number of entries in the inventory."""2112 """Return the number of entries in the inventory."""
21122113
=== modified file 'breezy/bzr/inventorytree.py'
--- breezy/bzr/inventorytree.py 2019-06-15 01:02:49 +0000
+++ breezy/bzr/inventorytree.py 2019-06-15 17:35:57 +0000
@@ -893,16 +893,15 @@
893 # FIXME: nested tree support893 # FIXME: nested tree support
894 for result in self.target.root_inventory.iter_changes(894 for result in self.target.root_inventory.iter_changes(
895 self.source.root_inventory):895 self.source.root_inventory):
896 result = TreeChange(*result)
896 if specific_file_ids is not None:897 if specific_file_ids is not None:
897 file_id = result[0]898 if result.file_id not in specific_file_ids:
898 if file_id not in specific_file_ids:
899 # A change from the whole tree that we don't want to show yet.899 # A change from the whole tree that we don't want to show yet.
900 # We may find that we need to show it for delta consistency, so900 # We may find that we need to show it for delta consistency, so
901 # stash it.901 # stash it.
902 discarded_changes[result[0]] = result902 discarded_changes[result.file_id] = result
903 continue903 continue
904 new_parent_id = result[4][1]904 precise_file_ids.add(result.parent_id[1])
905 precise_file_ids.add(new_parent_id)
906 yield result905 yield result
907 changed_file_ids.add(result[0])906 changed_file_ids.add(result[0])
908 if specific_file_ids is not None:907 if specific_file_ids is not None:
909908
=== modified file 'breezy/bzr/vf_repository.py'
--- breezy/bzr/vf_repository.py 2019-05-29 03:22:34 +0000
+++ breezy/bzr/vf_repository.py 2019-06-15 17:35:57 +0000
@@ -85,6 +85,7 @@
85from ..trace import (85from ..trace import (
86 mutter86 mutter
87 )87 )
88from ..tree import TreeChange
8889
8990
90class VersionedFileRepositoryFormat(RepositoryFormat):91class VersionedFileRepositoryFormat(RepositoryFormat):
@@ -374,12 +375,12 @@
374 changes = {}375 changes = {}
375 for change in iter_changes:376 for change in iter_changes:
376 # This probably looks up in basis_inv way to much.377 # This probably looks up in basis_inv way to much.
377 if change[1][0] is not None:378 if change.path[0] is not None:
378 head_candidate = [basis_inv.get_entry(change[0]).revision]379 head_candidate = [basis_inv.get_entry(change.file_id).revision]
379 else:380 else:
380 head_candidate = []381 head_candidate = []
381 changes[change[0]] = change, merged_ids.get(change[0],382 changes[change.file_id] = change, merged_ids.get(
382 head_candidate)383 change.file_id, head_candidate)
383 unchanged_merged = set(merged_ids) - set(changes)384 unchanged_merged = set(merged_ids) - set(changes)
384 # Extend the changes dict with synthetic changes to record merges of385 # Extend the changes dict with synthetic changes to record merges of
385 # texts.386 # texts.
@@ -403,13 +404,14 @@
403 # by the user. So we discard this change.404 # by the user. So we discard this change.
404 pass405 pass
405 else:406 else:
406 change = (file_id,407 change = TreeChange(
407 (basis_inv.id2path(file_id), tree.id2path(file_id)),408 file_id,
408 False, (True, True),409 (basis_inv.id2path(file_id), tree.id2path(file_id)),
409 (basis_entry.parent_id, basis_entry.parent_id),410 False, (True, True),
410 (basis_entry.name, basis_entry.name),411 (basis_entry.parent_id, basis_entry.parent_id),
411 (basis_entry.kind, basis_entry.kind),412 (basis_entry.name, basis_entry.name),
412 (basis_entry.executable, basis_entry.executable))413 (basis_entry.kind, basis_entry.kind),
414 (basis_entry.executable, basis_entry.executable))
413 changes[file_id] = (change, merged_ids[file_id])415 changes[file_id] = (change, merged_ids[file_id])
414 # changes contains tuples with the change and a set of inventory416 # changes contains tuples with the change and a set of inventory
415 # candidates for the file.417 # candidates for the file.
@@ -419,7 +421,7 @@
419 inv_delta = self._basis_delta421 inv_delta = self._basis_delta
420 modified_rev = self._new_revision_id422 modified_rev = self._new_revision_id
421 for change, head_candidates in viewvalues(changes):423 for change, head_candidates in viewvalues(changes):
422 if change[3][1]: # versioned in target.424 if change.versioned[1]: # versioned in target.
423 # Several things may be happening here:425 # Several things may be happening here:
424 # We may have a fork in the per-file graph426 # We may have a fork in the per-file graph
425 # - record a change with the content from tree427 # - record a change with the content from tree
@@ -427,11 +429,11 @@
427 # - carry over the tree that hasn't changed429 # - carry over the tree that hasn't changed
428 # We may have a change against all trees430 # We may have a change against all trees
429 # - record the change with the content from tree431 # - record the change with the content from tree
430 kind = change[6][1]432 kind = change.kind[1]
431 file_id = change[0]433 file_id = change.file_id
432 entry = _entry_factory[kind](file_id, change[5][1],434 entry = _entry_factory[kind](file_id, change.name[1],
433 change[4][1])435 change.parent_id[1])
434 head_set = self._heads(change[0], set(head_candidates))436 head_set = self._heads(change.file_id, set(head_candidates))
435 heads = []437 heads = []
436 # Preserve ordering.438 # Preserve ordering.
437 for head_candidate in head_candidates:439 for head_candidate in head_candidates:
@@ -478,7 +480,7 @@
478 # other process reverts it while commit is running (with480 # other process reverts it while commit is running (with
479 # the revert happening after iter_changes did its481 # the revert happening after iter_changes did its
480 # examination).482 # examination).
481 if change[7][1]:483 if change.executable[1]:
482 entry.executable = True484 entry.executable = True
483 else:485 else:
484 entry.executable = False486 entry.executable = False
@@ -489,11 +491,11 @@
489 nostore_sha = parent_entry.text_sha1491 nostore_sha = parent_entry.text_sha1
490 else:492 else:
491 nostore_sha = None493 nostore_sha = None
492 file_obj, stat_value = tree.get_file_with_stat(change[1][1])494 file_obj, stat_value = tree.get_file_with_stat(change.path[1])
493 try:495 try:
494 entry.text_sha1, entry.text_size = self._add_file_to_weave(496 entry.text_sha1, entry.text_size = self._add_file_to_weave(
495 file_id, file_obj, heads, nostore_sha)497 file_id, file_obj, heads, nostore_sha)
496 yield change[1][1], (entry.text_sha1, stat_value)498 yield change.path[1], (entry.text_sha1, stat_value)
497 except errors.ExistingContent:499 except errors.ExistingContent:
498 # No content change against a carry_over parent500 # No content change against a carry_over parent
499 # Perhaps this should also yield a fs hash update?501 # Perhaps this should also yield a fs hash update?
@@ -505,23 +507,23 @@
505 elif kind == 'symlink':507 elif kind == 'symlink':
506 # Wants a path hint?508 # Wants a path hint?
507 entry.symlink_target = tree.get_symlink_target(509 entry.symlink_target = tree.get_symlink_target(
508 change[1][1])510 change.path[1])
509 if (carry_over_possible and511 if (carry_over_possible and
510 parent_entry.symlink_target ==512 parent_entry.symlink_target ==
511 entry.symlink_target):513 entry.symlink_target):
512 carried_over = True514 carried_over = True
513 else:515 else:
514 self._add_file_to_weave(516 self._add_file_to_weave(
515 change[0], BytesIO(), heads, None)517 change.file_id, BytesIO(), heads, None)
516 elif kind == 'directory':518 elif kind == 'directory':
517 if carry_over_possible:519 if carry_over_possible:
518 carried_over = True520 carried_over = True
519 else:521 else:
520 # Nothing to set on the entry.522 # Nothing to set on the entry.
521 # XXX: split into the Root and nonRoot versions.523 # XXX: split into the Root and nonRoot versions.
522 if change[1][1] != '' or self.repository.supports_rich_root():524 if change.path[1] != '' or self.repository.supports_rich_root():
523 self._add_file_to_weave(525 self._add_file_to_weave(
524 change[0], BytesIO(), heads, None)526 change.file_id, BytesIO(), heads, None)
525 elif kind == 'tree-reference':527 elif kind == 'tree-reference':
526 if not self.repository._format.supports_tree_reference:528 if not self.repository._format.supports_tree_reference:
527 # This isn't quite sane as an error, but we shouldn't529 # This isn't quite sane as an error, but we shouldn't
@@ -531,7 +533,7 @@
531 raise errors.UnsupportedOperation(533 raise errors.UnsupportedOperation(
532 tree.add_reference, self.repository)534 tree.add_reference, self.repository)
533 reference_revision = tree.get_reference_revision(535 reference_revision = tree.get_reference_revision(
534 change[1][1])536 change.path[1])
535 entry.reference_revision = reference_revision537 entry.reference_revision = reference_revision
536 if (carry_over_possible538 if (carry_over_possible
537 and parent_entry.reference_revision ==539 and parent_entry.reference_revision ==
@@ -539,7 +541,7 @@
539 carried_over = True541 carried_over = True
540 else:542 else:
541 self._add_file_to_weave(543 self._add_file_to_weave(
542 change[0], BytesIO(), heads, None)544 change.file_id, BytesIO(), heads, None)
543 else:545 else:
544 raise AssertionError('unknown kind %r' % kind)546 raise AssertionError('unknown kind %r' % kind)
545 if not carried_over:547 if not carried_over:
@@ -548,8 +550,8 @@
548 entry.revision = parent_entry.revision550 entry.revision = parent_entry.revision
549 else:551 else:
550 entry = None552 entry = None
551 new_path = change[1][1]553 new_path = change.path[1]
552 inv_delta.append((change[1][0], new_path, change[0], entry))554 inv_delta.append((change.path[0], new_path, change.file_id, entry))
553 if new_path == '':555 if new_path == '':
554 seen_root = True556 seen_root = True
555 # The initial commit adds a root directory, but this in itself is not557 # The initial commit adds a root directory, but this in itself is not
556558
=== modified file 'breezy/bzr/workingtree.py'
--- breezy/bzr/workingtree.py 2019-06-04 00:08:59 +0000
+++ breezy/bzr/workingtree.py 2019-06-15 17:35:57 +0000
@@ -426,19 +426,18 @@
426426
427 # Bail out if we are going to delete files we shouldn't427 # Bail out if we are going to delete files we shouldn't
428 if not keep_files and not force:428 if not keep_files and not force:
429 for (file_id, path, content_change, versioned, parent_id, name,429 for change in self.iter_changes(
430 kind, executable) in self.iter_changes(430 self.basis_tree(), include_unchanged=True,
431 self.basis_tree(), include_unchanged=True,431 require_versioned=False, want_unversioned=True,
432 require_versioned=False, want_unversioned=True,432 specific_files=files):
433 specific_files=files):433 if change.versioned[0] is False:
434 if versioned[0] is False:
435 # The record is unknown or newly added434 # The record is unknown or newly added
436 files_to_backup.append(path[1])435 files_to_backup.append(change.path[1])
437 elif (content_change and (kind[1] is not None)436 elif (change.changed_content and (change.kind[1] is not None)
438 and osutils.is_inside_any(files, path[1])):437 and osutils.is_inside_any(files, change.path[1])):
439 # Versioned and changed, but not deleted, and still438 # Versioned and changed, but not deleted, and still
440 # in one of the dirs to be deleted.439 # in one of the dirs to be deleted.
441 files_to_backup.append(path[1])440 files_to_backup.append(change.path[1])
442441
443 def backup(file_to_backup):442 def backup(file_to_backup):
444 backup_name = self.controldir._available_backup_name(443 backup_name = self.controldir._available_backup_name(
445444
=== modified file 'breezy/commit.py'
--- breezy/commit.py 2019-03-04 01:44:35 +0000
+++ breezy/commit.py 2019-06-15 17:35:57 +0000
@@ -69,6 +69,7 @@
69 minimum_path_selection,69 minimum_path_selection,
70 )70 )
71from .trace import mutter, note, is_quiet71from .trace import mutter, note, is_quiet
72from .tree import TreeChange
72from .urlutils import unescape_for_display73from .urlutils import unescape_for_display
73from .i18n import gettext74from .i18n import gettext
7475
@@ -96,14 +97,11 @@
96 :return: iter_changes function97 :return: iter_changes function
97 """98 """
98 for change in iter_changes:99 for change in iter_changes:
99 old_path = change[1][0]100 new_excluded = (change.path[1] is not None and
100 new_path = change[1][1]101 is_inside_any(exclude, change.path[1]))
101102
102 new_excluded = (new_path is not None and103 old_excluded = (change.path[0] is not None and
103 is_inside_any(exclude, new_path))104 is_inside_any(exclude, change.path[0]))
104
105 old_excluded = (old_path is not None and
106 is_inside_any(exclude, old_path))
107105
108 if old_excluded and new_excluded:106 if old_excluded and new_excluded:
109 continue107 continue
@@ -701,29 +699,28 @@
701 deleted_paths = []699 deleted_paths = []
702 for change in iter_changes:700 for change in iter_changes:
703 if report_changes:701 if report_changes:
704 old_path = change[1][0]702 old_path = change.path[0]
705 new_path = change[1][1]703 new_path = change.path[1]
706 versioned = change[3][1]704 versioned = change.versioned[1]
707 kind = change[6][1]705 kind = change.kind[1]
708 versioned = change[3][1]706 versioned = change.versioned[1]
709 if kind is None and versioned:707 if kind is None and versioned:
710 # 'missing' path708 # 'missing' path
711 if report_changes:709 if report_changes:
712 reporter.missing(new_path)710 reporter.missing(new_path)
713 if change[6][0] == 'symlink' and not self.work_tree.supports_symlinks():711 if change.kind[0] == 'symlink' and not self.work_tree.supports_symlinks():
714 trace.warning('Ignoring "%s" as symlinks are not '712 trace.warning('Ignoring "%s" as symlinks are not '
715 'supported on this filesystem.' % (change[1][0],))713 'supported on this filesystem.' % (change.path[0],))
716 continue714 continue
717 deleted_paths.append(change[1][1])715 deleted_paths.append(change[1][1])
718 # Reset the new path (None) and new versioned flag (False)716 # Reset the new path (None) and new versioned flag (False)
719 change = (change[0], (change[1][0], None), change[2],717 change = change.discard_new()
720 (change[3][0], False)) + change[4:]718 new_path = change.path[1]
721 new_path = change[1][1]
722 versioned = False719 versioned = False
723 elif kind == 'tree-reference':720 elif kind == 'tree-reference':
724 if self.recursive == 'down':721 if self.recursive == 'down':
725 self._commit_nested_tree(change[1][1])722 self._commit_nested_tree(change[1][1])
726 if change[3][0] or change[3][1]:723 if change.versioned[0] or change.versioned[1]:
727 yield change724 yield change
728 if report_changes:725 if report_changes:
729 if new_path is None:726 if new_path is None:
730727
=== modified file 'breezy/delta.py'
--- breezy/delta.py 2019-06-03 21:25:01 +0000
+++ breezy/delta.py 2019-06-15 17:35:57 +0000
@@ -125,48 +125,48 @@
125 delta = TreeDelta()125 delta = TreeDelta()
126 # mutter('start compare_trees')126 # mutter('start compare_trees')
127127
128 for (file_id, path, content_change, versioned, parent_id, name, kind,128 for change in new_tree.iter_changes(
129 executable) in new_tree.iter_changes(old_tree, want_unchanged,129 old_tree, want_unchanged, specific_files, extra_trees=extra_trees,
130 specific_files, extra_trees=extra_trees,130 require_versioned=require_versioned,
131 require_versioned=require_versioned,131 want_unversioned=want_unversioned):
132 want_unversioned=want_unversioned):132 if change.versioned == (False, False):
133 if versioned == (False, False):133 delta.unversioned.append((change.path[1], None, change.kind[1]))
134 delta.unversioned.append((path[1], None, kind[1]))134 continue
135 continue135 if not include_root and (None, None) == change.parent_id:
136 if not include_root and (None, None) == parent_id:136 continue
137 continue137 fully_present = tuple(
138 fully_present = tuple((versioned[x] and kind[x] is not None) for138 (change.versioned[x] and change.kind[x] is not None)
139 x in range(2))139 for x in range(2))
140 if fully_present[0] != fully_present[1]:140 if fully_present[0] != fully_present[1]:
141 if fully_present[1] is True:141 if fully_present[1] is True:
142 delta.added.append((path[1], file_id, kind[1]))142 delta.added.append((change.path[1], change.file_id, change.kind[1]))
143 else:143 else:
144 if kind[0] == 'symlink' and not new_tree.supports_symlinks():144 if change.kind[0] == 'symlink' and not new_tree.supports_symlinks():
145 trace.warning(145 trace.warning(
146 'Ignoring "%s" as symlinks '146 'Ignoring "%s" as symlinks '
147 'are not supported on this filesystem.' % (path[0],))147 'are not supported on this filesystem.' % (change.path[0],))
148 else:148 else:
149 delta.removed.append((path[0], file_id, kind[0]))149 delta.removed.append(
150 (change.path[0], change.file_id, change.kind[0]))
150 elif fully_present[0] is False:151 elif fully_present[0] is False:
151 delta.missing.append((path[1], file_id, kind[1]))152 delta.missing.append((change.path[1], change.file_id, change.kind[1]))
152 elif name[0] != name[1] or parent_id[0] != parent_id[1]:153 elif change.name[0] != change.name[1] or change.parent_id[0] != change.parent_id[1]:
153 # If the name changes, or the parent_id changes, we have a rename154 # If the name changes, or the parent_id changes, we have a rename
154 # (if we move a parent, that doesn't count as a rename for the155 # (if we move a parent, that doesn't count as a rename for the
155 # file)156 # file)
156 delta.renamed.append((path[0],157 delta.renamed.append(
157 path[1],158 (change.path[0], change.path[1], change.file_id,
158 file_id,159 change.kind[1], change.changed_content,
159 kind[1],160 (change.executable[0] != change.executable[1])))
160 content_change,161 elif change.kind[0] != change.kind[1]:
161 (executable[0] != executable[1])))162 delta.kind_changed.append(
162 elif kind[0] != kind[1]:163 (change.path[1], change.file_id, change.kind[0], change.kind[1]))
163 delta.kind_changed.append((path[1], file_id, kind[0], kind[1]))164 elif change.changed_content or change.executable[0] != change.executable[1]:
164 elif content_change or executable[0] != executable[1]:165 delta.modified.append((change.path[1], change.file_id, change.kind[1],
165 delta.modified.append((path[1], file_id, kind[1],166 change.changed_content,
166 content_change,167 (change.executable[0] != change.executable[1])))
167 (executable[0] != executable[1])))
168 else:168 else:
169 delta.unchanged.append((path[1], file_id, kind[1]))169 delta.unchanged.append((change.path[1], change.file_id, change.kind[1]))
170170
171 delta.removed.sort()171 delta.removed.sort()
172 delta.added.sort()172 delta.added.sort()
173173
=== modified file 'breezy/diff.py'
--- breezy/diff.py 2019-06-15 14:43:05 +0000
+++ breezy/diff.py 2019-06-15 17:35:57 +0000
@@ -1060,23 +1060,24 @@
1060 def get_encoded_path(path):1060 def get_encoded_path(path):
1061 if path is not None:1061 if path is not None:
1062 return path.encode(self.path_encoding, "replace")1062 return path.encode(self.path_encoding, "replace")
1063 for (file_id, paths, changed_content, versioned, parent, name, kind,1063 for change in sorted(iterator, key=changes_key):
1064 executable) in sorted(iterator, key=changes_key):
1065 # The root does not get diffed, and items with no known kind (that1064 # The root does not get diffed, and items with no known kind (that
1066 # is, missing) in both trees are skipped as well.1065 # is, missing) in both trees are skipped as well.
1067 if parent == (None, None) or kind == (None, None):1066 if change.parent_id == (None, None) or change.kind == (None, None):
1068 continue1067 continue
1069 if kind[0] == 'symlink' and not self.new_tree.supports_symlinks():1068 if change.kind[0] == 'symlink' and not self.new_tree.supports_symlinks():
1070 warning(1069 warning(
1071 'Ignoring "%s" as symlinks are not '1070 'Ignoring "%s" as symlinks are not '
1072 'supported on this filesystem.' % (paths[0],))1071 'supported on this filesystem.' % (change.path[0],))
1073 continue1072 continue
1074 oldpath, newpath = paths1073 oldpath, newpath = change.path
1075 oldpath_encoded = get_encoded_path(paths[0])1074 oldpath_encoded = get_encoded_path(change.path[0])
1076 newpath_encoded = get_encoded_path(paths[1])1075 newpath_encoded = get_encoded_path(change.path[1])
1077 old_present = (kind[0] is not None and versioned[0])1076 old_present = (change.kind[0] is not None and change.versioned[0])
1078 new_present = (kind[1] is not None and versioned[1])1077 new_present = (change.kind[1] is not None and change.versioned[1])
1079 renamed = (parent[0], name[0]) != (parent[1], name[1])1078 executable = change.executable
1079 kind = change.kind
1080 renamed = (change.parent_id[0], change.name[0]) != (change.parent_id[1], change.name[1])
10801081
1081 properties_changed = []1082 properties_changed = []
1082 properties_changed.extend(1083 properties_changed.extend(
@@ -1104,7 +1105,7 @@
1104 # modified *somehow*, either content or execute bit.1105 # modified *somehow*, either content or execute bit.
1105 self.to_file.write(b"=== modified %s '%s'%s\n" % (kind[0].encode('ascii'),1106 self.to_file.write(b"=== modified %s '%s'%s\n" % (kind[0].encode('ascii'),
1106 newpath_encoded, prop_str))1107 newpath_encoded, prop_str))
1107 if changed_content:1108 if change.changed_content:
1108 self._diff(oldpath, newpath, kind[0], kind[1])1109 self._diff(oldpath, newpath, kind[0], kind[1])
1109 has_changes = 11110 has_changes = 1
1110 if renamed:1111 if renamed:
11111112
=== modified file 'breezy/git/commit.py'
--- breezy/git/commit.py 2019-06-15 13:38:17 +0000
+++ breezy/git/commit.py 2019-06-15 17:35:57 +0000
@@ -88,32 +88,32 @@
8888
89 def record_iter_changes(self, workingtree, basis_revid, iter_changes):89 def record_iter_changes(self, workingtree, basis_revid, iter_changes):
90 seen_root = False90 seen_root = False
91 for (file_id, path, changed_content, versioned, parent, name, kind,91 for change in iter_changes:
92 executable) in iter_changes:92 if change.kind[1] in ("directory",):
93 if kind[1] in ("directory",):
94 self._inv_delta.append(93 self._inv_delta.append(
95 (path[0], path[1], file_id, entry_factory[kind[1]](94 (change.path[0], change.path[1], change.file_id,
96 file_id, name[1], parent[1])))95 entry_factory[change.kind[1]](
97 if kind[0] in ("file", "symlink"):96 change.file_id, change.name[1], change.parent_id[1])))
98 self._blobs[path[0].encode("utf-8")] = None97 if change.kind[0] in ("file", "symlink"):
98 self._blobs[change.path[0].encode("utf-8")] = None
99 self._any_changes = True99 self._any_changes = True
100 if path[1] == "":100 if change.path[1] == "":
101 seen_root = True101 seen_root = True
102 continue102 continue
103 self._any_changes = True103 self._any_changes = True
104 if path[1] is None:104 if change.path[1] is None:
105 self._inv_delta.append((path[0], path[1], file_id, None))105 self._inv_delta.append((change.path[0], change.path[1], change.file_id, None))
106 self._blobs[path[0].encode("utf-8")] = None106 self._blobs[change.path[0].encode("utf-8")] = None
107 continue107 continue
108 try:108 try:
109 entry_kls = entry_factory[kind[1]]109 entry_kls = entry_factory[change.kind[1]]
110 except KeyError:110 except KeyError:
111 raise KeyError("unknown kind %s" % kind[1])111 raise KeyError("unknown kind %s" % change.kind[1])
112 entry = entry_kls(file_id, name[1], parent[1])112 entry = entry_kls(change.file_id, change.name[1], change.parent_id[1])
113 if kind[1] == "file":113 if change.kind[1] == "file":
114 entry.executable = executable[1]114 entry.executable = change.executable[1]
115 blob = Blob()115 blob = Blob()
116 f, st = workingtree.get_file_with_stat(path[1])116 f, st = workingtree.get_file_with_stat(change.path[1])
117 try:117 try:
118 blob.data = f.read()118 blob.data = f.read()
119 finally:119 finally:
@@ -122,29 +122,29 @@
122 entry.text_sha1 = osutils.sha_string(blob.data)122 entry.text_sha1 = osutils.sha_string(blob.data)
123 self.store.add_object(blob)123 self.store.add_object(blob)
124 sha = blob.id124 sha = blob.id
125 elif kind[1] == "symlink":125 elif change.kind[1] == "symlink":
126 symlink_target = workingtree.get_symlink_target(path[1])126 symlink_target = workingtree.get_symlink_target(change.path[1])
127 blob = Blob()127 blob = Blob()
128 blob.data = symlink_target.encode("utf-8")128 blob.data = symlink_target.encode("utf-8")
129 self.store.add_object(blob)129 self.store.add_object(blob)
130 sha = blob.id130 sha = blob.id
131 entry.symlink_target = symlink_target131 entry.symlink_target = symlink_target
132 st = None132 st = None
133 elif kind[1] == "tree-reference":133 elif change.kind[1] == "tree-reference":
134 sha = read_submodule_head(workingtree.abspath(path[1]))134 sha = read_submodule_head(workingtree.abspath(change.path[1]))
135 reference_revision = workingtree.get_reference_revision(path[1])135 reference_revision = workingtree.get_reference_revision(change.path[1])
136 entry.reference_revision = reference_revision136 entry.reference_revision = reference_revision
137 st = None137 st = None
138 else:138 else:
139 raise AssertionError("Unknown kind %r" % kind[1])139 raise AssertionError("Unknown kind %r" % change.kind[1])
140 mode = object_mode(kind[1], executable[1])140 mode = object_mode(change.kind[1], change.executable[1])
141 self._inv_delta.append((path[0], path[1], file_id, entry))141 self._inv_delta.append((change.path[0], change.path[1], change.file_id, entry))
142 encoded_new_path = path[1].encode("utf-8")142 encoded_new_path = change.path[1].encode("utf-8")
143 self._blobs[encoded_new_path] = (mode, sha)143 self._blobs[encoded_new_path] = (mode, sha)
144 if st is not None:144 if st is not None:
145 yield path[1], (entry.text_sha1, st)145 yield change.path[1], (entry.text_sha1, st)
146 if self._mapping.generate_file_id(encoded_new_path) != file_id:146 if self._mapping.generate_file_id(encoded_new_path) != change.file_id:
147 self._override_fileids[encoded_new_path] = file_id147 self._override_fileids[encoded_new_path] = change.file_id
148 else:148 else:
149 self._override_fileids[encoded_new_path] = None149 self._override_fileids[encoded_new_path] = None
150 if not seen_root and len(self.parents) == 0:150 if not seen_root and len(self.parents) == 0:
151151
=== modified file 'breezy/git/object_store.py'
--- breezy/git/object_store.py 2019-06-06 22:22:47 +0000
+++ breezy/git/object_store.py 2019-06-15 17:35:57 +0000
@@ -249,16 +249,15 @@
249 raise KeyError249 raise KeyError
250250
251 # Find all the changed blobs251 # Find all the changed blobs
252 for (file_id, path, changed_content, versioned, parent, name, kind,252 for change in tree.iter_changes(base_tree):
253 executable) in tree.iter_changes(base_tree):253 if change.name[1] in BANNED_FILENAMES:
254 if name[1] in BANNED_FILENAMES:
255 continue254 continue
256 if kind[1] == "file":255 if change.kind[1] == "file":
257 sha1 = tree.get_file_sha1(path[1])256 sha1 = tree.get_file_sha1(change.path[1])
258 blob_id = None257 blob_id = None
259 try:258 try:
260 (pfile_id, prevision) = find_unchanged_parent_ie(259 (pfile_id, prevision) = find_unchanged_parent_ie(
261 file_id, kind[1], sha1, other_parent_trees)260 change.file_id, change.kind[1], sha1, other_parent_trees)
262 except KeyError:261 except KeyError:
263 pass262 pass
264 else:263 else:
@@ -271,35 +270,35 @@
271 if not changed_content:270 if not changed_content:
272 # no-change merge ?271 # no-change merge ?
273 blob = Blob()272 blob = Blob()
274 blob.data = tree.get_file_text(path[1])273 blob.data = tree.get_file_text(change.path[1])
275 blob_id = blob.id274 blob_id = blob.id
276 if blob_id is None:275 if blob_id is None:
277 new_blobs.append((path[1], file_id))276 new_blobs.append((change.path[1], change.file_id))
278 else:277 else:
279 shamap[path[1]] = blob_id278 shamap[path[1]] = blob_id
280 if add_cache_entry is not None:279 if add_cache_entry is not None:
281 add_cache_entry(280 add_cache_entry(
282 ("blob", blob_id),281 ("blob", blob_id),
283 (file_id, tree.get_file_revision(path[1])), path[1])282 (file_id, tree.get_file_revision(change.path[1])), change.path[1])
284 elif kind[1] == "symlink":283 elif change.kind[1] == "symlink":
285 target = tree.get_symlink_target(path[1])284 target = tree.get_symlink_target(change.path[1])
286 blob = symlink_to_blob(target)285 blob = symlink_to_blob(target)
287 shamap[path[1]] = blob.id286 shamap[change.path[1]] = blob.id
288 if add_cache_entry is not None:287 if add_cache_entry is not None:
289 add_cache_entry(288 add_cache_entry(
290 blob, (file_id, tree.get_file_revision(path[1])), path[1])289 blob, (change.file_id, tree.get_file_revision(change.path[1])), change.path[1])
291 try:290 try:
292 find_unchanged_parent_ie(291 find_unchanged_parent_ie(
293 file_id, kind[1], target, other_parent_trees)292 change.file_id, change.kind[1], target, other_parent_trees)
294 except KeyError:293 except KeyError:
295 if changed_content:294 if change.changed_content:
296 yield (path[1], blob,295 yield (change.path[1], blob,
297 (file_id, tree.get_file_revision(path[1])))296 (change.file_id, tree.get_file_revision(change.path[1])))
298 elif kind[1] is None:297 elif change.kind[1] is None:
299 shamap[path[1]] = None298 shamap[change.path[1]] = None
300 elif kind[1] != 'directory':299 elif change.kind[1] != 'directory':
301 raise AssertionError(kind[1])300 raise AssertionError(change.kind[1])
302 for p in path:301 for p in change.path:
303 if p is None:302 if p is None:
304 continue303 continue
305 dirty_dirs.add(osutils.dirname(p))304 dirty_dirs.add(osutils.dirname(p))
306305
=== modified file 'breezy/git/workingtree.py'
--- breezy/git/workingtree.py 2019-06-04 00:08:59 +0000
+++ breezy/git/workingtree.py 2019-06-15 17:35:57 +0000
@@ -350,23 +350,22 @@
350350
351 # Bail out if we are going to delete files we shouldn't351 # Bail out if we are going to delete files we shouldn't
352 if not keep_files and not force:352 if not keep_files and not force:
353 for (file_id, path, content_change, versioned, parent_id, name,353 for change in self.iter_changes(
354 kind, executable) in self.iter_changes(354 self.basis_tree(), include_unchanged=True,
355 self.basis_tree(), include_unchanged=True,355 require_versioned=False, want_unversioned=True,
356 require_versioned=False, want_unversioned=True,356 specific_files=files):
357 specific_files=files):357 if change.versioned[0] is False:
358 if versioned[0] is False:
359 # The record is unknown or newly added358 # The record is unknown or newly added
360 files_to_backup.append(path[1])359 files_to_backup.append(change.path[1])
361 files_to_backup.extend(360 files_to_backup.extend(
362 osutils.parent_directories(path[1]))361 osutils.parent_directories(change.path[1]))
363 elif (content_change and (kind[1] is not None)362 elif (change.changed_content and (change.kind[1] is not None)
364 and osutils.is_inside_any(files, path[1])):363 and osutils.is_inside_any(files, change.path[1])):
365 # Versioned and changed, but not deleted, and still364 # Versioned and changed, but not deleted, and still
366 # in one of the dirs to be deleted.365 # in one of the dirs to be deleted.
367 files_to_backup.append(path[1])366 files_to_backup.append(change.path[1])
368 files_to_backup.extend(367 files_to_backup.extend(
369 osutils.parent_directories(path[1]))368 osutils.parent_directories(change.path[1]))
370369
371 for f in files:370 for f in files:
372 if f == '':371 if f == '':
373372
=== modified file 'breezy/merge.py'
--- breezy/merge.py 2019-06-03 05:21:20 +0000
+++ breezy/merge.py 2019-06-15 17:35:57 +0000
@@ -852,14 +852,13 @@
852 self.interesting_files, trees=[self.other_tree])852 self.interesting_files, trees=[self.other_tree])
853 this_entries = dict(self.this_tree.iter_entries_by_dir(853 this_entries = dict(self.this_tree.iter_entries_by_dir(
854 specific_files=this_interesting_files))854 specific_files=this_interesting_files))
855 for (file_id, paths, changed, versioned, parents, names, kind,855 for change in iterator:
856 executable) in iterator:856 if change.path[0] is not None:
857 if paths[0] is not None:
858 this_path = _mod_tree.find_previous_path(857 this_path = _mod_tree.find_previous_path(
859 self.base_tree, self.this_tree, paths[0])858 self.base_tree, self.this_tree, change.path[0])
860 else:859 else:
861 this_path = _mod_tree.find_previous_path(860 this_path = _mod_tree.find_previous_path(
862 self.other_tree, self.this_tree, paths[1])861 self.other_tree, self.this_tree, change.path[1])
863 this_entry = this_entries.get(this_path)862 this_entry = this_entries.get(this_path)
864 if this_entry is not None:863 if this_entry is not None:
865 this_name = this_entry.name864 this_name = this_entry.name
@@ -869,12 +868,13 @@
869 this_name = None868 this_name = None
870 this_parent = None869 this_parent = None
871 this_executable = None870 this_executable = None
872 parents3 = parents + (this_parent,)871 parents3 = change.parent_id + (this_parent,)
873 names3 = names + (this_name,)872 names3 = change.name + (this_name,)
874 paths3 = paths + (this_path, )873 paths3 = change.path + (this_path, )
875 executable3 = executable + (this_executable,)874 executable3 = change.executable + (this_executable,)
876 result.append((file_id, changed, paths3,875 result.append(
877 parents3, names3, executable3))876 (change.file_id, change.changed_content, paths3,
877 parents3, names3, executable3))
878 return result878 return result
879879
880 def _entries_lca(self):880 def _entries_lca(self):
881881
=== modified file 'breezy/mutabletree.py'
--- breezy/mutabletree.py 2019-06-03 23:45:30 +0000
+++ breezy/mutabletree.py 2019-06-15 17:35:57 +0000
@@ -202,7 +202,7 @@
202 try:202 try:
203 change = next(changes)203 change = next(changes)
204 # Exclude root (talk about black magic... --vila 20090629)204 # Exclude root (talk about black magic... --vila 20090629)
205 if change[4] == (None, None):205 if change.parent_id == (None, None):
206 change = next(changes)206 change = next(changes)
207 return True207 return True
208 except StopIteration:208 except StopIteration:
209209
=== modified file 'breezy/plugins/fastimport/revision_store.py'
--- breezy/plugins/fastimport/revision_store.py 2018-11-25 20:44:56 +0000
+++ breezy/plugins/fastimport/revision_store.py 2019-06-15 17:35:57 +0000
@@ -25,6 +25,7 @@
25 osutils,25 osutils,
26 revision as _mod_revision,26 revision as _mod_revision,
27 )27 )
28from ...tree import TreeChange
28from ...bzr import (29from ...bzr import (
29 inventory,30 inventory,
30 )31 )
@@ -118,49 +119,53 @@
118 old_ie = None119 old_ie = None
119 if ie is None:120 if ie is None:
120 raise AssertionError('How is both old and new None?')121 raise AssertionError('How is both old and new None?')
121 change = (file_id,122 change = TreeChange(
122 (old_path, new_path),123 file_id,
123 False,124 (old_path, new_path),
124 (False, False),125 False,
125 (None, None),126 (False, False),
126 (None, None),127 (None, None),
127 (None, None),128 (None, None),
128 (None, None),129 (None, None),
129 )130 (None, None),
130 change = (file_id,131 )
131 (old_path, new_path),132 change = TreeChange(
132 True,133 file_id,
133 (False, True),134 (old_path, new_path),
134 (None, ie.parent_id),135 True,
135 (None, ie.name),136 (False, True),
136 (None, ie.kind),137 (None, ie.parent_id),
137 (None, ie.executable),138 (None, ie.name),
138 )139 (None, ie.kind),
140 (None, ie.executable),
141 )
139 else:142 else:
140 if ie is None:143 if ie is None:
141 change = (file_id,144 change = TreeChange(
142 (old_path, new_path),145 file_id,
143 True,146 (old_path, new_path),
144 (True, False),147 True,
145 (old_ie.parent_id, None),148 (True, False),
146 (old_ie.name, None),149 (old_ie.parent_id, None),
147 (old_ie.kind, None),150 (old_ie.name, None),
148 (old_ie.executable, None),151 (old_ie.kind, None),
149 )152 (old_ie.executable, None),
153 )
150 else:154 else:
151 content_modified = (ie.text_sha1 != old_ie.text_sha1 or155 content_modified = (ie.text_sha1 != old_ie.text_sha1 or
152 ie.text_size != old_ie.text_size)156 ie.text_size != old_ie.text_size)
153 # TODO: ie.kind != old_ie.kind157 # TODO: ie.kind != old_ie.kind
154 # TODO: symlinks changing targets, content_modified?158 # TODO: symlinks changing targets, content_modified?
155 change = (file_id,159 change = TreeChange(
156 (old_path, new_path),160 file_id,
157 content_modified,161 (old_path, new_path),
158 (True, True),162 content_modified,
159 (old_ie.parent_id, ie.parent_id),163 (True, True),
160 (old_ie.name, ie.name),164 (old_ie.parent_id, ie.parent_id),
161 (old_ie.kind, ie.kind),165 (old_ie.name, ie.name),
162 (old_ie.executable, ie.executable),166 (old_ie.kind, ie.kind),
163 )167 (old_ie.executable, ie.executable),
168 )
164 yield change169 yield change
165170
166171
167172
=== modified file 'breezy/plugins/launchpad/lp_propose.py'
--- breezy/plugins/launchpad/lp_propose.py 2019-01-28 21:00:58 +0000
+++ breezy/plugins/launchpad/lp_propose.py 2019-06-15 17:35:57 +0000
@@ -224,7 +224,6 @@
224224
225def modified_files(old_tree, new_tree):225def modified_files(old_tree, new_tree):
226 """Return a list of paths in the new tree with modified contents."""226 """Return a list of paths in the new tree with modified contents."""
227 for f, (op, path), c, v, p, n, (ok, k), e in new_tree.iter_changes(227 for change in new_tree.iter_changes(old_tree):
228 old_tree):228 if change.changed_content and change.kind[1] == 'file':
229 if c and k == 'file':
230 yield str(path)229 yield str(path)
231230
=== modified file 'breezy/plugins/propose/launchpad.py'
--- breezy/plugins/propose/launchpad.py 2019-06-15 14:25:08 +0000
+++ breezy/plugins/propose/launchpad.py 2019-06-15 17:35:57 +0000
@@ -687,7 +687,6 @@
687687
688def modified_files(old_tree, new_tree):688def modified_files(old_tree, new_tree):
689 """Return a list of paths in the new tree with modified contents."""689 """Return a list of paths in the new tree with modified contents."""
690 for f, (op, path), c, v, p, n, (ok, k), e in new_tree.iter_changes(690 for change in new_tree.iter_changes(old_tree):
691 old_tree):691 if change.changed_content and change.kind[1] == 'file':
692 if c and k == 'file':
693 yield str(path)692 yield str(path)
694693
=== modified file 'breezy/rename_map.py'
--- breezy/rename_map.py 2018-11-11 04:08:32 +0000
+++ breezy/rename_map.py 2019-06-15 17:35:57 +0000
@@ -177,24 +177,24 @@
177 with ui_factory.nested_progress_bar() as task:177 with ui_factory.nested_progress_bar() as task:
178 iterator = self.tree.iter_changes(basis, want_unversioned=True,178 iterator = self.tree.iter_changes(basis, want_unversioned=True,
179 pb=task)179 pb=task)
180 for (file_id, paths, changed_content, versioned, parent, name,180 for change in iterator:
181 kind, executable) in iterator:181 if change.kind[1] is None and change.versioned[1]:
182 if kind[1] is None and versioned[1]:182 if not self.tree.has_filename(
183 if not self.tree.has_filename(self.tree.id2path(parent[0])):183 self.tree.id2path(change.parent_id[0])):
184 missing_parents.setdefault(184 missing_parents.setdefault(
185 parent[0], set()).add(file_id)185 change.parent_id[0], set()).add(change.file_id)
186 if kind[0] == 'file':186 if change.kind[0] == 'file':
187 missing_files.add(file_id)187 missing_files.add(change.file_id)
188 else:188 else:
189 # other kinds are not handled189 # other kinds are not handled
190 pass190 pass
191 if versioned == (False, False):191 if change.versioned == (False, False):
192 if self.tree.is_ignored(paths[1]):192 if self.tree.is_ignored(change.path[1]):
193 continue193 continue
194 if kind[1] == 'file':194 if change.kind[1] == 'file':
195 candidate_files.add(paths[1])195 candidate_files.add(change.path[1])
196 if kind[1] == 'directory':196 if change.kind[1] == 'directory':
197 for _dir, children in self.tree.walkdirs(paths[1]):197 for _dir, children in self.tree.walkdirs(change.path[1]):
198 for child in children:198 for child in children:
199 if child[2] == 'file':199 if child[2] == 'file':
200 candidate_files.add(child[0])200 candidate_files.add(child[0])
201201
=== modified file 'breezy/shelf.py'
--- breezy/shelf.py 2018-11-17 16:53:10 +0000
+++ breezy/shelf.py 2019-06-15 17:35:57 +0000
@@ -98,39 +98,38 @@
98 ('modify text', file_id)98 ('modify text', file_id)
99 ('modify target', file_id, target_target, work_target)99 ('modify target', file_id, target_target, work_target)
100 """100 """
101 for (file_id, paths, changed, versioned, parents, names, kind,101 for change in self.iter_changes:
102 executable) in self.iter_changes:
103 # don't shelve add of tree root. Working tree should never102 # don't shelve add of tree root. Working tree should never
104 # lack roots, and bzr misbehaves when they do.103 # lack roots, and bzr misbehaves when they do.
105 # FIXME ADHB (2009-08-09): should still shelve adds of tree roots104 # FIXME ADHB (2009-08-09): should still shelve adds of tree roots
106 # when a tree root was deleted / renamed.105 # when a tree root was deleted / renamed.
107 if kind[0] is None and names[1] == '':106 if change.kind[0] is None and change.name[1] == '':
108 continue107 continue
109 # Also don't shelve deletion of tree root.108 # Also don't shelve deletion of tree root.
110 if kind[1] is None and names[0] == '':109 if change.kind[1] is None and change.name[0] == '':
111 continue110 continue
112 if kind[0] is None or versioned[0] is False:111 if change.kind[0] is None or change.versioned[0] is False:
113 self.creation[file_id] = (kind[1], names[1], parents[1],112 self.creation[change.file_id] = (
114 versioned)113 change.kind[1], change.name[1], change.parent_id[1], change.versioned)
115 yield ('add file', file_id, kind[1], paths[1])114 yield ('add file', change.file_id, change.kind[1], change.path[1])
116 elif kind[1] is None or versioned[0] is False:115 elif change.kind[1] is None or change.versioned[0] is False:
117 self.deletion[file_id] = (kind[0], names[0], parents[0],116 self.deletion[change.file_id] = (
118 versioned)117 change.kind[0], change.name[0], change.parent_id[0], change.versioned)
119 yield ('delete file', file_id, kind[0], paths[0])118 yield ('delete file', change.file_id, change.kind[0], change.path[0])
120 else:119 else:
121 if names[0] != names[1] or parents[0] != parents[1]:120 if change.name[0] != change.name[1] or change.parent_id[0] != change.parent_id[1]:
122 self.renames[file_id] = (names, parents)121 self.renames[change.file_id] = (change.name, change.parent_id)
123 yield ('rename', file_id) + paths122 yield ('rename', change.file_id) + change.path
124123
125 if kind[0] != kind[1]:124 if change.kind[0] != change.kind[1]:
126 yield ('change kind', file_id, kind[0], kind[1], paths[0])125 yield ('change kind', change.file_id, change.kind[0], change.kind[1], change.path[0])
127 elif kind[0] == 'symlink':126 elif change.kind[0] == 'symlink':
128 t_target = self.target_tree.get_symlink_target(paths[0])127 t_target = self.target_tree.get_symlink_target(change.path[0])
129 w_target = self.work_tree.get_symlink_target(paths[1])128 w_target = self.work_tree.get_symlink_target(change.path[1])
130 yield ('modify target', file_id, paths[0], t_target,129 yield ('modify target', change.file_id, change.path[0], t_target,
131 w_target)130 w_target)
132 elif changed:131 elif change.changed_content:
133 yield ('modify text', file_id)132 yield ('modify text', change.file_id)
134133
135 def shelve_change(self, change):134 def shelve_change(self, change):
136 """Shelve a change in the iter_shelvable format."""135 """Shelve a change in the iter_shelvable format."""
137136
=== modified file 'breezy/tests/per_intertree/test_compare.py'
--- breezy/tests/per_intertree/test_compare.py 2018-12-18 20:55:37 +0000
+++ breezy/tests/per_intertree/test_compare.py 2019-06-15 17:35:57 +0000
@@ -26,6 +26,7 @@
26 transform,26 transform,
27 )27 )
28from breezy.osutils import has_symlinks28from breezy.osutils import has_symlinks
29from breezy.tree import TreeChange
29from breezy.tests.per_intertree import TestCaseWithTwoTrees30from breezy.tests.per_intertree import TestCaseWithTwoTrees
30from breezy.tests import (31from breezy.tests import (
31 features,32 features,
@@ -50,10 +51,9 @@
5051
51def _change_key(change):52def _change_key(change):
52 """Return a valid key for sorting Tree.iter_changes entries."""53 """Return a valid key for sorting Tree.iter_changes entries."""
53 (file_id, paths, content_changed, versioned, parent, name, kind,54 return (change.file_id or b'', (change.path[0] or '', change.path[1] or ''),
54 executable) = change55 change.versioned, change.parent_id, change.name, change.kind,
55 return (file_id or b'', (paths[0] or '', paths[1] or ''), versioned,56 change.executable)
56 parent, name, kind, executable)
5757
5858
59class TestCompare(TestCaseWithTwoTrees):59class TestCompare(TestCaseWithTwoTrees):
@@ -553,9 +553,10 @@
553553
554 def added(self, tree, file_id):554 def added(self, tree, file_id):
555 path, entry = self.get_path_entry(tree, file_id)555 path, entry = self.get_path_entry(tree, file_id)
556 return (file_id, (None, path), True, (False, True), (None, entry.parent_id),556 return TreeChange(
557 (None, entry.name), (None, entry.kind),557 file_id, (None, path), True, (False, True), (None, entry.parent_id),
558 (None, entry.executable))558 (None, entry.name), (None, entry.kind),
559 (None, entry.executable))
559560
560 @staticmethod561 @staticmethod
561 def get_path_entry(tree, file_id):562 def get_path_entry(tree, file_id):
@@ -569,43 +570,48 @@
569570
570 def content_changed(self, tree, file_id):571 def content_changed(self, tree, file_id):
571 path, entry = self.get_path_entry(tree, file_id)572 path, entry = self.get_path_entry(tree, file_id)
572 return (file_id, (path, path), True, (True, True),573 return TreeChange(
573 (entry.parent_id, entry.parent_id),574 file_id, (path, path), True, (True, True),
574 (entry.name, entry.name), (entry.kind, entry.kind),575 (entry.parent_id, entry.parent_id),
575 (entry.executable, entry.executable))576 (entry.name, entry.name), (entry.kind, entry.kind),
577 (entry.executable, entry.executable))
576578
577 def kind_changed(self, from_tree, to_tree, file_id):579 def kind_changed(self, from_tree, to_tree, file_id):
578 from_path, old_entry = self.get_path_entry(from_tree, file_id)580 from_path, old_entry = self.get_path_entry(from_tree, file_id)
579 path, new_entry = self.get_path_entry(to_tree, file_id)581 path, new_entry = self.get_path_entry(to_tree, file_id)
580 return (file_id, (from_path, path), True, (True, True),582 return TreeChange(
581 (old_entry.parent_id, new_entry.parent_id),583 file_id, (from_path, path), True, (True, True),
582 (old_entry.name, new_entry.name),584 (old_entry.parent_id, new_entry.parent_id),
583 (old_entry.kind, new_entry.kind),585 (old_entry.name, new_entry.name),
584 (old_entry.executable, new_entry.executable))586 (old_entry.kind, new_entry.kind),
587 (old_entry.executable, new_entry.executable))
585588
586 def missing(self, file_id, from_path, to_path, parent_id, kind):589 def missing(self, file_id, from_path, to_path, parent_id, kind):
587 _, from_basename = os.path.split(from_path)590 _, from_basename = os.path.split(from_path)
588 _, to_basename = os.path.split(to_path)591 _, to_basename = os.path.split(to_path)
589 # missing files have both paths, but no kind.592 # missing files have both paths, but no kind.
590 return (file_id, (from_path, to_path), True, (True, True),593 return TreeChange(
591 (parent_id, parent_id),594 file_id, (from_path, to_path), True, (True, True),
592 (from_basename, to_basename), (kind, None), (False, False))595 (parent_id, parent_id),
596 (from_basename, to_basename), (kind, None), (False, False))
593597
594 def deleted(self, tree, file_id):598 def deleted(self, tree, file_id):
595 entry = tree.root_inventory.get_entry(file_id)599 entry = tree.root_inventory.get_entry(file_id)
596 path = tree.id2path(file_id)600 path = tree.id2path(file_id)
597 return (file_id, (path, None), True, (True, False), (entry.parent_id, None),601 return TreeChange(
598 (entry.name, None), (entry.kind, None),602 file_id, (path, None), True, (True, False), (entry.parent_id, None),
599 (entry.executable, None))603 (entry.name, None), (entry.kind, None),
604 (entry.executable, None))
600605
601 def renamed(self, from_tree, to_tree, file_id, content_changed):606 def renamed(self, from_tree, to_tree, file_id, content_changed):
602 from_path, from_entry = self.get_path_entry(from_tree, file_id)607 from_path, from_entry = self.get_path_entry(from_tree, file_id)
603 to_path, to_entry = self.get_path_entry(to_tree, file_id)608 to_path, to_entry = self.get_path_entry(to_tree, file_id)
604 return (file_id, (from_path, to_path), content_changed, (True, True),609 return TreeChange(
605 (from_entry.parent_id, to_entry.parent_id),610 file_id, (from_path, to_path), content_changed, (True, True),
606 (from_entry.name, to_entry.name),611 (from_entry.parent_id, to_entry.parent_id),
607 (from_entry.kind, to_entry.kind),612 (from_entry.name, to_entry.name),
608 (from_entry.executable, to_entry.executable))613 (from_entry.kind, to_entry.kind),
614 (from_entry.executable, to_entry.executable))
609615
610 def unchanged(self, tree, file_id):616 def unchanged(self, tree, file_id):
611 path, entry = self.get_path_entry(tree, file_id)617 path, entry = self.get_path_entry(tree, file_id)
@@ -613,17 +619,19 @@
613 name = entry.name619 name = entry.name
614 kind = entry.kind620 kind = entry.kind
615 executable = entry.executable621 executable = entry.executable
616 return (file_id, (path, path), False, (True, True),622 return TreeChange(
617 (parent, parent), (name, name), (kind, kind),623 file_id, (path, path), False, (True, True),
618 (executable, executable))624 (parent, parent), (name, name), (kind, kind),
625 (executable, executable))
619626
620 def unversioned(self, tree, path):627 def unversioned(self, tree, path):
621 """Create an unversioned result."""628 """Create an unversioned result."""
622 _, basename = os.path.split(path)629 _, basename = os.path.split(path)
623 kind = tree._comparison_data(None, path)[0]630 kind = tree._comparison_data(None, path)[0]
624 return (None, (None, path), True, (False, False), (None, None),631 return TreeChange(
625 (None, basename), (None, kind),632 None, (None, path), True, (False, False), (None, None),
626 (None, False))633 (None, basename), (None, kind),
634 (None, False))
627635
628 def sorted(self, changes):636 def sorted(self, changes):
629 return sorted(changes, key=_change_key)637 return sorted(changes, key=_change_key)
@@ -1086,8 +1094,9 @@
1086 tree1, tree2 = self.mutable_trees_to_locked_test_trees(tree1, tree2)1094 tree1, tree2 = self.mutable_trees_to_locked_test_trees(tree1, tree2)
1087 self.not_applicable_if_missing_in('file', tree1)1095 self.not_applicable_if_missing_in('file', tree1)
1088 root_id = tree1.path2id('')1096 root_id = tree1.path2id('')
1089 expected = [(b'file-id', ('file', None), False, (True, False),1097 expected = [
1090 (root_id, None), ('file', None), (None, None), (False, None))]1098 TreeChange(b'file-id', ('file', None), False, (True, False),
1099 (root_id, None), ('file', None), (None, None), (False, None))]
1091 self.assertEqual(expected, self.do_iter_changes(tree1, tree2))1100 self.assertEqual(expected, self.do_iter_changes(tree1, tree2))
10921101
1093 def test_only_in_target_and_missing(self):1102 def test_only_in_target_and_missing(self):
@@ -1100,8 +1109,9 @@
1100 tree1, tree2 = self.mutable_trees_to_locked_test_trees(tree1, tree2)1109 tree1, tree2 = self.mutable_trees_to_locked_test_trees(tree1, tree2)
1101 self.not_applicable_if_missing_in('file', tree2)1110 self.not_applicable_if_missing_in('file', tree2)
1102 root_id = tree1.path2id('')1111 root_id = tree1.path2id('')
1103 expected = [(b'file-id', (None, 'file'), False, (False, True),1112 expected = [
1104 (None, root_id), (None, 'file'), (None, None), (None, False))]1113 TreeChange(b'file-id', (None, 'file'), False, (False, True),
1114 (None, root_id), (None, 'file'), (None, None), (None, False))]
1105 self.assertEqual(expected, self.do_iter_changes(tree1, tree2))1115 self.assertEqual(expected, self.do_iter_changes(tree1, tree2))
11061116
1107 def test_only_in_target_missing_subtree_specific_bug_367632(self):1117 def test_only_in_target_missing_subtree_specific_bug_367632(self):
@@ -1116,10 +1126,12 @@
1116 self.not_applicable_if_missing_in('a-dir', tree2)1126 self.not_applicable_if_missing_in('a-dir', tree2)
1117 root_id = tree1.path2id('')1127 root_id = tree1.path2id('')
1118 expected = [1128 expected = [
1119 (b'dir-id', (None, 'a-dir'), False, (False, True),1129 TreeChange(
1120 (None, root_id), (None, 'a-dir'), (None, None), (None, False)),1130 b'dir-id', (None, 'a-dir'), False, (False, True),
1121 (b'file-id', (None, 'a-dir/a-file'), False, (False, True),1131 (None, root_id), (None, 'a-dir'), (None, None), (None, False)),
1122 (None, b'dir-id'), (None, 'a-file'), (None, None), (None, False))1132 TreeChange(
1133 b'file-id', (None, 'a-dir/a-file'), False, (False, True),
1134 (None, b'dir-id'), (None, 'a-file'), (None, None), (None, False))
1123 ]1135 ]
1124 # bug 367632 showed that specifying the root broke some code paths,1136 # bug 367632 showed that specifying the root broke some code paths,
1125 # so we check this contract with and without it.1137 # so we check this contract with and without it.
@@ -1136,10 +1148,11 @@
1136 tree1, tree2 = self.mutable_trees_to_locked_test_trees(tree1, tree2)1148 tree1, tree2 = self.mutable_trees_to_locked_test_trees(tree1, tree2)
1137 self.assertEqual(sorted([self.unchanged(tree1, b'root-id'),1149 self.assertEqual(sorted([self.unchanged(tree1, b'root-id'),
1138 self.unchanged(tree1, b'b-id'),1150 self.unchanged(tree1, b'b-id'),
1139 (b'a-id', ('a', 'd'), True, (True, True),1151 TreeChange(
1140 (b'root-id', b'root-id'), ('a',1152 b'a-id', ('a', 'd'), True, (True, True),
1141 'd'), ('file', 'file'),1153 (b'root-id', b'root-id'), ('a', 'd'),
1142 (False, False)), self.unchanged(tree1, b'c-id')]),1154 ('file', 'file'),
1155 (False, False)), self.unchanged(tree1, b'c-id')]),
1143 self.do_iter_changes(tree1, tree2, include_unchanged=True))1156 self.do_iter_changes(tree1, tree2, include_unchanged=True))
11441157
1145 def test_compare_subtrees(self):1158 def test_compare_subtrees(self):
@@ -1163,22 +1176,24 @@
1163 self.assertEqual([], list(tree2.iter_changes(tree1)))1176 self.assertEqual([], list(tree2.iter_changes(tree1)))
1164 subtree1.commit('commit', rev_id=b'commit-a')1177 subtree1.commit('commit', rev_id=b'commit-a')
1165 self.assertEqual([1178 self.assertEqual([
1166 (b'root-id',1179 TreeChange(
1167 (u'', u''),1180 b'root-id',
1168 False,1181 (u'', u''),
1169 (True, True),1182 False,
1170 (None, None),1183 (True, True),
1171 (u'', u''),1184 (None, None),
1172 ('directory', 'directory'),1185 (u'', u''),
1173 (False, False)),1186 ('directory', 'directory'),
1174 (b'subtree-id',1187 (False, False)),
1175 ('sub', 'sub',),1188 TreeChange(
1176 False,1189 b'subtree-id',
1177 (True, True),1190 ('sub', 'sub',),
1178 (b'root-id', b'root-id'),1191 False,
1179 ('sub', 'sub'),1192 (True, True),
1180 ('tree-reference', 'tree-reference'),1193 (b'root-id', b'root-id'),
1181 (False, False))],1194 ('sub', 'sub'),
1195 ('tree-reference', 'tree-reference'),
1196 (False, False))],
1182 list(tree2.iter_changes(tree1,1197 list(tree2.iter_changes(tree1,
1183 include_unchanged=True)))1198 include_unchanged=True)))
11841199
11851200
=== modified file 'breezy/tests/per_repository/test_check.py'
--- breezy/tests/per_repository/test_check.py 2018-11-11 04:08:32 +0000
+++ breezy/tests/per_repository/test_check.py 2019-06-15 17:35:57 +0000
@@ -20,6 +20,7 @@
20from breezy import (20from breezy import (
21 revision as _mod_revision,21 revision as _mod_revision,
22 )22 )
23from breezy.tree import TreeChange
23from breezy.tests.per_repository import TestCaseWithRepository24from breezy.tests.per_repository import TestCaseWithRepository
2425
2526
@@ -32,8 +33,9 @@
32 self.overrideEnv('BRZ_EMAIL', 'foo@sample.com')33 self.overrideEnv('BRZ_EMAIL', 'foo@sample.com')
33 builder = branch.get_commit_builder([], branch.get_config_stack())34 builder = branch.get_commit_builder([], branch.get_config_stack())
34 list(builder.record_iter_changes(None, _mod_revision.NULL_REVISION, [35 list(builder.record_iter_changes(None, _mod_revision.NULL_REVISION, [
35 (b'TREE_ROOT', (None, ''), True, (False, True), (None, None),36 TreeChange(
36 (None, ''), (None, 'directory'), (None, False))]))37 b'TREE_ROOT', (None, ''), True, (False, True), (None, None),
38 (None, ''), (None, 'directory'), (None, False))]))
37 builder.finish_inventory()39 builder.finish_inventory()
38 rev_id = builder.commit('first post')40 rev_id = builder.commit('first post')
39 result = branch.repository.check(None, check_repo=True)41 result = branch.repository.check(None, check_repo=True)
4042
=== modified file 'breezy/tests/per_repository/test_commit_builder.py'
--- breezy/tests/per_repository/test_commit_builder.py 2018-11-25 20:44:56 +0000
+++ breezy/tests/per_repository/test_commit_builder.py 2019-06-15 17:35:57 +0000
@@ -26,6 +26,7 @@
26 revision as _mod_revision,26 revision as _mod_revision,
27 tests,27 tests,
28 )28 )
29from breezy.tree import TreeChange
29from breezy.bzr import (30from breezy.bzr import (
30 inventorytree,31 inventorytree,
31 )32 )
@@ -193,10 +194,11 @@
193 with tree.lock_write():194 with tree.lock_write():
194 builder = tree.branch.get_commit_builder([rev_id])195 builder = tree.branch.get_commit_builder([rev_id])
195 try:196 try:
196 delete_change = (foo_id, ('foo', None), True, (True, False),197 delete_change = TreeChange(
197 (tree.path2id(''), None), ('foo',198 foo_id, ('foo', None), True, (True, False),
198 None), ('file', None),199 (tree.path2id(''), None),
199 (False, None))200 ('foo', None), ('file', None),
201 (False, None))
200 list(builder.record_iter_changes(tree, rev_id,202 list(builder.record_iter_changes(tree, rev_id,
201 [delete_change]))203 [delete_change]))
202 self.assertEqual(("foo", None, foo_id, None),204 self.assertEqual(("foo", None, foo_id, None),
203205
=== modified file 'breezy/tests/test__dirstate_helpers.py'
--- breezy/tests/test__dirstate_helpers.py 2019-06-03 21:25:01 +0000
+++ breezy/tests/test__dirstate_helpers.py 2019-06-15 17:35:57 +0000
@@ -1260,7 +1260,7 @@
1260 state._sha1_provider = UppercaseSHA1Provider()1260 state._sha1_provider = UppercaseSHA1Provider()
1261 # If we used the standard provider, it would look like nothing has1261 # If we used the standard provider, it would look like nothing has
1262 # changed1262 # changed
1263 file_ids_changed = [change[0] for change1263 file_ids_changed = [change.file_id for change
1264 in tree.iter_changes(tree.basis_tree())]1264 in tree.iter_changes(tree.basis_tree())]
1265 self.assertEqual([b'a-file-id'], file_ids_changed)1265 self.assertEqual([b'a-file-id'], file_ids_changed)
12661266
@@ -1291,12 +1291,9 @@
1291 self.overrideAttr(dirstate, '_process_entry', self._process_entry)1291 self.overrideAttr(dirstate, '_process_entry', self._process_entry)
12921292
1293 def assertChangedFileIds(self, expected, tree):1293 def assertChangedFileIds(self, expected, tree):
1294 tree.lock_read()1294 with tree.lock_read():
1295 try:1295 file_ids = [info.file_id for info
1296 file_ids = [info[0] for info
1297 in tree.iter_changes(tree.basis_tree())]1296 in tree.iter_changes(tree.basis_tree())]
1298 finally:
1299 tree.unlock()
1300 self.assertEqual(sorted(expected), sorted(file_ids))1297 self.assertEqual(sorted(expected), sorted(file_ids))
13011298
1302 def test_exceptions_raised(self):1299 def test_exceptions_raised(self):
13031300
=== modified file 'breezy/tests/test_commit.py'
--- breezy/tests/test_commit.py 2019-06-03 23:24:45 +0000
+++ breezy/tests/test_commit.py 2019-06-15 17:35:57 +0000
@@ -38,6 +38,7 @@
38 BzrError,38 BzrError,
39 LockContention,39 LockContention,
40 )40 )
41from ..tree import TreeChange
41from . import (42from . import (
42 TestCase,43 TestCase,
43 TestCaseWithTransport,44 TestCaseWithTransport,
@@ -894,30 +895,34 @@
894895
895 def test_add_file_not_excluded(self):896 def test_add_file_not_excluded(self):
896 changes = [897 changes = [
897 ('fid', (None, 'newpath'),898 TreeChange(
898 0, (False, False), ('pid', 'pid'), ('newpath', 'newpath'),899 'fid', (None, 'newpath'),
899 ('file', 'file'), (True, True))]900 0, (False, False), ('pid', 'pid'), ('newpath', 'newpath'),
901 ('file', 'file'), (True, True))]
900 self.assertEqual(changes, list(902 self.assertEqual(changes, list(
901 filter_excluded(changes, ['otherpath'])))903 filter_excluded(changes, ['otherpath'])))
902904
903 def test_add_file_excluded(self):905 def test_add_file_excluded(self):
904 changes = [906 changes = [
905 ('fid', (None, 'newpath'),907 TreeChange(
906 0, (False, False), ('pid', 'pid'), ('newpath', 'newpath'),908 'fid', (None, 'newpath'),
907 ('file', 'file'), (True, True))]909 0, (False, False), ('pid', 'pid'), ('newpath', 'newpath'),
910 ('file', 'file'), (True, True))]
908 self.assertEqual([], list(filter_excluded(changes, ['newpath'])))911 self.assertEqual([], list(filter_excluded(changes, ['newpath'])))
909912
910 def test_delete_file_excluded(self):913 def test_delete_file_excluded(self):
911 changes = [914 changes = [
912 ('fid', ('somepath', None),915 TreeChange(
913 0, (False, None), ('pid', None), ('newpath', None),916 'fid', ('somepath', None),
914 ('file', None), (True, None))]917 0, (False, None), ('pid', None), ('newpath', None),
918 ('file', None), (True, None))]
915 self.assertEqual([], list(filter_excluded(changes, ['somepath'])))919 self.assertEqual([], list(filter_excluded(changes, ['somepath'])))
916920
917 def test_move_from_or_to_excluded(self):921 def test_move_from_or_to_excluded(self):
918 changes = [922 changes = [
919 ('fid', ('oldpath', 'newpath'),923 TreeChange(
920 0, (False, False), ('pid', 'pid'), ('oldpath', 'newpath'),924 'fid', ('oldpath', 'newpath'),
921 ('file', 'file'), (True, True))]925 0, (False, False), ('pid', 'pid'), ('oldpath', 'newpath'),
926 ('file', 'file'), (True, True))]
922 self.assertEqual([], list(filter_excluded(changes, ['oldpath'])))927 self.assertEqual([], list(filter_excluded(changes, ['oldpath'])))
923 self.assertEqual([], list(filter_excluded(changes, ['newpath'])))928 self.assertEqual([], list(filter_excluded(changes, ['newpath'])))
924929
=== modified file 'breezy/tests/test_transform.py'
--- breezy/tests/test_transform.py 2019-06-03 23:45:30 +0000
+++ breezy/tests/test_transform.py 2019-06-15 17:35:57 +0000
@@ -2838,7 +2838,7 @@
2838 self.addCleanup(preview.finalize)2838 self.addCleanup(preview.finalize)
2839 preview.delete_versioned(preview.trans_id_tree_path('foo'))2839 preview.delete_versioned(preview.trans_id_tree_path('foo'))
2840 preview_tree = preview.get_preview_tree()2840 preview_tree = preview.get_preview_tree()
2841 out = StringIO()2841 out = BytesIO()
2842 log = BytesIO()2842 log = BytesIO()
2843 trace.push_log_file(log)2843 trace.push_log_file(log)
2844 os_symlink = getattr(os, 'symlink', None)2844 os_symlink = getattr(os, 'symlink', None)
@@ -2847,8 +2847,7 @@
2847 show_diff_trees(revision_tree, preview_tree, out)2847 show_diff_trees(revision_tree, preview_tree, out)
2848 lines = out.getvalue().splitlines()2848 lines = out.getvalue().splitlines()
2849 finally:2849 finally:
2850 if os_symlink:2850 os.symlink = os_symlink
2851 os.symlink = os_symlink
2852 self.assertContainsRe(2851 self.assertContainsRe(
2853 log.getvalue(),2852 log.getvalue(),
2854 b'Ignoring "foo" as symlinks are not supported on this filesystem')2853 b'Ignoring "foo" as symlinks are not supported on this filesystem')
28552854
=== modified file 'breezy/transform.py'
--- breezy/transform.py 2019-03-04 01:44:35 +0000
+++ breezy/transform.py 2019-06-15 17:35:57 +0000
@@ -71,6 +71,7 @@
71 )71 )
72from .tree import (72from .tree import (
73 find_previous_path,73 find_previous_path,
74 TreeChange,
74 )75 )
7576
7677
@@ -1002,16 +1003,17 @@
1002 and from_parent == to_parent and from_name == to_name1003 and from_parent == to_parent and from_name == to_name
1003 and from_executable == to_executable):1004 and from_executable == to_executable):
1004 continue1005 continue
1005 results.append((file_id, (from_path, to_path), modified,1006 results.append(
1006 (from_versioned, to_versioned),1007 TreeChange(
1007 (from_parent, to_parent),1008 file_id, (from_path, to_path), modified,
1008 (from_name, to_name),1009 (from_versioned, to_versioned),
1009 (from_kind, to_kind),1010 (from_parent, to_parent),
1010 (from_executable, to_executable)))1011 (from_name, to_name),
1012 (from_kind, to_kind),
1013 (from_executable, to_executable)))
10111014
1012 def path_key(t):1015 def path_key(c):
1013 paths = t[1]1016 return (c.path[0] or '', c.path[1] or '')
1014 return (paths[0] or '', paths[1] or '')
1015 return iter(sorted(results, key=path_key))1017 return iter(sorted(results, key=path_key))
10161018
1017 def get_preview_tree(self):1019 def get_preview_tree(self):
@@ -1991,7 +1993,7 @@
1991 self._all_children_cache = {}1993 self._all_children_cache = {}
1992 self._path2trans_id_cache = {}1994 self._path2trans_id_cache = {}
1993 self._final_name_cache = {}1995 self._final_name_cache = {}
1994 self._iter_changes_cache = dict((c[0], c) for c in1996 self._iter_changes_cache = dict((c.file_id, c) for c in
1995 self._transform.iter_changes())1997 self._transform.iter_changes())
19961998
1997 def _content_change(self, file_id):1999 def _content_change(self, file_id):
@@ -2413,8 +2415,8 @@
2413 if changes is None:2415 if changes is None:
2414 get_old = True2416 get_old = True
2415 else:2417 else:
2416 changed_content, versioned, kind = (changes[2], changes[3],2418 changed_content, versioned, kind = (
2417 changes[6])2419 changes.changed_content, changes.versioned, changes.kind)
2418 if kind[1] is None:2420 if kind[1] is None:
2419 return None2421 return None
2420 get_old = (kind[0] == 'file' and versioned[0])2422 get_old = (kind[0] == 'file' and versioned[0])
@@ -2693,8 +2695,9 @@
2693 new_desired_files = desired_files2695 new_desired_files = desired_files
2694 else:2696 else:
2695 iter = accelerator_tree.iter_changes(tree, include_unchanged=True)2697 iter = accelerator_tree.iter_changes(tree, include_unchanged=True)
2696 unchanged = [(p[0], p[1]) for (f, p, c, v, d, n, k, e)2698 unchanged = [
2697 in iter if not (c or e[0] != e[1])]2699 change.path for change in iter
2700 if not (change.changed_content or change.executable[0] != change.executable[1])]
2698 if accelerator_tree.supports_content_filtering():2701 if accelerator_tree.supports_content_filtering():
2699 unchanged = [(tp, ap) for (tp, ap) in unchanged2702 unchanged = [(tp, ap) for (tp, ap) in unchanged
2700 if not next(accelerator_tree.iter_search_rules([ap]))]2703 if not next(accelerator_tree.iter_search_rules([ap]))]
@@ -2907,19 +2910,19 @@
2907 skip_root = False2910 skip_root = False
2908 try:2911 try:
2909 deferred_files = []2912 deferred_files = []
2910 for id_num, (file_id, path, changed_content, versioned, parent, name,2913 for id_num, change in enumerate(change_list):
2911 kind, executable) in enumerate(change_list):2914 file_id = change.file_id
2912 target_path, wt_path = path2915 target_path, wt_path = change.path
2913 target_versioned, wt_versioned = versioned2916 target_versioned, wt_versioned = change.versioned
2914 target_parent, wt_parent = parent2917 target_parent, wt_parent = change.parent_id
2915 target_name, wt_name = name2918 target_name, wt_name = change.name
2916 target_kind, wt_kind = kind2919 target_kind, wt_kind = change.kind
2917 target_executable, wt_executable = executable2920 target_executable, wt_executable = change.executable
2918 if skip_root and wt_parent is None:2921 if skip_root and wt_parent is None:
2919 continue2922 continue
2920 trans_id = tt.trans_id_file_id(file_id)2923 trans_id = tt.trans_id_file_id(file_id)
2921 mode_id = None2924 mode_id = None
2922 if changed_content:2925 if change.changed_content:
2923 keep_content = False2926 keep_content = False
2924 if wt_kind == 'file' and (backups or target_kind is None):2927 if wt_kind == 'file' and (backups or target_kind is None):
2925 wt_sha1 = working_tree.get_file_sha1(wt_path)2928 wt_sha1 = working_tree.get_file_sha1(wt_path)
@@ -3231,18 +3234,16 @@
3231 """3234 """
3232 tt = TreeTransform(target_tree)3235 tt = TreeTransform(target_tree)
3233 try:3236 try:
3234 for (file_id, paths, changed_content, versioned, parent, name, kind,3237 for change in target_tree.iter_changes(source_tree, include_unchanged=True):
3235 executable) in target_tree.iter_changes(source_tree,3238 if change.changed_content:
3236 include_unchanged=True):3239 continue
3237 if changed_content:3240 if change.kind != ('file', 'file'):
3238 continue3241 continue
3239 if kind != ('file', 'file'):3242 if change.executable[0] != change.executable[1]:
3240 continue3243 continue
3241 if executable[0] != executable[1]:3244 trans_id = tt.trans_id_tree_path(change.path[1])
3242 continue
3243 trans_id = tt.trans_id_tree_path(paths[1])
3244 tt.delete_contents(trans_id)3245 tt.delete_contents(trans_id)
3245 tt.create_hardlink(source_tree.abspath(paths[0]), trans_id)3246 tt.create_hardlink(source_tree.abspath(change.path[0]), trans_id)
3246 tt.apply()3247 tt.apply()
3247 finally:3248 finally:
3248 tt.finalize()3249 tt.finalize()
32493250
=== modified file 'breezy/tree.py'
--- breezy/tree.py 2019-06-15 15:17:02 +0000
+++ breezy/tree.py 2019-06-15 17:35:57 +0000
@@ -153,11 +153,21 @@
153 return tuple(self) == other153 return tuple(self) == other
154 return False154 return False
155155
156 def __lt__(self, other):
157 return tuple(self) < tuple(other)
158
156 def __getitem__(self, i):159 def __getitem__(self, i):
157 if isinstance(i, slice):160 if isinstance(i, slice):
158 return tuple(self).__getitem__(i)161 return tuple(self).__getitem__(i)
159 return getattr(self, self.__slots__[i])162 return getattr(self, self.__slots__[i])
160163
164 def discard_new(self):
165 return self.__class__(
166 self.file_id, (self.path[0], None), self.changed_content,
167 (self.versioned[0], None), (self.parent_id[0], None),
168 (self.name[0], None), (self.kind[0], None),
169 (self.executable[0], None))
170
161171
162class Tree(object):172class Tree(object):
163 """Abstract file tree.173 """Abstract file tree.
@@ -1094,18 +1104,18 @@
1094 new_parent_id = result[4][1]1104 new_parent_id = result[4][1]
1095 precise_file_ids.add(new_parent_id)1105 precise_file_ids.add(new_parent_id)
1096 if changes:1106 if changes:
1097 if (result[6][0] == 'directory' and1107 if (result.kind[0] == 'directory' and
1098 result[6][1] != 'directory'):1108 result.kind[1] != 'directory'):
1099 # This stopped being a directory, the old children have1109 # This stopped being a directory, the old children have
1100 # to be included.1110 # to be included.
1101 if source_entry is None:1111 if source_entry is None:
1102 # Reusing a discarded change.1112 # Reusing a discarded change.
1103 source_entry = self._get_entry(1113 source_entry = self._get_entry(
1104 self.source, result[1][0])1114 self.source, result.path[0])
1105 precise_file_ids.update(1115 precise_file_ids.update(
1106 child.file_id1116 child.file_id
1107 for child in self.source.iter_child_entries(result[1][0]))1117 for child in self.source.iter_child_entries(result.path[0]))
1108 changed_file_ids.add(result[0])1118 changed_file_ids.add(result.file_id)
1109 yield result1119 yield result
11101120
1111 def file_content_matches(1121 def file_content_matches(

Subscribers

People subscribed via source and target branches