Mercurial and Git clients can push and pull from this alias URL to interact with this repository. You can change to which repository an alias points by going to the Aliases link on the project page.
# hglib.py - Mercurial API wrappers for TortoiseHg## Copyright 2007 Steve Borho <steve@borho.org>## This software may be used and distributed according to the terms of the# GNU General Public License version 2, incorporated herein by reference.importosimportreimportsysimportshleximporttimeimportinspectfrommercurialimportdemandimportdemandimport.disable()try:# hg >= 1.7frommercurial.cmdutilimportupdatedirexceptImportError:# hg <= 1.6frommercurial.patchimportupdatedirdemandimport.enable()frommercurialimportui,util,extensions,match,bundlerepo,url,cmdutilfrommercurialimportdispatch,encoding,templatefilters,filemerge_encoding=encoding.encoding_encodingmode=encoding.encodingmode_fallbackencoding=encoding.fallbackencoding# extensions which can cause problem with TortoiseHg_extensions_blacklist=('color','pager','progress')fromtortoisehg.utilimportpathsfromtortoisehg.util.hgversionimporthgversiondeftounicode(s):""" Convert the encoding of string from MBCS to Unicode. Based on mercurial.util.tolocal(). Return 'unicode' type string. """ifsisNone:returnNoneifisinstance(s,unicode):returnsforein('utf-8',_encoding):try:returns.decode(e,'strict')exceptUnicodeDecodeError:passreturns.decode(_fallbackencoding,'replace')deffromunicode(s,errors='strict'):""" Convert the encoding of string from Unicode to MBCS. Return 'str' type string. If you don't want an exception for conversion failure, specify errors='replace'. """ifsisNone:returnNones=unicode(s)# s can be QtCore.QStringforencin(_encoding,_fallbackencoding):try:returns.encode(enc)exceptUnicodeEncodeError:passreturns.encode(_encoding,errors)# last ditchdeftoutf(s):""" Convert the encoding of string from MBCS to UTF-8. Return 'str' type string. """ifsisNone:returnNonereturntounicode(s).encode('utf-8').replace('\0','')deffromutf(s):""" Convert the encoding of string from UTF-8 to MBCS Return 'str' type string. """ifsisNone:returnNonetry:returns.decode('utf-8').encode(_encoding)except(UnicodeDecodeError,UnicodeEncodeError):passtry:returns.decode('utf-8').encode(_fallbackencoding)except(UnicodeDecodeError,UnicodeEncodeError):passu=s.decode('utf-8','replace')# last ditchreturnu.encode(_encoding,'replace')_tabwidth=Nonedefgettabwidth(ui):global_tabwidthif_tabwidthisnotNone:return_tabwidthtabwidth=ui.config('tortoisehg','tabwidth')try:tabwidth=int(tabwidth)iftabwidth<1ortabwidth>16:tabwidth=0except(ValueError,TypeError):tabwidth=0_tabwidth=tabwidthreturntabwidth_maxdiff=Nonedefgetmaxdiffsize(ui):global_maxdiffif_maxdiffisnotNone:return_maxdiffmaxdiff=ui.config('tortoisehg','maxdiff')try:maxdiff=int(maxdiff)ifmaxdiff<1:maxdiff=sys.maxintexcept(ValueError,TypeError):maxdiff=1024# 1MB by default_maxdiff=maxdiff*1024return_maxdiff_deadbranch=Nonedefgetdeadbranch(ui):'''return a list of dead branch names in UTF-8'''global_deadbranchif_deadbranchisNone:db=toutf(ui.config('tortoisehg','deadbranch',''))dblist=[b.strip()forbindb.split(',')]_deadbranch=dblistreturn_deadbranchdefgetlivebranch(repo):'''return a list of live branch names in UTF-8'''lives=[]deads=getdeadbranch(repo.ui)cl=repo.changelogforbranch,headsinrepo.branchmap().iteritems():# branch encoded in UTF-8ifbranchindeads:# ignore branch names in tortoisehg.deadbranchcontinuebheads=[hforhinheadsif('close'notincl.read(h)[5])]ifnotbheads:# ignore branches with all heads closedcontinuelives.append(branch.replace('\0',''))returnlivesdefgetlivebheads(repo):'''return a list of revs of live branch heads'''bheads=[]forb,lsinrepo.branchmap().iteritems():bheads+=[repo[x]forxinls]heads=[x.rev()forxinbheadsifnotx.extra().get('close')]heads.sort()heads.reverse()returnheads_hidetags=Nonedefgethidetags(ui):global_hidetagsif_hidetagsisNone:tags=toutf(ui.config('tortoisehg','hidetags',''))taglist=[t.strip()fortintags.split()]_hidetags=taglistreturn_hidetagsdefgetfilteredtags(repo):filtered=[]hides=gethidetags(repo.ui)fortaginlist(repo.tags()):iftagnotinhides:filtered.append(tag)returnfiltereddefgetrawctxtags(changectx):'''Returns the tags for changectx, converted to UTF-8 but unfiltered for hidden tags'''value=[toutf(tag)fortaginchangectx.tags()]iflen(value)==0:returnNonereturnvaluedefgetctxtags(changectx):'''Returns all unhidden tags for changectx, converted to UTF-8'''value=getrawctxtags(changectx)ifvalue:htlist=gethidetags(changectx._repo.ui)tags=[tagfortaginvalueiftagnotinhtlist]iflen(tags)==0:returnNonereturntagsreturnNonedefgetmqpatchtags(repo):'''Returns all tag names used by MQ patches, or []'''ifhasattr(repo,'mq'):repo.mq.parse_series()returnrepo.mq.series[:]else:return[]defgetcurrentqqueue(repo):"""Return the name of the current patch queue."""ifnothasattr(repo,'mq'):returnNonecur=os.path.basename(repo.mq.path)ifcur.startswith('patches-'):cur=cur[8:]returncurdefdiffexpand(line):'Expand tabs in a line of diff/patch text'if_tabwidthisNone:gettabwidth(ui.ui())ifnot_tabwidthorlen(line)<2:returnlinereturnline[0]+line[1:].expandtabs(_tabwidth)_fontconfig=Nonedefgetfontconfig(_ui=None):global_fontconfigif_fontconfigisNone:if_uiisNone:_ui=ui.ui()# defaults_fontconfig={'fontcomment':'monospace 10','fontdiff':'monospace 10','fontlist':'sans 9','fontlog':'monospace 10'}# overwrite defaults with configured valuesforname,valin_ui.configitems('gtools'):ifvalandname.startswith('font'):_fontconfig[name]=valreturn_fontconfigdefinvalidaterepo(repo):repo.dirstate.invalidate()ifisinstance(repo,bundlerepo.bundlerepository):# Work around a bug in hg-1.3. repo.invalidate() breaks# overlay bundlereposreturnrepo.invalidate()# way _bookmarks / _bookmarkcurrent cached changed# from 1.4 to 1.5...forcachedAttrin('_bookmarks','_bookmarkcurrent'):# Check if it's a property or normal value...ifis_descriptor(repo,cachedAttr):# The very act of calling hasattr would# re-cache the property, so just assume it's# already cached, and catch the error if it wasn't.try:delattr(repo,cachedAttr)exceptAttributeError:passelifhasattr(repo,cachedAttr):setattr(repo,cachedAttr,None)if'mq'inrepo.__dict__:#do not create if it does not existrepo.mq.invalidate()defenabledextensions():"""Return the {name: shortdesc} dict of enabled extensions shortdesc is in local encoding. """returnextensions.enabled()[0]defallextensions():"""Return the {name: shortdesc} dict of known extensions shortdesc is in local encoding. """enabledexts=enabledextensions()disabledexts=extensions.disabled()[0]exts=(disabledextsor{}).copy()exts.update(enabledexts)returnextsdefvalidateextensions(enabledexts):"""Report extensions which should be disabled Returns the dict {name: message} of extensions expected to be disabled. message is 'utf-8'-encoded string. """fromtortoisehg.util.i18nimport_# avoid cyclic dependencyexts={}ifos.name!='posix':exts['inotify']=_('inotify is not supported on this platform')if'win32text'inenabledexts: exts['eol'] = _('eol is incompatible with win32text')
if 'eol' in enabledexts:
exts['win32text'] = _('win32text is incompatible with eol')
+ if 'perfarce' in enabledexts:+ exts['hgsubversion'] = _('hgsubversion is incompatible with perfarce')+ if 'hgsubversion' in enabledexts:+ exts['perfarce'] = _('perfarce is incompatible with hgsubversion') return exts
def loadextension(ui, name):
# Between Mercurial revisions 1.2 and 1.3, extensions.load() stopped# calling uisetup() after loading an extension. This could do# unexpected things if you use an hg version < 1.3extensions.load(ui,name,None)mod=extensions.find(name)uisetup=getattr(mod,'uisetup',None)ifuisetup:uisetup(ui)def_loadextensionwithblacklist(orig,ui,name,path):ifname.startswith('hgext.')orname.startswith('hgext/'):shortname=name[6:]else:shortname=nameifshortnamein_extensions_blacklistandnotpath:# only bundled extreturnreturnorig(ui,name,path)defwrapextensionsloader():"""Wrap extensions.load(ui, name) for blacklist to take effect"""extensions.wrapfunction(extensions,'load',_loadextensionwithblacklist)defcanonpaths(list):'Get canonical paths (relative to root) for list of files'# This is a horrible hack. Please remove this when HG acquires a# decent case-folding solution.canonpats=[]cwd=os.getcwd()root=paths.find_root(cwd)forfinlist:try:canonpats.append(util.canonpath(root,cwd,f))exceptutil.Abort:# Attempt to resolve case folding conflicts.fu=f.upper()cwdu=cwd.upper()iffu.startswith(cwdu):canonpats.append(util.canonpath(root,cwd,f[len(cwd+os.sep):]))else:# May already be canonicalcanonpats.append(f)returncanonpatsdefescapepath(path):'Before passing a file path to hg API, it may need escaping'p=pathif'['inpor'{'inpor'*'inpor'?'inp:return'path:'+pelse:returnpdefnormpats(pats):'Normalize file patterns'normpats=[]forpatinpats:kind,p=match._patsplit(pat,None)ifkind:normpats.append(pat)else:if'['inpor'{'inpor'*'inpor'?'inp:normpats.append('glob:'+p)else:normpats.append('path:'+p)returnnormpatsdefmergetools(ui,values=None):'returns the configured merge tools and the internal ones'ifvalues==None:values=[]seen=values[:]forkey,valueinui.configitems('merge-tools'):t=key.split('.')[0]iftnotinseen:seen.append(t)# Ensure the tool is installediffilemerge._findtool(ui,t):values.append(t)values.append('internal:merge')values.append('internal:prompt')values.append('internal:dump')values.append('internal:local')values.append('internal:other')values.append('internal:fail')returnvalues_difftools=Nonedefdifftools(ui):global_difftoolsif_difftools:return_difftoolsdeffixup_extdiff(diffopts):if'$child'notindiffopts:diffopts.append('$parent1')diffopts.append('$child')if'$parent2'indiffopts:mergeopts=diffopts[:]diffopts.remove('$parent2')else:mergeopts=[]returndiffopts,mergeoptstools={}forcmd,pathinui.configitems('extdiff'):ifcmd.startswith('cmd.'):cmd=cmd[4:]ifnotpath:path=cmddiffopts=ui.config('extdiff','opts.'+cmd,'')diffopts=shlex.split(diffopts)diffopts,mergeopts=fixup_extdiff(diffopts)tools[cmd]=[path,diffopts,mergeopts]elifcmd.startswith('opts.'):continueelse:# command = path optsifpath:diffopts=shlex.split(path)path=diffopts.pop(0)else:path,diffopts=cmd,[]diffopts,mergeopts=fixup_extdiff(diffopts)tools[cmd]=[path,diffopts,mergeopts]mt=[]mergetools(ui,mt)fortinmt:ift.startswith('internal:'):continuedopts=ui.config('merge-tools',t+'.diffargs','')mopts=ui.config('merge-tools',t+'.diff3args','')dopts,mopts=shlex.split(dopts),shlex.split(mopts)tools[t]=[filemerge._findtool(ui,t),dopts,mopts]_difftools=toolsreturntools_funcre=re.compile('\w')defgetchunkfunction(data,linenum):"""Return the function containing the chunk at linenum. Stolen from mercurial/mdiff.py. """# Walk backwards starting from the line before the chunk# to find a line starting with an alphanumeric char.forxinxrange(int(linenum)-2,-1,-1):t=data[x].rstrip()if_funcre.match(t):return' '+t[:40]returnNonedefhgcmd_toq(q,label,args):''' Run an hg command in a background thread, pipe all output to a Queue object. Assumes command is completely noninteractive. '''classQui(ui.ui):def__init__(self,src=None):super(Qui,self).__init__(src)self.setconfig('ui','interactive','off')defwrite(self,*args,**opts):ifself._buffers:self._buffers[-1].extend([str(a)forainargs])else:forainargs:iflabel:q.put((str(a),opts.get('label','')))else:q.put(str(a))defplain(self):returnTrueu=Qui()oldterm=os.environ.get('TERM')os.environ['TERM']='dumb'ret=dispatch._dispatch(u,list(args))ifoldterm:os.environ['TERM']=oldtermreturnretdefget_reponame(repo):ifrepo.ui.config('tortoisehg','fullpath',False):name=repo.rootelifrepo.ui.config('web','name',False):name=repo.ui.config('web','name')else:name=os.path.basename(repo.root)returntoutf(name)defdisplaytime(date):returnutil.datestr(date,'%Y-%m-%d %H:%M:%S %1%2')defutctime(date):returntime.strftime("%Y-%m-%d %H:%M:%S",time.gmtime(date[0]))defage(date):returntemplatefilters.age(date)defusername(user):author=templatefilters.person(user)ifnotauthor:author=util.shortuser(user)returnauthordefget_revision_desc(fctx,curpath=None):"""return the revision description as a string"""author=tounicode(username(fctx.user()))rev=fctx.linkrev()# If the source path matches the current path, don't bother including it.ifcurpathandcurpath==fctx.path():source=''else:source='(%s)'%fctx.path()date=age(fctx.date())l=tounicode(fctx.description()).replace('\0','').splitlines()summary=landl[0]or''return'%s@%s%s:%s "%s"'%(author,rev,source,date,summary)defvalidate_synch_path(path,repo):''' Validate the path that must be used to sync operations (pull, push, outgoing and incoming) '''return_path=pathforalias,path_auxinrepo.ui.configitems('paths'):ifpath==alias:return_path=path_auxelifpath==url.hidepassword(path_aux):return_path=path_auxreturnreturn_pathdefget_repo_bookmarks(repo,values=False):""" Will return the bookmarks for the given repo if the bookmarks extension is loaded. By default, returns a list of bookmark names; if values is True, returns a dict mapping names to nodes. If the extension is not loaded, returns an empty list/dict. """try:bookmarks=extensions.find('bookmarks')exceptKeyError:returnvaluesand{}or[]ifbookmarks:# Bookmarks changed from 1.4 to 1.5...ifhasattr(bookmarks,'parse'):marks=bookmarks.parse(repo)elifhasattr(repo,'_bookmarks'):marks=repo._bookmarkselse:marks={}else:marks={}ifvalues:returnmarkselse:returnmarks.keys()defget_repo_bookmarkcurrent(repo):""" Will return the current bookmark for the given repo if the bookmarks extension is loaded, and the track.current option is on. If the extension is not loaded, or track.current is not set, returns None """try:bookmarks=extensions.find('bookmarks')exceptKeyError:returnNoneifbookmarksandrepo.ui.configbool('bookmarks','track.current'):# Bookmarks changed from 1.4 to 1.5...ifhasattr(bookmarks,'current'):returnbookmarks.current(repo)elifhasattr(repo,'_bookmarkcurrent'):returnrepo._bookmarkcurrentreturnNonedefis_rev_current(repo,rev):''' Returns True if the revision indicated by 'rev' is the current working directory parent. If rev is '' or None, it is assumed to mean 'tip'. '''ifrevin('',None):rev='tip'rev=repo.lookup(rev)parents=repo.parents()iflen(parents)>1:returnFalsereturnrev==parents[0].node()defis_descriptor(obj,attr):""" Returns True if obj.attr is a descriptor - ie, accessing the attribute will actually invoke the '__get__' method of some object. Returns False if obj.attr exists, but is not a descriptor, and None if obj.attr was not found at all. """forclsininspect.getmro(obj.__class__):ifattrincls.__dict__:returnhasattr(cls.__dict__[attr],'__get__')returnNonedefexport(repo,revs,template='hg-%h.patch',fp=None,switch_parent=False,opts=None):''' export changesets as hg patches. Mercurial moved patch.export to cmdutil.export after version 1.5 (change e764f24a45ee in mercurial). '''try:returncmdutil.export(repo,revs,template,fp,switch_parent,opts)exceptAttributeError:frommercurialimportpatchreturnpatch.export(repo,revs,template,fp,switch_parent,opts)
Attach a Trello Card
Add a tag
Your session has expired
You are no longer logged in. Please log in and try your request again.
Filter RSS Feed
This RSS feed URL allows you to see the contents of your current filter using any feed reader.
This link includes a special authentication token. If you share the URL with anyone else, they can see this RSS feed's activity. You can disable these tokens when needed.
Your current filter is unsaved; changing it won't affect this RSS feed.