o ]Lbe@sHdZddlmZddlZddlZddlZddlZddlmZddl m Z ddl m Z ddl mZmZmZmZmZmZmZmZmZmZmZddlmZdd lmZd Zed Z d Z!ej"dhddZ#diddZ$ddZ%ddZ&e!fddZ'ddZ(ddZ)GdddejZ*dhdd Z+d!d"Z,djd#d$Z-dkd&d'Z.dkd(d)Z/d*d+Z0d,d-Z1d.d/Z2d0d1Z3d2d3Z4d4d5Z5dld6d7Z6d8d9Z7d:d;Z8dd?Z:d@dAZ;dBdCZdHdIZ?dJdKZ@dLdMZAdNdOZBdPdQZCdRdSZDdTdUZEGdVdWdWeFZGdXdYZHdZd[ZId\d]ZJd^d_ZKd`daZLdbdcZMGdddedeeNZOdldfdgZPdS)mzGlargefiles utility code: must not import other modules in this package.)absolute_importN)_)hex)open) dirstateencodingerrorhttpconnectionmatchpycompat requirementsscmutilsparseutilvfs)hashutil) timestamps.hglf/ largefilesTccs0t|dd}||_z dVW||_dS||_w)NlfstatusF)getattrr)repovalueoldvaluer9/usr/lib/python3/dist-packages/hgext/largefiles/lfutil.pyr,s  r cCsh|}|s|r|jtd|d}|r'zt|}Wnty&ttd|w|dur2ttd|S)Nsminsize)defaults)largefiles: size must be number (not %s) s-minimum size for largefiles must be specified)configlongnamefloat ValueErrorrAbortr)ui assumelfilesoptrlfsizerrr getminsize6s   r'c Csttj|z t||WdSty]t|d*}t|}t |D]}| |q*Wdn1scCs||d}|r |Sd}tjr-tjdtjd}|r#tj||St ddd|f}nStj rJtjd}|rAtj|dd|St d d|f}n6tj rvtjd }|r\tj||Stjd}|rltj|d |St dd d|f}n t t d tjt j t d ||d)z5Return the location of the "global" largefiles cache.s usercacheNs LOCALAPPDATAsAPPDATAs7define %s or %s in the environment, or set %s.usercachesHOMEsLibrarysCachess1define %s in the environment, or set %s.usercachesXDG_CACHE_HOMEs.cachesunknown operating system: %s sunknown %s usercache location)hint) configpathr iswindowsrenvirongetr*r+r;risdarwinisposixrr"osname)r#namer+r?appdatahomerrrr<[sN      r<cCst||}tj|SN)r>r*r+exists)r#r=r+rrr inusercaches  rLcCsnt||\}}|r|jtd||St|j|r5|jtd|t||}tt|j|||SdS)zReturn store path of the largefile with the specified hash. As a side effect, the file might be linked from user cache. Return None if the file can't be found locally.sfound %s in store sfound %s in system cache N) findstorepathr#noterrL storepathr:r>)rr=r+rKrrrfindfiles  rPcseZdZfddZfddZfddZdfdd Zfd d Zfd d ZfddZ fddZ fddZ ddZ fddZ ZS)largefilesdirstatectt|t|SrJ)superrQ __getitem__unixpath)selfkey __class__rrrTzlargefilesdirstate.__getitem__crRrJ)rSrQ set_trackedrUrVfrXrrr[rZzlargefilesdirstate.set_trackedcrRrJ)rSrQ set_untrackedrUr\rXrrr^rZz largefilesdirstate.set_untrackedNcrRrJ)rSrQnormalrU)rVr]parentfiledatarXrrr_szlargefilesdirstate.normalcrRrJ)rSrQremoverUr\rXrrrarZzlargefilesdirstate.removecrRrJ)rSrQaddrUr\rXrrrbrZzlargefilesdirstate.addcrRrJ)rSrQdroprUr\rXrrrcrZzlargefilesdirstate.dropcrRrJ)rSrQforgetrUr\rXrrrdrZzlargefilesdirstate.forgetcrRrJ)rSrQ normallookuprUr\rXrrrerZzlargefilesdirstate.normallookupcCsdSNFrr\rrr_ignoreszlargefilesdirstate._ignorecs&|r |jdddtt|ddS)Nslargefiles/dirstatesplain)location) addbackuprSrQr1)rVtrrXrrr1szlargefilesdirstate.writerJ)__name__ __module__ __qualname__rTr[r^r_rarbrcrdrergr1 __classcell__rrrXrrQs        rQc sj}t}t||}tjjv}t||jjj fddj |}|rp| ||dspt }jj |gddd} t| dkrI|||| D]} t| } |j| ddddqPWd |S1skwY|S) z Return a dirstate object that tracks largefiles: i.e. its root is the repo root, but it is saved in .hg/largefiles/dirstate. cs tSrJ)rmatcherrrrrs z openlfdirstate..sdirstateFsubreposunknownignoredrT) p1_tracked wc_trackedpossibly_dirtyN)rrvfsmodr;r DIRSTATE_V2_REQUIREMENTrQrootr _validate nodeconstantsrKgetstandinmatcherwalklenr) parentchange splitstandin update_file) r#rcreater lfstorediropeneruse_dirstate_v2 lfdirstaterostandinsstandinlfilerrpropenlfdirstates>       rc Cs|d}t}|j|gdddd\}}}|j|j}}|d} |D]O} z|t| } Wn ty7d} Ynw| rEt| t| | krK| | q"| | | |  } | j } | j }t| |}|durq| ||f}|| |q"|S)N.Frsrucleanrt)matchmodalwaysstatusmodifiedrr LookupError readasstandinhashfilewjoinappendlstatr4st_sizerreliable_mtime_of set_clean)rrpctxr unsuresmtime_boundaryrrwctxrfctxstmodesizemtime cache_datarrrlfdirstatestatuss2         rcs.|durt}fdd|DS)zNreturn a list of largefiles in the working copy or the specified changesetNcs*g|]}dusj|jrt|qSrJ)r get_entry any_trackedr.0r]rrevrr s zlistlfiles..)r~r)rrrorrr listlfiless   rFcCstjt|||S)zBReturn true if a largefile with the given hash exists in the store)r*r+rKrOrr= forcelocalrrrinstoresrcCs,|s|r|j|jt|S|jt|S)zbReturn the correct location in the repository largefiles store for a file with the given hash.)sharedrreljoin sharedpathrr;rrrrrO#s rOcCsJt||d}t||r|dfS|r!t||dr!t||ddfS|dfS)zSearch through the local store path(s) to find the file for the given hash. If the file is not found, its path in the primary store is returned. The return value is a tuple of (path, exists(path)). FT)rOrrrr=r+rrrrM+s  rMc Cs|j}t||}|durdS||||t|d%}||d}tt||}Wdn1s7wYWdn1sFwY||krc|j t d|||f| |dSdS)a.Copy the specified largefile from the repo or system cache to filename in the repository. Return true on success or false if the file was not found in either cache (which should not happened: this is meant to be called only after ensuring that the needed largefile exists in the cache).NFr(swbs'%s: data corruption in %s with hash %s T) wvfsrPr)r,r;r copyandhashrr0r#warnrunlink)rr=filenamerr+srcfddestfdgothashrrr copyfromcache=s&  rcCs\|j}t||}t||rdS||r t||||dS|jtd||fdS)Ns0%s: largefile %s not available from local store ) rrrrKcopytostoreabsoluter;r#rr)rctxfilefstandinrr=rrr copytostoreVs   rcCsD||}|D]}t|}|dur||vrt||||qdS)z4Copy all largefiles in a given revision to the storeN)filesrmanifestr)rnoderrrealfilerrrcopyalltostoreds rc Cst|j|rtt|j|t||dSttj t||t |d1}tj t|||j j d}t|D]}||q8Wdn1sJwYWdn1sYwYt||dS)Nr() createmode)rLr#r:r>rOrr)r*r+r,rr/storerr0r1linktousercache)rrr=r7r8r9rrrrns   rcCs t|j|}tt|||dS)zRLink / copy the largefile with the specified hash from the store to the cache.N)r>r#r:rOrrrrr|s rcs~|jtdd}|r/|s/fdd|D}|s#g}tj|d||d}|Stj|dg|d}|S)zDReturn a match object that applies rmatcher to the standin directorycSdSrJr)r]msgrrrrqz#getstandinmatcher..csg|]}|qSr)r;)rpat standindirrrrrsz%getstandinmatcher..N)badfn)r shortnamerrr;r r )rrmatcherrpatsr rrrr~s  r~cs(t|}|jfdd}||_|S)zReturn a matcher that accepts standins corresponding to the files accepted by rmatcher. Pass the list of files in the matcher as the paths specified by the user.cs|o t|SrJ)matchfnrr] isstandinrrrcomposedmatchfnsz.composestandinmatcher..composedmatchfn)r~r)rrsmatcherrrrrcomposestandinmatchers rcCstt|S)zLReturn the repo-relative path to the standin for the specified big file.)shortnameslashrpconvertrrrrrs rcCs |tS)zsReturn true if filename is a big file standin. filename must be in Mercurial's internal form (slash-separated).) startswithrrrrrrs rcCs6t|dd}t|dkr|dtkr|dSdS)Nrr)rrsplitrr)rbitsrrrrsrcCsJ||}|j|rt|}t|}t||||dSttd|)zRe-calculate hash value of lfile and write it into standin This assumes that "lfutil.standin(lfile) == standin", for efficiency. s%s: file not found!N) rrrKr getexecutable writestandinrr"r)rrrrr= executablerrr updatestandins  rcCs |S)zxread hex hash from given filectx of standin file This encapsulates how "standin" data is stored into storage layer.)datastrip)rrrrrs rcCs|||d|r dp ddS)z#write hash to / xN)wwrite)rrr=rrrrrsrcCs4td}|D] }||||qt|S)zRead bytes from instream (iterable) and write them to outfile, computing the SHA-1 hash of the data along the way. Return the hash.r)rsha1updater1rdigest)instreamoutfilehasherrrrrrs    rcCsFtj|sdSt|d }t|WdS1swYdS)Nrr()r*r+rKrhexsha1)rfdrrrrs  $rcCs*t|j}|tj@o|tj@o|tj@SrJ)r*r3r4S_IXUSRS_IXGRPS_IXOTH)rrrrrrs  rcGs*dd}|||}|D]}|||}q |S)NcSs0|ds |d7}|dr|dd}||S)Nrr)endswithr)leftrightrrrr;s   zurljoin..joinr)firstsecondargr;urlarrrurljoins   rcCs.t}t|D]}||q t|S)zUhexsha1 returns the hex-encoded sha1 sum of the data in the file-like object data)rrrr0rrr)fileobjhr9rrrrs  rcCst||dS)Nr()r httpsendfile)r#rrrrrsrcCsttj|S)z@Return a version of path normalized for use with the lfdirstate.)rrr*r+normpath)r+rrrrUsrUcCs8d|jvrtdd|jDrdStt|j|dS)z,Return true if the repo is a largefile repo.rcss|] }t|dvVqdS)rN)rrrrr s  zislfilesrepo..TF)r anyr datafilesrr#rprrr islfilesrepos r c@seZdZddZdS)storeprotonotcapablecC ||_dSrJ) storetypes)rVrrrr__init__" zstoreprotonotcapable.__init__N)rkrlrmrrrrrr !s r c Cspg}t|}|d}|jj|gdddD]!}t|}zt||}Wn ty-d}Ynw|||fq|S)NFrr)r~rrrrIOErrorr)rrrorrrr=rrrgetstandinsstate&s  rcCsPt|}||jvr|j|ddddS|j|}|j||j|j|jdddS)NF)rvrwT)rwrvp2_inforx)rrrrtrackedrvr)rrrre lfstandinentryrrrsynclfdirstate6s   rcCs|}t|j|}|"|||D]}t|}|dur(t|||dqWdn1s3wY||t ||dSrf) rrr#rrrrr1currenttransactionr)origrrrrr]rrrr markcommittedEs   rcCs>t|t|}g}|D]}|d|vr||dq |S)Nr)setsymmetric_differencer) oldstandins newstandinschangedstandinsfilelistr]rrrgetlfilestoupdateds r"c sjj}|tdtdt|d}t|D]\}}||fdd|D}tdd |}Wdn1sAwYt| } t|dkr| } | } | } | D] } | | vro| | qd| D] } | | vr}| | qr| D]} | | | | dks| | | | dkr| | q| D]}t|r||vr||t||qqWddS1swYdS) Nsfinding outgoing largefiless revisions)unittotalcsg|] }|jkr|qSr)nullid)rprprrrvsz%getlfilestoupload..F)rr)r# makeprogressrr enumeraterparentsrrrrp1p2rbrCrr)rmissingaddfuncr'progressinr)rrmcmp1mp2r]fnrrprgetlfilestouploadmsJ        ( "r5cs|j}|dus |rQt||}t}|j|gdddd\}}}||j|j|j}t|D]} | |vrNt | } |j | rN|j | rNt || | q2|St|| ||_t||} |jj| gdddsq|St||}D]} t| } || jrt || | qxt|}|j|jt7_g} |jD]+} t | } | vs| vr|j| js|j| jsqn|j| jsq| | q| |_fdd}||_|S)zUpdate standins in the working directory according to specified match This returns (possibly modified) ``match`` object to be used for subsequent commit process. NFrrrcs|r|vS|vSrJrrlfiles origmatchfnrrrrsz&updatestandinsbymatch..matchfn)r#rrrrraddedremovedrrrrKr _subdirlfsr_filesrrrrrrcopyrsortedrr)rr r#r dirtymatchrrr modifiedfilesrrr actualfilesr]rrr6rupdatestandinsbymatchsb             rBc@s eZdZdZddZddZdS)automatedcommithookaStateful hook to update standins at the 1st commit of resuming For efficiency, updating standins in the working directory should be avoided while automated committing (like rebase, transplant and so on), because they should be updated before committing. But the 1st commit of resuming automated committing (e.g. ``rebase --continue``) should update them, because largefiles may be modified manually. cCrrJ)resuming)rVrDrrrrrzautomatedcommithook.__init__cCs|jr d|_t||S|Srf)rDrB)rVrr rrr__call__s zautomatedcommithook.__call__N)rkrlrm__doc__rrErrrrrCs rCcCs0|durt|dr|jdS|r|jSddS)a)Return the function to write largefiles specific status out If ``forcibly`` is ``None``, this returns the last element of ``repo._lfstatuswriters`` as "default" writer function. Otherwise, this returns the function to always write out (or ignore if ``not forcibly``) status. Ns_largefilesenabledc_rrJr)roptsrrrrqrz!getstatuswriter..)r safehasattr_lfstatuswritersr)r#rforciblyrrrgetstatuswriters  rL)T)r)NN)FrJ)QrF __future__r contextlibr=r*r3mercurial.i18nrmercurial.nodermercurial.pycompatr mercurialrrrr r rr r r rrrrymercurial.utilsrmercurial.dirstateutilsrrrrcontextmanagerrr'r:r>r<rLrPrQrrrrrOrMrrrrrr~rrrrrrrrrrrrrrUr  Exceptionr rrrr"r5rBobjectrCrLrrrrsx    4    2 *(            !j