2857
2857
backups, merge_modified, basis_tree=None):
2858
2858
if basis_tree is not None:
2859
2859
basis_tree.lock_read()
2860
change_list = target_tree.iter_changes(working_tree,
2860
# We ask the working_tree for its changes relative to the target, rather
2861
# than the target changes relative to the working tree. Because WT4 has an
2862
# optimizer to compare itself to a target, but no optimizer for the
2864
change_list = working_tree.iter_changes(target_tree,
2861
2865
specific_files=specific_files, pb=pb)
2862
2866
if target_tree.get_root_id() is None:
2863
2867
skip_root = True
2867
2871
deferred_files = []
2868
2872
for id_num, (file_id, path, changed_content, versioned, parent, name,
2869
2873
kind, executable) in enumerate(change_list):
2870
if skip_root and file_id[0] is not None and parent[0] is None:
2874
target_path, wt_path = path
2875
target_versioned, wt_versioned = versioned
2876
target_parent, wt_parent = parent
2877
target_name, wt_name = name
2878
target_kind, wt_kind = kind
2879
target_executable, wt_executable = executable
2880
if skip_root and wt_parent is None:
2872
2882
trans_id = tt.trans_id_file_id(file_id)
2874
2884
if changed_content:
2875
2885
keep_content = False
2876
if kind[0] == 'file' and (backups or kind[1] is None):
2886
if wt_kind == 'file' and (backups or target_kind is None):
2877
2887
wt_sha1 = working_tree.get_file_sha1(file_id)
2878
2888
if merge_modified.get(file_id) != wt_sha1:
2879
2889
# acquire the basis tree lazily to prevent the
2885
2895
if file_id in basis_tree:
2886
2896
if wt_sha1 != basis_tree.get_file_sha1(file_id):
2887
2897
keep_content = True
2888
elif kind[1] is None and not versioned[1]:
2898
elif target_kind is None and not target_versioned:
2889
2899
keep_content = True
2890
if kind[0] is not None:
2900
if wt_kind is not None:
2891
2901
if not keep_content:
2892
2902
tt.delete_contents(trans_id)
2893
elif kind[1] is not None:
2894
parent_trans_id = tt.trans_id_file_id(parent[0])
2903
elif target_kind is not None:
2904
parent_trans_id = tt.trans_id_file_id(wt_parent)
2895
2905
backup_name = tt._available_backup_name(
2896
name[0], parent_trans_id)
2906
wt_name, parent_trans_id)
2897
2907
tt.adjust_path(backup_name, parent_trans_id, trans_id)
2898
new_trans_id = tt.create_path(name[0], parent_trans_id)
2899
if versioned == (True, True):
2908
new_trans_id = tt.create_path(wt_name, parent_trans_id)
2909
if wt_versioned and target_versioned:
2900
2910
tt.unversion_file(trans_id)
2901
2911
tt.version_file(file_id, new_trans_id)
2902
2912
# New contents should have the same unix perms as old
2904
2914
mode_id = trans_id
2905
2915
trans_id = new_trans_id
2906
if kind[1] in ('directory', 'tree-reference'):
2916
if target_kind in ('directory', 'tree-reference'):
2907
2917
tt.create_directory(trans_id)
2908
if kind[1] == 'tree-reference':
2918
if target_kind == 'tree-reference':
2909
2919
revision = target_tree.get_reference_revision(file_id,
2911
2921
tt.set_tree_reference(revision, trans_id)
2912
elif kind[1] == 'symlink':
2922
elif target_kind == 'symlink':
2913
2923
tt.create_symlink(target_tree.get_symlink_target(file_id),
2915
elif kind[1] == 'file':
2925
elif target_kind == 'file':
2916
2926
deferred_files.append((file_id, (trans_id, mode_id)))
2917
2927
if basis_tree is None:
2918
2928
basis_tree = working_tree.basis_tree()
2926
2936
merge_modified[file_id] = new_sha1
2928
2938
# preserve the execute bit when backing up
2929
if keep_content and executable[0] == executable[1]:
2930
tt.set_executability(executable[1], trans_id)
2931
elif kind[1] is not None:
2932
raise AssertionError(kind[1])
2933
if versioned == (False, True):
2939
if keep_content and wt_executable == target_executable:
2940
tt.set_executability(target_executable, trans_id)
2941
elif target_kind is not None:
2942
raise AssertionError(target_kind)
2943
if not wt_versioned and target_versioned:
2934
2944
tt.version_file(file_id, trans_id)
2935
if versioned == (True, False):
2945
if wt_versioned and not target_versioned:
2936
2946
tt.unversion_file(trans_id)
2937
if (name[1] is not None and
2938
(name[0] != name[1] or parent[0] != parent[1])):
2939
if name[1] == '' and parent[1] is None:
2947
if (target_name is not None and
2948
(wt_name != target_name or wt_parent != target_parent)):
2949
if target_name == '' and target_parent is None:
2940
2950
parent_trans = ROOT_PARENT
2942
parent_trans = tt.trans_id_file_id(parent[1])
2943
if parent[0] is None and versioned[0]:
2944
tt.adjust_root_path(name[1], parent_trans)
2952
parent_trans = tt.trans_id_file_id(target_parent)
2953
if wt_parent is None and wt_versioned:
2954
tt.adjust_root_path(target_name, parent_trans)
2946
tt.adjust_path(name[1], parent_trans, trans_id)
2947
if executable[0] != executable[1] and kind[1] == "file":
2948
tt.set_executability(executable[1], trans_id)
2956
tt.adjust_path(target_name, parent_trans, trans_id)
2957
if wt_executable != target_executable and target_kind == "file":
2958
tt.set_executability(target_executable, trans_id)
2949
2959
if working_tree.supports_content_filtering():
2950
2960
for index, ((trans_id, mode_id), bytes) in enumerate(
2951
2961
target_tree.iter_files_bytes(deferred_files)):