o k`@sddlZddlmZmZddlmZddlmZmZm Z ddl m Z m Z ddl TddlmZmZmZddlmZmZdd lmZmZdd lmZmZdd lmZmZmZdd lm Z dd l!m"Z"ddl#m$Z$m%Z%m&Z&ddZ'Gddde(Z)Gddde(Z*Gddde+Z,Gddde+Z-Gddde+Z.Gddde/Z0Gddde/Z1Gdd d eZ2Gd!d"d"eZ3Gd#d$d$e4ed%Z5Gd&d'd'e4ed%Z6Gd(d)d)e4ed%Z7Gd*d+d+e7Z8dS),N)ABCMetaabstractmethod)datetime)AdminCommandErrorIAdminCommandProvider get_dir_list) ConfigSectionOption)*)IResourceManagerResourceResourceNotFound)as_bool native_path) get_thread_id threading)time_nowutc)exception_to_unicodeprintout to_unicode_)IRequestFilter)ChromeITemplateProvider add_warningcCs| p |dtdfvS)z3Check whether `reponame` is the default repository. (default)rreponamer 9/usr/lib/python3/dist-packages/trac/versioncontrol/api.py is_default"r"c@eZdZdZdS)InvalidRepositoryz.Exception raised when a repository is invalid.N__name__ __module__ __qualname____doc__r r r r!r%'r%c@r$)InvalidConnectorz8Exception raised when a repository connector is invalid.Nr&r r r r!r,+r+r,c@s$eZdZdZdZddZddZdS)IRepositoryConnectorz6Provide support for a specific version control system.NcCdS)a}Return the types of version control systems that are supported. Yields `(repotype, priority)` pairs, where `repotype` is used to match against the repository's `type` attribute. If multiple provider match a given type, the `priority` is used to choose between them (highest number is highest priority). If the `priority` returned is negative, this indicates that the connector for the given `repotype` indeed exists but can't be used for some reason. The `error` property can then be used to store an error message or exception relevant to the problem detected. Nr r r r r!get_supported_types4z(IRepositoryConnector.get_supported_typescCr.)zLReturn a Repository instance for the given repository type and dir. Nr ) repos_type repos_dirparamsr r r!get_repositoryCr0z#IRepositoryConnector.get_repository)r'r(r)r*errorr/r4r r r r!r-/s  r-c@seZdZdZddZdS)IRepositoryProviderz,Provide known named instances of Repository.cCr.)aGenerate repository information for known repositories. Repository information is a key,value pair, where the value is a dictionary which must contain at the very least either of the following entries: - `'dir'`: the repository directory which can be used by the connector to create a `Repository` instance. This defines a "real" repository. - `'alias'`: the name of another repository. This defines an alias to another (real) repository. Optional entries: - `'type'`: the type of the repository (if not given, the default repository type will be used). - `'description'`: a description of the repository (can contain WikiFormatting). - `'hidden'`: if set to `'true'`, the repository is hidden from the repository index (default: `'false'`). - `'sync_per_request'`: if set to `'true'`, the repository will be synchronized on every request (default: `'false'`). - `'url'`: the base URL for checking out the repository. Nr r r r r!get_repositoriesKr0z$IRepositoryProvider.get_repositoriesN)r'r(r)r*r7r r r r!r6Hs r6c@s eZdZdZddZddZdS)IRepositoryChangeListenerz#Listen for changes in repositories.cCr.)z8Called after a changeset has been added to a repository.Nr )repos changesetr r r!changeset_addedor0z)IRepositoryChangeListener.changeset_addedcCr.)zCalled after a changeset has been modified in a repository. The `old_changeset` argument contains the metadata of the changeset prior to the modification. It is `None` if the old metadata cannot be retrieved. Nr )r9r: old_changesetr r r!changeset_modifiedrr0z,IRepositoryChangeListener.changeset_modifiedN)r'r(r)r*r;r=r r r r!r8ls r8c@seZdZdZeeedZddZddZ ddZ d d Z d d Z d dZ ddZd"ddZddZddZddZd"ddZddZddZd d!ZdS)#DbRepositoryProviderz6Component providing repositories registered in the DB.)alias descriptiondirhiddennamesync_per_requesttypeurlcCsi}|jdddd|jDD]\}}}|dur$|||i|<qi}|D]#\}}d|vrEd|vs;d|vrE||d <|||d<t|d |d <q+t|S) z;Retrieve repositories specified in the repository DB table.z9SELECT id, name, value FROM repository WHERE name IN (%s),css|]}d|VqdS)z'%s'Nr ).0eachr r r! sz8DbRepositoryProvider.get_repositories..NrCrAr?idrD) envdb_queryjoinrepository_attrs setdefaultitemsrgetiter)selfr9rKrCvalue reponamesinfor r r!r7s   z%DbRepositoryProvider.get_repositoriesccsbddd|j|jfVddd|j|jfVddd |j|jfVd d d d |j|j|j fVdS)Nzrepository addz [type]zAdd a source repositoryzrepository aliasz z Create an alias for a repositoryzrepository removezzRemove a source repositoryzrepository setz zeSet an attribute of a repository The following keys are supported: %s z, ) _complete_add_do_add_complete_alias _do_alias_complete_repos _do_removerNrO _complete_set_do_setrTr r r!get_admin_commandss&  z'DbRepositoryProvider.get_admin_commandscCst|j}dd|DS)NcSsg|]}|pdqS)rr )rHrr r r! sz6DbRepositoryProvider.get_reponames..)RepositoryManagerrLget_all_repositories)rTrmr r r! get_reponamess z"DbRepositoryProvider.get_reponamescCs8t|dkr t|ddSt|dkrt|jSdS)NT)lenrrcrLr/rTargsr r r!rXs  z"DbRepositoryProvider._complete_addcCt|dkr |SdS)Nrgrjrfrkr r r!rZ z$DbRepositoryProvider._complete_aliascCrm)Nrnrkr r r!r\roz$DbRepositoryProvider._complete_reposcCs*t|dkr |St|dkr|jSdS)Nrprg)rjrfrOrkr r r!r^s  z"DbRepositoryProvider._complete_setNcCs||tj||dSN)add_repositoryospathabspath)rTrrAtype_r r r!rYszDbRepositoryProvider._do_addcCs|||dSrq) add_alias)rTrtargetr r r!r[zDbRepositoryProvider._do_aliascCs||dSrq)remove_repository)rTrr r r!r]szDbRepositoryProvider._do_removecCs||jvr ttd|d|dkrtj|}||||i|s#d}|dkr1ttd|ddS|dkr?ttd|ddSdS) NzInvalid key "%(key)s"keyrArz0You should now run "repository resync %(name)s".rCrEz1You may have to run "repository resync %(name)s".)rOrrrsrtrumodify_repositoryr)rTrr|rUr r r!r_s    zDbRepositoryProvider._do_setcCstj|s ttdt|rd}t|j}|r'||vr'ttd|d|jj }| |}| d|d|f|d|p=dfgWdn1sKwY| dS) zAdd a repository.)The repository directory must be absolutez/The repository type '%(type)s' is not supported)rE.z8Cannot remove the repository "%(repos)s" used in aliasesrr9z"DELETE FROM repository WHERE id=%sz#DELETE FROM revision WHERE repos=%sz&DELETE FROM node_change WHERE repos=%sN) r"rcrLrdanyvaluesrrrrr)rTrrerrrKr rr!rzs"       z&DbRepositoryProvider.remove_repositoryc sntrd|d}t|rd}t|j}|kr6|}tfdd|Dr6ttdp2dd|jj o}| }|krT|d|frTttd |pPdd | D]I\}} ||j vrbqX|d vrlt| rld} |d vrxt | rvd nd} |dkrtjt| sttd|d| ||f|d||fs|d||| fqXWdn1swY|dS)z"Modify attributes of a repository.rrCc3rrrrrr r!rJrz9DbRepositoryProvider.modify_repository..z8Cannot rename the repository "%(repos)s" used in aliasesrrzQSELECT id FROM repository WHERE name='name' AND value=%sz)The repository "%(name)s" already exists.r})r?rC)rBrD1NrArz6UPDATE repository SET value=%s WHERE id=%s AND name=%sz4SELECT value FROM repository WHERE id=%s AND name=%szqINSERT INTO repository (id, name, value) VALUES (%s, %s, %s) )r"rRrcrLrdrrrrrrrQrOrrsrtrrr) rTrchanges new_reponamererrrKkvr rr!r~s\        z&DbRepositoryProvider.modify_repositoryrq)r'r(r)r* implementsr6rrOr7rarfrXrZr\r^rYr[r]r_rrrwrzr~r r r r!r>{s&    r>c@seZdZdZeeeeedZ dZ dZ e e Ze eZe eZeddZeddd d Zd d Zd dZddZddZd:ddZddZddZddZddZddZd d!Z d"d#Z!d$d%Z"d&d'Z#d(d)Z$d*d+Z%d,d-Z&d.d/Z'd0d1Z(d2d3Z)d:d4d5Z*d6d7Z+d8d9Z,dS);rczVersion control system manager.r:source repositoryraOne of the methods for registering repositories is to populate the `[repositories]` section of `trac.ini`. This is especially suited for setting up aliases, using a [TracIni#GlobalConfiguration shared configuration], or specifying repositories at the time of environment creation. See [TracRepositoryAdmin#ReposTracIni TracRepositoryAdmin] for details on the format of this section, and look elsewhere on the page for information on other repository providers. versioncontroldefault_repository_typesvnzDefault repository connector type. This is used as the default repository type for repositories defined in the [TracIni#repositories-section repositories] section or using the "Repositories" admin panel. cCs i|_t|_d|_d|_dSrq)_cacherLock_lock _connectors_all_repositoriesr`r r r!__init__ds  zRepositoryManager.__init__c Cs|t|jur|D]{}t|dsq t}|dpd}z ||d}|WnOt y6Yq t yS}zt |t d|t |dWYd}~n.d}~wty|}zt |t d|t |d|jd|t|dd WYd}~nd}~ww|jd |t|q |S) NrDrCrzdCan't synchronize with repository "%(name)s" (%(error)s). Look in the Trac log for more information.rCr5zFailed to sync with repository "%(name)s": %(error)s; repository information may be out of date. Look in the Trac log for more information including mitigation strategies.zFailed to sync with repository "%s"; You may be able to reduce the impact of this issue by configuring the sync_per_request option; see https://trac.edgewall.org/wiki/TracRepositoryAdmin#ExplicitSync for more detail: %sT) tracebackz-Synchronized '%s' repository in %0.2f seconds)rrLrdrrrRrr4syncr,rrrr Exceptionlogr5rrW)rTreqhandler repo_infostart repo_namerer r r!pre_process_requestlsH     z%RepositoryManager.pre_process_requestcCs |||fSrqr )rTrtemplatedatametadatar r r!post_process_requests z&RepositoryManager.post_process_requestccs|jV|jV|jVdSrq)changeset_realm source_realmrepository_realmr`r r r!get_resource_realmss z%RepositoryManager.get_resource_realmsNc Ks&|j|jkr |j}|o |j}|j}|rtd||dStd|dS|j|jkr}|j}|o-|j}|j}d}|dkr^||}||j|j} | j rLtd} n| j rStd} |jr]td |jd}n td } |jrjd |j}|rrtd |d nd} td| ||| dS|j|j kr|jstdStd|jd SdS)NzChangeset %(rev)s in %(repo)s)revrzChangeset %(rev)srrsummary directoryfilez at version %(rev)srtz@%sz in %(repo)srz(%(kind)s %(id)s%(at_version)s%(in_repo)s)kindrK at_versionin_repozDefault repositoryzRepository %(repo)s) realmrparentrKrrr4get_nodeversionisdirisfiler) rTresourceformatkwargsrrrKrr9noderrr r r!get_resource_descriptionsD         z*RepositoryManager.get_resource_descriptioncKs~|j|jkr|j}||j|r|jpdS|j|jkr/|j}|j|r%|jp&d|j|jp,ddS|j|jkr=||jp;dSdS)Nr) rrrr:rKrbrowserrr)rTrhrefrrr r r!get_resource_urls   z"RepositoryManager.get_resource_urlcCs|j|jkr |j}n|jj}t|j|}|sdS|j|jkr4z ||jWdSt y3YdSw|j|j krPz | |j|j WdSt yOYdSw|j|jkrXdSdS)NFT)rrrKrrcrLr4r get_changesetNoSuchChangesetrrr NoSuchNode)rTrrr9r r r!resource_existss.       z!RepositoryManager.resource_existsc cs|j}i}|D]}|dr||rddi||dd<q|D]$}||}d|vr0|d7}|drE||vrE|||ddid <q!|D]}d|vrg|dd \}}||vrg|d krg|||||<qH|D] \}}||fVqldS) zRetrieve repositories specified in TracIni. The `[repositories]` section can be used to specify a list of repositories. z.dirrDFN.z.aliasir?rp)repositories_sectionendswithrRrPrsplitrQ) rTrrVoptionr?rCdetailrrWr r r!r7s.  z"RepositoryManager.get_repositoriescCgSrqr r`r r r!get_htdocs_dirssz!RepositoryManager.get_htdocs_dirscCsddlm}|ddgS)Nr)resource_filenameztrac.versioncontrol templates) pkg_resourcesr)rTrr r r!get_templates_dirss  z$RepositoryManager.get_templates_dirscCsdd|jD}t|S)z.Return the list of supported repository types.cSs.h|]}|p gD] \}}|dkr |q qS)r)r/)rH connectorrvprior r r! s z8RepositoryManager.get_supported_types..) connectorslist)rTtypesr r r!r/ sz%RepositoryManager.get_supported_typescCstjtjt|d}g}|D])\}}t|d}|r>tjtj|d}||r>| |}|r>| |q|S)zRetrieve the repositories based on the given directory. :param directory: the key for identifying the repositories. :return: list of `Repository` instances. rrA) rsrtrNnormcaserrdrQrR startswithr4append)rTrrrrepoinforAr9r r r!get_repositories_by_dirs   z)RepositoryManager.get_repositories_by_dircCs||jj0}|d|fD] \}|WdS|dddd}|d|d|f|WdS1s7wYdS)zReturn a unique id for the given repository name. This will create and save a new id if none is found. Note: this should probably be renamed as we're dealing exclusively with *db* repository ids here. z8SELECT id FROM repository WHERE name='name' AND value=%sNz+SELECT COALESCE(MAX(id), 0) FROM repositoryrrprrC)rLr)rTrrrKr r r!r$s  $z#RepositoryManager.get_repository_idc Cs>|pd}||i}d|vr|d}||i}t|d}|s'dS|dp.|j}|jjb|jNt}||jvrF|j|}ni}|j|<||}|sut j |sct j |jj |}| |}||||}|||<|WdWdS1swYWddS1swYdS)aRetrieve the appropriate `Repository` for the given repository name. :param reponame: the key for specifying the repository. If no name is given, take the default repository. :return: if no corresponding repository was defined, simply return `None`. :raises InvalidConnector: if the repository connector cannot be opened. :raises InvalidRepository: if the repository cannot be opened. rr?rANrE)rdrRrrrLrrrrrsrtrrN_get_connectorr4copy) rTrrrdirrtypetidrr9rr r r!r47s:      "z RepositoryManager.get_repositorycCsg}|r |ddnd}|D]}|dd}||r(|t||fq|r<||d\}}||d}nd}||||dpIdfS)a9Retrieve a matching `Repository` for the given `path`. :param path: the eventually scoped repository-scoped path :return: a `(reponame, repos, path)` triple, where `path` is the remaining part of `path` once the `reponame` has been truncated, if needed. /rhNr)striprdrrrjsortr4rstrip)rTrtmatchesrstripped_reponamelengthr r r!get_repository_by_pathas     z(RepositoryManager.get_repository_by_pathcCs<|r|jj|j|jfvr|jjr|jjjS|j}|sdSdS)zRecover the appropriate repository from the current context. Lookup the closest source or changeset resource in the context hierarchy and return the name of its associated repository. N)rrrrrrK)rTcontextr r r!get_default_repositoryxs   z(RepositoryManager.get_default_repositorycCsv|js8i}|jD],}|pgD]#\}}||vr |jd|q||d<d|vr/|||d<|||<qq||_|jS)z?Return a dictionary of repository information, indexed by name.z$Discarding duplicate repository '%s'rCrK)r providersr7rwarningr)rTall_repositoriesproviderrrWr r r!rds   z&RepositoryManager.get_all_repositoriesc CsXt}|D]}z||}Wn tyYqw|dur#||qt|dddS)zXReturn a sorted list of all real repositories (i.e. excluding aliases). NcS|jSrqrrr r r!z9RepositoryManager.get_real_repositories..r{)setrdr4raddsorted)rTrrr9r r r!get_real_repositoriess   z'RepositoryManager.get_real_repositoriescCs@|ji|_d|_Wdn1swY|jdS)z+Reload the repositories from the providers.N)rrrconfigtouchr`r r r!rs z%RepositoryManager.reload_repositoriescs|jd||pd|||}g}|r|ntj|}||}|r)dn|r8fdd|D}|sN|j dpA|t d|pJt ddgSg}t |d d d D]}|j p^d}| |D]}g} |d krz||} Wn"ty} z|t| |j d |||WYd} ~ qed} ~ ww| | z||} Wn9tyz ||||} Wn#ty} z|t| |j d |||WYd} ~ Yqed} ~ wwYnw|jd||||jD]} t| ||| g| RqqeqX|S)zNotify repositories and change listeners about repository events. The supported events are the names of the methods defined in the `IRepositoryChangeListener` interface. z-Event %s on repository '%s' for changesets %rrNcsg|] }|kr|qSr )get_base)rHrbaser r!rbs z,RepositoryManager.notify..z)Found no repositories matching '%s' base.zRepository '%(repo)s' not foundrcSrrqrrr r r!rrz*RepositoryManager.notify..r{r=zMNo changeset '%s' found in repository '%s'. Skipping subscribers for event %sz-Event %s on repository '%s' for revision '%s')rdebugr4r rsrtrurrrrrrrsync_changesetrrrrchange_listenersgetattr)rTeventrrevsr9rrAerrorsrrlr<rr:listenerr r r!notifys             zRepositoryManager.notifycCsj|r3|tks J|j|j|i}|D]\}}|qWddS1s,wYdSdS)z>Free `Repository` instances bound to a given thread identifierN)rrrpoprQclose)rTrrrr9r r r!shutdowns "zRepositoryManager.shutdownc Cs||dd\}}|sdSd}d|vr|dd\}}z|||}Wn ttfy1YdSw|}|r>t|SdS)aRead the file specified by `path` :param path: the repository-scoped path. The repository revision may specified by appending `@` followed by the revision, otherwise the HEAD revision is assumed. :return: the file content as a `str` string. `None` is returned if the file is not found. :since: 1.2.2 rpN@)rsplitrrr get_contentrread)rTrtr9rrcontentr r r!read_file_by_paths  z#RepositoryManager.read_file_by_pathcCs|jdur4i|_|jD](}|pgD]\}}||f}||jvr+||j|dkr+d}|r2||j|<qq ||jvrR|j|\}}|dkrF|Sttd|t|jdttd|d)zRetrieve the appropriate connector for the given repository type. Note that the self._lock must be held when calling this method. Nrprz8Unsupported version control system "%(name)s": %(error)srzUnsupported version control system "%(name)s": Can't find an appropriate component, maybe the corresponding plugin was not enabled? r})rrr/r,rrr5)rTrrrvrkeepr r r!rs6     z RepositoryManager._get_connectorrq)-r'r(r)r*rrr r6rrrrExtensionPointr-rrr8rrrr rrrrrrrrr7rrr/rrr4rrrdrrrrrrr r r r!rc@sR  $ $ *  D rcc@seZdZddZdS)rcCst|td|dtddS)Nz&No changeset %(rev)s in the repositoryrzNo such changeset)r rrrTrr r r!r6s zNoSuchChangeset.__init__Nr'r(r)rr r r r!r5s rc@seZdZdddZdS)rNcCs>|dur td||d}ntd|||d}t||tddS)Nz$No node %(path)s at revision %(rev)s)rtrz-%(msg)s: No node %(path)s at revision %(rev)s)msgrtrz No such node)rr r)rTrtrr"r r r!r>s zNoSuchNode.__init__rqr!r r r r!r=src@s`eZdZdZdZdZejZe ddZ ddZ dd Z e d d Zd d ZdBddZdCddZddZddZddZe ddZddZddZdBdd Ze dBd!d"Ze d#d$Ze d%d&Ze d'd(Ze d)d&Ze dDd+d,Ze dDd-d.Zd/d0Z e d1d2Z!e dEd3d4Z"e d5d6Z#e d7d8Z$d9d:Z%d;d<Z&e =dFd>d?Z'd@dAZ(e(Z)dS)G RepositoryzABase class for a repository provided by a version control system.FrcCst|j|jSrq)r rrr`r r r!rPzRepository.resourcecCs*||_||_|d|_|d|_||_dS)auInitialize a repository. :param name: a unique name identifying the repository, usually a type-specific prefix followed by the path to the repository. :param params: a `dict` of parameters for the repository. Contains the name of the repository under the key "name" and the surrogate key that identifies the repository in the database under the key "id". :param log: a logger instance. :raises InvalidRepository: if the repository cannot be opened. rCrKN)rCr3rrKr)rTrCr3rr r r!rTs    zRepository.__init__cCsd|jj|j|j|jfS)Nz <%s %r %r %r>) __class__r'rKrCscoper`r r r!__repr__hs zRepository.__repr__cCr.)z'Close the connection to the repository.Nr r`r r r!rlzRepository.closecCr)zReturn the name of the base repository for this repository. This function returns the name of the base repository to which scoped repositories belong. For non-scoped repositories, it returns the repository name. r}r`r r r!r qszRepository.get_baseNcCr.)zClear any data that may have been cached in instance properties. `youngest_rev` can be specified as a way to force the value of the `youngest_rev` property (''will change in 0.12''). Nr )rT youngest_revr r r!clearzzRepository.clearcCr.)acPerform a sync of the repository cache, if relevant. If given, `rev_callback` must be a callable taking a `rev` parameter. The backend will call this function for each `rev` it decided to synchronize, once the synchronization changes are committed to the cache. When `clean` is `True`, the cache is cleaned first. Nr )rT rev_callbackcleanr r r!rzRepository.synccCr.)aResync the repository cache for the given `rev`, if relevant. Returns a "metadata-only" changeset containing the metadata prior to the resync, or `None` if the old values cannot be retrieved (typically when the repository is not cached). Nr r r r r!r zRepository.sync_changesetcCr)aGenerate a list of interesting places in the repository. `rev` might be used to restrict the list of available locations, but in general it's best to produce all known locations. The generated results must be of the form (category, name, path, rev). r r r r r!get_quickjump_entriesr.z Repository.get_quickjump_entriescCr.)a2Return the repository URL for the given path and revision. The returned URL can be `None`, meaning that no URL has been specified for the repository, an absolute URL, or a scheme-relative URL starting with `//`, in which case the scheme of the request should be prepended. Nr rTrtrr r r! get_path_urlr/zRepository.get_path_urlcCr.)z?Retrieve a Changeset corresponding to the given revision `rev`.Nr r r r r!rr(zRepository.get_changesetcCr.)zReturn a globally unique identifier for the ''rev'' changeset. Two changesets from different repositories can sometimes refer to the ''very same'' changeset (e.g. the repositories are clones). Nr r r r r!get_changeset_uidr0zRepository.get_changeset_uidccsJ|j}|r#||}|j|krdS|j|kr|V||}|sdSdS)zMGenerate Changeset belonging to the given time period (start, stop). N)r)rdate previous_rev)rTrstoprchgsetr r r!get_changesetss     zRepository.get_changesetscCs(z |||WdStyYdSw)zTell if there's a node at the specified (path,rev) combination. When `rev` is `None`, the latest revision is implied. TF)rrr1r r r!has_nodes   zRepository.has_nodecCr.)aXRetrieve a Node from the repository at the given path. A Node represents a directory or a file at a given revision in the repository. If the `rev` parameter is specified, the Node corresponding to that revision is returned, otherwise the Node corresponding to the youngest revision is returned. Nr r1r r r!rs zRepository.get_nodecCr.)z4Return the oldest revision stored in the repository.Nr r`r r r!get_oldest_revr(zRepository.get_oldest_revcC|Srq)r:r`r r r!rzRepository.cCr.)z/Return the youngest revision in the repository.Nr r`r r r!get_youngest_revr(zRepository.get_youngest_revcCr;rq)r=r`r r r!rr<rcCr.)zReturn the revision immediately preceding the specified revision. If `path` is given, filter out ancestor revisions having no changes below `path`. In presence of multiple parents, this follows the first parent. Nr rTrrtr r r!r5 zRepository.previous_revcCr.)zReturn the revision immediately following the specified revision. If `path` is given, filter out descendant revisions having no changes below `path`. In presence of multiple children, this follows the first child. Nr r>r r r!next_revr?zRepository.next_revcCs||}|dur |gSgS)z3Return a list of parents of the specified revision.N)r5)rTrrr r r! parent_revss zRepository.parent_revscCr.)zjProvides a total order over revisions. Return `True` if `rev1` is an ancestor of `rev2`. Nr )rTrev1rev2r r r!rev_older_thanr+zRepository.rev_older_thancCr.)aRetrieve all the revisions containing this path. If given, `rev` is used as a starting point (i.e. no revision ''newer'' than `rev` should be returned). The result format should be the same as the one of Node.get_history() Nr )rTrtrlimitr r r!get_path_historyr.zRepository.get_path_historycCr.)z7Return a canonical representation of path in the repos.Nr )rTrtr r r!normalize_pathr(zRepository.normalize_pathcCr.)aReturn a (unique) canonical representation of a revision. It's up to the backend to decide which string values of `rev` (usually provided by the user) should be accepted, and how they should be normalized. Some backends may for instance want to match against known tags or branch names. In addition, if `rev` is `None` or '', the youngest revision should be returned. :raise NoSuchChangeset: If the given `rev` isn't found. Nr r r r r! normalize_revszRepository.normalize_revcC||}|dur t|S|S)zReturn a compact string representation of a revision in the repos. :raise NoSuchChangeset: If the given `rev` isn't found. :since 1.2: Always returns a string or `None`. NrHstrrTrnorm_revr r r! short_rev%s zRepository.short_revcCrI)aAReturn a string representation of a revision in the repos for displaying to the user. This can be a shortened revision string, e.g. for repositories using long hashes. :raise NoSuchChangeset: If the given `rev` isn't found. :since 1.2: Always returns a string or `None`. NrJrLr r r! display_rev/s zRepository.display_revrpcCr.)afGenerates changes corresponding to generalized diffs. Generator that yields change tuples (old_node, new_node, kind, change) for each node change between the two arbitrary (path,rev) pairs. The old_node is assumed to be None when the change is an ADD, the new_node is assumed to be None when the change is a DELETE. Nr )rTold_pathold_revnew_pathnew_revignore_ancestryr r r! get_changes<s zRepository.get_changescCsd||jddvS)zd|jj|jf}|jdur|dt|j7}d|jj|fS)Nz%s:%sr<%s %r>)r9rCrtrrKr%r'rTrCr r r!r'ls z Node.__repr__cCr.)zReturn a stream for reading the content of the node. This method will return `None` for directories. The returned object must support a `read([len])` method. Nr r`r r r!rrr/zNode.get_contentTcCr;)aReturn a stream for reading the content of the node, with some standard processing applied. :param keyword_substitution: if `True`, meta-data keywords present in the content like ``$Rev$`` are substituted (which keyword are substituted and how they are substituted is backend specific) :param eol_hint: which style of line ending is expected if `None` was explicitly specified for the file itself in the version control backend (for example in Subversion, if it was set to ``'native'``). It can be `None`, ``'LF'``, ``'CR'`` or ``'CRLF'``. )r)rTkeyword_substitutioneol_hintr r r!get_processed_content{szNode.get_processed_contentcCr.)zGenerator that yields the immediate child entries of a directory. The entries are returned in no particular order. If the node is a file, this method returns `None`. Nr r`r r r! get_entriesr/zNode.get_entriescCr.)aProvide backward history for this Node. Generator that yields `(path, rev, chg)` tuples, one for each revision in which the node was changed. This generator will follow copies and moves of a node (if the underlying version control system supports that), which will be indicated by the first element of the tuple (i.e. the path) changing. Starts with an entry for the current revision. :param limit: if given, yield at most ``limit`` results. Nr )rTrEr r r! get_history zNode.get_historycCs(d}|dD] }|rd}q|SdS)zzReturn the change event corresponding to the previous revision. This returns a `(path, rev, chg)` tuple. TrgFN)ri)rTskippr r r! get_previouss zNode.get_previouscCr.)zProvide detailed backward history for the content of this Node. Retrieve an array of revisions, one `rev` for each line of content for that node. Only expected to work on (text) FILE nodes, of course. Nr r`r r r!get_annotationsr.zNode.get_annotationscCr.)zReturns the properties (meta-data) of the node, as a dictionary. The set of properties depends on the version control system. Nr r`r r r!get_propertiesr+zNode.get_propertiescCr.)zUThe length in bytes of the content. Will be `None` for a directory. Nr r`r r r!get_content_lengthr+zNode.get_content_lengthcCr;rq)rpr`r r r!rr<z Node.cCr.)zgThe MIME type corresponding to the content, if known. Will be `None` for a directory. Nr r`r r r!get_content_typer+zNode.get_content_typecCr;rq)rqr`r r r!rr<cCs|jddS)Nrrh)rtrr`r r r!get_nameryz Node.get_namecCr;rq)rrr`r r r!rr<cCsdSrqr r`r r r!get_last_modifiedszNode.get_last_modifiedcCr;rq)rsr`r r r!rr<cC |jtjkSrq)rr`rar`r r r!r cCrtrq)rr`rbr`r r r!rrucCs|jrdnd||jvS)z6Return True if view permission is granted on the node.rV FILE_VIEW)rrrXr r r!rZs zNode.is_viewable)TNrq)#r'r(r)r*rarbrcrrr\r created_rev created_pathrr'rrrgrhrirmrnrorpcontent_lengthrq content_typerrrCrs last_modifiedrrrZr^r r r r!r`PsL                r`c@seZdZdZdZdZdZdZdZeeefZ eefZ e e Z e j ZeddZd d Zd d Zd dZeddZddZddZddZddZeZdS) Changesetz>Represents a set of changes committed at once in a repository.rrdeleteeditmovecCst|j|j|jjdS)N)r)r rrr9rr`r r r!rr#zChangeset.resourcecCs*||_||_|p d|_|pd|_||_dS)Nr)r9rmessageauthorr4rTr9rrrr4r r r!rs    zChangeset.__init__cCs"d|jj|jf}d|jj|fS)Nz%s@%src)r9rCrr%r'rdr r r!r'szChangeset.__repr__cCr)adReturns the properties (meta-data) of the node, as a dictionary. The set of properties depends on the version control system. Warning: this used to yield 4-elements tuple (besides `name` and `text`, there were `wikiflag` and `htmlclass` values). This is now replaced by the usage of IPropertyRenderer (see #1601). r r`r r r!ror?zChangeset.get_propertiescCr.)aSGenerator that produces a tuple for every change in the changeset. The tuple will contain `(path, kind, change, base_path, base_rev)`, where `change` can be one of Changeset.ADD, Changeset.COPY, Changeset.DELETE, Changeset.EDIT or Changeset.MOVE, and `kind` is one of Node.FILE or Node.DIRECTORY. The `path` is the targeted path for the `change` (which is the ''deleted'' path for a DELETE change). The `base_path` and `base_rev` are the source path and rev for the action (`None` and `-1` in the case of an ADD change). Nr r`r r r!rUrjzChangeset.get_changescCr)aYield branches to which this changeset belong. Each branch is given as a pair `(name, head)`, where `name` is the branch name and `head` a flag set if the changeset is a head for this branch (i.e. if it has no children changeset). r r`r r r! get_branches!r+zChangeset.get_branchescCr)zSYield tags associated with this changeset. .. versionadded :: 1.0 r r`r r r!get_tags)zChangeset.get_tagscCr)zZYield bookmarks associated with this changeset. .. versionadded :: 1.1.5 r r`r r r! get_bookmarks0rzChangeset.get_bookmarkscCsd||jvS)z;Return True if view permission is granted on the changeset.CHANGESET_VIEW)rrXr r r!rZ7r$zChangeset.is_viewableN)r'r(r)r*ADDCOPYDELETEEDITMOVE DIFF_CHANGES OTHER_CHANGES ALL_CHANGESrcrrr\rrr'rorrUrrrrZr^r r r r!r|s.   r|cs*eZdZdZdfdd ZddZZS)EmptyChangesetzeChangeset that contains no changes. This is typically used when the changeset can't be retrieved.Ncs0|dur tdddtd}t|||||dS)Nirp)tzinfo)rrsuperrrr%r r!rBszEmptyChangeset.__init__cCstgSrq)rSr`r r r!rUGszEmptyChangeset.get_changes)NNN)r'r(r)r*rrU __classcell__r r rr!r>sr)9os.pathrsabcrrr trac.adminrrr trac.configrr trac.core trac.resourcer r r trac.utilrrtrac.util.concurrencyrrtrac.util.datefmtrrtrac.util.textrrrtrac.util.translationr trac.web.apirtrac.web.chromerrrr"rr%r, Interfacer-r6r8 Componentr>rcrrobjectr#r`r|rr r r r!sF   $Fx  V