a 3۾_@sdZddlmZddlZddlZddlZddlmZmZddl m Z ddl m Z ddl mZmZmZmZmZmZmZmZmZmZmZddlmZmZmZmZmZmZm Z m!Z!m"Z"m#Z#m$Z$m%Z%m&Z&dd l'm(Z(d Z)d Z*Gd d d e+Z,Gddde,Z-Gddde-Z.Gddde,Z/Gddde+Z0Gddde0Z1ddZ2ddZ3d)ddZ4Gdd d e+Z5Gd!d"d"e+Z6d#d$Z7Gd%d&d&e,Z8d'd(Z9dS)*z/Git object store interfaces and implementation.BytesION) tree_changes walk_trees) NotTreeError)GitFile) CommitShaFileTagTreeZERO_SHA hex_to_sha sha_to_hexhex_to_filename S_ISGITLINK object_class valid_hexsha) PackPackData PackInflaterPackFileDisappeared iter_sha1pack_objects_to_datawrite_pack_headerwrite_pack_index_v2write_pack_datawrite_pack_objectcompute_file_sha PackIndexerPackStreamCopier)ANNOTATED_TAG_SUFFIXinfopackc@seZdZdZddZddZddZdd Zd d Ze d d Z ddZ ddZ ddZ ddZd2ddZd3ddZd4ddZd5ddZdddd d!dfd"d#Zd$d%Zd6d&d'Zd7d)d*Zd+d,Zeed-d!fd.d/Zd0d1ZdS)8BaseObjectStorezObject store interface.csfdd|DS)Ncs.g|]&\}}|vr|ts|tks|qS)endswithr r ).0refshaselfr$6/usr/lib/python3/dist-packages/dulwich/object_store.py Ls  z7BaseObjectStore.determine_wants_all..)items)r*Zrefsr$r)r+determine_wants_allKsz#BaseObjectStore.determine_wants_allcCs t||S)zIterate over the objects for the specified shas. Args: shas: Iterable object with SHAs Returns: Object iterator )ObjectStoreIterator)r*Zshasr$r$r+ iter_shasQszBaseObjectStore.iter_shascCst|jdS)=Check if a particular object is present by SHA1 and is loose.N)NotImplementedErrorcontains_looser*r(r$r$r+r3ZszBaseObjectStore.contains_loosecCst|jdS)>Check if a particular object is present by SHA1 and is packed.N)r2contains_packedr4r$r$r+r6^szBaseObjectStore.contains_packedcCs||p||S)Check if a particular object is present by SHA1. This method makes no distinction between loose and packed objects. )r6r3r4r$r$r+ __contains__bszBaseObjectStore.__contains__cCstdS)zIterable of pack objects.N)r2r)r$r$r+packsiszBaseObjectStore.packscCst|jdS)Obtain the raw text for an object. Args: name: sha for the object. Returns: tuple with numeric type and object contents. N)r2get_rawr*namer$r$r+r;nszBaseObjectStore.get_rawcCs||\}}tj|||dS)zObtain an object by SHA1.r()r;r Zfrom_raw_string)r*r(type_numZuncompr$r$r+ __getitem__wszBaseObjectStore.__getitem__cCst|jdS5Iterate over the SHAs that are present in this store.N)r2__iter__r)r$r$r+rC|szBaseObjectStore.__iter__cCst|jdSz3Add a single object to this object store. N)r2 add_objectr*objr$r$r+rEszBaseObjectStore.add_objectNcCst|jdSzAdd a set of objects to this object store. Args: objects: Iterable over a list of (object, path) tuples N)r2 add_objectsr*objectsprogressr$r$r+rIszBaseObjectStore.add_objectscCsX|dkr dS|\}}}zt|||||jdWntyL|Yn0|SdS)zAdd pack data to this object store. Args: num_items: Number of items to add pack_data: Iterator over pack data tuples rNcompression_level)add_packrpack_compression_level BaseException)r*countZ pack_datarLfcommitabortr$r$r+ add_pack_datas  zBaseObjectStore.add_pack_dataFc csPt|||||||dD]4}|jj|jjf|jj|jjf|jj|jjffVqdS)aFind the differences between the contents of two trees Args: source: SHA1 of the source tree target: SHA1 of the target tree want_unchanged: Whether unchanged files should be reported include_trees: Whether to include trees change_type_same: Whether to report files changing type in the same entry. Returns: Iterator over tuples with (oldpath, newpath), (oldmode, newmode), (oldsha, newsha) )want_unchanged include_treeschange_type_samerename_detectorN)roldpathnewmoder()r*sourcetargetrWrXrYrZZchanger$r$r+rs zBaseObjectStore.tree_changesccs:t||dD](\}}|jdur*t|jr.|r |Vq dS)aWIterate the contents of a tree and all subtrees. Iteration is depth-first pre-order, as in e.g. os.walk. Args: tree_id: SHA1 of the tree. include_trees: If True, include tree objects in the iteration. Returns: Iterator over TreeEntry namedtuples for all the objects in a tree. N)rr^statS_ISDIR)r*Ztree_idrXentry_r$r$r+iter_tree_contentss   z"BaseObjectStore.iter_tree_contentscCs|jSNparentsrTr$r$r+zBaseObjectStore.c Cs"t|||||||d}t|jdS)a`Find the missing objects required for a set of revisions. Args: haves: Iterable over SHAs already in common. wants: Iterable over SHAs of objects to fetch. shallow: Set of shallow commit SHA1s to skip progress: Simple progress function that will be called with updated progress strings. get_tagged: Function that returns a dict of pointed-to sha -> tag sha for including tags. get_parents: Optional function for getting the parents of a commit. Returns: Iterator over (sha, path) pairs. ) get_parentsN)MissingObjectFinderiternext) r*haveswantsshallowrL get_taggedrlZdepthfinderr$r$r+find_missing_objectss z$BaseObjectStore.find_missing_objectscCs:g}t|}|r6||vr,||||t|}q |S)zFind which revisions this store has in common using graphwalker. Args: graphwalker: A graphwalker object. Returns: List of SHAs that are in common )roappendack)r*Z graphwalkerrpr(r$r$r+find_common_revisionss   z%BaseObjectStore.find_common_revisionscCs|||||}||S)a-Iterate over the contents of a pack file. Args: have: List of SHA1s of objects that should not be sent want: List of SHA1s of objects that should be sent shallow: Set of shallow commit SHA1s to skip progress: Optional progress reporting method )rur0)r*havewantrrrLZmissingr$r$r+generate_pack_contentss z&BaseObjectStore.generate_pack_contentsTcCst|||||S)apGenerate pack data objects for a set of wants/haves. Args: have: List of SHA1s of objects that should not be sent want: List of SHA1s of objects that should be sent shallow: Set of shallow commit SHA1s to skip ofs_delta: Whether OFS deltas can be included progress: Optional progress reporting method )rr{)r*ryrzrrrLZ ofs_deltar$r$r+generate_pack_datas z"BaseObjectStore.generate_pack_datacCs2||}t|j}|tur.|j\}}||}q|S)aPeel all tags from a SHA. Args: sha: The object SHA to peel. Returns: The fully-peeled SHA1 of a tag object, after peeling all intermediate tags; if the original ref does not point to a tag, this will equal the original SHA1. )rZ type_namer object)r*r(rGZ obj_classr$r$r+peel_sha s    zBaseObjectStore.peel_shacCs|jSrfrgrir$r$r+rjrkc Csxt}t}g}|||rp|d}||vr<||q||vr||||vrXq||} ||| q||fS)aCollect all ancestors of heads up to (excluding) those in common. Args: heads: commits to start from common: commits to end at, or empty set to walk repository completely get_parents: Optional function for getting the parents of a commit. Returns: a tuple (A, B) where A - all commits reachable from heads but not present in common, B - common (shared) elements that are directly reachable from heads r)setextendpopadd) r*headscommonrrrlbasescommitsZqueueecmtr$r$r+_collect_ancestorss    z"BaseObjectStore._collect_ancestorscCsdS)z,Close any files opened by this object store.Nr$r)r$r$r+close:szBaseObjectStore.close)N)N)FFFN)F)NN)NNT)__name__ __module__ __qualname____doc__r.r0r3r6r8propertyr9r;r@rCrErIrVrrerurxr{r|r~rrrr$r$r$r+r#HsD           r#c@seZdZd-ddZeddZddZdd Zd d Zd d Z ddZ ddZ ddZ eddZ ddZddZddZddZddZd d!Zd"d#Zd$d%Zd&d'Zd(d)Zd.d+d,Zd*S)/PackBasedObjectStorecCsi|_||_dSrf) _pack_cacherP)r*rPr$r$r+__init__AszPackBasedObjectStore.__init__cCsgSrfr$r)r$r$r+ alternatesEszPackBasedObjectStore.alternatesc Cs8|jD],}z||vrWdSWqty0Yq0qdS)zpCheck if a particular object is present by SHA1 and is packed. This does not check alternates. TF)r9r)r*r(r"r$r$r+r6Is   z$PackBasedObjectStore.contains_packedcCs6||s||rdS|jD]}||vrdSqdS)r7TF)r6r3r)r*r( alternater$r$r+r8Vs  z!PackBasedObjectStore.__contains__cCs.|j|}||ur*||j|<|r*|dS)z9Add a newly appeared pack to the cache by path. N)rgetr)r*Z base_namer"Z prev_packr$r$r+_add_cached_packbs   z%PackBasedObjectStore._add_cached_packcCs*|j}i|_|r&|\}}|q dSrf)rpopitemr)r*Z pack_cacher=r"r$r$r+_clear_cached_packsls  z(PackBasedObjectStore._clear_cached_packscCs |jSrf)rvaluesr)r$r$r+_iter_cached_packsssz'PackBasedObjectStore._iter_cached_packscCst|jdSrf)r2_update_pack_cacher)r$r$r+rvsz'PackBasedObjectStore._update_pack_cachecCs |dSrf)rr)r$r$r+ryszPackBasedObjectStore.closecCst|t|SzList with pack objects.)listrrr)r$r$r+r9|szPackBasedObjectStore.packsccs |jD]}|D] }|VqqdS)z=Iterate over the SHAs of all the objects in alternate stores.N)r)r*rZalternate_objectr$r$r+_iter_alternate_objectss z,PackBasedObjectStore._iter_alternate_objectscCst|jdS)z+Iterate over the SHAs of all loose objects.N)r2_iter_loose_objectsr)r$r$r+rsz(PackBasedObjectStore._iter_loose_objectscCst|jdSrf)r2_get_loose_objectr4r$r$r+rsz&PackBasedObjectStore._get_loose_objectcCst|jdSrf)r2_remove_loose_objectr4r$r$r+rsz)PackBasedObjectStore._remove_loose_objectcCst|jdSrf)r2 _remove_packr<r$r$r+rsz!PackBasedObjectStore._remove_packcCsXt}|D]}|||dfq|t||D]\}}||jq:t|S)zGPack loose objects. Returns: Number of objects packed N) rrrrrIrridlen)r*rKr(rGr\r$r$r+pack_loose_objectss  z'PackBasedObjectStore.pack_loose_objectsc Cst}|D]}|||qdd|D}dd|jD}|D] \}}|dd|DqJ||}| | d|D]}| |j q|D]\}}| |q|t|S)zRepack the packs in this repository. Note that this implementation is fairly naive and currently keeps all objects in memory while it repacks. cSsh|] }|dfqSrfr$r&rGr$r$r+ rkz.PackBasedObjectStore.repack..cSsi|]}||qSr$)r=r&pr$r$r+ rkz/PackBasedObjectStore.repack..css|]}|dfVqdSrfr$rr$r$r+ rkz.PackBasedObjectStore.repack..N)rrrrr9r-update iterobjectsrIrr=rrrrr) r*Z loose_objectsr(rKZ old_packsr=r"Z consolidatedrGr$r$r+repacks   zPackBasedObjectStore.repackc csj||D],}z|D] }|VqWqty:Yq0q|D] }|VqF|D] }|VqZdSrA)rrrrr)r*r"r(r$r$r+rCs     zPackBasedObjectStore.__iter__cCs||duS)zoCheck if a particular object is present by SHA1 and is loose. This does not check alternates. N)rr4r$r$r+r3sz#PackBasedObjectStore.contains_loosec Cs$|tkrt|t|dkr*t|}|}n$t|dkr@|}d}ntd|f|D],}z||WSttfyYqV0qV|durt|}| |}|dur|j | fS| D](}z||WStyYq0q|j D]*}z||WStyYq0qt|dS)zObtain the raw fulltext for an object. Args: name: sha for the object. Returns: tuple with numeric type and object contents. (NzInvalid object name %r)r KeyErrorrr AssertionErrorrr;rrrr? as_raw_stringrr)r*r=r(Zhexshar"retrr$r$r+r;s<       zPackBasedObjectStore.get_rawNcCs|jt|d|iS)zAdd a set of objects to this object store. Args: objects: Iterable over (object, path) tuples, should support __len__. Returns: Pack object of the objects written. rL)rVrrJr$r$r+rIs z PackBasedObjectStore.add_objects)r)N)rrrrrrr6r8rrrrrr9rrrrrrrrCr3r;rIr$r$r$r+r?s.       )rcseZdZdZd)fdd ZddZeddZed d Z d d Z d dZ ddZ ddZ ddZddZddZddZddZddZdd Zd!d"Zd#d$Zd%d&Zed'd(ZZS)*DiskObjectStorez+Git-style object store that exists on disk.rcs@tt|j|d||_tj|jt|_d|_||_ ||_ dS)zOpen an object store. Args: path: Path of the object store. loose_compression_level: zlib compression level for loose objects pack_compression_level: zlib compression level for pack objects )rPN) superrrr\osjoinPACKDIRpack_dir _alternatesloose_compression_levelrP)r*r\rrP __class__r$r+r s zDiskObjectStore.__init__cCsd|jj|jfS)Nz<%s(%r)>)rrr\r)r$r$r+__repr__szDiskObjectStore.__repr__cCszt|dd}Wnty.d}Yn0zt|dd}Wnty^|}Yn0zt|dd}Wnty|}Yn0||||S)N)scores compressionrslooseCompressionZpackCompression)intrdecoder)clsr\ZconfigZdefault_compression_levelrrPr$r$r+ from_config s&      zDiskObjectStore.from_configcCs:|jdur|jSg|_|D]}|jt|q|jSrf)r_read_alternate_pathsrvr)r*r\r$r$r+r3s   zDiskObjectStore.alternatesc cszttj|jtdd}Wnty0YdS0|l|D]R}|d}|drZq@tj |rtt |Vq@t tjt |j|Vq@Wdn1s0YdS)Nrrb #) rrr\rINFODIRFileNotFoundError readlinesrstrip startswithisabsfsdecodefsencode)r*rSliner$r$r+r<s     z%DiskObjectStore._read_alternate_pathsc Cszttj|jtWnty,Yn0tj|jtd}t|dx}zt|d}WntylYn40|| | Wdn1s0Y| t |dWdn1s0Ytj |stj|j|}|j t|dS)z4Add an alternate path to this object store. rwbrNr)rmkdirr\rrFileExistsErrorropenrwritereadrrrrvr)r*r\Zalternates_pathrSZorig_fr$r$r+add_alternate_pathLs    ,2 z"DiskObjectStore.add_alternate_pathc Cszt|j}Wnty.|gYS0t}|D]P}|dr:|dr:tj |dd}||vr:|dt d }| |q:g}|D]6}||j vrt tj|j|}||||j |<qt|j |D]}|j |q|S)z4Read and iterate over new pack files and cache them.pack-.packr.idxN)rlistdirrrrrrr%r\splitextrrrrrrvr) r*Zpack_dir_contentsZ pack_filesr=Zidx_nameZ pack_nameZ new_packsrSr"r$r$r+rbs*      z"DiskObjectStore._update_pack_cachecCs t|j|Srf)rr\r4r$r$r+_get_shafile_pathsz!DiskObjectStore._get_shafile_pathccs^t|jD]L}t|dkrq ttj|j|D]"}t||}t|sPq4|Vq4q dS)N)rrr\rrrr)r*baserestr(r$r$r+rs z#DiskObjectStore._iter_loose_objectscCs0||}z t|WSty*YdS0dSrf)rr Z from_pathrr*r(r\r$r$r+rs    z!DiskObjectStore._get_loose_objectcCst||dSrf)rremoverr4r$r$r+rsz$DiskObjectStore._remove_loose_objectcCsRz|jtj|j=Wnty(Yn0|t|jjt|j jdSrf) rrr\basename _basenamerrrdataindex)r*r"r$r$r+rs zDiskObjectStore._remove_packcCs0tdd|D}|d}tj|jd|S)Ncss|]}|dVqdS)rNr$)r&rcr$r$r+rrkz5DiskObjectStore._get_pack_basepath..asciir)rrrr\rr)r*entriessuffixr$r$r+_get_pack_basepaths z"DiskObjectStore._get_pack_basepathcCspt|}|dt|t|t||t|dd}|dtj|D]N}t|dksjJ| |\}} | } t ||| ||j d} | || | fqV|} || ||||} | d}tjdkr zt|WntyYn0t||t| dd }z t||| |W|n |0t| }||| ||S) aMove a specific file containing a pack into the pack directory. Note: The file should be on the same file system as the packs directory. Args: f: Open file object for the pack. path: Path to the pack file. copier: A PackStreamCopier to use for writing pack data. indexer: A PackIndexer for indexing the pack. rZend_ofsr)r(rNrwin32rr)rseekrrext_refsflushrrSEEK_CURr;tellrrPrvdigestrrsortrsysplatformrrrenamerrrUrZcheck_length_and_checksumr)r*rSr\copierindexerrnew_shaext_shar?roffsetZcrc32pack_shaZpack_base_name target_packZ index_file final_packr$r$r+_complete_thin_packsH           z#DiskObjectStore._complete_thin_packc Csddl}|j|jdd\}}t|dF}t||jd}t||||d}|| ||||WdS1st0YdS)awAdd a new thin pack to this object store. Thin packs are packs that contain deltas with parents that exist outside the pack. They should never be placed in the object store directly, and always indexed and completed as they are copied. Args: read_all: Read function that blocks until the number of requested bytes are read. read_some: Read function that returns at least one byte, but may not return the number of bytes requested. Returns: A Pack object pointing at the now-completed thin pack in the objects/pack directory. rNZ tmp_pack_)dirprefixzw+bZresolve_ext_refZ delta_iter) tempfilemkstempr\rfdopenrr;rverifyr) r*read_all read_somerfdr\rSrrr$r$r+ add_thin_packszDiskObjectStore.add_thin_packc Cst|p}|}||}|d}tj|sjt|d }t|||Wdn1s`0YWdn1s~0Y|j D]}|j |kr|Sq|d}t j dkrzt |WntyYn0t||t|} ||| | S)zMove a specific file containing a pack into the pack directory. Note: The file should be on the same file system as the packs directory. Args: path: Path to the pack file. rrNrr)rZsorted_entriesrrr\existsrrZget_stored_checksumr9rrrrrrrr) r*r\rrrZ index_namerSr"rrr$r$r+ move_in_packs(    L       zDiskObjectStore.move_in_packcsRddl}|jjdd\tdfdd}fdd }||fS) zAdd a new pack to this object store. Returns: Fileobject to write to, a commit function to call when the pack is finished and an abort function. rNr)rrrcsFttjdkr4StdSdS)Nr)rrfsyncrr\getsizerrr$rSr r\r*r$r+rT,s   z(DiskObjectStore.add_pack..commitcstdSrf)rrrr$)rSr\r$r+rU6sz'DiskObjectStore.add_pack..abort)rrrrr)r*rrTrUr$rr+rO!s   zDiskObjectStore.add_packcCs||j}tj|}zt|Wnty8Yn0tj|rJdSt|d$}| |j |j dWdn1s~0YdS)z^Add a single object to this object store. Args: obj: Object to add NrrM) rrrr\dirnamerrrrrZas_legacy_objectr)r*rGr\rrSr$r$r+rE;s     zDiskObjectStore.add_objectcCsRzt|Wnty Yn0ttj|dttj|t||S)Nr!)rrrr\rr)rr\r$r$r+initMs zDiskObjectStore.init)rr)rrrrrr classmethodrrrrrrrrrrrrrr rrOrEr __classcell__r$r$rr+r s2    C rcseZdZdZfddZddZddZdd Zd d Ze d d Z ddZ ddZ ddZ ddZdddZddZddZddZZS) MemoryObjectStorez.Object store that keeps all objects in memory.cstt|i|_d|_dS)Nr)rrr_datarPr)rr$r+r[szMemoryObjectStore.__init__cCs6t|dkr|St|dkr$t|Std|fdS)NrrzInvalid sha %r)rr ValueErrorr4r$r$r+ _to_hexsha`s   zMemoryObjectStore._to_hexshacCs|||jvS)r1)rrr4r$r$r+r3hsz MemoryObjectStore.contains_loosecCsdS)r5Fr$r4r$r$r+r6lsz!MemoryObjectStore.contains_packedcCst|jS)rB)rnrkeysr)r$r$r+rCpszMemoryObjectStore.__iter__cCsgSrr$r)r$r$r+r9tszMemoryObjectStore.packscCs|||}|j|fS)r:)rr?r)r*r=rGr$r$r+r;yszMemoryObjectStore.get_rawcCs|j||Srf)rrcopyr<r$r$r+r@szMemoryObjectStore.__getitem__cCs|j||=dS)z3Delete an object from this store, for testing only.N)rrr<r$r$r+ __delitem__szMemoryObjectStore.__delitem__cCs||j|j<dSrD)rrrrFr$r$r+rEszMemoryObjectStore.add_objectNcCs|D]\}}||qdSrH)rE)r*rKrLrGr\r$r$r+rIs zMemoryObjectStore.add_objectscs&tfdd}dd}||fS)aAdd a new pack to this object store. Because this object store doesn't support packs, we extract and add the individual objects. Returns: Fileobject to write to and a commit function to call when the pack is finished. csBtt}t|jD]} |q.dSrf) rZ from_filergetvaluerrrZ for_pack_datar;rE)rrGrSr*r$r+rTsz*MemoryObjectStore.add_pack..commitcSsdSrfr$r$r$r$r+rUsz)MemoryObjectStore.add_pack..abortr)r*rTrUr$rr+rOs zMemoryObjectStore.add_packc Cst|}|dt|t|t|t|dd}|D]2}t|dksTJ||\}}t||||dq@|}| |dS)zComplete a thin pack by adding external references. Args: f: Open file object for the pack. indexer: A PackIndexer for indexing the pack. rrrrr>N) rrrrrrr;rrr) r*rSrrrrr?rrr$r$r+rs   z%MemoryObjectStore._complete_thin_packcCsj|\}}}z6t||jd}t||||d}||||Wnty^|Yn0|dS)aAdd a new thin pack to this object store. Thin packs are packs that contain deltas with parents that exist outside the pack. Because this object store doesn't support packs, we extract and add the individual objects. Args: read_all: Read function that blocks until the number of requested bytes are read. read_some: Read function that returns at least one byte, but may not return the number of bytes requested. rrN)rOrr;rr rrQ)r*r r rSrTrUrrr$r$r+r s  zMemoryObjectStore.add_thin_pack)N)rrrrrrr3r6rCrr9r;r@rrErIrOrr rr$r$rr+rXs     rc@seZdZdZddZdS)ObjectIteratorz%Interface for iterating over objects.cCst|jdSrf)r2rr)r$r$r+rszObjectIterator.iterobjectsN)rrrrrr$r$r$r+r sr c@s`eZdZdZddZddZddZdd Zd d Zd d Z ddZ ddZ ddZ ddZ dS)r/z3ObjectIterator that works on top of an ObjectStore.cCs||_||_g|_dS)zCreate a new ObjectIterator. Args: store: Object store to retrieve from sha_iter: Iterator over (sha, path) tuples N)storesha_iter_shas)r*r!r"r$r$r+rszObjectStoreIterator.__init__ccs&|D]\}}|j||fVqdS)z&Yield tuple with next object and path.N)itershasr!rr$r$r+rCszObjectStoreIterator.__iter__ccs|D]\}}|VqdS)zIterate over just the objects.Nr$)r*or\r$r$r+rs zObjectStoreIterator.iterobjectsccs4|jD] }|Vq|jD]}|j||VqdS)zIterate over the SHAs.N)r#r"rvr4r$r$r+r$s    zObjectStoreIterator.itershascCs|tkr dS||jvS)aCheck if an object is present. Note: This checks if the object is present in the underlying object store, not if it would be yielded by the iterator. Args: needle: SHA1 of the object to check for F)r r!)r*Zneedler$r$r+r8 s z ObjectStoreIterator.__contains__cCs |j|S)zFind an object by SHA1. Note: This retrieves the object from the underlying object store. It will also succeed if the object would not be returned by the iterator. )r!)r*keyr$r$r+r@szObjectStoreIterator.__getitem__cCstt|S)zReturn the number of objects.)rrr$r)r$r$r+__len__ szObjectStoreIterator.__len__cCsddl}|dt|S)NrzUse bool() instead.)warningswarnDeprecationWarning_empty)r*r(r$r$r+empty$s zObjectStoreIterator.emptycCs2|}z t|Wnty(YdS0dSdSNTF)r$ro StopIteration)r*itr$r$r+r+)s   zObjectStoreIterator._emptycCs | S)z*Indicate whether this object has contents.)r+r)r$r$r+__bool__2szObjectStoreIterator.__bool__N)rrrrrrCrr$r8r@r'r,r+r0r$r$r$r+r/s   r/cCs&||}t|tst||||S)zLook up an object in a Git tree. Args: lookup_obj: Callback for retrieving object by SHA1 root_sha: SHA1 of the root tree path: Path to lookup Returns: A tuple of (mode, SHA) of the resulting path. ) isinstancer rZ lookup_path)Z lookup_objZroot_shar\treer$r$r+tree_lookup_path7s  r3cCsP||}|D]:\}}}t|s||vr||t|rt|||qdS)zCollect SHA1s of files and directories for specified tree. Args: obj_store: Object store to get objects by SHA from tree_sha: tree reference to walk kset: set to fill with references to files and directories N) iteritemsrrrarb_collect_filetree_revs) obj_storeZtree_shaZksetZfiletreer=r^r(r$r$r+r5Fs   r5Fc Cst}t}t}|D]}z ||}Wnty>|s:Yq0t|trV||qt|tr|||jd}t||g|d\} } }|| O}|| O}||O}q||q|||fS)a4Split object id list into three lists with commit, tag, and other SHAs. Commits referenced by tags are included into commits list as well. Only SHA1s known in this repository will get through, and unless ignore_unknown argument is True, KeyError is thrown for SHA1 missing in the repository Args: obj_store: Object store to get objects by SHA1 from lst: Collection of commit and tag SHAs ignore_unknown: True to skip SHA1 missing in the repository silently. Returns: A tuple of (commits, tags, others) SHA1s )ignore_unknown)rrr1rrr r}_split_commits_and_tags) r6Zlstr8rZtagsZothersrr%Ztaggedctr$r$r+r9Vs,          r9c@s:eZdZdZdddddfddZddZd d ZeZdS) rma1Find the objects missing from another object store. Args: object_store: Object store containing at least all objects to be sent haves: SHA1s of commits not to send (already present in target) wants: SHA1s of commits to send progress: Optional function to report progress to. get_tagged: Function that returns a dict of pointed-to sha -> tag sha for including tags. get_parents: Optional function for getting the parents of a commit. tagged: dict of pointed-to sha -> tag sha for including tags NcCs|jSrfrgrir$r$r+rjrkzMissingObjectFinder.cCs(||_|durt}||_t||d\}} } t||d\} } } |j|||jdd}|j| |||jd\}}t|_|D](}|j|||}t||j|jqx| D]}|j|q| | }| | }| |}| |}tdd|D|_ |dur dd|_ n||_ |r|p i|_ dS) NTF)rrrlrcSsg|]}|ddfqS)NFr$)r&wr$r$r+r,rkz0MissingObjectFinder.__init__..cSsdSrfr$)xr$r$r+rjrkz.MissingObjectFinder.__init__..) object_storerZ _get_parentsr9rsha_donerr5r2 differenceunionobjects_to_sendrL_tagged)r*r>rprqrrrLrsrlZ have_commitsZ have_tagsZ have_othersZ want_commitsZ want_tagsZ want_othersZ all_ancestorsZmissing_commitsZcommon_commitshrr;Z missing_tagsZmissing_othersr$r$r+rsB          zMissingObjectFinder.__init__csjfdd|DdS)Ncsg|]}|djvr|qS)r)r?)r&rr)r$r+r,sz0MissingObjectFinder.add_todo..)rBr)r*rr$r)r+add_todoszMissingObjectFinder.add_todocCs|js dS|j\}}}||jvrq(q|s|j|}t|trV||jddfgnFt|trz|dd| Dn"t|t r||j dddfg||j vr||j |ddfg|j ||dt|jd||fS) NFcSs,g|]$\}}}t|s||t| fqSr$)rrarb)r&nmsr$r$r+r,sz,MissingObjectFinder.next..r7Tzcounting objects: %d r)rBrr?r>r1rrEr2r r4r r}rCrrLrencode)r*r(r=Zleafr%r$r$r+ros0         zMissingObjectFinder.next)rrrrrrEro__next__r$r$r$r+rm~s 5rmc@s.eZdZdZd ddZddZddZeZdS) ObjectStoreGraphWalkerzGraph walker that finds what commits are missing from an object store. :ivar heads: Revisions without descendants in the local repo :ivar get_parents: Function to retrieve parents in the local repo NcCs.t||_||_i|_|dur$t}||_dS)zCreate a new instance. Args: local_heads: Heads to start search with get_parents: Function for finding the parents of a SHA1. N)rrrlrhrr)r*Z local_headsrlrrr$r$r+rs  zObjectStoreGraphWalker.__init__cCst|dkrtd|t|g}|jr|D]}||jvr,|j|q,t}|D],}|j|}|durt||d|j|<qR|sq|}q"dS)z@Ack that a revision and its ancestors are present in the source.rzunexpected sha %r receivedN)rrrrrrhrr)r*r(Z ancestorsaZ new_ancestorspsr$r$r+rws        zObjectStoreGraphWalker.ackcsFjrBj}|}|j|<jfdd|D|SdS)z.Iterate over ancestors of heads in the target.csg|]}|jvr|qSr$rgrr)r$r+r,rkz/ObjectStoreGraphWalker.next..N)rrrlrhr)r*rrNr$r)r+ros   zObjectStoreGraphWalker.next)N)rrrrrrwrorKr$r$r$r+rLs   rLc Csi}|D]f\}}}z|dd\}}Wn.tyT|durD||=n ||f||<Yq0||g|||fq|D]f\} } z||| d} Wntyt} Yn0t|| | } t| dkr|| =qxt j | j f|| <qx| ||S)aCommit a specified set of changes to a tree structure. This will apply a set of changes on top of an existing tree, storing new objects in object_store. changes are a list of tuples with (path, mode, object_sha). Paths can be both blobs and trees. See the mode and object sha to None deletes the path. This method works especially well if there are only a small number of changes to a big tree. For a large number of changes to a large tree, use e.g. commit_tree. Args: object_store: Object store to store new objects in and retrieve old ones from. tree: Original tree root changes: changes to apply Returns: New tree root object /r7Nr) splitr setdefaultrvr-rr commit_tree_changesrraS_IFDIRrrE) r>r2ZchangesZnested_changesr\Znew_moderrZsubpathr=Z subchangesZ orig_subtreeZsubtreer$r$r+rRs,       rRc@sXeZdZdZdddZddZdddZed d Zd d Z d dZ ddZ ddZ dS)OverlayObjectStorez5Object store that can overlay multiple object stores.NcCs||_||_dSrf)r add_store)r*rrUr$r$r+rRszOverlayObjectStore.__init__cCs |jdurt|j|j|Srf)rUr2rE)r*r}r$r$r+rEVs  zOverlayObjectStore.add_objectcCs"|jdurt|j|j||Srf)rUr2rErIrJr$r$r+rI[s  zOverlayObjectStore.add_objectscCs g}|jD]}||jq |Srf)rrr9)r*rbr$r$r+r9`s zOverlayObjectStore.packsccs8t}|jD]&}|D]}||vr|V||qq dSrf)rrr)r*ZdonerVZo_idr$r$r+rCgs  zOverlayObjectStore.__iter__c Cs<|jD](}z||WSty,Yq0qt|dSrf)rr;r)r*Zsha_idrVr$r$r+r;os   zOverlayObjectStore.get_rawcCs |jD]}||rdSqdSr-)rr6r*r(rVr$r$r+r6ws  z"OverlayObjectStore.contains_packedcCs |jD]}||rdSqdSr-)rr3rWr$r$r+r3}s  z!OverlayObjectStore.contains_loose)N)N) rrrrrrErIrr9rCr;r6r3r$r$r$r+rTOs   rTccsB|D]0}|sq |dd\}}|dkr0q t|Vq dS)z'Yield the packs listed in a packs file. r7PN)r splitlinesrPrr)rSrkindr=r$r$r+read_packs_filesr\)F):riorrrarZdulwich.diff_treerrZdulwich.errorsrZ dulwich.filerZdulwich.objectsrr r r r r rrrrrZ dulwich.packrrrrrrrrrrrrrZ dulwich.refsr rrr}r#rrrr r/r3r5r9rmrLrRrTr\r$r$r$r+s>   4 < xKQ N (c=15