HEX
Server: Apache
System: Linux infong-uk86 4.4.400-icpu-106 #2 SMP Mon Sep 15 08:23:40 UTC 2025 x86_64
User: u44115835 (4976590)
PHP: 8.4.17
Disabled: NONE
Upload Files
File: //kunden/lib/python3/dist-packages/breezy/__pycache__/transform.cpython-39.pyc
a

�*�^��@s�ddlmZddlZddlZddlmZmZddlZddlm	Z
mZmZm
Z
mZmZe�e�d�ddlmZmZmZmZmZmZddlmZmZdd	lmZdd
lmZmZmZm Z m!Z!m"Z"ddl#m$Z$ddl%m&Z&m'Z'm(Z(dd
lm)Z)m*Z*dZ+dd�Z,Gdd�de-�Z.Gdd�de-�Z/Gdd�de/�Z0Gdd�dej1�Z2Gdd�de2�Z3dd�Z4dd�Z5e
�6�Z7e7�8de5d �e7�8d!e4d"�e7�9d�e
j:d#e7d$d%d&�Z;Gd'd(�d(e0�Z<Gd)d*�d*e0�Z=Gd+d,�d,e>j?�Z@d-d.�ZAGd/d0�d0e-�ZBdXd2d3�ZCd4d5�ZDd6d7�ZEd8d9�ZFd:d;�ZGd<d=�ZHd>d?�ZId@dA�ZJdYdBdC�ZKdDdE�ZLdZdFdG�ZMd[dHdI�ZNd\dJdK�ZOd]dLdM�ZPd^dNdO�ZQdPdQ�ZRdRdS�ZSGdTdU�dUe-�ZTdVdW�ZUdS)_�)�absolute_importN)�S_ISREG�S_IEXEC�)�config�errors�lazy_import�registry�trace�treea8
from breezy import (
    annotate,
    bencode,
    cleanup,
    controldir,
    commit,
    conflicts,
    delta,
    lock,
    multiparent,
    osutils,
    revision as _mod_revision,
    ui,
    urlutils,
    )
from breezy.bzr import (
    inventory,
    inventorytree,
    )
from breezy.i18n import gettext
)�DuplicateKey�MalformedTransform�ReusingTransform�CantMoveRoot�
ImmortalLimbo�NoFinalPath)�filtered_output_bytes�ContentFilterContext)�MutableTree)�
delete_any�	file_kind�pathjoin�sha_file�	splitpath�supports_symlinks)�
ProgressPhase)�	text_type�	viewitems�
viewvalues)�	InterTree�
TreeChangezroot-parentcCs||vrt|d��|||<dS)N��key)r)�mapr"�value�r%�2/usr/lib/python3/dist-packages/breezy/transform.py�
unique_addRs
r'c@seZdZdd�ZdS)�_TransformResultscCst�|�||_||_dS�N)�object�__init__�modified_paths�rename_count)�selfr,r-r%r%r&r+Ys
z_TransformResults.__init__N)�__name__�
__module__�__qualname__r+r%r%r%r&r(Xsr(c@sVeZdZdZd�dd�Zdd�Zdd	�Zd
d�Zdd
�Ze	e�Z
dd�Zdd�Zdd�Z
dd�Zdd�Zdd�Zdd�Zdd�Zdd�Zd d!�Zd"d#�Zd$d%�Zd&d'�Zd(d)�Zd*d+�Zd,d-�Zd�d/d0�Zd1d2�Zd3d4�Zd5d6�Zd7d8�Zd9d:�Z d;d<�Z!d=d>�Z"d?d@�Z#dAdB�Z$dCdD�Z%dEdF�Z&dGdH�Z'dIdJ�Z(dKdL�Z)dMdN�Z*dOdP�Z+dQdR�Z,dSdT�Z-dUdV�Z.dWdX�Z/dYdZ�Z0d[d\�Z1d]d^�Z2d_d`�Z3dadb�Z4dcdd�Z5d�dedf�Z6d�dgdh�Z7d�didj�Z8dkdl�Z9dmdn�Z:dodp�Z;dqdr�Z<dsdt�Z=dudv�Z>dwdx�Z?dydz�Z@d�d{d|�ZAd}d~�ZBdd��ZCd�d��ZDd�d��ZEd�d��ZFd�d�d��ZGd�d��ZHd�d��ZId�d��ZJd�d��ZKdS)��TreeTransformBasez-The base class for TreeTransform and its kin.NTcCs�t�|�||_d|_i|_i|_i|_i|_t�|_	i|_
i|_i|_i|_
i|_t�|_i|_i|_|�d�r�|�d�|_nd|_d|_||_||_d|_dS)aConstructor.

        :param tree: The tree that will be transformed, but not necessarily
            the output tree.
        :param pb: ignored
        :param case_sensitive: If True, the target of the transform is
            case sensitive, not just case preserving.
        r�NF)r*r+�_tree�
_id_number�	_new_name�_new_parent�
_new_contents�_observed_sha1s�set�_removed_contents�_new_executability�_new_reference_revision�_new_id�_non_present_ids�	_r_new_id�_removed_id�_tree_path_ids�_tree_id_paths�is_versioned�trans_id_tree_path�	_new_root�_doneZ_pb�_case_sensitive_targetr-)r.r�pb�case_sensitiver%r%r&r+bs.	

zTreeTransformBase.__init__cCs|S)�Support Context Manager API.r%�r.r%r%r&�	__enter__�szTreeTransformBase.__enter__cCs|��dS)rKN)�finalize)r.�exc_typeZexc_valZexc_tbr%r%r&�__exit__�szTreeTransformBase.__exit__cCs>|jdurdStjdD]}||j|�q|j��d|_dS)z�Release the working tree lock, if held.

        This is required if apply has not been invoked, but can be invoked
        even after apply.
        NZpost_transform)r4r�hooks�unlock)r.�hookr%r%r&rN�s

zTreeTransformBase.finalizecCs|jSr))rFrLr%r%r&Z
__get_root�szTreeTransformBase.__get_rootcCsd|j}|jd7_|S)zProduce a new tranform idznew-%sr)r5)r.�new_idr%r%r&�
_assign_id�s
zTreeTransformBase._assign_idcCs(|��}t|j||�t|j||�|S)z%Assign a transaction id to a new path)rUr'r6r7�r.�name�parent�trans_idr%r%r&�create_path�szTreeTransformBase.create_pathcCs6|durtd��||jkrt�||j|<||j|<dS)z5Change the path that is assigned to a transaction id.NzParent trans-id may not be None)�
ValueErrorrFrr6r7rVr%r%r&�adjust_path�s

zTreeTransformBase.adjust_pathcCs�|j}|�|�}|�|�D]N}||kr@|�|�|�|�|�|�|�|�}|dur\|�|�|�||�q|j�	d�|j
�	|�|�d�|_||kr�|j}|�|||�|�|�|�||�|�|j�dS)a~Emulate moving the root by moving all children, instead.

        We do this by undoing the association of root's transaction id with the
        current tree.  This allows us to create a new directory with that
        transaction id.  We unversion the root directory and version the
        physically new directory, and hope someone versions the tree root
        later.
        Nr3)
rF�
final_file_id�iter_tree_childrenr\�
final_name�final_parent�unversion_file�version_filerB�poprCrE�create_directory)r.rWrXZold_rootZold_root_file_id�child_id�file_idr%r%r&�adjust_root_path�s(	

�


z"TreeTransformBase.adjust_root_pathcCshdd�t|j�D�}t|�dkr$dSt|�dkr8td��|jdurP|d|_dS|d}|�|j�durt|�|�}n|�|j�}||jvr�|�|�n
|�	|�|�
|j�dur�|j|jvr�|�	|j�|dur�|�||j�t
|�|��|���|g�D]}|�|�|�|j|�q�||jv�r0|�|�n
|�|�|j|jv�rT|�|j�|j|=|j|=dS)a�Reinterpret requests to change the root directory

        Instead of creating a root directory, or moving an existing directory,
        all the attributes and children of the new root are applied to the
        existing root directory.

        This means that the old root trans-id becomes obsolete, so it is
        recommended only to invoke this after the root trans-id has become
        irrelevant.

        cSsg|]\}}|tkr|�qSr%)�ROOT_PARENT��.0�k�vr%r%r&�
<listcomp>�s�z5TreeTransformBase.fixup_new_roots.<locals>.<listcomp>rNzA tree cannot have two roots!r)rr7�lenr[rF�
final_kindr]r>�cancel_versioningra�tree_file_idrArb�listr^�	by_parent�getr\r_r8�cancel_creation�delete_contentsr;�cancel_deletionr6)r.Z	new_rootsZold_new_rootrf�childr%r%r&�fixup_new_roots�s>




�
z!TreeTransformBase.fixup_new_rootscCs�|durtd��||jvr2|j|dur2|j|Sz|j�|�}WnFtjy�||jvrj|j|YS|��}||j|<|YSYn0|�|�SdS)a$Determine or set the transaction id associated with a file ID.
        A new id is only created for file_ids that were never present.  If
        a transaction has been unversioned, it is deliberately still returned.
        (this will likely lead to an unversioned parent conflict.)
        NzNone is not a valid file id)	r[r@r4�id2pathr�NoSuchIdr?rUrE)r.rf�pathrYr%r%r&�trans_id_file_id#s


z"TreeTransformBase.trans_id_file_idcCs<|�|�}||jvr2|��|j|<||j|j|<|j|S)z=Determine (and maybe set) the transaction ID for a tree path.)�canonical_pathrBrUrC�r.r|r%r%r&rE:s


z$TreeTransformBase.trans_id_tree_pathcCs(|j|}|dkrtS|�tj�|��S)z'Determine id of the parent in the tree.r3)rCrhrE�osr|�dirname�r.rYr|r%r%r&�get_tree_parentBs
z!TreeTransformBase.get_tree_parentcCs"|�|�}|dur|j�|�dS)z2Schedule the contents of a path entry for deletionN)�	tree_kindr;�add)r.rY�kindr%r%r&rvIs
z!TreeTransformBase.delete_contentscCs|j�|�dS)zCancel a scheduled deletionN)r;�remove�r.rYr%r%r&rwOsz!TreeTransformBase.cancel_deletioncCs|j�|�dS)z+Schedule a path entry to become unversionedN)rAr�r�r%r%r&raSsz TreeTransformBase.unversion_filecCs|�|�|�|�dS)z%Delete and unversion a versioned fileN)rvrar�r%r%r&�delete_versionedWs
z"TreeTransformBase.delete_versionedcCs$|dur|j|=nt|j||�dS)zQSchedule setting of the 'execute' bit
        To unschedule, set to None
        N)r<r')r.Z
executabilityrYr%r%r&�set_executability\s
z#TreeTransformBase.set_executabilitycCst|j||�dS)z-Set the reference associated with a directoryN)r'r=)r.�revision_idrYr%r%r&�set_tree_referenceesz$TreeTransformBase.set_tree_referencecCs.|durt��t|j||�t|j||�dS)z$Schedule a file to become versioned.N)r[r'r>r@)r.rfrYr%r%r&rbiszTreeTransformBase.version_filecCs|j|}|j|=|j|=dS)z$Undo a previous versioning of a fileN)r>r@)r.rYrfr%r%r&rpps
z#TreeTransformBase.cancel_versioningFcCs�t�}|rT|j�|j�}|�|j�|�|j�|�|j�|j�|�}||jf}n|j|j|j|j|jf}|D]}|�	|�qpt
t|��|��S)z�Determine the paths of all new and changed files.

        :param filesystem_only: if True, only calculate values for files
            that require renames or execute bit changes.
        )
r:�
_needs_rename�
differencer6�difference_updater7r8r>r<�update�sorted�
FinalPaths�	get_paths)r.�filesystem_onlyZnew_idsZ	stale_idsZneeds_renameZid_sets�id_setr%r%r&�	new_pathsvs�zTreeTransformBase.new_pathscs�t�}t�fdd��jD��}�j�j|�jfD]}|�|�q0t�j�}|��j�|�	|��fdd�|D�}|�|�|D]}|���
|��q�tt���
|��S)aLDetermine which trans_ids need new Inventory entries.

        An new entry is needed when anything that would be reflected by an
        inventory entry changes, including file name, file_id, parent file_id,
        file kind, and the execute bit.

        Some care is taken to return entries with real changes, not cases
        where the value is deleted and then restored to its original value,
        but some actually unchanged values may be returned.

        :returns: A list of (path, trans_id) for all items requiring an
            inventory change. Ordered by path.
        c3s&|]}�j|��|�kr|VqdSr))r>rq�rj�trLr%r&�	<genexpr>�s�z7TreeTransformBase._inventory_altered.<locals>.<genexpr>c3s&|]}��|���|�kr|VqdSr))r�ror�rLr%r&r��s�)r:r>r6r7r<r�r;�intersection_updater8r�r^r�r�r�)r.Zchanged_idsZnew_file_idr�Zchanged_kind�parent_trans_idr%rLr&�_inventory_altered�s
�


z$TreeTransformBase._inventory_alteredcCs0||jvr|j|S||jvr"dS|�|�SdS)aDetermine the final file kind, after any changes applied.

        :return: None if the file does not exist/has no contents.  (It is
            conceivable that a path would be created without the corresponding
            contents insertion command)
        N)r8r;r�r�r%r%r&ro�s



zTreeTransformBase.final_kindcCs|j�|�S)z5Determine the tree path associated with the trans_id.)rCrtr�r%r%r&�	tree_path�szTreeTransformBase.tree_pathcCs8|�|�}|durdS|j|kr,|j�d�S|j�|�S)z>Determine the file id associated with the trans_id in the treeNr3)r�rFr4�path2idr�r%r%r&rq�s

zTreeTransformBase.tree_file_idcCs:z|j|WSty.||jvr*YdSYn0|�|�S)z�Determine the file id after any changes are applied, or None.

        None indicates that the file will not be versioned after changes are
        applied.
        N)r>�KeyErrorrArqr�r%r%r&r]�s
zTreeTransformBase.final_file_idcCs>|�|�}|dur|St|j�D]\}}||kr |Sq dS)z�Return the inactive file_id associated with a transaction id.
        That is, the one in the tree or in non_present_ids.
        The file_id may actually be active, too.
        N)rqrr?)r.rYrfr"r$r%r%r&�inactive_file_id�s
z"TreeTransformBase.inactive_file_idcCs.z|j|WSty(|�|�YS0dS)zyDetermine the parent file_id, after any changes are applied.

        ROOT_PARENT is returned for the tree root.
        N)r7r�r�r�r%r%r&r`�szTreeTransformBase.final_parentcCsZz|j|WStyTztj�|j|�WYStyNt||��Yn0Yn0dS)z<Determine the final filename, after all changes are applied.N)r6r�r�r|�basenamerCrr�r%r%r&r_�szTreeTransformBase.final_namecsbi}tt�j��}|��fdd�t�j�D��|D](\}}||vrNt�||<||�|�q4|S)z�Return a map of parent: children for known parents.

        Only new paths and parents of tree files with assigned ids are used.
        c3s|]}|��|�fVqdSr))r`r�rLr%r&r�s�z.TreeTransformBase.by_parent.<locals>.<genexpr>)rrrr7�extendrCr:r�)r.rs�itemsrY�	parent_idr%rLr&rs�s�
zTreeTransformBase.by_parentcCs||jvp||jvS)z-Return True if a trans_id's path has changed.)r6r7r�r%r%r&�path_changed
szTreeTransformBase.path_changedcCs
||jvSr))r8r�r%r%r&�new_contentsszTreeTransformBase.new_contentscCs�|jdurt��g}|��|��}|�|�|��|�|���|�|�|��|�|���|�|�	|��|�|�
��|�|���|�|���|S)z9Find any violations of inventory or filesystem invariantsT)
rGr�_add_tree_childrenrsr��_unversioned_parents�
_parent_loops�_duplicate_entries�_duplicate_ids�_parent_type_conflicts�_improper_versioning�_executability_conflicts�_overwrite_conflicts)r.�	conflictsrsr%r%r&�find_conflictss
z TreeTransformBase.find_conflictscCs"|��}t|�dkrt|d��dS)Nr�r�)r�rnr
)r.r�r%r%r&�_check_malformed$sz"TreeTransformBase._check_malformedcs�t����}|��fdd��jD���jD]J}��|�}|dur^�j�|�dkrv|�|�q,��	|�dkr,|�|�q,|D]}t��
|��q|dS)z�Add all the children of all active parents to the known paths.

        Active parents are those which gain children, and those which are
        removed.  This is a necessary first step in detecting conflicts.
        csg|]}��|�dkr|�qS)�	directory)r�r�rLr%r&rm0s�z8TreeTransformBase._add_tree_children.<locals>.<listcomp>Nr�)rrrsr�r;rAr�r4�stored_kind�appendr�r^)r.�parentsrYr|r�r%rLr&r�)s

z$TreeTransformBase._add_tree_childrencCs�|dur|���|g�}|D]}|�|�|krdSq|j�|d�}|durPdSt||�}|j�|d�}|dur�t�|j�	|��St
d|||f��dS)abDoes a parent already have a name child.

        :param name: The searched for name.

        :param parent_id: The parent for which the check is made.

        :param known_children: The already known children. This should have
            been recently obtained from `self.by_parent.get(parent_id)`
            (or will be if None is passed).
        NTFzchild_id is missing: %s, %s, %s)rsrtr_rC�joinpathrB�osutils�lexistsr4�abspath�AssertionError)r.rWr��known_childrenrx�parent_pathZ
child_pathrer%r%r&�_has_named_child>s
�z"TreeTransformBase._has_named_childcs(�����g��t�|���fdd��S)z�Find an available backup name.

        :param name: The basename of the file.

        :param target_id: The directory trans_id where the backup should
            be placed.
        cs��|���Sr))r���base�r�r.�	target_idr%r&�<lambda>fs�z:TreeTransformBase._available_backup_name.<locals>.<lambda>)rsrtr�Zavailable_backup_name)r.rWr�r%r�r&�_available_backup_name[s
�z(TreeTransformBase._available_backup_namec	Csxg}|jD]h}t�}|}|tkr
|�|�z|�|�}WntyNYq
Yn0||krf|�d|f�||vrq
qq
|S)z#No entry should be its own ancestor�parent loop)r7r:rhr�r`r�r�)r.r�rY�seenr�r%r%r&r�is


zTreeTransformBase._parent_loopscCs^g}t|�D]L\}}|tkrq|�|�dur.q|D]$}|�|�dur2|�d|f�qq2q|S)z@If parent directories are versioned, children must be versioned.N�unversioned parent)rrhr]r�)r.rsr�r��childrenrer%r%r&r�{sz&TreeTransformBase._unversioned_parentscCsfg}|jD]V}|�|�}|dkr,|j��s,q
|durD|�d|f�q
|j�|�s
|�d||f�q
|S)z}Cannot version a file with no contents, or a bad type.

        However, existing entries with no contents are okay.
        �symlinkN�versioning no contentszversioning bad kind)r>ror4rr�Zversionable_kind)r.r�rYr�r%r%r&r��s

z&TreeTransformBase._improper_versioningcCsNg}|jD]>}|�|�dur,|�d|f�q
|�|�dkr
|�d|f�q
|S)a2Check for bad executability changes.

        Only versioned files may have their executability set, because
        1. only versioned entries can have executability under windows
        2. only files can be executable.  (The execute bit on a directory
           does not indicate searchability)
        Nzunversioned executability�fileznon-file executability)r<r]r�ro�r.r�rYr%r%r&r��s
z*TreeTransformBase._executability_conflictscCsDg}|jD]4}|�|�durq
||jvr
|�d||�|�f�q
|S)z-Check for overwrites (not permitted on Win32)NZ	overwrite)r8r�r;r�r_r�r%r%r&r��s

�z&TreeTransformBase._overwrite_conflictscCs�g}|j|jfiifkr|St|�D]�}g}|D]2}|�|�}|dur0|jsT|��}|�||f�q0|��d}d}|D]P\}}	|�|	�}
|�	|	�}|
dur�|dur�qx||kr�|�d||	|f�|}|	}qxq$|S)z5No directory may have two entries with the same name.N�	duplicate)
r6r7rr_rH�lowerr��sortror])r.rsr�r�Zname_ids�	child_tidrW�	last_nameZ
last_trans_idrYr�rfr%r%r&r��s4



�z$TreeTransformBase._duplicate_entriesc	s�g}z�j��}Wntjy*gYS0t�fdd��jD��}|�|�}t�j�D]6\}}||vrX�j�	|�}��
|�}|�d||f�qX|S)z'Each inventory id may only be used oncec3s|]}��|�VqdSr))rq�rjrYrLr%r&r���z3TreeTransformBase._duplicate_ids.<locals>.<genexpr>�duplicate id)r4�all_file_idsr�UnsupportedOperationr:rAr�rr>rzrEr�)	r.r�Zall_idsZremoved_tree_idsZactive_tree_idsrYrfr|Zold_trans_idr%rLr&r��s
�

z TreeTransformBase._duplicate_idscCs�g}t|�D]t\}}|tkrqd}|D]}|�|�dur&d}qBq&|rHq|�|�}|durj|�d|f�q|dkr|�d|f�q|S)z%Children must have a directory parentTNF�missing parentr��non-directory parent)rrhror�)r.rsr�r�r�Zno_childrenrer�r%r%r&r��s"
z(TreeTransformBase._parent_type_conflictscCs�|j��r�|j|}|j�|�}t�|�j}|r�t�d�}t�|�|d|@B}|d@rh|d|@O}|d@r�|d|@O}n|d@}t�	||�dS)	z)Set the executability of versioned files r�@�r� �i����N)
r4Z_supports_executabler<r�r��stat�st_mode�umaskr��chmod_if_possible)r.r|rY�new_executabilityr�Zcurrent_moder�Zto_moder%r%r&�_set_executability�s



z$TreeTransformBase._set_executabilitycCs$|�||�}|dur |�||�|S)z1Helper function to create a new filesystem entry.N)rZrb�r.rWr�rfrYr%r%r&�
_new_entryszTreeTransformBase._new_entrycCs6|�|||�}|j|||d�|dur2|�||�|S)a�Convenience method to create files.

        name is the name of the file to create.
        parent_id is the transaction id of the parent directory of the file.
        contents is an iterator of bytestrings, which will be used to produce
        the file.
        :param file_id: The inventory ID of the file, if it is to be versioned.
        :param executable: Only valid when a file_id has been supplied.
        ��sha1N)r��create_filer�)r.rWr��contentsrf�
executabler�rYr%r%r&�new_files
zTreeTransformBase.new_filecCs|�|||�}|�|�|S)aConvenience method to create directories.

        name is the name of the directory to create.
        parent_id is the transaction id of the parent directory of the
        directory.
        file_id is the inventory ID of the directory, if it is to be versioned.
        )r�rdr�r%r%r&�
new_directory+s
zTreeTransformBase.new_directorycCs|�|||�}|�||�|S)a@Convenience method to create symbolic link.

        name is the name of the symlink to create.
        parent_id is the transaction id of the parent directory of the symlink.
        target is a bytestring of the target of the symlink.
        file_id is the inventory ID of the file, if it is to be versioned.
        )r��create_symlink)r.rWr��targetrfrYr%r%r&�new_symlink7szTreeTransformBase.new_symlinkcCst|j��dS)a?Schedule an item to be orphaned.

        When a directory is about to be removed, its children, if they are not
        versioned are moved out of the way: they don't have a parent anymore.

        :param trans_id: The trans_id of the existing item.
        :param parent_id: The parent trans_id of the item.
        N��NotImplementedError�
new_orphan�r.rYr�r%r%r&r�Cs	zTreeTransformBase.new_orphancCsJg}|��|D]4}||jvr"qq|�|�dur<|�|�qd}qFq|S)a�Find the potential orphans in a directory.

        A directory can't be safely deleted if there are versioned files in it.
        If all the contained files are unversioned then they can be orphaned.

        The 'None' return value means that the directory contains at least one
        versioned file and should not be deleted.

        :param dir_id: The directory trans id.

        :return: A list of the orphan trans ids or None if at least one
             versioned file is present.
        N)rsr;r]r�)r.�dir_id�orphansr�r%r%r&�_get_potential_orphansNs
z(TreeTransformBase._get_potential_orphanscCsVt|j�}|�|j�|�|j�|�|j�|�|j�|�|j�|�|j�|S)z9Return the set of transform ids affected by the transform)	r:rAr�r>r;r8r<r6r7�r.�	trans_idsr%r%r&�
_affected_idsms
zTreeTransformBase._affected_idscCsV|��}i}i}|D]8}|�|�}|dur2|||<|�|�}|dur|||<q||fS)zAReturn mapping of file_ids to trans_ids in the to and from statesN)r�rqr])r.r��from_trans_ids�to_trans_idsrYZfrom_file_idZ
to_file_idr%r%r&�_get_file_id_mapsxs


z#TreeTransformBase._get_file_id_mapscCs�|j�|�}|r6t|jj|gd��d}|j}|j}n6d}|durLd}d}n tj�	|�}|�
|�}|�|�}|dur�|j�||�\}}	}
nd}d}	||||	fS)zpGet data about a file in the from (tree) state

        Return a (name, parent, kind, executable) tuple
        ��specific_filesrNF)
rCrt�nextr4�iter_entries_by_dirrWr�r�r|r�r�rq�_comparison_data)r.�
from_trans_id�from_versioned�	from_pathZ
from_entry�	from_name�from_parentZtree_parent�	from_kind�from_executableZ
from_statsr%r%r&�_from_file_data�s,��

�
z!TreeTransformBase._from_file_datacCsX|�|�}|�|�}|�|�|��}||jvr:|j|}n||krH|}nd}||||fS)zpGet data about a file in the to (target) state

        Return a (name, parent, kind, executable) tuple
        F)r_ror]r`r<)r.�to_trans_idrr�to_name�to_kind�	to_parent�
to_executabler%r%r&�
_to_file_data�s


zTreeTransformBase._to_file_datac
Cstt|�}|��\}}g}t|��|�D�]2}d}|�|�}|durPd}||}nd}|�|�}	|	durpd}
|}	nd}
|s~d}n|j�|�}|
s�d}n
|�|	�}|�|||�\}
}}}|�|	||�\}}}}||kr�d}n|dvr�|	|ks�|	|j	vr�d}|�s&||
k�r&||k�r&|
|k�r&||k�r&q&|�
t|||f|||
f||f|
|f||f||f��q&dd�}tt
||d��S)a�Produce output in the same format as Tree.iter_changes.

        Will produce nonsensical results if invoked while inventory/filesystem
        conflicts (as reported by TreeTransform.find_conflicts()) are present.

        This reads the Transform, but only reproduces changes involving a
        file_id.  Files that are not versioned in either of the FROM or TO
        states are not reflected.
        FNT)r�r�cSs|jdpd|jdpdfS)Nrr3r)r|)�cr%r%r&�path_key�sz0TreeTransformBase.iter_changes.<locals>.path_keyr!)r�r�r:�unionrtrC�get_pathr	rr8r�r �iterr�)r.Zfinal_pathsr�r�ZresultsrfZmodifiedrrr
Zto_versionedrZto_pathrrrrrr
rrrr%r%r&�iter_changes�sj




�
�
�����
��	zTreeTransformBase.iter_changescCst|�S)z�Return a tree representing the result of the transform.

        The tree is a snapshot, and altering the TreeTransform will invalidate
        it.
        )�_PreviewTreerLr%r%r&�get_preview_tree�sz"TreeTransformBase.get_preview_treecCs|��|rBt|j��t|j��}|D]}|�|�dur&t���q&|��\}
}|t	j
krn|durhtd��g}n|g}|dur�|�|�|j
��|kr�td|j
���d���tj�|	||�}	|j|||||	|
d�}|��}t|�|||����|��|�|�}
|�|
d|
�|
S)aCommit the result of this TreeTransform to a branch.

        :param branch: The branch to commit to.
        :param message: The message to attach to the commit.
        :param merge_parents: Additional parent revision-ids specified by
            pending merges.
        :param strict: If True, abort the commit if there are unversioned
            files.
        :param timestamp: if not None, seconds-since-epoch for the time and
            date.  (May be a float.)
        :param timezone: Optional timezone for timestamp, as an offset in
            seconds.
        :param committer: Optional committer in email-id format.
            (e.g. "J Random Hacker <jrandom@example.com>")
        :param authors: Optional list of authors in email-id format.
        :param revprops: Optional dictionary of revision properties.
        :param revision_id: Optional revision id.  (Specifying a revision-id
            may reduce performance for some non-native formats.)
        :return: The revision_id of the revision committed.
        Nz-Cannot supply merge parents for first commit.z+TreeTransform not based on branch basis: %s�utf-8)�	timestamp�timezone�	committer�revpropsr�r)r�r:r8r�r>r]rZStrictCommitFailedZlast_revision_info�
_mod_revisionZ
NULL_REVISIONr[r�r4Zget_revision_id�decode�commitZCommitZupdate_revpropsZget_commit_builderrrrZrecord_iter_changesrZfinish_inventoryZset_last_revision_info)r.�branch�messageZ
merge_parents�strictrrrZauthorsrr�ZunversionedrYZrevnoZlast_rev_id�
parent_idsZbuilderZpreviewr%r%r&rsD


��
�
zTreeTransformBase.commitcCsH|�|�}z"|dus$|j�|�dkr*WdSWntjyBYdS0|S�Nr�)r�r4r�r�
NoSuchFiler�r%r%r&�_text_parent>s

zTreeTransformBase._text_parentcCs$|�|�}|durdS|j�|�fS)z/Get texts for compression parents of this file.Nr%)r&r4Z
get_file_textr�r%r%r&�_get_parents_textsGs
z$TreeTransformBase._get_parents_textscCs$|�|�}|durdS|j�|�fS)z/Get lines for compression parents of this file.Nr%)r&r4�get_file_linesr�r%r%r&�_get_parents_linesNs
z$TreeTransformBase._get_parents_linesc
cs�dd�t|j�D�}dd�t|j�D�}dd�t|j�D�}dd�t|j�D�}dd�t|j�D�}dd�t|j�D�}dd	�|jD�}d
d	�|jD�}	|j	||||||	||d�	}
|�
t�|
�d�Vtt|j
��D]�\}}|d
k�rFt|�|�d��}
|
��}Wd�n1�s0Y|�|�}tj�||�}d�|���}|dk�rTd}|dk�r~|�|�}t|t��s~|�d�}|�
||�d�|�d�ff�Vq�dS)znSerialize this TreeTransform.

        :param serializer: A Serialiser like pack.ContainerSerializer.
        cSs"i|]\}}|�d�|�d��qS�r��encoderir%r%r&�
<dictcomp>Zs�z/TreeTransformBase.serialize.<locals>.<dictcomp>cSs"i|]\}}|�d�|�d��qSr*r+rir%r%r&r-\s�cSsi|]\}}|�d�|�qSr*r+rir%r%r&r-^s�cSs i|]\}}|�d�t|��qSr*)r,�intrir%r%r&r-`s�cSs"i|]\}}|�d�|�d��qSr*r+rir%r%r&r-bs�cSsi|]\}}||�d��qSr*r+rir%r%r&r-ds�cSsg|]}|�d��qSr*r+r�r%r%r&rmfs�z/TreeTransformBase.serialize.<locals>.<listcomp>cSsg|]}|�d��qSr*r+r�r%r%r&rmhs�)	�
_id_number�	_new_name�_new_parent�_new_executability�_new_id�_tree_path_ids�_removed_id�_removed_contents�_non_present_ids))sattribsr��rbNr�r�r�r�ascii)rr6r7r>r<rBr?r;rAr5Zbytes_record�bencoder�r8�open�_limbo_name�	readlinesr)�multiparent�MultiParentZ
from_lines�joinZto_patch�_read_symlink_target�
isinstance�bytesr,)r.Z
serializer�new_name�
new_parentrTr�Z
tree_path_idsZnon_present_idsZremoved_contentsZ
removed_id�attribsrYr�Zcur_file�linesr��mpdiff�contentr%r%r&�	serializeUsj����������
(




�zTreeTransformBase.serializecCs�t|�\}}t�|�}|d|_dd�t|d�D�|_dd�t|d�D�|_dd�t|d�D�|_d	d�t|d
�D�|_dd�t|j�D�|_	i|_
i|_t|d�D]0\}}|�d
�}|�d
�}||j
|<||j|<q�dd�|dD�|_
tdd�|dD��|_dd�t|d�D�|_|D]�\\\}}}|�d
�}|�d�}|dk�r|tj�|�}	|	�|�|��}
|�|
|�|dk�r�|�|�|dk�r(|�|�d
�|��q(dS)z�Deserialize a stored TreeTransform.

        :param records: An iterable of (names, content) tuples, as per
            pack.ContainerPushParser.
        r/cSs"i|]\}}|�d�|�d��qSr*�rrir%r%r&r-�s�z1TreeTransformBase.deserialize.<locals>.<dictcomp>r0cSs"i|]\}}|�d�|�d��qSr*rKrir%r%r&r-�s�r1cSs i|]\}}|�d�t|��qSr*)r�boolrir%r%r&r-�s�r2cSsi|]\}}|�d�|�qSr*rKrir%r%r&r-�s�r3cSsi|]\}}||�qSr%r%rir%r%r&r-�r�r4rcSsh|]}|�d��qSr*rKr�r%r%r&�	<setcomp>�s�z0TreeTransformBase.deserialize.<locals>.<setcomp>r5css|]}|�d�VqdS)rNrKr�r%r%r&r��s�z0TreeTransformBase.deserialize.<locals>.<genexpr>r6cSsi|]\}}||�d��qSr*rKrir%r%r&r-�s�r7r9r�r�r�N)r�r:Zbdecoder5rr6r7r<r>r@rBrCrrAr:r;r?r>r?Z
from_patchZto_linesr'r�rdr�)r.Zrecords�namesrIrFZbytepathrYr|r�rHrGr%r%r&�deserialize�sV


�
�
�
�


��

�





zTreeTransformBase.deserializecCst|j��dS)�PSchedule creation of a new file.

        :seealso: new_file.

        :param contents: an iterator of strings, all of which will be written
            to the target destination.
        :param trans_id: TreeTransform handle
        :param mode_id: If not None, force the mode of the target file to match
            the mode of the object referenced by mode_id.
            Otherwise, we will try to preserve mode bits of an existing file.
        :param sha1: If the sha1 of this content is already known, pass it in.
            We can use it to prevent future sha1 computations.
        N)r�r�)r.r�rY�mode_idr�r%r%r&r��szTreeTransformBase.create_filecCst|j��dS)�OSchedule creation of a new directory.

        See also new_directory.
        N)r�rdr�r%r%r&rd�sz"TreeTransformBase.create_directorycCst|j��dS)�qSchedule creation of a new symbolic link.

        target is a bytestring.
        See also new_symlink.
        N)r�r�)r.r�rYr%r%r&r��sz TreeTransformBase.create_symlinkcCst|j��dS)� Schedule creation of a hard linkN)r��create_hardlink�r.r|rYr%r%r&rU�sz!TreeTransformBase.create_hardlinkcCst|j��dS�z)Cancel the creation of new file contents.N)r�rur�r%r%r&ru�sz!TreeTransformBase.cancel_creation)NT)F)NNN)N)N)NFNNNNNN)NN)Lr/r0r1�__doc__r+rMrPrNZ_TreeTransformBase__get_root�property�rootrUrZr\rgryr}rEr�rvrwrar�r�r�rbrpr�r�ror�rqr]r�r`r_rsr�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r	rrrrr&r'r)rJrOr�rdr�rUrur%r%r%r&r2_s�
4
	 =	
'



�


 D�
:	2.
r2c@s�eZdZdZd$dd�Zdd�Zdd	�Zd
d�Zdd
�Zdd�Z	dd�Z
dd�Zd%dd�Zdd�Z
dd�Zdd�Zdd�Zdd�Zd d!�Zd"d#�ZdS)&�DiskTreeTransformz,Tree transform storing its contents on disk.NTcCsVt�||||�||_d|_i|_t�|_i|_i|_t�|_	d|_
t�|j�|_
dS)a�Constructor.
        :param tree: The tree that will be transformed, but not necessarily
            the output tree.
        :param limbodir: A directory where new files can be stored until
            they are installed in their proper places
        :param pb: ignored
        :param case_sensitive: If True, the target of the transform is
            case sensitive, not just case preserving.
        N)r2r+�	_limbodir�_deletiondir�_limbo_filesr:�_possibly_stale_limbo_files�_limbo_children�_limbo_children_namesr��_creation_mtimer�r�_create_symlinks)r.r�limbodirrIrJr%r%r&r+�s
zDiskTreeTransform.__init__cCs|jdurdSz�tt|j��}|�|j�|jdd�|D]D}zt|�Wq:ty|}z|j	t	j
krh�WYd}~q:d}~00q:zt|j�Wnty�t|j��Yn0z|j
dur�t|j
�Wnty�t�|j
��Yn0Wt�|�nt�|�0dS)z�Release the working tree lock, if held, clean up limbo dir.

        This is required if apply has not been invoked, but can be invoked
        even after apply.
        NT��reverse)r4rrrr^r�r_r�r�OSError�errno�ENOENTr\rr]rZImmortalPendingDeletionr2rN)r.Zlimbo_pathsr|�er%r%r&rN�s,

zDiskTreeTransform.finalizecCst�|j�S)z4Check if the limbo path supports the executable bit.)r�Zsupports_executabler\rLr%r%r&�_limbo_supports_executablesz,DiskTreeTransform._limbo_supports_executablecCs,|j�|�}|dur(|�|�}||j|<|S)z!Generate the limbo name of a fileN)r^rt�_generate_limbo_path)r.rY�
limbo_namer%r%r&r< s


zDiskTreeTransform._limbo_namecCs|j�|�t|j|�S)z�Generate a limbo path using the trans_id as the relative path.

        This is suitable as a fallback, and when the transform should not be
        sensitive to the path encoding of the limbo directory.
        )r�r�rr\r�r%r%r&rl(sz&DiskTreeTransform._generate_limbo_pathcCs�|j�|�}|j�|�}t�||||�||jvr|||jvr||�|g�||kr`|j|�	|�||ksp||kr||j
||=dSr))r7rtr6r2r\r^r��_rename_in_limbor`r�ra)r.rWrXrYZprevious_parentZ
previous_namer%r%r&r\1s
�zDiskTreeTransform.adjust_pathcCs�|D]�}|j|}|j�|�|j|=||jvr2q|�|�}t�||�|j�|�|�|�D],}|j|}||t	|�d�}||j|<q^qdS)a�Fix limbo names so that the right final path is produced.

        This means we outsmarted ourselves-- we tried to avoid renaming
        these files later by creating them with their final names in their
        final parents.  But now the previous name or parent is no longer
        suitable, so we have to rename them.

        Even for trans_ids that have no new contents, we must remove their
        entries from _limbo_files, because they are now stale.
        N)
r^r_r�r8r<r��renamer��_limbo_descendantsrn)r.r�rY�old_path�new_path�
descendantZ	desc_pathr%r%r&rn=s



z"DiskTreeTransform._rename_in_limbocCs4t|j�|g��}t|�D]}|�|�|��q|S)z@Return the set of trans_ids whose limbo paths descend from this.)r:r`rtrrr�rp)r.rYZdescendantsrsr%r%r&rpVsz$DiskTreeTransform._limbo_descendantscCs�|�|�}t|d��(}t|j|d�|�|�Wd�n1sB0Y|�|�|�||t�|dur�|t�	|�f|j
|<dS)rP�wbr�N)r<r;r'r8�
writelines�
_set_mtime�	_set_moderr��lstatr9)r.r�rYrQr�rW�fr%r%r&r�]s
(
zDiskTreeTransform.create_filecCst�|�|��Sr))r��readlinkr<r�r%r%r&rAwsz&DiskTreeTransform._read_symlink_targetcCs,|jdurt��|_t�||j|jf�dS)ztAll files that are created get the same mtime.

        This time is set by the first object to be created.
        N)rb�timer��utimerr%r%r&rvzs

zDiskTreeTransform._set_mtimec
Cs�|�|�}zt�||�Wn<tyV}z$|jtjkr8�t�|��WYd}~n
d}~00zt|j	|d�Wnt
y�t�|��Yn0dS)rTNr�)r<r��linkrgrhZEPERMrZHardLinkNotSupportedr'r8�
BaseException�unlink)r.r|rYrWrjr%r%r&rU�s
 
z!DiskTreeTransform.create_hardlinkcCs"t�|�|��t|j|d�dS)rRr�N)r��mkdirr<r'r8r�r%r%r&rd�sz"DiskTreeTransform.create_directorycCsf|jrt�||�|��n:zt|��|�}WntyBd}Yn0t�d|f�t	|j
|d�dS)rSNz1Unable to create symlink "%s" on this filesystem.r�)rcr�r�r<r�rr�r
�warningr'r8)r.r�rYr|r%r%r&r��s
�z DiskTreeTransform.create_symlinkcCsZ|j|=||jvr|j|=|j�|�}|durH|�|�|j|=|j|=t|�|��dSrW)r8r9r`rtrnrarr<�r.rYr�r%r%r&ru�s

z!DiskTreeTransform.cancel_creationcCs$|j��}|�d�}||||�dS)N�transform.orphan_policy)r4Zget_config_stackrt)r.rYr�ZconfZ
handle_orphanr%r%r&r��s

zDiskTreeTransform.new_orphan)NT)NN)r/r0r1rXr+rNrkr<rlr\rnrpr�rArvrUrdr�rur�r%r%r%r&r[�s"
"	
	r[c@seZdZdZdZdd�ZdS)�OrphaningErrorTz(Error while orphaning %s in %s directorycCstj�|�||_||_dSr))r�BzrErrorr+�orphanrX)r.r�rXr%r%r&r+�szOrphaningError.__init__N)r/r0r1Zinternal_error�_fmtr+r%r%r%r&r��sr�c@seZdZdZdd�ZdS)�OrphaningForbiddenz*Policy: %s doesn't allow creating orphans.cCstj�|�||_dSr))rr�r+�policy)r.r�r%r%r&r+�szOrphaningForbidden.__init__N)r/r0r1r�r+r%r%r%r&r��sr�cCspd}|�|�}|�|�dur&|�|�|j|}|�|�}|�||�}|�|||�t�dt	||�|f�dS)a.See TreeTransformBase.new_orphan.

    This creates a new orphan in the `brz-orphans` dir at the root of the
    `TreeTransform`.

    :param tt: The TreeTransform orphaning `trans_id`.

    :param orphan_id: The trans id that should be orphaned.

    :param parent_id: The orphan parent trans id.
    zbrz-orphansNz%s has been orphaned in %s)
rErordrCr_r�r\r
r�r�)�tt�	orphan_idr�Zorphan_dir_basenameZod_idr�Zactual_namerDr%r%r&�move_orphan�s




�r�cCstd��dS)zrSee TreeTransformBase.new_orphan.

    This refuses to create orphan, letting the caller handle the conflict.
    �neverN)r�)r�r�r�r%r%r&�
refuse_orphan�sr��conflictz>Leave orphans in place and create a conflict on the directory.Zmovez,Move orphans into the brz-orphans directory.r�z6Policy for orphaned files during transform operations.r�)�helpZinvalidc@sleZdZdZddd�Zdd�Zdd�Zd	d
�Zdd�Zd
d�Z	ddd�Z
dd�Zdd�Zdd�Z
dd�ZdS)�
TreeTransforma�
Represent a tree transformation.

    This object is designed to support incremental generation of the transform,
    in any order.

    However, it gives optimum performance when parent directories are created
    before their contents.  The transform is then able to put child files
    directly in their parent directory, avoiding later renames.

    It is easy to produce malformed transforms, but they are generally
    harmless.  Attempting to apply a malformed transform will cause an
    exception to be raised before any modifications are made to the tree.

    Many kinds of malformed transforms can be corrected with the
    resolve_conflicts function.  The remaining ones indicate programming error,
    such as trying to create a file with no path.

    Two sets of file creation methods are supplied.  Convenience methods are:
     * new_file
     * new_directory
     * new_symlink

    These are composed of the low-level methods:
     * create_path
     * create_file or create_directory or create_symlink
     * version_file
     * set_executability

    Transform/Transaction ids
    -------------------------
    trans_ids are temporary ids assigned to all files involved in a transform.
    It's possible, even common, that not all files in the Tree have trans_ids.

    trans_ids are used because filenames and file_ids are not good enough
    identifiers; filenames change, and not all files have file_ids.  File-ids
    are also associated with trans-ids, so that moving a file moves its
    file-id.

    trans_ids are only valid for the TreeTransform that generated them.

    Limbo
    -----
    Limbo is a temporary directory use to hold new versions of files.
    Files are added to limbo by create_file, create_directory, create_symlink,
    and their convenience variants (new_*).  Files may be removed from limbo
    using cancel_creation.  Files are renamed from limbo into their final
    location as part of TreeTransform.apply

    Limbo must be cleaned up, by either calling TreeTransform.apply or
    calling TreeTransform.finalize.

    Files are placed into limbo inside their parent directories, where
    possible.  This reduces subsequent renames, and makes operations involving
    lots of files faster.  This optimization is only possible if the parent
    directory is created *before* creating any of its children, so avoid
    creating children before parents, where possible.

    Pending-deletion
    ----------------
    This temporary directory is used by _FileMover for storing files that are
    about to be deleted.  In case of rollback, the files will be restored.
    FileMover does not delete files until it is sure that a rollback will not
    happen.
    NcCs�|��zDt�|j�d��}t�|tj�t�|j�d��}t�|tj	�Wnt
yh|���Yn0i|_i|_
t�|||||j�||_dS)z�Note: a tree_write lock is taken on the tree.

        Use TreeTransform.finalize() to release the lock (can be omitted if
        TreeTransform.apply() called).
        Zlimbozpending-deletionN)�lock_tree_writeZurlutilsZlocal_path_from_urlZ
_transportr�r�Zensure_empty_directory_existsrZ
ExistingLimboZExistingPendingDeletionr~rR�
_realpaths�	_relpathsr[r+rJr])r.rrIrdZdeletiondirr%r%r&r+Ms2
��
���zTreeTransform.__init__cCs�|j�|�}||jvr |j|Stj�|�\}}||jvrLtj�|�|j|<|j|}t||�}||jvr�t|j||�}|�	d�}n|j�
|�}||j|<|S)z$Get the canonical tree-relative pathz/\)r4r�r�r�r|�splitr��realpathr�rstrip�relpath)r.r|�absr�r�r�r%r%r&r~ks






zTreeTransform.canonical_pathcCsF|j�|�}|durdSzt|j�|��WStjy@YdS0dS)zyDetermine the file kind in the working tree.

        :returns: The file kind or None if the file does not exist
        N)rCrtrr4r�rr%r�r%r%r&r�~szTreeTransform.tree_kindc
Cs�|dur|}z|j|}Wnty.YdS0zt�|j�|��j}WnFty�}z.|jtj	tj
fvrxWYd}~dS�WYd}~n
d}~00||�r�t�|�
|�|�dS�z�Set the mode of new file contents.
        The mode_id is the existing file to get the mode from (often the same
        as trans_id).  The operation is only performed if there's a mode match
        according to typefunc.
        N)rCr�r�r�r4r�r�rgrhriZENOTDIRr�r�r<)r.rYrQ�typefuncrq�moderjr%r%r&rw�szTreeTransform._set_modec
cs�z|j|}Wnty"YdS0zt�|j�|��}WnDty~}z,t�|�sh|j	t	j
t	jfvsh�WYd}~dSd}~00|D](}t||�}|j�
|�r�q�|�|�Vq�dS)�1Iterate through the entry's tree children, if anyN)rCr�r��listdirr4r�rgr�Z_is_error_enotdirrhriZESRCHr�Zis_control_filenamerE)r.r�r|r�rjrx�	childpathr%r%r&r^�s"
�
z TreeTransform.iter_tree_childrencCs�|j�|�}d}|j�|�dkr�|j�|�}|dur�||jvrZt�|j|<i|j|<d}n^|jr~|j|�|�|dfvr�d}n:t|j|�D]&\}}||kr�q�|�	�|�	�kr�q�q�d}|s�t
�||�St|j
||�}|j|�|�||j||<|S)apGenerate a limbo path using the final path if possible.

        This optimizes the performance of applying the tree transform by
        avoiding renames.  These renames can be avoided only when the parent
        directory is already scheduled for creation.

        If the final path cannot be used, falls back to using the trans_id as
        the relpath.
        Fr�NT)r7rtr8r6r`r:rarHrr�r[rlrr^r�)r.rYrXZuse_direct_path�filenameZ
l_filenameZ
l_trans_idrmr%r%r&rl�s8


��z"TreeTransform._generate_limbo_pathFc
	CsVtjdD]}||j|�q
|s(|��tj����}|dur\|�td�dd�|�	�}d}n|}d}|durtt
�}n|}zL|�td�d|d|�|�|�|�td�d|d|�|�|�}	Wnt
y�|���Yn
0|��Wd�n1s�0Y|�|j�du�r(dd�|D�}|j�|�|��d	|_|��t|	|j�S)
a�Apply all changes to the inventory and filesystem.

        If filesystem or inventory conflicts are present, MalformedTransform
        will be thrown.

        If apply succeeds, finalize is not necessary.

        :param no_conflicts: if True, the caller guarantees there are no
            conflicts, so no check is made.
        :param precomputed_delta: An inventory delta to use instead of
            calculating one.
        :param _mover: Supply an alternate FileMover, for testing
        Z
pre_transformNzApply phaser�rcSsg|]}|ddkr|�qS)rr3r%)rjrjr%r%r&rmr�z'TreeTransform.apply.<locals>.<listcomp>T)rrQr4r��ui�
ui_factory�nested_progress_barr��gettext�_generate_inventory_delta�
_FileMover�_apply_removals�_apply_insertionsr~�rollback�apply_deletionsr]rZZapply_inventory_delta�_apply_observed_sha1srGrNr(r-)
r.�no_conflicts�precomputed_deltaZ_moverrS�child_pb�inventory_delta�offset�moverr,r%r%r&�apply�s<
&zTreeTransform.applyc
s2g}���}t|�t�j�}tj�����}t�j�D]p\}}|ddkr\|�td�||�|�j	krt�j
�d�}n
��|�}|�j
vr�q6�j|}|�|d|df�q6t�fdd�|D��}	t|�D�]D\}\}}|ddkr�|�td�|t�j�|�|	|}|du�rqƈ�|�}
|
du�r8�j
��j
�|��}
��|�}|	�|�}|du�r`��|�}|�jv�r�t�|�j|���j|�d�j|�}
nt�|
��|�||�}
z�j
�|
j�}Wntj �y�d}Yn0�j!�|�}|du�r�||
_"|�|||
j|
f�q�Wd�n1�s$0Y|S)	z6Generate an inventory delta for the current transform.�
r�
removing filer3Nc3s |]\}}|��|�fVqdSr))r])rj�pr�rLr%r&r�+r�z:TreeTransform._generate_inventory_delta.<locals>.<genexpr>�adding file)#r�rnrAr�r�r��	enumerater�r�rFr4r�rqr@rCr��dictror�rzr`rtr]r=�	inventoryZ
TreeReferencer6r7�
make_entryr_rfrr{r<r�)r.r�r�Z
total_entriesr��numrYrfr|Znew_path_file_idsr�r��parent_file_id�	new_entryrqr�r%rLr&r�sp
�



�
�







��

�&z'TreeTransform._generate_inventory_deltac
Cstt|j�dd�}tj����}t|�D]�\}\}}|dkr<q&|�td�|t	|��|j
�|�}||jvr�t
j�|j|�}|�||�q&||jvs�||jvr&z|�||�|��Wn4tjy�}	z|	jtjkrЂWYd}	~	q&d}	~	00|jd7_q&Wd�n1�s0YdS)aDPerform tree operations that remove directory/inventory names.

        That is, delete files that are to be deleted, and put any files that
        need renaming into limbo.  This must be done in strict child-to-parent
        order.

        If inventory_delta is None, no inventory delta generation is performed.
        Trer3r�Nr)r�rrBr�r�r�r�r�r�rnr4r�r;r�r|r@r]�
pre_deleter6r7ror<r�TransformRenameFailedrhrir-)
r.r��
tree_pathsr�r�r|rY�	full_pathZdelete_pathrjr%r%r&r�Ps&	

�zTreeTransform._apply_removalsc
Cs�|jdd�}g}tj����*}t|�D�]\}\}}|ddkrV|�td�|t|��|j�	|�}||j
vr�z|�|�|�|�Wn4t
jy�}	z|	jtjkr��WYd}	~	nd}	~	00|jd7_||jvs�|�|�r�||jvr�|�|�||jv�r|�||�||jvr&|j|\}
}t�|�}|
|f|j|<q&Wd�n1�sN0Y|D]\}}||jv�r\|j|=�q\|j��|S)axPerform tree operations that insert directory/inventory names.

        That is, create any files that need to be created, and restore from
        limbo any files that needed renaming.  This must be done in strict
        parent-to-child order.

        If inventory_delta is None, no inventory delta is calculated, and
        no list of modified paths is returned.
        T)r�r�rr�Nr)r�r�r�r�r�r�r�rnr4r�r�ror<rr�rhrir-r8r�r�r<r�r9r�rxr^�clear)
r.r�r�r,r�r�r|rYr�rjZo_sha1Zo_st_val�str%r%r&r�ns@

�

�



0
zTreeTransform._apply_insertionscCs8t|�}t|j�D] \}}|�|�}|j�||�qdS)a5After we have finished renaming everything, update observed sha1s

        This has to be done after self._tree.apply_inventory_delta, otherwise
        it doesn't know anything about the files we are updating. Also, we want
        to do this as late as possible, so that most entries end up cached.
        N)r�rr9rr4Z_observed_sha1)r.�pathsrYZobservedr|r%r%r&r��s
z#TreeTransform._apply_observed_sha1s)N)FNN)r/r0r1rXr+r~r�rwr^rlr�r�r�r�r�r%r%r%r&r�sA

/
080r�c@sBeZdZdZddd�Zdd�Zdd	�Zd
d�Zdd
�Zdd�Z	dS)�TransformPreviewz�A TreeTransform for generating preview trees.

    Unlike TreeTransform, this version works when the input tree is a
    RevisionTree, rather than a WorkingTree.  As a result, it tends to ignore
    unversioned files in the input tree.
    NTcCs*|��tjdd�}t�|||||�dS)Nz
bzr-limbo-)�prefix)�	lock_readr�Zmkdtempr[r+)r.rrIrJrdr%r%r&r+�szTransformPreview.__init__cCs|Sr)r%rr%r%r&r~�szTransformPreview.canonical_pathcCs8|j�|�}|durdS|j�|�d}|dkr4d}|S)Nr�missing)rCrtr4�path_content_summary)r.rYr|r�r%r%r&r��szTransformPreview.tree_kindcCsdSr�r%)r.rYrQr�r%r%r&rw�szTransformPreview._set_modeccs�z|j|}Wnty"YdS0zt|jj|gd��d}WntyTYdS0t|di�}|D]}t||�}|�|�VqfdS)r�Nr�rr�)	rCr�r�r4r�
StopIteration�getattrr�rE)r.r�r|�entryr�rxr�r%r%r&r^�s ��
z#TransformPreview.iter_tree_childrencCst|j��dSr)r�r�r%r%r&r��szTransformPreview.new_orphan)NT)
r/r0r1rXr+r~r�rwr^r�r%r%r%r&r��s
		r�c@s�eZdZdZdd�Zdd�Zdd�Zdd	�Zd
d�Zdd
�Z	dd�Z
edd��Zdd�Z
dd�Zdd�Zdd�Zedd��Zdd�Zdd�Zd d!�Zd"d#�Zdad%d&�Zd'd(�Zd)d*�Zdbd,d-�Zd.d/�Zd0d1�Zdcd3d4�Zd5d6�Zddd8d9�Zd:d;�Zd<d=�Z d>d?�Z!d@dA�Z"dedBdC�Z#dfdDdE�Z$dFdG�Z%dHdI�Z&dJdK�Z'dLdM�Z(dgdNdO�Z)dPdQ�Z*dRdS�Z+e,j-fdTdU�Z.dVdW�Z/dhdYdZ�Z0d[d\�Z1d]d^�Z2d_d`�Z3d+S)irz9Partial implementation of Tree to support show_diff_treescCsL||_t|�|_d|_g|_i|_i|_i|_tdd�|j�	�D��|_
dS)Ncss|]}|j|fVqdSr)�rf�rjrr%r%r&r��r�z(_PreviewTree.__init__.<locals>.<genexpr>)�
_transformr��_final_paths�_PreviewTree__by_parent�_parent_ids�_all_children_cache�_path2trans_id_cache�_final_name_cacher�r�_iter_changes_cache�r.�	transformr%r%r&r+�s
�z_PreviewTree.__init__cCsdS�NFr%rLr%r%r&�supports_tree_reference�sz$_PreviewTree.supports_tree_referencecCs|j�|�}|duo|jS)z/Return True if the content of this file changedN)r�rt�changed_content)r.rf�changesr%r%r&�_content_change�sz_PreviewTree._content_changecCs(t|jjdd�}|dur$|jjjj}|S)NZ_repository)r�r�r4r Z
repository)r.�repor%r%r&�_get_repositorysz_PreviewTree._get_repositoryc	csH|��D]:}z|�|�VWqtjy@|���|�VYq0qdSr))�get_parent_idsZ
revision_treerZNoSuchRevisionInTreer��r.r�r%r%r&�_iter_parent_treess
z_PreviewTree._iter_parent_treescsV�fdd�|��D�}|��|f||�|��|��}|j}||jvrR|j�|�|S)Ncs g|]}�|�|����f�qSr%)Zget_file_revisionrzr�r�r%r&rms�z3_PreviewTree._get_file_revision.<locals>.<listcomp>)r�Z	add_linesr(r�ZtextsZfallback_versionedfilesr�)r.r|rfZvfZ
tree_revisionZparent_keysr�Zbase_vfr%r�r&�_get_file_revisions
��
z_PreviewTree._get_file_revisioncCs|j�|�}t�|�Sr))r�r<r�rx)r.rYrWr%r%r&�_stat_limbo_filesz_PreviewTree._stat_limbo_filecCs|jdur|j��|_|jSr))r�r�rsrLr%r%r&�
_by_parents
z_PreviewTree._by_parentcCsJ|�|�\}}}}|dkr$d}d}n|j�|�|��}|�|�}||dfS)Nr�F)r�r�r]�_path2trans_id�
is_executable)r.r�r|r��sizer��link_or_sha1rfr%r%r&r$s
z_PreviewTree._comparison_datacCsdSr�r%rLr%r%r&�	is_locked.sz_PreviewTree.is_lockedcCst�|j�Sr))�lockZLogicalLockResultrRrLr%r%r&r�1sz_PreviewTree.lock_readcCsdSr)r%rLr%r%r&rR5sz_PreviewTree.unlockcCsttj��dS)z5This Tree does not use inventory as its backing data.N)r�r�root_inventoryrLr%r%r&r�8sz_PreviewTree.root_inventorycsBt�jj���}|��fdd��jjD��|�t�jj��|S)Nc3s|]}�j�|�VqdSr))r�rqr�rLr%r&r�?s�z,_PreviewTree.all_file_ids.<locals>.<genexpr>)	r:r�r4r�r�rAr�rr>)r.Ztree_idsr%rLr&r�=s�z_PreviewTree.all_file_idscsLt�jj���}|��fdd��jjD��|��fdd��jjD��|S)Nc3s|]}�j�|�VqdSr)�r�rEr�rLr%r&r�Gs�z3_PreviewTree.all_versioned_paths.<locals>.<genexpr>c3s|]}�j�|�VqdSr))r��_determine_pathr�rLr%r&r�Ks�)r:r�r4�all_versioned_pathsr�rAr�r>)r.r�r%rLr&r�Ds��z _PreviewTree.all_versioned_pathscCs�|j�|t�}|tur|St|�}|jj}|D]^}|�|�D]>}|j�|�}|durj|j�|�}||j|<||kr<|}q.q<d|j|<dSq.||j|<|Sr))	r�rtr*rr�rZ�
_all_childrenr�r_)r.r|rYZsegmentsZ
cur_parentZcur_segmentrxr_r%r%r&r�Qs$


z_PreviewTree._path2trans_idcCs4t|t�r"|gkrdg}tj|�}|j�|�|��S�Nr3)rBrrr�rr�r]r�rr%r%r&r�gs


z_PreviewTree.path2id�downcCs>|j�|�}z|j�|�WSty8t�||��Yn0dSr))r�r}r�r�rrr{)r.rfZrecurserYr%r%r&rzns
z_PreviewTree.id2pathcCsX|j�|�}|dur|St|j�|��}|�|jj�|�|j�|g��||j|<|Sr))	r�rtr:r�r^r�r7r�r�r�r%r%r&r�us
z_PreviewTree._all_childrenc#sft�fdd��jj��D��}|��jj�|��jj�|D]"}�j�|�dur>�j�	|�Vq>dS)Nc3s|]}�j�|�VqdSr)r�)rjr�rLr%r&r��r�z&_PreviewTree.extras.<locals>.<genexpr>)
r:r�r4�extrasr�r8rAr]r�r�)r.Zpossible_extrasrYr%rLr&r��s
�z_PreviewTree.extrasNccs�|D]�\}}|j�|�}|dur"q|dur<|j�|�|vr<q|j�|�}|durh|jj�|jj�|��}t�	||j�
|�||�}||fVqdSr))r�r]r�rror4r�rzr�r�r_)r.Zordered_entriesr�rYr�rfr�r�r%r%r&�_make_inv_entries�s&��
�z_PreviewTree._make_inv_entriescCs�tg}g}t|�dkr�|��}|j�|�}t|�|��}tt||j	�
|���}|j|jd�|�
t|��|D]}|�||f�qnq
|S)Nrr!)rhrnrcr�r]rrr�r��zipr�r�r�rtr��reversedr�)r.�todo�ordered_idsrXr�r�r�rYr%r%r&�_list_files_by_dir�sz_PreviewTree._list_files_by_dirc#sR|�|���durt�|���fdd�|���D�}|�|�D]\}�|Vq>dS)Ncsg|]}|�f�qSr%r%)rj�child_trans_id�rYr%r&rm�r�z3_PreviewTree.iter_child_entries.<locals>.<listcomp>)r�rr%r�r�)r.r|r�r�r%r�r&�iter_child_entries�s


�z_PreviewTree.iter_child_entriesFccs@|rtd��|��}|�||�D]\}}|j�|�|fVq dS)N�(follow tree references not yet supported)r�r�r�r�r)r.r��recurse_nestedr�r�rYr%r%r&r�s��z _PreviewTree.iter_entries_by_dirc	Csrg}|�|�}|j�|�}|�|�D]}|�||f�q$g}|�|�D]\}}|�|j�|�|f�qF|��|S)zCReturn path, entry for items in a directory without recursing down.)	r�r�r]r�r�r�r�rr�)	r.Zdir_pathr�Zdir_trans_idr�r�Zpath_entriesr�rYr%r%r&�_iter_entries_for_dir�s
z"_PreviewTree._iter_entries_for_dirTc
cs�|rtd��|dkrd}|r�d}|r,|d}|��}|D]H\}}|jdkrP|sPq8|rp|�|�s`q8|t|�d�}|d|j|fVq8n`|dur�|dur�t�ddt|�	d��}	ddd|	fV|�
|p�d�}|D]\}}|d|j|fVq�dS)	zSee WorkingTree.list_files.r��.N�/r3�VTr�)r�rrW�
startswithrnr�r�r�rhr�r)
r.Zinclude_rootZfrom_dir�	recursiver�r��entriesr|r�Z
root_entryr%r%r&�
list_files�s6�
�z_PreviewTree.list_filescCs(|�|�}|durt�|��|j�|�Sr))r�rr%r�rorVr%r%r&r��s

z_PreviewTree.kindcCsP|�|�}|durt�|��z|jj|WStyJ|jj�|�YS0dSr))r�rr%r�r8r�r4r�rVr%r%r&r��s

z_PreviewTree.stored_kindcCsT|�|�}|durt�|��|�|�s>|jj�|jj�|��S|�|�}|�	|�j
S)zSee Tree.get_file_mtimeN)r�rr%r�r�r4�get_file_mtimerzr�r��st_mtime)r.r|rfrYr%r%r&r�s


�
z_PreviewTree.get_file_mtimecCsp|�|�}|durt�|��|j�|�}|dkr4dS||jjvrL|�|�jS|�|�dkrh|jj	�
|�SdSdS)zSee Tree.get_file_sizeNr�)r�rr%r�ror8r��st_sizer�r4�
get_file_size)r.r|rYr�r%r%r&r		s

z_PreviewTree.get_file_sizecCs�|�|�}|durt�|��|jj�|�}|dur@|jj�|�S|dkr~|�|��}dt	|�fWd�S1st0YdS)Nr�ZSHA1)
r�rr%r�r8rtr4�get_file_verifier�get_filer�r.r|Z
stat_valuerYr�Zfileobjr%r%r&r	s

z_PreviewTree.get_file_verifiercCs~|�|�}|durt�|��|jj�|�}|dur@|jj�|�S|dkrz|�|��}t	|�Wd�S1sp0YdSr$)
r�rr%r�r8rtr4�
get_file_sha1r
rrr%r%r&r#	s

z_PreviewTree.get_file_sha1cCsD|�|�}|durt�|��|jj�|�}|dur@|jj�|�S|Sr))r�rr%r�r=rtr4�get_reference_revision)r.r|rY�reference_revisionr%r%r&r.	s

z#_PreviewTree.get_reference_revisionc
Cs�|�|�}|durdSz|jj|WSty�z|jj�|�WYSty�}z*|jtjkrrWYd}~YdS�WYd}~n d}~0t	j
y�YYdS0Yn0dSr�)r�r�r<r�r4r�rgrhrirr%)r.r|rYrjr%r%r&r�7	s
z_PreviewTree.is_executablecCs<|�|�}||jjvrdS||jjvr*dS|jj�|�SdS)NTF)r�r�r8r;r4�has_filenamerVr%r%r&rG	s
z_PreviewTree.has_filenamecCs�|�|�}|j}|j�|�}|j�|�}|dur`|dusB||jvrFdS|j�|�}|\}}}}	n~d}	|�|�}
||j	vr|d}|dkr�t
�|
�}|j}|�
�s�d}q�|jt@}nd}d}|dkr�t
�|
�}	t|	t�s�|	�tj�}	|j�||�}||||	fS)N)r�NNN�tree-referencer�Fr�)r�r�rCrtr8r;r4r�r<r=r�rxr
rkr�rrzrBrrr�Z_fs_encr<)r.r|rYr�r�r�Zsummaryr�r�r�rmZstatvalr%r%r&r�P	s6





z!_PreviewTree.path_content_summarycCsL||jjus|s|s|r6t�||�j||||||d�S|rBtd��|j��S)z�See InterTree.iter_changes.

        This has a fast path that is only used when the from_tree matches
        the transform tree, and no fancy options are supplied.
        )�include_unchangedr�rI�extra_trees�require_versioned�want_unversionedz!want_unversioned is not supported)r�r4rrrr[)r.Z	from_treerr�rIrrrr%r%r&rp	s ���z_PreviewTree.iter_changescCsB|�|�}|�|�s"|jj�|�S|�|�}|j�|�}t|d�S)zSee Tree.get_filer8)r�r�r�r4r
r�r<r;�r.r|rfrYrWr%r%r&r
�	s


z_PreviewTree.get_filecCs|�|�dfSr))r
rr%r%r&�get_file_with_stat�	sz_PreviewTree.get_file_with_statc
Cs�|�|�}|j�|�}|dur$d}n:|j|j|j}}}|ddurJdS|ddko\|d}|rv|jjj||d�}	ng}	|dur�|	S|s�|	St	�
|	g|�|���|�S)NTrrr�)�default_revision)
r�r�rtr��	versionedr�r�r4�
annotate_iterZannotateZ
reannotater
r=)
r.r|rrfr�Zget_oldr�rr�Zold_annotationr%r%r&r�	s,
�
��z_PreviewTree.annotate_itercCsB|�|�}|�|�s"|jj�|�S|�|�}|j�|�}t�|�S)zSee Tree.get_symlink_target)	r�r�r�r4�get_symlink_targetr�r<r�rzrr%r%r&r�	s


z_PreviewTree.get_symlink_targetr3c	cs|jjg}t|�dk�r|��}g}g}|�d�}|j�|�}|j�|�}|�|�D]�}|j�|�}	|j�	|�}
|j�|�}|j�
|�}|dur�|}
nd}|jj�|jj�
|��}
|
dkr�|�|�|�|	|
|d||
f�qT|��|�|�r�||f|fV|�t||jjdd��q
dS)Nrr�unknownr�T)r"rf)r�rZrnrcr�r�rr]r�r_ror4r�rzr�r�rr�r�)r.r��pendingr�r�Zsubdirsr�r�reZpath_from_rootr�rfr�Zversioned_kindr%r%r&�walkdirs�	s<

�
�
�z_PreviewTree.walkdirscCs|jSr)�r�rLr%r%r&r��	sz_PreviewTree.get_parent_idscCs
||_dSr)r!)r.r#r%r%r&�set_parent_ids�	sz_PreviewTree.set_parent_idscCs|jj�|�Sr))r�r4�get_revision_treer�r%r%r&r#�	sz_PreviewTree.get_revision_tree)r�)N)NF)FNTF)N)N)FNNNTF)r3)4r/r0r1rXr+r�r�r�r�r�r�rYr�rr�r�rRr�r�r�r�r�rzr�r�r�r�r�rrrr�r�rrrrrr�rr�rr
rrZCURRENT_REVISIONrrr r�r"r#r%r%r%r&r�sl




	
	

�
!	

		 �
	�
 	
rcCs"|dus|dkr|St||�SdS)z:Join tree-relative paths, handling the tree root speciallyNr3)r)rXrxr%r%r&r��	sr�c@s0eZdZdZdd�Zdd�Zdd�Zdd	�Zd
S)r�z�Make path calculation cheap by memoizing paths.

    The underlying tree must not be manipulated between calls, or else
    the results will likely be incorrect.
    cCst�|�i|_||_dSr))r*r+�_known_pathsr�r�r%r%r&r+�	s
zFinalPaths.__init__cCsT||jjks|tkrdS|j�|�}|j�|�}||jjkr@|St|�|�|�SdSr�)r�rZrhr_r`rr)r.rYrWr�r%r%r&r��	szFinalPaths._determine_pathcCs$||jvr|�|�|j|<|j|S)z.Find the final path associated with a trans_id)r$r�r�r%r%r&r
s
zFinalPaths.get_pathcs�fdd�|D�S)Ncsg|]}��|�|f�qSr%)rr�rLr%r&rm
r�z(FinalPaths.get_paths.<locals>.<listcomp>r%r�r%rLr&r�
szFinalPaths.get_pathsN)r/r0r1rXr+r�rr�r%r%r%r&r��	s

r�FcCsnt���R}|�|���|�|���|dur<|�|���t|||||�Wd�S1s`0YdS)a�Create working tree for a branch, using a TreeTransform.

    This function should be used on empty trees, having a tree root at most.
    (see merge and revert functionality for working with existing trees)

    Existing files are handled like so:

    - Existing bzrdirs take precedence over creating new items.  They are
      created as '%s.diverted' % name.
    - Otherwise, if the content on disk matches the content we are building,
      it is silently replaced.
    - Otherwise, conflict resolution will move the old file to 'oldname.moved'.

    :param tree: The tree to convert wt into a copy of
    :param wt: The working tree that files will be placed into
    :param accelerator_tree: A tree which can be used for retrieving file
        contents more quickly than tree itself, i.e. a workingtree.  tree
        will be used for cases where accelerator_tree's content is different.
    :param hardlink: If true, hard-link files to accelerator_tree, where
        possible.  accelerator_tree must implement abspath, i.e. be a
        working tree.
    :param delta_from_tree: If true, build_tree may use the input Tree to
        generate the inventory delta.
    N)Zcleanup�	ExitStack�
enter_contextr�r��_build_tree)r�wt�accelerator_tree�hardlink�delta_from_treeZ
exit_stackr%r%r&�
build_tree

s

�r,c$
s�t|���D]\}}|dkrtj|jd��qi�tj��}tdd|�}|�	d�dur�|�	d�|�	d�kr�|�
|�	d��|��|��}	t
�}
�z |��|	�d��|�	d�<tj����2}g}d}t|���}
|r�g}nd}|
dk�rt
�}|��D]\}}|�dd�|D��q�t|���D�]�\}\}}|�td	�|t|�|
�|jdu�rX�q d
}|j}|�rz|�d|||f�||v�r|�|�}t|�}|dk�r�ztj�|�Wntj�y�Yn0|
�|�||
v�rt|||||��r|	� |	�|��|dk�rd}�|j}|j!d
k�r~|	�"|j#|�}|�|<|	�$||�|�%|�}|�r`|	�&||�||||j'f}|�||f�nt(||	|||��|<|�r �|}|	�|�}t)|	||��q |dt|�}t*|	||||||�Wd�n1�s�0Y|��t
�fdd�|
D����fdd�}t+|	|d�} t| �dk�rFd}t,| |	�}!|!D]}"t-�.t/|"���qTz|�0|!�Wntj1�y�Yn0|	j2d|d�}#W|	�3�|�4�n|	�3�|�4�0|#S)zSee build_tree.rr�zBuild phaser�r3Ncss|]}|dVqdS�rNr%�rjryr%r%r&r�U
r�z_build_tree.<locals>.<genexpr>z
Building treeFr�Tr�rc3s|]}�|VqdSr)r%r.)�
file_trans_idr%r&r��
r�cst||��Sr))�resolve_checkout�r�r)�divert_transr%r&�resolver�
sz_build_tree.<locals>.resolver)�	pass_func)r�r�)5r�r�rZWorkingTreeAlreadyPopulatedZbasedirr�r�r�rr�Zset_root_id�flush�
get_transformr:�
next_phaserErnr r�rr�r�rfr�r�rZ
controldirZ
ControlDirr;ZNotBranchErrorr��_content_matchrvr�rZrWrbr�r��	text_sha1�new_by_entry�_reparent_children�
_create_files�resolve_conflicts�cook_conflictsr
r�rZ
add_conflictsr�r�rNZfinished)$rr(r)r*r+r�Z_unusedZtop_pb�ppr��divertrIZdeferred_contents�totalr�Zexisting_files�dir�filesr�r�Zreparentrf�target_pathr�r�rYr�Z
trans_data�new_trans_id�
old_parentr�r3�
raw_conflictsr�r��resultr%)r2r/r&r'-
s�


���





��


�
�
�$
�
�
r'c	s�t|�|}|j}�dur"|}	�n0�j|dd�}
dd�|
D�}���rX�fdd�|D�}t|�}g}	d}|D]�\}
\}}}}|�|�}|dur�|	�|||||ff�ql|�td�|||�|r�|�	��
|�|�nl��|��P}t�
|�}|���r|�|�}t||t||��}|j|||d�Wd�n1�s60Y|d	7}ql||7}t|�|	��D]b\}\\}}}}}|���r�|�|�}t||t||��}|j|||d�|�td�|||��q`dS)
NT�rcSs,g|]$}|js|jd|jdks|j�qS)rr)r�r�r|)rj�changer%r%r&rm�
s�z!_create_files.<locals>.<listcomp>cs(g|] \}}t��|g��s||f�qSr%)r�Ziter_search_rules)rj�tpZap�r)r%r&rm�
s�rzAdding file contentsr�r)rnr4r�supports_content_filteringr�rtr�r�r�rUr�r
r��
file_iterator�_content_filter_stackrrr�r��iter_files_bytes)r�rZ
desired_filesrIr�r)r*rAr(Znew_desired_filesrZ	unchanged�countZunused_tree_pathrYrfr�r9Zaccelerator_pathry�chunks�filtersr�r%rLr&r<�
sZ�

��


�0
�

�r<cCs(|�|�D]}|�|�|�||�q
dSr))r^r\r_)r�rFrErxr%r%r&r;�
sr;cCs2|��}||D]}|�|�|�||�q||Sr))rsr\r_)r�rFrErsrxr%r%r&�_reparent_transform_children�
srTc	Cs�|j|krdS|jdkrdS|jdkr�t|d��b}|�|��8}t�||�rfWd�Wd�dSWd�n1sz0YWd�q�1s�0Yn"|jdkr�|�|�t�|�kr�dSdS)NFr�Tr�r8r�)r�r;r
r�Z
compare_filesrr�rz)rr�r�r�rD�f1�f2r%r%r&r8�
s


�Z
r8c
Cs�t�}dd�|D�D]�\}}|dkr,t|��|�|d�rL|d}|d}n|d}|d}|�|�}||vr�|�|�d}	|�|	||�|�|d||f�q|�|�d}	|�|	||�|�|d	||f�q|S)
Ncss|]}|d|fVqdSr-r%r�r%r%r&r��
r�z#resolve_checkout.<locals>.<genexpr>r�rr�z	.divertedzDiverted to�.moved�Moved existing file to)r:r�r�r`r_r\r�)
r�r�r@�
new_conflicts�c_typer�r�Zold_filer`rDr%r%r&r0�
s,

��r0cCs�|j}|j}|dkrd|�|��4}|�|�}|�||t�|�|j|�Wd�S1sX0Ynb|dvr�|�|||j�}	|dkr�|�	|j
|	�|	S|dkr�|�|�}
|�|||
|j�St
�||��dS)z2Create a new file according to its inventory entryr�N�r�rrr�)rWr�r
r�r�r�rNrfr�r�rrr�rZBadFileKindError)r|r�r�r�rrWr�ryr�rYr�r%r%r&r:s$
�$
r:c
Cs�|�|�}|dkr|�|�n�|dkr�|durD|�|�}t�|�}nd}zR|j}|��r||dur||�|�}	t||	t	||��}|�
||�W|dur�|��q�|dur�|��0n(|dkr�|�|�
|�|�ntd|��dS)aCreate new file contents according to tree contents.

    :param filter_tree_path: the tree path to use to lookup
      content filters to apply to the bytes output in the working tree.
      This only applies if the working tree supports content filtering.
    r�r�Nr�zUnknown kind %r)r�rdr
r�rNr4rMrOrrr��closer�rr�)
r�rYrr|rR�filter_tree_pathr�ryr(rSr%r%r&�create_from_trees0


�
�r^cCs|jdkr|�|j|�dS)zCSet the executability of a trans_id according to an inventory entryr�N)r�r�r�)r�r�rYr%r%r&�create_entry_executability?s
r_c	Cs�tj��}z�|����|�|���}tdd|�}t||||||�\}}	|rftj|j	d�}t�
|��|�|D]}
t�
t|
��qj|��|��|��r�|�|	�Wd�n1s�0YWd�n1s�0YW|��n
|��0|S)z;Revert a working tree's contents to those of a target tree.zRevert phase�)Zunversioned_filterN)r�r�r�r�r6r�_prepare_revert_transformZdeltaZ_ChangeReporterZ
is_ignoredZreport_changesrr
r�rr7r�Zsupports_merge_modifiedZset_merge_modifiedr�)�working_tree�target_tree�	filenames�backupsrIZchange_reporterr�r?r��merge_modifiedr�r%r%r&�revertEs(
��Hrgc
s�tj���6}|dur|��}t|�||||||�}Wd�n1sF0Ytj���$}t||�fdd��}	Wd�n1s�0Yt|	|�}
|
|fS)Ncst||��Sr))�
conflict_passr1�rcr%r&r�hr�z+_prepare_revert_transform.<locals>.<lambda>)r�r�r�rf�_alter_filesr=r>)rbrcr�rdrer?�
basis_treerfr�rGr�r%rir&ra]s�"�"
rac)CsT|dur|��|j|||d�}|�d�s0d}	nd}	�zg}
t|�D�]P\}}|j}
|j\}}|j\}}|j\}}|j\}}|j	\}}|j
\}}|	r�|dur�qD|�|
�}d}|j�r�d}|dk�rN|s�|du�rN|�
|�}|�|�|k�rN|du�r|��}|��t�||�}|�|�}|du�r:|du�rN|�sNd}n||�
|�k�rNd}|du�r�|�sj|�|�nd|du�r�|�|�} |�|| �}!|�|!| |�|�|| �}"|�r�|�r�|�|�|�|
|"�|}|"}|dv�r|�|�|dk�r�|�|�}#|�|#|�n�|dk�r"|�|�|�|�n�|dk�r�|
�||||
ff�|du�rZ|��}|��|�
|�}$t�||�}|�|�}|du�r�|$|�
|�k�r�||v�r�||=n|$||<|�r�||k�r�|�||�n|du�r�t|��|�s�|�r�|�|
|�|�r|�s|�|�|du�rz||k�s*||k�rz|dk�rD|du�rDt }%n
|�|�}%|du�rl|�rl|�!||%�n|�||%|�||krD|dkrD|�||�qD|�"��r�|�#|
�D]D\\}}}
}&|�$|
�}'|�%|'�}(t&|&|(t'|'|��}&|�(|&||��q�n*|�#|
�D]\\}}}
}&|�(|&||��q�|�)�W|du�rP|�*�n|du�rN|�*�0|S)	N)r�rIr3TFr�r[rr�)+r�rrDr�rfr|rr�rWr�r�r}r�rrtrkrZfind_source_pathrvr�r\rZrarbrdrr�r�rr�r�r�rhrgrMrPrzrOrrr�ryrR))rbrcr�rIr�rerfrkZchange_listZ	skip_rootZdeferred_filesZid_numrJrfrDZwt_pathZtarget_versionedZwt_versionedZ
target_parentZ	wt_parentZtarget_nameZwt_nameZtarget_kindZwt_kindZtarget_executableZ
wt_executablerYrQZkeep_contentZwt_sha1Zbasis_interZ
basis_pathr�Zbackup_namerEZrevisionZnew_sha1Zparent_transrCr]rSr%r%r&rjms��














�



�
��
�



�



��

�

��


�

rjcCs�|durt}t�}tj���x}td�D]T}|�td�|dd�|��}t	|�dkrj|Wd�S|�|||��q&t
|d��Wd�n1s�0YdS)z<Make many conflict-resolution attempts, but die if they failNr�zResolution passrrr�)rhr:r�r�r��ranger�r�r�rnr
)r�rIr4rY�nr�r%r%r&r=�sr=c
Cs�t�}dd�|D�D�]l\}}|dkrP|�|d�|�|d|d|df�q|dkr�|�|d�}|�|d�r�|d|d}}n|d|d}}|�|�d}	|�|	||�|�|d	||f�q|d
k�r&|d}
|�|
�s�|�|
�}
q�|�|d|
|�|
�f�|�|�|
�|�|
�|
�q|dk�r�|d}||jv�r�d
}|�	|�}
|
�r�d}|
D]8}z|�
||�Wn t�y�d
}Y�q�Yn0�q`|�r�|�|�|�dd|f�n�d
}z|�|�Wn�t
�y~|du�rz|�|�}|du�r|�|�}t|j|�|�gd��\}}|jdu�r^d}t|||j�}|D]}|�|d|f��qDn|�|j�}|�|j||�Yn0|�r�|�|�|�|d|f�q|dk�r�|�|d�}|�r�|�d�|k�r�q|�||d�|�|d|df�q|dk�rl|d}|�|�}|�|�}|�|�}|�|d||�}t|||�|du�rZ|�|�|�|d|f�q|dkr|�|d�q|S)z�Resolve some classes of conflicts.

    :param tt: The transform to resolve conflicts in
    :param conflicts: The conflicts to resolve
    :param path_tree: A Tree to get supplemental paths from
    css|]}|d|fVqdSr-r%r�r%r%r&r�
r�z conflict_pass.<locals>.<genexpr>r�rzUnversioned existing filer�r�rWrXr�zCancelled mover�TFzdeleting parentzNot deletingNr�z
Moved to rootzCreated directoryr�r3zVersioned directoryr�z.newr�)r:rar�r`r�r_r\r�r;r�r�r�rwrr]r�r�rrzr�rTrZr}rWrdr�rbr�rp)r�r�Z	path_treerYrZr�r`Z
existing_filer�rDZcurrYrwr��oZcreaterf�_r�Zmovedrxr�r�Z
parent_parent�parent_namer�Z
new_parent_idr%r%r&rhs���


�


�




����
�







�

rhcCst||�}t|tjjd�S)z8Generate a list of cooked conflicts, sorted by file pathr!)�iter_cook_conflictsr�r��ConflictZsort_key)rGr�Z
conflict_iterr%r%r&r>ps
r>c
	cs�t|�}|D]�}|d}|d}|�|d�}|�|d�}t|�dkr`tjj||||d�Vq|�|d�}|�|d�}	tjj||||||	d�VqdS)Nrrr�r`)�actionr|rf)rsr|rfZ
conflict_pathZconflict_file_id)r�rr]rnr�rr�factory)
rGr��fpr�rZrsZ
modified_pathZmodified_idZconflicting_pathZconflicting_idr%r%r&rqvs$�
�rqc@s8eZdZdZdd�Zdd�Zdd�Zdd	�Zd
d�ZdS)
r�z>Moves and deletes files for TreeTransform, tracking operationscCsg|_g|_dSr))�past_renames�pending_deletionsrLr%r%r&r+�sz_FileMover.__init__c
Cs�zt�||�Wn\tyl}zD|jtjtjfvrBt�|t|���t�	||t|�|j��WYd}~n
d}~00|j
�||f�dS)z'Rename a file from one path to another.N)r�rorgrhZEEXISTZ	ENOTEMPTYrZ
FileExists�strr�rvr��r.�from_�torjr%r%r&ro�s,z_FileMover.renamecCs|�||�|j�|�dS)z�Rename a file out of the way and mark it for deletion.

        Unlike os.unlink, this works equally well for files and directories.
        :param from_: The current file path
        :param to: A temporary path for the file
        N)rorwr�)r.rzr{r%r%r&r��sz_FileMover.pre_deletecCspt|j�D]T\}}zt�||�Wq
ty\}z"t�||t|�|j��WYd}~q
d}~00q
d|_d|_	dS)z,Reverse all renames that have been performedN)
r�rvr�rorgrr�rxrhrwryr%r%r&r��s.z_FileMover.rollbackcCs$|jD]}t|�qd|_d|_dS)zApply all marked deletionsN)rwrrvrr%r%r&r��s

z_FileMover.apply_deletionsN)	r/r0r1rXr+ror�r�r�r%r%r%r&r��s
r�cCs�|����}|j|dd�D]`}|jr$q|jdkr0q|jd|jdkrFq|�|jd�}|�|�|�|�	|jd�|�q|�
�Wd�n1s�0YdS)z�Where possible, hard-link files in a tree to those in another tree.

    :param target_tree: Tree to change
    :param source_tree: Tree to hard-link from
    TrI)r�r�rrN)r6rr�r�r�rEr|rvrUr�r�)rcZsource_treer�rJrYr%r%r&�	link_tree�s


r|)NFF)NN)FNN)NN)N)NN)N)VZ
__future__rr�rhr�rrr{r3rZ_mod_configrrr	r
r�globalsrr
rrrrrSrrZmutabletreerr�rrrrrrZprogressrZsixishrrrrr rhr'r*r(r2r[r�r�r�r�r�ZRegistryZorphaning_registry�registerZ_set_default_keyZRegistryOptionZopt_transform_orphanr�r�Z
inventorytreeZ
InventoryTreerr�r�r,r'r<r;rTr8r0r:r^r_rgrarjr=rhr>rqr�r|r%r%r%r&�<module>s�   h	��
�+6| �
#q/�
"�
�
�


n1