o ]Lb@sddlmZddlZddlZddlZddlZddlZddlZddlZddl Z ddl Z ddl m Z ddlmZmZmZddlmZmZmZmZmZmZmZmZmZmZmZmZm Z m!Z"ddl#m$Z$m%Z%m&Z&m'Z'da(ej)Z)ej*Z*ej+Z+e j,Z,dd Z-d d Z.Gd d d ej/Z0ddZ1ddZ2ddZ3ddZ4ddddZ5ddZ6d(ddZ7ddZ8Gdd d e9Z:Gd!d"d"e:Z;Gd#d$d$e:ZdS)))absolute_importN)_)binhexshort)cmdutilencodingerrorexchange logcmdutilmatchmergepathutilphasespycompatscmutil subrepoutilutilvfs)dateutilhashutilprocutilurlutilcCs6tt|}t|}|jstt|j}|S)zU get a path or url and if it is a path expand it and return an absolute path ) r urllocalpathr expandpathurlschemenormpathabspathpath)r expandedpathur#3/usr/lib/python3/dist-packages/mercurial/subrepo.py_expandedabspath8s  r%cCsttt|ddS)zEget a unique filename for the store hash cache of a remote repositoryr )rrsha1r%digest) remotepathr#r#r$_getstorehashcachenameCsr*c@seZdZdZddZdS) SubrepoAbortzEException class used to avoid handling a subrepo error more than oncecOs:|dd|_|dd|_tjj|g|Ri|dS)Nsubrepocause)popr,r-r Abort__init__)selfargskwr#r#r$r0KszSubrepoAbort.__init__N)__name__ __module__ __qualname____doc__r0r#r#r#r$r+Hs r+csfdd}|S)Nc sz|g|Ri|}W|Sty}z|d}~wtjyB}zt|}|jdtd|}t||j|tdd}~ww)N s(in subrepository "%s"))hintr,r-) r+r r/ subrelpathmessagerr9sysexc_info)r1r2kargsresexr,errormsgfuncr#r$decoratedmethodRs z-annotatesubrepoerror..decoratedmethodr#)rCrDr#rBr$annotatesubrepoerrorQs rEcCs>|rtdt|||f}n tdt|||f}||dS)Ns subrepository sources for %s differ you can use (l)ocal source (%s) or (r)emote source (%s). what do you want to do?$$ &Local $$ &Remotes subrepository sources for %s differ (in checked out version) you can use (l)ocal source (%s) or (r)emote source (%s). what do you want to do?$$ &Local $$ &Remoter)rr: promptchoice)uisubdirtylocalremotemsgr#r#r$ _updatepromptfs   rMc Cs|D]C\}}}t|D]\}}||kr||=nq ||dkr'q|D]}|dkrF|td||||||q)qdS)Ns.hghgrcs5warning: removing potentially hostile 'hgrc' in '%s' ) walk enumeratelowerbasenamewarnrjoinunlinkreljoin) rGrignoredirnamedirsnamesidfr#r#r$ _sanitizeys*  r^cCsd|dsd|vst||krttd|t|j||j |r0ttd|dS)N~$+subrepo path contains illegal component: %ss$subrepo '%s' traverses symbolic link) startswithrrr r/rr pathauditorrootwvfsislink)repor r#r#r$_auditsubrepopaths   rhTF)hggitsvncCsz|dddstjtdtddt|d}|dd||s.tjtd |tdd|tvr;ttd |dS) NsubrepossallowedTssubrepos not enableds)see 'hg help config.subrepos' for detailsr9Fs %s:alloweds%s subrepos not allowedsunknown subrepo type %s) configboolr r/rSUBREPO_ALLOWED_DEFAULTSgettypes)rGkinddefaultr#r#r$ _checktypes  rtcCsvddlm}|a|}t|||j|}t|j|d|r,|d|||df}t|d|||dd|S)z>return instance of the right subrepo class for subrepo in pathrhgrN) rvrgrhsubstatertrGsubrevrq)ctxr allowwdir allowcreatehrgstater#r#r$r,s   r,cCsnddlm}|a|}t|||j|}t|j|dd}|ddkr(d}t|d|||d|fdS) z=return an empty subrepo in pctx for the extant subrepo in ctxrrurwris(0000000000000000000000000000000000000000rT)rxrvrgrhryrtrGrq)r{r pctxr~rgrrzr#r#r$ nullsubrepos    rc@sBeZdZddZddZddZdLdd ZdLd d ZdMd dZddZ ddZ ddZ ddZ ddZ dNddZddZddZdd Zd!d"Zd#d$Zd%d&Zd'd(Zd)d*Zd+d,Zd-d.Zd/d0Zd1d2ZdOd3d4Zd5d6ZdPd8d9Zd:d;Zdd?Z d@dAZ!dBdCZ"dDdEZ#dNdFdGZ$e%dHdIZ&e%dJdKZ'd S)QabstractsubrepocCs|j|_||_||_dS)zInitialize abstractsubrepo part ``ctx`` is the context referring this subrepository in the parent repository. ``path`` is the path to this subrepository as seen from innermost repository. N)rgrG_ctx_path)r1r{r r#r#r$r0s  zabstractsubrepo.__init__cCdS)zAdd the hgwebdir entries for this subrepo, and any of its subrepos. ``serverpath`` is the path component of the URL for this repo. ``webconf`` is the dictionary of hgwebdir entries. Nr#r1 serverpathwebconfr#r#r$ addwebdirpathszabstractsubrepo.addwebdirpathcCr)z returns true if the repository has not changed since it was last cloned from or pushed to a given repository. Fr#r1r r#r#r$ storecleanzabstractsubrepo.storecleanFcCt)a returns true if the dirstate of the subrepo is dirty or does not match current stored state. If ignoreupdate is true, only check whether the subrepo has uncommitted changes in its dirstate. If missing is true, check for deleted files. NotImplementedErrorr1 ignoreupdatemissingr#r#r$rIzabstractsubrepo.dirtycCs"|j||drtdt|SdS)zreturn reason string if it is ``dirty()`` Returned string should have enough information for the message of exception. This returns None, otherwise. rrs)uncommitted changes in subrepository "%s"N)rIrr:rr#r#r$ dirtyreasons zabstractsubrepo.dirtyreasonNcCs$|j|dd}|rtj||ddS)z+raise Abort if subrepository is ``dirty()``TrrmN)rr r/)r1rr9rr#r#r$ bailifchangedszabstractsubrepo.bailifchangedcCr)zpcurrent working directory base state, disregarding .hgsubstate state and working directory modificationsrr1r#r#r$ basestateszabstractsubrepo.basestatecCr)z7check if path is a subrepository within this repositoryFr#rr#r#r$ checknestedzabstractsubrepo.checknestedcCr)zcommit the current changes to the subrepo with the given log message. Use given user and date if possible. Return the new state of the subrepo. r)r1textuserdater#r#r$commit"rzabstractsubrepo.commitcCstjS)z6returns phase of specified state in the subrepository.)rpublicr1rr#r#r$phase)szabstractsubrepo.phasecCr)zTremove the subrepo (should verify the dirstate is not dirty first) rrr#r#r$remove-rzabstractsubrepo.removecCr)zTrun whatever commands are needed to put the subrepo into this state r)r1r overwriter#r#r$rp4szabstractsubrepo.getcCr)z/merge currently-saved state with the new state.rrr#r#r$r:rzabstractsubrepo.mergecCr)zhperform whatever action is analogous to 'hg push' This may be a no-op on some systems. rr1optsr#r#r$push>rzabstractsubrepo.pushcKsgSNr#r1rGr prefixuipathfn explicitonlyrr#r#r$addEzabstractsubrepo.addcCs|jd|tdfdS)Ns%s: %ssaddremove is not supportedrrGrSr)r1matcherrrrr#r#r$ addremoveHszabstractsubrepo.addremovecKrNrr#)r1r fm fntemplaterrr#r#r$catLrzabstractsubrepo.catc KstgggggggSr)rstatus)r1rev2rr#r#r$rOszabstractsubrepo.statuscKsdSrr#)r1rGdiffoptsnode2r rrr#r#r$diffRrzabstractsubrepo.diffcCrrr#)r1rGdestrr#r#r$outgoingUrzabstractsubrepo.outgoingcCrrr#)r1rGsourcerr#r#r$incomingXrzabstractsubrepo.incomingcCr)zreturn filename iteratorrrr#r#r$files[rzabstractsubrepo.filescCr)z9return file data, optionally passed through repo decodersrr1namedecoder#r#r$filedata_rzabstractsubrepo.filedatacCr)zreturn file flagsrr#)r1rr#r#r$ fileflagscrzabstractsubrepo.fileflagscCs tj|dS)z,Resolve the fileset expression for this repobadfn)matchmodnever)r1cwdexprrr#r#r$ matchfilesetgs zabstractsubrepo.matchfilesetcCr)z)handle the files command for this subreporr#)r1rGmrrfmtsubreposr#r#r$ printfileskrzabstractsubrepo.printfilesTc sdurfdd|D}n|}t|}t|}|jjtd|td|d}|d|D]%} || } d| vr?dp@d } d | v} ||| | | | | || q2| |S) Ncg|]}|r|qSr#r#.0r]r r#r$ qz+abstractsubrepo.archive..archiving (%s)files)unittotalrxiil) rlenr:rG makeprogressrupdateraddfiler incrementcomplete) r1archiverrr rrrrelpathprogressrflagsmodesymlinkr#rr$archiveos&   zabstractsubrepo.archivecCr)zv walk recursively through the directory tree, finding all files matched by the match function Nr#)r1r r#r#r$rOzabstractsubrepo.walkcCsggfSrr#r1r rrdryrun interactiver#r#r$forgetzabstractsubrepo.forgetc Cs|td|jdS)zremove the matched files from the subrepository and the filesystem, possibly by force and/or after the file has been removed from the filesystem. Return 0 on success, 1 on any warning. s)warning: removefiles not implemented (%s)r)appendrr r1rrrafterforcerrwarningsr#r#r$ removefiless zabstractsubrepo.removefilescOs$|jtd|d|dfgS)Ns)%s: reverting %s subrepos is unsupported rrwrr1rypatsrr#r#r$reverts zabstractsubrepo.revertcCs|Srr#r1revidr#r#r$shortidrzabstractsubrepo.shortidcCr)zH convert this repository from shared to normal storage. Nr#rr#r#r$unsharerzabstractsubrepo.unsharecCr)a1verify the revision of this repository that is held in `_state` is present and not hidden. Return 0 on success or warning, 1 on any error. In the case of ``onpush``, warnings or errors will raise an exception if the result of pushing would be a broken remote repository. rr#)r1onpushr#r#r$verifyrzabstractsubrepo.verifycCst|jj|jS)z@return vfs to access the working directory of this subrepository)vfsmodrrrgrerTrrr#r#r$rezabstractsubrepo.wvfscCs|jt|j|jSzCreturn path to this subrepository as seen from outermost repository)rerV reporelpathrrgrrr#r#r$_relpathrzabstractsubrepo._relpathFF)FNFrNT)(r4r5r6r0rrrIrrrrrrrrprrrrrrrrrrrrrrrrOrrrrrr propertycachererr#r#r#r$rsN         rcseZdZfddZeddZddZddZd d Ze d d Z d dZ ddZ ddZ eddZeddZeddZeddZeddZeddZedZd!d"Zed[d$d%Zd&d'Zd(d)Zed*d+Zed,d-Zed.d/Zd0d1Zed\d2d3Zed4d5Zed6d7Zed8d9Zed:d;Z edd?Z"d@dAZ#edBdCZ$ed]dDdEZ%dFdGZ&edHdIZ'edJdKZ(edLdMZ)dNdOZ*dPdQZ+edRdSZ,d\dTdUZ-e dVdWZ.e dXdYZ/Z0S)^ hgsubrepoc sHtt|||||_|}|t|}|o"|j d| }t j |}t j t j t|} | |krCttd|tj|j||d|_t j |jjt j |krftd||jjf||urr|j|_|jj|_dD]\} } |j| | } | r|j| | | dqy|jddd d|||d |dS) Ns%s/.hgracreates9failed to reject unsafe subrepo path: %s (expanded to %s)))uiscommitsubrepossubrepor s_usedassubreposTruer)superrr0_statergwjoinr localpathreexistsosr normcaserealpathrr r/rrv repositorybaseui_repordProgrammingError unfilteredrGconfig setconfig _initrepo) r1r{r rr}rrdr  norm_root real_rootskv __class__r#r$r0s8       zhgsubrepo.__init__cCst|jt||dSr)rrrr:rr#r#r$rszhgsubrepo.addwebdirpathcCs8|j ||WdS1swYdSr)rlock _storecleanrr#r#r$rs $zhgsubrepo.storecleancCsJd}||}||D] }|t|dkrd}nq |r#t|ddu}|S)NTF)_calcstorehash_readstorehashcachenext)r1r clean itercachefilehashr#r#r$r%s zhgsubrepo._storecleanccsPd}dt|V|jj}|D]}tt||}d||fVqdS)zcalculate a unique "store hash" This method is used to to detect when there are changes that may require a push to a given remote path.)s bookmarkssstore/phaserootssstore/00changelog.is# %s %s = %s N)r%rrrrr'tryreadr()r1r)filelistrrelnamer+r#r#r$r&szhgsubrepo._calcstorehashcCst|jjdS)Nscache/storehash)rrrrTrr#r#r$_cachestorehashvfs szhgsubrepo._cachestorehashvfscCst|}|j|dS)z7read the store hash cache for a given remote repositoryr)r*r0 tryreadlines)r1r) cachefiler#r#r$r' szhgsubrepo._readstorehashcachecCs^t|}|jt||}|j}|j||dddWddS1s(wYdS)zcache the current store hash Each remote repo requires its own store hash cache, because a subrepo store may be "clean" versus a given remote repo, but not versus another swbT)r notindexedN)r*rr$listr&r0 writelines)r1r)r3 storehashrr#r#r$_cachestorehashs  "zhgsubrepo._cachestorehashcCs,|jdur |jdS|jd}|j|S)zBfetch the context for this subrepo revision, possibly a workingctxNr)rrevrr )r1r9r#r#r$_getctxs   zhgsubrepo._getctxcs|j_|j_|rAdgfdd}tjdd}tjddd}|d|||kr1|d|jjd td dSdS) Ns[paths] cs0|rd||fjd||ddSdS)Nr,spathsr )rrGr)keyvaluelinesr1r#r$ addpathconfig.sz*hgsubrepo._initrepo..addpathconfigF)abortTsdefaults default-pushrNr) r _subparent _subsource _abssourcerwriter tonativeeolrT)r1 parentreporr r?defpath defpushpathr#r=r$r&s   zhgsubrepo._initrepocKstj||j||||fi|Sr)rrrrr#r#r$r;s z hgsubrepo.addcCs&t|}d|d<t|j||||S)NTrl)copyrrr)r1rrrrr#r#r$rAs zhgsubrepo.addremovecKs6|jd}|j|}tj|j|j|||||fi|Sr)r rrrrG)r1r rrrrr9r{r#r#r$rJs  z hgsubrepo.catc Ksz|jd}|j|}|j|}|jj||fi|WStjyG}z|jtd|t|ft gggggggWYd}~Sd}~ww)Nr*warning: error "%s" in subrepository "%s" ) r rrr RepoLookupErrorrGrSrr:r)r1rrrev1ctx1ctx2instr#r#r$rRs    "zhgsubrepo.statusc Ksz*t|jd}|durt|}tj||j||j||j||f|dd|WdStjyL}z|jt d|t |fWYd}~dSd}~ww)NrT)r listsubreposrJ) rr r diffordiffstatrr rKrGrSrr:) r1rGrrr rrnode1rOr#r#r$r`s2   zhgsubrepo.diffNTc s||jd|}rfdd|D}|jd}|j|}t|j|t|j|fgt |||}|j D]} t || d} t | } || d} || || | |7}q=|S)N)ricrr#r#rrr#r$r~rz%hgsubrepo.archive..rT/)_getr rrr prefetchfilesr9 matchfilesrrryr,r subdirmatcher) r1rrr rrr9r{rsubpathrsubmatch subprefixr#rr$rys       zhgsubrepo.archiveFcCsH|jd}|dkr |s dS|jd}||kr|sdS|j|dS)NrrT)r)r rp1rrI)r1rrrwr#r#r$rIs    zhgsubrepo.dirtycCs|jdSN.)rrrr#r#r$rzhgsubrepo.basestatecCs|j|j|Sr)r _checknestedrrr#r#r$rzhgsubrepo.checknestedcCsV|ds |jdS|jdt||j|||}|s'|jdSt|S)NTr^scommitting subrepo %s )rIrrrGdebugr:r)r1rrrnr#r#r$rs zhgsubrepo.commitcCs|j|pdSr])rrrr#r#r$rszhgsubrepo.phasecCs0|jtdt|t|j|jjddS)Nremoving subrepo %s F)rGnoterr:rvr)rnullidrr#r#r$rszhgsubrepo.removecs |\}}}jj}|jvrtjdks|sdS|j_tjfdd}tjdkrڈjj|rut ruj t dtf|}zt jjjj|jjddd}W|n|w|_nV|rj dd } | rt| } | j dd d } ni} j t d ttf|}zt jjjji|jjd| d \} } W|n|w| _j||dddSj t dttf} |}z tj|W|n|w| rdS)NrTcstjiSr)rvpeerrr#r1srcurlr#r$sz hgsubrepo._get..ssharing subrepo %s from %s F)r bookmarksssharepools poolnaming)rlsmodecloning subrepo %s from %s )r shareoptsrpulling subrepo %s from %s )rrArrsharedrBrCrrmtreervislocalrGrrr:sharerrdcloserJrrrr hidepasswordclonerr8rr pull)r1rrrevisionrrrFgetpeerrgrppoolrnotherclonedcleansubr#rhr$rTs            zhgsubrepo._getc Cs||}|\}}}|j}|jd|j|r7|}||} | r7|jtd|dd|jf|}|rBt ||dSt ||dS)Nsgetting subrepo %s s,revision %s in subrepository "%s" is hidden rr&) rTrrGrbrrhiddenrSrr clean_updater) r1rrinreporrxrrrgurepor{r#r#r$rps"  z hgsubrepo.getcsjdjdfdd}jd}rDkr?tj|r=|dSdS|dS|dS)Nr^rcskr!kr!jdttjddSkr1jdtdSjdttjdddS)Nsupdating subrepository "%s" rsskipping subrepository "%s" smerging subrepository "%s" F)remind)branchrGrbr:rvrrrr#anccurdstr1rr#r$ mergefunc*s   z"hgsubrepo.merge..mergefunc)rTrancestorrIrMrG)r1rrwctxr#rr$r#s       zhgsubrepo.mergec Cs|d}|d}|d}|jd}|j}t|D]}|||dkr*dSqt|jd}|sK||rK|j t dt |t |fdS|j t d t |t |ft|jd|i|} ztj|j| ||d } W| n| w||| jS) Nforces new_branchssshr^rFTs4no changes made to subrepo %s since last push to %s spushing subrepo %s to %s ) newbranch)rprrysortedrHrrCrrGrrr:rrurvrgr rtr8cgresult) r1rrrsshcsubsrdsturlr{r?r#r#r$rDs:        zhgsubrepo.pushcCTd|vsd|vrt|}|dd|ddt|j}tj||j|||dSNsrevsbranch)rX)rIr.rrepo_rel_or_abs_sourcerrvr)r1rGrrrXr#r#r$rg     zhgsubrepo.outgoingcCrr)rIr.rrrrvr)r1rGrrrXr#r#r$rprzhgsubrepo.incomingcCs |jd}|j|}|Sr)r rmanifestkeys)r1r9r{r#r#r$rys   zhgsubrepo.filescCs2|jd}|j||}|r|j||}|Sr)r rdata wwritedata)r1rrr9rr#r#r$rs zhgsubrepo.filedatacCs|jd}|j|}||Sr)r rr)r1rr9r{r#r#r$rs   zhgsubrepo.fileflagsc CsD|jdur |jd}n |jd}|j|}t|||||||Sr)rr9rr rr) r1rGrrrrrr{r9r#r#r$rs    zhgsubrepo.printfilesc Cs|jdur |jd}n |jd}|j|}|j|||dg}|jD]9}||}z|j|||d} tj|| |d} | | Wq#t j y\|j td|jt||Yq#wt|dkrg|dSt|S)Nrrs#skipping missing subrepository: %s r)rr9rr rryrHrprefixdirmatcherrr LookupErrorrGrrrerVrr unionmatcher) r1rrrr{r9matchersrXrHsmpmr#r#r$rs*       zhgsubrepo.matchfilesetcCs|jd}||Sr)rrO)r1r r{r#r#r$rOs  zhgsubrepo.walkc Cstj|j|j|||d||dS)NT)rr)rrrGrrr#r#r$rszhgsubrepo.forgetc Cst|j|j||||||| Sr)rrrGrrr#r#r$rs zhgsubrepo.removefilescOsn|jtd|d|ds'|}d|d<|d|d<|j|i||ds5|j|dd dSdS) Nreverting subrepo %s r no_backuprrr9dry_runTr)rGrrrprI filerevertrr#r#r$rs   zhgsubrepo.revertcOsH|j|d}|drdg}ng}tj|j|j|g|Ri|dS)Nr9allsset:modified())rrprrrG)r1rrr{r#r#r$rs  $zhgsubrepo.filerevertcC |ddS)Nr&r#rr#r#r$r zhgsubrepo.shortidcCsDddlm}|a|jr|jtd|jt|j|jdS)Nrrusunsharing subrepo '%s' ) rxrvrrprGrrrr)r1r~r#r#r$rs  zhgsubrepo.unsharecCsz1|jd}|j|}|r/td|jt|jf}|r&t ||jj d|WdSt j yZtd|jt|jf}|rNt ||jj d|YdSw)Nrs%subrepo '%s' is hidden in revision %ss%s rs%subrepo '%s' not found in revision %s)r rrr~rrrrnoder r/rGrSrK)r1rr9r{rLr#r#r$r s,     zhgsubrepo.verifycCs|jjS)z.return own wvfs for efficiency and consistency)rrerr#r#r$re,szhgsubrepo.wvfscCs t|jSr)rrrr#r#r$r1s zhgsubrepo._relpathrrrr)1r4r5r6r0rErrr%r&rr0r'r8r:rrrrrrrrIrrrrrrTrprrrrrrrrrrOrrrrrrrrer __classcell__r#r#r"r$rs "                [   "           rcseZdZfddZd#ddZeddZd d Zd d Zd dZ ddZ e d$ddZ ddZ e ddZe ddZe d%ddZe ddZddZe dd Zd!d"ZZS)& svnsubrepocsBtt|||||_td|_|jstt d|j dS)Nrks+'svn' executable not found for subrepo '%s') r rr0r rfindexe_exer r/rrr1r{r rr}r"r#r$r09s  zsvnsubrepo.__init__rFc Cs$|jg}i}|jstj|d<|ddvr|d|||dur6|j|j j |j |}||t tj}|d}|rI||d<|d=d|d<tjttj|fd tjtjtjt|d |} ttj| \} } | } |s| jrt| pd | j| r|j | d | | fS) Nstdinr)updatecheckoutcommits--non-interactiveLC_ALLsLANGCs LC_MESSAGES)bufsize close_fdsstdoutstderrenvsexited with code %d )!rrGr subprocessPIPErextendrerVrrgorigrootrdictr environrpPopenrrapplyr tonativestrclosefds tonativeenvmapr fromnativeeol communicatestrip returncoder r/rS) r1commandsfilenamefailokcmdextrakwr rlc_allprrr#r#r$ _svncommandBsN           zsvnsubrepo._svncommandcCsP|jddgdd\}}td|}|sttdt|dt|dfS)N --version--quiet)rs ^(\d+)\.(\d+)s cannot retrieve svn tool versionrrw)rresearchr r/rintgroup)r1outputerrrr#r#r$ _svnversionps zsvnsubrepo._svnversioncC|jd S)N.svnrerrr#r#r$ _svnmissingzr_zsvnsubrepo._svnmissingcCs|ddg\}}tjj|}|d}d\}}|r1s z#svnsubrepo.files..rr) rrrrrrrrrrT childNodesrr)r1rrpathsrrrrr#r#r$r(s zsvnsubrepo.filescCs|dg|dS)Nscatr)rrr#r#r$r9zsvnsubrepo.filedata)rFrr)r4r5r6r0rrrrrrrrErIrrrrprrrrrr#r#r"r$r8s0  .  %        rcs\eZdZfddZddZeddZeddZdFd d ZdFd dZ dGddZ ddZ ddZ ddZ ddZddZddZddZdd Zd!d"Zd#d$Zd%d&Zd'd(ZedHd)d*Zd+d,ZedId-d.Zed/d0Zed1d2Zed3d4Zed5d6Zed7d8ZdJd:d;Z edd?Z"ed@dAZ#edBdCZ$dDdEZ%Z&S)K gitsubrepocs>tt|||||_|||_||_|dSr) r rr0r rgr_abspathrA _ensuregitrr"r#r$r0>s   zgitsubrepo.__init__c Csfz d|_|dg\}}Wnwty}zktd}td}|jtjkr1t||jt |j ft j rnz d|_|dg\}}Wn8tym}z |jtjkr[tjtd|j|dt||jt |j fd}~wwtjtd|j|dWYd}~nd}~ww||}|d kr|jtd dS|d krttd |d kr|jtddSdS)Nrjrs(error executing git for subrepo '%s': %ss'check git is installed and in your PATHsgit.cmds1couldn't find 'git' or 'git.cmd' for subrepo '%s'rms"couldn't find git for subrepo '%s'unknownscannot retrieve git version aborts,git subrepo requires at least 1.6.0 or laterwarnings-git subrepo requires at least 1.6.0 or later )_gitexecutable _gitnodirrrerrnoENOENTr r/rr strtolocalstrerrorr iswindows _checkversionrGrS)r1outrr genericerror notfoundhinte2 versionstatusr#r#r$r Es`      zgitsubrepo._ensuregitcCsjtd|}|rt|dt|dt|dfStd|}|r3t|dt|ddfSdS)Ns ^git version (\d+)\.(\d+)\.(\d+)rrws^git version (\d+)\.(\d+)rr)rrrr)r,rr#r#r$ _gitversionrs ( zgitsubrepo._gitversioncCs2t|}|dkr dS|dkrdS|dkrdSdS)aensure git version is new enough >>> _checkversion = gitsubrepo._checkversion >>> _checkversion(b'git version 1.6.0') 'ok' >>> _checkversion(b'git version 1.8.5') 'ok' >>> _checkversion(b'git version 1.4.0') 'abort' >>> _checkversion(b'git version 1.5.0') 'warning' >>> _checkversion(b'git version 1.9-rc0') 'ok' >>> _checkversion(b'git version 1.9.0.265.g81cdec2') 'ok' >>> _checkversion(b'git version 1.9.0.GIT') 'ok' >>> _checkversion(b'git version 12345') 'unknown' >>> _checkversion(b'no') 'unknown' rr!)rrrr")rrr#sok)rr2)r,versionr#r#r$r+~s zgitsubrepo._checkversionNFcCs|j|||ddS)N)rstreamr_gitdirr1rrr5r#r#r$ _gitcommandrazgitsubrepo._gitcommandcCs|j||||jdS)N)rr5r)r%rr8r#r#r$r7s zgitsubrepo._gitdirc Cs>|jd|jd|f|durtj}d|d<d|vr#d|d<d}|jjr0t t j d}|jj rDt |rD|d d krD|d d tjttj|jg|d ttj|t|tjtj|d}|rj|jdfS|j}||jd kr|jd kr|d }|dvr||jfSttd||j|jf||jfS)zCalls the git command The methods tries to call the git command. versions prior to 1.6.0 are not supported and very probably fail. s %s: git %s r8NrrsGIT_ALLOW_PROTOCOLsfile:git:http:https:sshwrdiffrs--colorr)rrrrrr)cat-file symbolic-refsgit %s error %d in %s) rGrbrrTr rrIquietropenrdevnull _colormoderinsertrrrrrr$rrrrreadrwaitrr r/r) r1rrr5rerrpiperretdatacommandr#r#r$r%sH       zgitsubrepo._gitnodircCr)N.gitrrr#r#r$ _gitmissingr_zgitsubrepo._gitmissingcCs|ddgS)Ns rev-parseHEADr9rr#r#r$ _gitstater_zgitsubrepo._gitstatecCs|gd\}}|r d}|S)N)r=rJrr6)r1currentrr#r#r$_gitcurrentbranchszgitsubrepo._gitcurrentbranchcCs>|ddd|g}|dd}|dtd}||dS)Nsremoteshows-nrrsURL: )r9splitindexr)r1rKr,liner[r#r#r$ _gitremotes zgitsubrepo._gitremotecCs|dd|g\}}|dkS)Nr<s-err6)r1rxr,coder#r#r$_githavelocallyszgitsubrepo._githavelocallycCs|d||g}||kS)N merge-baserK)r1r1r2baser#r#r$_gitisancestorszgitsubrepo._gitisancestorcCs|gddkS)N)configs--bool core.baretruerKrr#r#r$ _gitisbarerzgitsubrepo._gitisbarecCs|gddS)zThis must be run before git diff-index. diff-index only looks at changes to file stat; this command looks at file contents and updates the stat.)s update-index-qs --refreshNrKrr#r#r$_gitupdatestatszgitsubrepo._gitupdatestatcCsi}i}|gd}|dD],}|d\}}|ds$|ds$q|dr/|dr/q|||<||g|q||fS)zcreturns 2 things: a map from git branch to revision a map from revision to branches)s for-each-refs--formats%(objectname) %(refname)rr8s refs/heads/ refs/remotes/s/HEAD)r9rPrbendswith setdefaultr)r1 branch2rev rev2branchr,rRrxrefr#r#r$ _gitbranchmaps zgitsubrepo._gitbranchmapc Csri}|D]2}|dr q|ddd}|dd|g}|r6|dd|g}||d||dddf<q|S)z4return map of remote branch to local tracking branchrarSrwr[sbranch.%s.remotesbranch.%s.mergesrefs/remotes/%s/%s)rbrPr9)r1branchestrackingbbnamerKrfr#r#r$ _gittrackings zgitsubrepo._gittrackingcCs<d|vr|d}|dkrd|d|vr|S||_t|S)Ns://:rrS)findrBrC)r1rcolonr#r#r$rC)s  zgitsubrepo._abssourcecCs|r$t|||}|jtd|j|f|d||j g| |r+dS|jtd|j| df| dg| |sRt td||jfdS)Nrmsclonerooriginsfetchs1revision %s does not exist in subrepository "%s" )rIrrrCrGrrrr%rrUrSr9r r/)r1rrxr#r#r$_fetch2s,     zgitsubrepo._fetchcCs^|r |jddkS|rdS|s|jd|krdS||gd\}}|dkS)NrrT diff-indexrrJ)rIr r^rLr`r7)r1rrr,rTr#r#r$rIJszgitsubrepo.dirtycCs|Sr)rLrr#r#r$rXrzgitsubrepo.basestatecs|\}}s dS|r.gdkr-gddSnkrFrDddggddS\}}fddfdd}|vrd|dS|}d} |D]} | d krzd gdS| s| d s| } ql| r| gdS|} |d } | | vr|D] } | | vr| } nq| | vr| d d d } d| | gdS || | | r| |  kr׈| | gdd| gt j jddS|dS)N)r[r\sfalse)resets--hardrJrtrJcsDdg}rddg|d||tjjddS)NrrtrJ-frH)r9rr^rGre)r2r)rr1r#r$checkoutrs  z gitsubrepo.get..checkoutcs6jtdjjtddgdS)Ns1checking out detached HEAD in subrepository "%s" s5check out a git branch if you intend to make changes r_)rGrSrrr#)rvrxr1r#r$ rawcheckout}sz#gitsubrepo.get..rawcheckoutsrefs/heads/masterrarrSr1s-bmerges--ffrH)rrqr^r9rLrgrbrlrrPrZrNr^rGre)r1rrrrrrdrerwrhfirstlocalbranchrjrirKrJr#)rvrrxr1r$rp[sf          zgitsubrepo.getcCsl|rttd|jddd|g}tj}|r!|d|g7}|r+t |d|d<|j ||d| S) Nsubrepo %s is missingrs-ars--authors%Y-%m-%dT%H:%M:%S %1%2sGIT_AUTHOR_DATE)r) rIr r/rrr rrIrdatestrr9rL)r1rrrrrr#r#r$rs   zgitsubrepo.commitcs\}}|djdggd\}}fdd}r`kr\jdkpB|dk}tj|jdddddr^|dSdSdS|dS)NrVrrrcsFkr njdkrddgtjjddS)Nrrxs --no-commitrH)rpr r9r^rGrer#rYrxr1rr#r$rs  z#gitsubrepo.merge..mergefuncr) rqr9r r`r7rIrLrMrG)r1rrrrr,rTrrIr#r|r$rs   "  zgitsubrepo.mergec Cs\|d}|jds dS|rttd|j|\}}|jd|vr9||jdD] }|dr8dSq.t |D]\}}|drS| |jd|rSdSq>dg}|r^| d| }|r| |jd|sz|jtd|jd S|jtd |d d d |jf||d |g} | ddkS|jtd|j|jdfd S)NrrTrzsrefs/remotes/origin/spushrs7unrelated git branch checked out in subrepository "%s" Fs(pushing branch %s of subrepository "%s" rSrwrprsDno branch checked out in subrepository "%s" cannot push revision %s )rpr rIr r/rrrgrbr iteritemsrZrrNrGrSrrPr7) r1rrrdrerjrxrrMretr#r#r$rsZ       zgitsubrepo.pushc s|rgS|jdddd}t}|j|j|j|jfD]} || q|j} | g} fddt t| D} | D]:} | } dg}| rO| d|jsT| s_|td|| | |vrk| rj| | q>|dsx||| gq>| D] } |td || q{| S) NT)unknownr)crr#r#rrr#r$r%rz"gitsubrepo.add..saddrus adding %s rs%s already tracked! )rIrsetmodifiedaddeddeletedr)rrrrrexactrverboserrpr9rS)r1rGr rrrrrtrackedlrrejectedr]rrGr#rr$rs6      zgitsubrepo.addcCs|rdS|r|jtd|jdS|jtd|j|gd|j D]\}}|dkr7q.|t j krC|j |q.|j |q.dS)Nr rd)r[r\r]rH)rIrIrGrSrrrer9rereaddirstatS_IFDIRrqrU)r1r]rrr#r#r$r:s$ zgitsubrepo.removeTcCsd}|j\}}|s |S||||jd|gdd}tj|dd} t|} |jjtd| tdd } | d| D]H} | rAq:t | j } |rN|| sNq:| rV| j}n| | }|rb|}n |jtd | q:||| | j| ||d 7}| q:| |S) NrsarchiveT)r5zr|)fileobjrrr)rsskipping "%s" (unknown type)r)r rqr9tarfiler?r:rGrrrisdirrfsencoderissymlinkname extractfilerCrSrrrr)r1rrr rrrrx tarstreamtarrrinforkrr]r#r#r$rPs<        zgitsubrepo.archivec Ksx|jd}|r dS|sdS|D]$}|dd||fg}tj|j||j||d} | || qdS)NrrOs%s:%s)pathnamer) r anypatsrr9r makefileobjrrerVrDrt) r1r rrrrr9r]rfpr#r#r$rvs    zgitsubrepo.catc KsH|jd}|s |stgggggggSggg}}}||r,ddd||g}ndd|g}||}|dD]:} | d} | dkrGq;| | d| | | dd} } | d krb|| q;| d krl|| q;| d kru|| q;ggggf\} }}}gd }| d r|dg7}| dr|dg7}||}t }| || || ||dD]E} | sq| dd}| ddkr| ddd\}}n| dd}d}| ||r| ||dkr||q|dkr||q| dr|dg}|dD] } | |vr|| q t|||| |||S)Nrs diff-tree --no-renamesrrsr rMAD)rs --porcelains-zrs--untracked-files=allignoreds --ignoredrrwr1s??s!!r)sls-files) r rIrrr`r9rPrnrrprrr)r1rrrLrrremovedrGr,rRtabrr]rrrr) changedfilesst filename1 filename2r#r#r$rsr     "                     zgitsubrepo.statusc KsR|jd}ddg}|dr|dn|d|j|jr*|d|d|gn |d |d |g|jr=|d |jrE|d ||d gdkrX|j rX|d|||rd||d} | rt| ||d7} n(| |} dd| j | j | jfD} | D]} || r| ||d| gd7} q| r|| dSdS)Nrr;rrs--stats-U%ds--src-prefix=%s/s--dst-prefix=%s/s--src-prefix=a/%s/s--dst-prefix=b/%s/s--ignore-all-spaces--ignore-space-changer)rs--ignore-blank-linesrrcSsg|] }|D]}|qqSr#r#)rsublistr]r#r#r$rsz#gitsubrepo.diff..s--)r rcontextnoprefixrignorewsignorewsamountr2r9ignoreblanklinesalwaysrrrrrrD) r1rGrrr rrrRrrrrr]r#r#r$rsJ        zgitsubrepo.diffc Os|jtd|d|dsI|d}|j}|D]-}tj|j|}t |j|j |}|j td|tj |ft|j||q|dsU|j|ddgS)Nrrrs#saving current version of %s as %s rTr)rGrrrprrr rTrr backuppathrArerrrenamere) r1ryrrrrZr parentnamebaknamer#r#r$rs$    zgitsubrepo.revertcCr)Nr}r#rr#r#r$rrzgitsubrepo.shortid)NF)NFNrrr)'r4r5r6r0r  staticmethodr2r+r9r7r%rIrLrNrSrUrZr^r`rgrlrCrqrErIrrprrrrrrrrrrrrr#r#r"r$r=s^ -   #  6    X   2 &  &  C 1 r)rirkrj)FT)? __future__rrIr&rrrrr<rxml.dom.minidomri18nrrrrrrxrr r r r r rrrrrrrrrrutilsrrrrrvrr:rCrr%r*r/r+rErMr^rhrortr,robjectrrrrrqr#r#r#r$sj  @    exc