/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

Viewing changes to breezy/transform.py

  • Committer: Jelmer Vernooij
  • Date: 2020-09-02 15:11:17 UTC
  • mto: (7490.40.109 work)
  • mto: This revision was merged to the branch mainline in revision 7526.
  • Revision ID: jelmer@jelmer.uk-20200902151117-jeu7tarbz3dkuju0
Move more transform code.

Show diffs side-by-side

added added

removed removed

Lines of Context:
766
766
        tt.set_executability(entry.executable, trans_id)
767
767
 
768
768
 
769
 
def revert(working_tree, target_tree, filenames, backups=False,
770
 
           pb=None, change_reporter=None):
771
 
    """Revert a working tree's contents to those of a target tree."""
772
 
    pb = ui.ui_factory.nested_progress_bar()
773
 
    try:
774
 
        with target_tree.lock_read(), working_tree.transform(pb) as tt:
775
 
            pp = ProgressPhase("Revert phase", 3, pb)
776
 
            conflicts, merge_modified = _prepare_revert_transform(
777
 
                working_tree, target_tree, tt, filenames, backups, pp)
778
 
            if change_reporter:
779
 
                from . import delta
780
 
                change_reporter = delta._ChangeReporter(
781
 
                    unversioned_filter=working_tree.is_ignored)
782
 
                delta.report_changes(tt.iter_changes(), change_reporter)
783
 
            for conflict in conflicts:
784
 
                trace.warning(text_type(conflict))
785
 
            pp.next_phase()
786
 
            tt.apply()
787
 
            if working_tree.supports_merge_modified():
788
 
                working_tree.set_merge_modified(merge_modified)
789
 
    finally:
790
 
        pb.clear()
791
 
    return conflicts
792
 
 
793
 
 
794
 
def _prepare_revert_transform(working_tree, target_tree, tt, filenames,
 
769
def _prepare_revert_transform(es, working_tree, target_tree, tt, filenames,
795
770
                              backups, pp, basis_tree=None,
796
771
                              merge_modified=None):
797
772
    with ui.ui_factory.nested_progress_bar() as child_pb:
798
773
        if merge_modified is None:
799
774
            merge_modified = working_tree.merge_modified()
800
 
        merge_modified = _alter_files(working_tree, target_tree, tt,
 
775
        merge_modified = _alter_files(es, working_tree, target_tree, tt,
801
776
                                      child_pb, filenames, backups,
802
777
                                      merge_modified, basis_tree)
803
778
    with ui.ui_factory.nested_progress_bar() as child_pb:
807
782
    return conflicts, merge_modified
808
783
 
809
784
 
810
 
def _alter_files(working_tree, target_tree, tt, pb, specific_files,
 
785
def revert(working_tree, target_tree, filenames, backups=False,
 
786
           pb=None, change_reporter=None, merge_modified=None, basis_tree=None):
 
787
    """Revert a working tree's contents to those of a target tree."""
 
788
    with cleanup.ExitStack() as es:
 
789
        pb = es.enter_context(ui.ui_factory.nested_progress_bar())
 
790
        es.enter_context(target_tree.lock_read())
 
791
        tt = es.enter_context(working_tree.transform(pb))
 
792
        pp = ProgressPhase("Revert phase", 3, pb)
 
793
        conflicts, merge_modified = _prepare_revert_transform(
 
794
            es, working_tree, target_tree, tt, filenames, backups, pp)
 
795
        if change_reporter:
 
796
            from . import delta
 
797
            change_reporter = delta._ChangeReporter(
 
798
                unversioned_filter=working_tree.is_ignored)
 
799
            delta.report_changes(tt.iter_changes(), change_reporter)
 
800
        for conflict in conflicts:
 
801
            trace.warning(text_type(conflict))
 
802
        pp.next_phase()
 
803
        tt.apply()
 
804
        if working_tree.supports_merge_modified():
 
805
            working_tree.set_merge_modified(merge_modified)
 
806
    return conflicts
 
807
 
 
808
 
 
809
def _alter_files(es, working_tree, target_tree, tt, pb, specific_files,
811
810
                 backups, merge_modified, basis_tree=None):
812
811
    if basis_tree is not None:
813
 
        basis_tree.lock_read()
 
812
        es.enter_context(basis_tree.lock_read())
814
813
    # We ask the working_tree for its changes relative to the target, rather
815
814
    # than the target changes relative to the working tree. Because WT4 has an
816
815
    # optimizer to compare itself to a target, but no optimizer for the
821
820
        skip_root = True
822
821
    else:
823
822
        skip_root = False
824
 
    try:
825
 
        deferred_files = []
826
 
        for id_num, change in enumerate(change_list):
827
 
            target_path, wt_path = change.path
828
 
            target_versioned, wt_versioned = change.versioned
829
 
            target_parent = change.parent_id[0]
830
 
            target_name, wt_name = change.name
831
 
            target_kind, wt_kind = change.kind
832
 
            target_executable, wt_executable = change.executable
833
 
            if skip_root and wt_path == '':
834
 
                continue
835
 
            trans_id = tt.trans_id_file_id(change.file_id)
836
 
            mode_id = None
837
 
            if change.changed_content:
838
 
                keep_content = False
839
 
                if wt_kind == 'file' and (backups or target_kind is None):
840
 
                    wt_sha1 = working_tree.get_file_sha1(wt_path)
841
 
                    if merge_modified.get(wt_path) != wt_sha1:
842
 
                        # acquire the basis tree lazily to prevent the
843
 
                        # expense of accessing it when it's not needed ?
844
 
                        # (Guessing, RBC, 200702)
845
 
                        if basis_tree is None:
846
 
                            basis_tree = working_tree.basis_tree()
847
 
                            basis_tree.lock_read()
848
 
                        basis_inter = InterTree.get(basis_tree, working_tree)
849
 
                        basis_path = basis_inter.find_source_path(wt_path)
850
 
                        if basis_path is None:
851
 
                            if target_kind is None and not target_versioned:
852
 
                                keep_content = True
853
 
                        else:
854
 
                            if wt_sha1 != basis_tree.get_file_sha1(basis_path):
855
 
                                keep_content = True
856
 
                if wt_kind is not None:
857
 
                    if not keep_content:
858
 
                        tt.delete_contents(trans_id)
859
 
                    elif target_kind is not None:
860
 
                        parent_trans_id = tt.trans_id_tree_path(osutils.dirname(wt_path))
861
 
                        backup_name = tt._available_backup_name(
862
 
                            wt_name, parent_trans_id)
863
 
                        tt.adjust_path(backup_name, parent_trans_id, trans_id)
864
 
                        new_trans_id = tt.create_path(wt_name, parent_trans_id)
865
 
                        if wt_versioned and target_versioned:
866
 
                            tt.unversion_file(trans_id)
867
 
                            tt.version_file(
868
 
                                new_trans_id, file_id=getattr(change, 'file_id', None))
869
 
                        # New contents should have the same unix perms as old
870
 
                        # contents
871
 
                        mode_id = trans_id
872
 
                        trans_id = new_trans_id
873
 
                if target_kind in ('directory', 'tree-reference'):
874
 
                    tt.create_directory(trans_id)
875
 
                    if target_kind == 'tree-reference':
876
 
                        revision = target_tree.get_reference_revision(
877
 
                            target_path)
878
 
                        tt.set_tree_reference(revision, trans_id)
879
 
                elif target_kind == 'symlink':
880
 
                    tt.create_symlink(target_tree.get_symlink_target(
881
 
                        target_path), trans_id)
882
 
                elif target_kind == 'file':
883
 
                    deferred_files.append(
884
 
                        (target_path, (trans_id, mode_id, target_path)))
 
823
    deferred_files = []
 
824
    for id_num, change in enumerate(change_list):
 
825
        target_path, wt_path = change.path
 
826
        target_versioned, wt_versioned = change.versioned
 
827
        target_parent = change.parent_id[0]
 
828
        target_name, wt_name = change.name
 
829
        target_kind, wt_kind = change.kind
 
830
        target_executable, wt_executable = change.executable
 
831
        if skip_root and wt_path == '':
 
832
            continue
 
833
        trans_id = tt.trans_id_file_id(change.file_id)
 
834
        mode_id = None
 
835
        if change.changed_content:
 
836
            keep_content = False
 
837
            if wt_kind == 'file' and (backups or target_kind is None):
 
838
                wt_sha1 = working_tree.get_file_sha1(wt_path)
 
839
                if merge_modified.get(wt_path) != wt_sha1:
 
840
                    # acquire the basis tree lazily to prevent the
 
841
                    # expense of accessing it when it's not needed ?
 
842
                    # (Guessing, RBC, 200702)
885
843
                    if basis_tree is None:
886
844
                        basis_tree = working_tree.basis_tree()
887
 
                        basis_tree.lock_read()
888
 
                    new_sha1 = target_tree.get_file_sha1(target_path)
889
 
                    basis_inter = InterTree.get(basis_tree, target_tree)
890
 
                    basis_path = basis_inter.find_source_path(target_path)
891
 
                    if (basis_path is not None and
892
 
                            new_sha1 == basis_tree.get_file_sha1(basis_path)):
893
 
                        # If the new contents of the file match what is in basis,
894
 
                        # then there is no need to store in merge_modified.
895
 
                        if basis_path in merge_modified:
896
 
                            del merge_modified[basis_path]
 
845
                        es.enter_context(basis_tree.lock_read())
 
846
                    basis_inter = InterTree.get(basis_tree, working_tree)
 
847
                    basis_path = basis_inter.find_source_path(wt_path)
 
848
                    if basis_path is None:
 
849
                        if target_kind is None and not target_versioned:
 
850
                            keep_content = True
897
851
                    else:
898
 
                        merge_modified[target_path] = new_sha1
899
 
 
900
 
                    # preserve the execute bit when backing up
901
 
                    if keep_content and wt_executable == target_executable:
902
 
                        tt.set_executability(target_executable, trans_id)
 
852
                        if wt_sha1 != basis_tree.get_file_sha1(basis_path):
 
853
                            keep_content = True
 
854
            if wt_kind is not None:
 
855
                if not keep_content:
 
856
                    tt.delete_contents(trans_id)
903
857
                elif target_kind is not None:
904
 
                    raise AssertionError(target_kind)
905
 
            if not wt_versioned and target_versioned:
906
 
                tt.version_file(
907
 
                    trans_id, file_id=getattr(change, 'file_id', None))
908
 
            if wt_versioned and not target_versioned:
909
 
                tt.unversion_file(trans_id)
910
 
            if (target_name is not None
911
 
                    and (wt_name != target_name or change.is_reparented())):
912
 
                if target_path == '':
913
 
                    parent_trans = ROOT_PARENT
914
 
                else:
915
 
                    parent_trans = tt.trans_id_file_id(target_parent)
916
 
                if wt_path == '' and wt_versioned:
917
 
                    tt.adjust_root_path(target_name, parent_trans)
918
 
                else:
919
 
                    tt.adjust_path(target_name, parent_trans, trans_id)
920
 
            if wt_executable != target_executable and target_kind == "file":
921
 
                tt.set_executability(target_executable, trans_id)
922
 
        if working_tree.supports_content_filtering():
923
 
            for (trans_id, mode_id, target_path), bytes in (
924
 
                    target_tree.iter_files_bytes(deferred_files)):
925
 
                # We're reverting a tree to the target tree so using the
926
 
                # target tree to find the file path seems the best choice
927
 
                # here IMO - Ian C 27/Oct/2009
928
 
                filters = working_tree._content_filter_stack(target_path)
929
 
                bytes = filtered_output_bytes(
930
 
                    bytes, filters,
931
 
                    ContentFilterContext(target_path, working_tree))
932
 
                tt.create_file(bytes, trans_id, mode_id)
933
 
        else:
934
 
            for (trans_id, mode_id, target_path), bytes in target_tree.iter_files_bytes(
935
 
                    deferred_files):
936
 
                tt.create_file(bytes, trans_id, mode_id)
937
 
        tt.fixup_new_roots()
938
 
    finally:
939
 
        if basis_tree is not None:
940
 
            basis_tree.unlock()
 
858
                    parent_trans_id = tt.trans_id_tree_path(osutils.dirname(wt_path))
 
859
                    backup_name = tt._available_backup_name(
 
860
                        wt_name, parent_trans_id)
 
861
                    tt.adjust_path(backup_name, parent_trans_id, trans_id)
 
862
                    new_trans_id = tt.create_path(wt_name, parent_trans_id)
 
863
                    if wt_versioned and target_versioned:
 
864
                        tt.unversion_file(trans_id)
 
865
                        tt.version_file(
 
866
                            new_trans_id, file_id=getattr(change, 'file_id', None))
 
867
                    # New contents should have the same unix perms as old
 
868
                    # contents
 
869
                    mode_id = trans_id
 
870
                    trans_id = new_trans_id
 
871
            if target_kind in ('directory', 'tree-reference'):
 
872
                tt.create_directory(trans_id)
 
873
                if target_kind == 'tree-reference':
 
874
                    revision = target_tree.get_reference_revision(
 
875
                        target_path)
 
876
                    tt.set_tree_reference(revision, trans_id)
 
877
            elif target_kind == 'symlink':
 
878
                tt.create_symlink(target_tree.get_symlink_target(
 
879
                    target_path), trans_id)
 
880
            elif target_kind == 'file':
 
881
                deferred_files.append(
 
882
                    (target_path, (trans_id, mode_id, target_path)))
 
883
                if basis_tree is None:
 
884
                    basis_tree = working_tree.basis_tree()
 
885
                    es.enter_context(basis_tree.lock_read())
 
886
                new_sha1 = target_tree.get_file_sha1(target_path)
 
887
                basis_inter = InterTree.get(basis_tree, target_tree)
 
888
                basis_path = basis_inter.find_source_path(target_path)
 
889
                if (basis_path is not None and
 
890
                        new_sha1 == basis_tree.get_file_sha1(basis_path)):
 
891
                    # If the new contents of the file match what is in basis,
 
892
                    # then there is no need to store in merge_modified.
 
893
                    if basis_path in merge_modified:
 
894
                        del merge_modified[basis_path]
 
895
                else:
 
896
                    merge_modified[target_path] = new_sha1
 
897
 
 
898
                # preserve the execute bit when backing up
 
899
                if keep_content and wt_executable == target_executable:
 
900
                    tt.set_executability(target_executable, trans_id)
 
901
            elif target_kind is not None:
 
902
                raise AssertionError(target_kind)
 
903
        if not wt_versioned and target_versioned:
 
904
            tt.version_file(
 
905
                trans_id, file_id=getattr(change, 'file_id', None))
 
906
        if wt_versioned and not target_versioned:
 
907
            tt.unversion_file(trans_id)
 
908
        if (target_name is not None
 
909
                and (wt_name != target_name or change.is_reparented())):
 
910
            if target_path == '':
 
911
                parent_trans = ROOT_PARENT
 
912
            else:
 
913
                parent_trans = tt.trans_id_file_id(target_parent)
 
914
            if wt_path == '' and wt_versioned:
 
915
                tt.adjust_root_path(target_name, parent_trans)
 
916
            else:
 
917
                tt.adjust_path(target_name, parent_trans, trans_id)
 
918
        if wt_executable != target_executable and target_kind == "file":
 
919
            tt.set_executability(target_executable, trans_id)
 
920
    if working_tree.supports_content_filtering():
 
921
        for (trans_id, mode_id, target_path), bytes in (
 
922
                target_tree.iter_files_bytes(deferred_files)):
 
923
            # We're reverting a tree to the target tree so using the
 
924
            # target tree to find the file path seems the best choice
 
925
            # here IMO - Ian C 27/Oct/2009
 
926
            filters = working_tree._content_filter_stack(target_path)
 
927
            bytes = filtered_output_bytes(
 
928
                bytes, filters,
 
929
                ContentFilterContext(target_path, working_tree))
 
930
            tt.create_file(bytes, trans_id, mode_id)
 
931
    else:
 
932
        for (trans_id, mode_id, target_path), bytes in target_tree.iter_files_bytes(
 
933
                deferred_files):
 
934
            tt.create_file(bytes, trans_id, mode_id)
 
935
    tt.fixup_new_roots()
941
936
    return merge_modified
942
937
 
943
938