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.
# Published under the GNU GPL, v2 or later.# Copyright (C) 2007 Jelmer Vernooij <jelmer@samba.org># Copyright (C) 2007 Henry Ludemann <misc@hl.id.au># Copyright (C) 2007 TK Soh <teekaysoh@gmail.com>importosimporttempfileimportpythoncomfromwin32com.shellimportshell,shellconimportwin32conimportwin32processimportwin32eventimportwin32uiimportwin32guiimportwin32gui_structimportwin32apiimport_winregfrommercurialimporthgfrommercurialimportrepoas_repofromthgutilimport*# FIXME: quick workaround traceback caused by missing "closed" # attribute in win32trace.importsysfrommercurialimportuidefwrite_err(self,*args):forainargs:sys.stderr.write(str(a))ui.ui.write_err=write_errS_OK=0S_FALSE=1classTortoiseMenu(object):def__init__(self,menutext,helptext,handler,icon=None,state=True):self.menutext=menutextself.helptext=helptextself.handler=handlerself.state=stateself.icon=iconclassTortoiseSubmenu(object):def__init__(self,menutext,menus=[],icon=None):self.menutext=menutextself.menus=menus[:]self.icon=icondefadd_menu(self,menutext,helptext,handler,icon=None,state=True):self.menus.append(TortoiseMenu(menutext,helptext,handler,icon,state))defadd_sep(self):self.menus.append(TortoiseMenuSep())defget_menus(self):returnself.menusclassTortoiseMenuSep(object):def__init__(self):passdefopen_repo(path):root=find_root(path)ifroot:try:repo=hg.repository(ui.ui(),path=root)returnrepoexcept_repo.RepoError:passreturnNonedefopen_dialog(cmd,cmdopts='',cwd=None,root=None,filelist=[],gui=True):app_path=find_path("hgproc",get_prog_root(),'.EXE;.BAT')iffilelist:fd,tmpfile=tempfile.mkstemp(prefix="tortoisehg_filelist_")os.write(fd,"\n".join(filelist))os.close(fd)# start gpopengpopts="--command %s"%cmdifroot:gpopts+=" --root %s"%shellquote(root)iffilelist:gpopts+=" --listfile %s --deletelistfile"%(shellquote(tmpfile))ifcwd:gpopts+=" --cwd %s"%shellquote(cwd)ifnotgui:gpopts+=" --nogui"cmdline='%s%s -- %s'%(shellquote(app_path),gpopts,cmdopts)try:run_program(cmdline)exceptwin32api.error,details:win32ui.MessageBox("Error executing command - %s"%(details),"gpopen")defget_clone_repo_name(dir,repo_name):dest_clone=os.path.join(dir,repo_name)ifos.path.exists(dest_clone):dest_clone=os.path.join(dir,"Clone of "+repo_name)i=2whileos.path.exists(dest_clone):dest_clone=os.path.join(dir,"Clone of (%s) %s"%(i,repo_name))i+=1returndest_clonedefrun_program(cmdline):print"run_program: %s"%(cmdline)importsubprocesspop=subprocess.Popen(cmdline,shell=False,creationflags=win32con.CREATE_NO_WINDOW,stderr=subprocess.STDOUT,stdout=subprocess.PIPE,stdin=subprocess.PIPE)"""Windows shell extension that adds context menu items to Mercurial repository"""classContextMenuExtension:_reg_progid_="Mercurial.ShellExtension.ContextMenu"_reg_desc_="Mercurial Shell Extension"_reg_clsid_="{EEE9936B-73ED-4D45-80C9-AF918354F885}"_com_interfaces_=[shell.IID_IShellExtInit,shell.IID_IContextMenu]_public_methods_=["Initialize",# From IShellExtInit"QueryContextMenu","InvokeCommand","GetCommandString"# IContextMenu]registry_keys=[(_winreg.HKEY_CLASSES_ROOT,r"*\shellex\ContextMenuHandlers\TortoiseHg",[(None,_reg_clsid_)]),(_winreg.HKEY_CLASSES_ROOT,r"Directory\Background\shellex\ContextMenuHandlers\TortoiseHg",[(None,_reg_clsid_)]),(_winreg.HKEY_CLASSES_ROOT,r"Directory\shellex\ContextMenuHandlers\TortoiseHg",[(None,_reg_clsid_)]),(_winreg.HKEY_CLASSES_ROOT,r"Folder\shellex\ContextMenuHandlers\TortoiseHg",[(None,_reg_clsid_)]),(_winreg.HKEY_CLASSES_ROOT,r"Directory\shellex\DragDropHandlers\TortoiseHg",[(None,_reg_clsid_)]),(_winreg.HKEY_CLASSES_ROOT,r"Folder\shellex\DragDropHandlers\TortoiseHg",[(None,_reg_clsid_)]),]def__init__(self):self._folder=Noneself._filenames=[]self._handlers={}defInitialize(self,folder,dataobj,hkey):iffolder:self._folder=shell.SHGetPathFromIDList(folder)ifdataobj:format_etc=win32con.CF_HDROP,None,1,-1,pythoncom.TYMED_HGLOBALsm=dataobj.GetData(format_etc)num_files=shell.DragQueryFile(sm.data_handle,-1)foriinrange(num_files):self._filenames.append(shell.DragQueryFile(sm.data_handle,i))def_create_menu(self,parent,menus,pos,idCmd,idCmdFirst):formenu_infoinmenus:iftype(menu_info)==TortoiseMenuSep:win32gui.InsertMenu(parent,pos,win32con.MF_BYPOSITION|win32con.MF_SEPARATOR,idCmdFirst+idCmd,None)eliftype(menu_info)==TortoiseSubmenu:submenu=win32gui.CreatePopupMenu()idCmd=self._create_menu(submenu,menu_info.get_menus(),0,idCmd,idCmdFirst)opt={'text':menu_info.menutext,'wID':idCmdFirst+idCmd,'hSubMenu':submenu,}ifmenu_info.icon:icon_path=get_icon_path("tortoise",menu_info.icon)opt['hbmpChecked']=opt['hbmpUnchecked']= \
icon_to_bitmap(icon_path)item,_=win32gui_struct.PackMENUITEMINFO(**opt)win32gui.InsertMenuItem(parent,pos,True,item)self._handlers[idCmd]=("",lambdax,y:0)eliftype(menu_info)==TortoiseMenu:fstate=win32con.MF_BYCOMMANDifmenu_info.stateisFalse:fstate|=win32con.MF_GRAYEDopt={'text':menu_info.menutext,'fState':fstate,'wID':idCmdFirst+idCmd,}ifmenu_info.icon:icon_path=get_icon_path("tortoise",menu_info.icon)opt['hbmpChecked']=opt['hbmpUnchecked']= \
icon_to_bitmap(icon_path)item,_=win32gui_struct.PackMENUITEMINFO(**opt)win32gui.InsertMenuItem(parent,pos,True,item)self._handlers[idCmd]=(menu_info.helptext,menu_info.handler)idCmd+=1pos+=1returnidCmddefQueryContextMenu(self,hMenu,indexMenu,idCmdFirst,idCmdLast,uFlags):ifuFlags&shellcon.CMF_DEFAULTONLY:return0thgmenu=[]# hg menus# a brutal hack to detect if we are the first menu to go on to the # context menu. If we are not the first, then add a menu separator# The number '30000' is just a guess based on my observationprint"idCmdFirst = ",idCmdFirstifidCmdFirst>=30000:thgmenu.append(TortoiseMenuSep())# As we are a context menu handler, we can ignore verbs.self._handlers={}ifself._folderandself._filenames:# get menus with drag-n-drop supportcommands=self._get_commands_dragdrop()else:# add regularly used commit menu to main context menurpath=self._folderorself._filenames[0]ifopen_repo(rpath):thgmenu.append(TortoiseMenu(_("HG Commit..."),_("Commit changes in repository"),self._commit,icon="menucommit.ico"))# get other menus for hg submenucommands=self._get_commands()# add common menu itemscommands.append(TortoiseMenuSep())commands.append(TortoiseMenu(_("About"),_("About TortoiseHg"),self._about,icon="menuabout.ico"))ifcommands:# create submenus with Hg commandsthgmenu.append(TortoiseSubmenu("TortoiseHG",commands,icon="hg.ico"))thgmenu.append(TortoiseMenuSep())idCmd=self._create_menu(hMenu,thgmenu,indexMenu,0,idCmdFirst)# Return total number of menus & submenus we've addedreturnidCmdelse:# no applicable Hg actionsreturn0def_get_commands_dragdrop(self):""" Get a list of commands valid for the current selection. Each command is a tuple containing (display text, handler). """print"_get_commands_dragdrop() on %s"%", ".join(self._filenames)# we can only accept dropping one itemiflen(self._filenames)>1:return[]# open repodrag_repo=Nonedrop_repo=Noneprint"drag = %s"%self._filenames[0]print"drop = %s"%self._folderdrag_path=self._filenames[0]drag_repo=open_repo(drag_path)ifnotdrag_repo:return[]ifdrag_repoanddrag_repo.root!=drag_path:return[]# dragged item must be a hg repo root directorydrop_repo=open_repo(self._folder)result=[]result.append(TortoiseMenu(_("Create Clone"),_("Create clone here from source"),self._clone_here,icon="menuclone.ico"))ifdrop_repo:result.append(TortoiseMenu(_("Synchronize"),_("Synchronize with dragged repository"),self._synch_here,icon="menusynch.ico"))returnresultdef_get_commands(self):""" Get a list of commands valid for the current selection. Each command is a tuple containing (display text, handler). """print"_get_commands() on %s"%", ".join(self._filenames)# open reporesult=[]rpath=self._folderorself._filenames[0]repo=open_repo(rpath)ifrepoisNone:result.append(TortoiseMenu(_("Clone a Repository"),_("clone a repository"),self._clone,icon="menuclone.ico"))result.append(TortoiseMenu(_("Create Repository Here"),_("create a new repository in this directory"),self._init,icon="menucreaterepos.ico",state=os.path.isdir(rpath)))else:result.append(TortoiseMenu(_("View File Status"),_("Repository status"),self._status,icon="menushowchanged.ico"))# Visual Diff (any extdiff command)has_vdiff=repo.ui.config('tortoisehg','vdiff','')!=''result.append(TortoiseMenu(_("Visual Diff"),_("View changes using GUI diff tool"),self._vdiff,icon="TortoiseMerge.ico",state=has_vdiff))result.append(TortoiseMenu(_("Add Files"),_("Add files to Hg repository"),self._add,icon="menuadd.ico"))result.append(TortoiseMenu(_("Remove Files"),_("Remove selected files on the next commit"),self._remove,icon="menudelete.ico"))result.append(TortoiseMenu(_("Undo Changes"),_("Revert selected files"),self._revert,icon="menurevert.ico"))# we can only annotate file but not directoriesannotatible=len(self._filenames)>0forfinself._filenames:ifnotos.path.isfile(f):annotatible=Falsebreakresult.append(TortoiseMenu(_("Annotate Files"),_("show changeset information per file line"),self._annotate,icon="menublame.ico",state=annotatible))result.append(TortoiseMenuSep())result.append(TortoiseMenu(_("Update To Revision"),_("update working directory"),self._update,icon="menucheckout.ico"))can_merge=len(repo.heads())>1and \
len(repo.changectx(None).parents())<2result.append(TortoiseMenu(_("Merge Revisions"),_("merge working directory with another revision"),self._merge,icon="menumerge.ico",state=can_merge))# show un-merge menu per merge status of working directoryiflen(repo.changectx(None).parents())>1:result.append(TortoiseMenu(_("Undo Merge"),_("Undo merge by updating to revision"),self._merge,icon="menuunmerge.ico"))result.append(TortoiseMenuSep())result.append(TortoiseMenu(_("View Changelog"),_("View revision history"),self._history,icon="menulog.ico"))result.append(TortoiseMenu(_("Search Repository"),_("Search revisions of files for a text pattern"),self._grep,icon="menurepobrowse.ico"))ifrepo.ui.config('tortoisehg','view'):result.append(TortoiseMenu(_("Revision Graph"),_("View history with DAG graph"),self._view,icon="menurevisiongraph.ico"))result.append(TortoiseMenuSep())result.append(TortoiseMenu(_("Synchronize..."),_("Synchronize with remote repository"),self._synch,icon="menusynch.ico"))result.append(TortoiseMenu(_("Recovery..."),_("General repair and recovery of repository"),self._recovery,icon="general.ico"))result.append(TortoiseMenu(_("Web Server"),_("start web server for this repository"),self._serve,icon="proxy.ico")) result.append(TortoiseMenu(_("Create Clone"),
_("Clone a repository here"),
self._clone, icon="menuclone.ico"))
-if repo.root != rpath:- result.append(TortoiseMenu(_("Create Repository Here"),
- _("create a new repository in this directory"),
-self._init, icon="menucreaterepos.ico",
-state=os.path.isdir(rpath)))
+can_init = repo.root != rpath and os.path.isdir(rpath)+ result.append(TortoiseMenu(_("Create Repository Here"),
+ _("create a new repository in this directory"),
+ self._init, icon="menucreaterepos.ico",
+ state=can_init))
# config setttings menu
result.append(TortoiseMenuSep())
optmenu=TortoiseSubmenu(_("Settings"),icon="menusettings.ico")optmenu.add_menu(_("Global"),_("Configure user wide settings"),self._config_user,icon="settings_user.ico")ifrepo:optmenu.add_menu(_("Repository"),_("Configure settings local to this repository"),self._config_repo,icon="settings_repo.ico")result.append(optmenu)returnresultdefInvokeCommand(self,ci):mask,hwnd,verb,params,dir,nShow,hotkey,hicon=ciifverb>>16:# This is a textual verb invocation... not supported.returnS_FALSEifverbnotinself._handlers:raiseException("Unsupported command id %i!"%verb)self._handlers[verb][1](hwnd)defGetCommandString(self,cmd,uFlags):ifuFlags&shellcon.GCS_VALIDATEAoruFlags&shellcon.GCS_VALIDATEW:ifcmdinself._handlers:returnS_OKreturnS_FALSEifuFlags&shellcon.GCS_VERBAoruFlags&shellcon.GCS_VERBW:returnS_FALSEifuFlags&shellcon.GCS_HELPTEXTAoruFlags&shellcon.GCS_HELPTEXTW:# The win32com.shell implementation encodes the resultant# string into the correct encoding depending on the flags.returnself._handlers[cmd][0]returnS_FALSEdef_commit(self,parent_window):self._run_dialog('commit')def_config_user(self,parent_window):self._run_dialog('config',noargs=True)def_config_repo(self,parent_window):self._run_dialog('config')def_vdiff(self,parent_window):'''[tortoisehg] vdiff = <any extdiff command>'''diff=ui.ui().config('tortoisehg','vdiff',None)ifnotdiff:msg="You must configure tortoisehg.vdiff in your Mercurial.ini"title="Visual Diff Not Configured"win32ui.MessageBox(msg,title,win32con.MB_OK|win32con.MB_ICONERROR)returntargets=self._filenamesor[self._folder]root=find_root(targets[0])open_dialog(diff,root=root,filelist=targets,gui=False)def_view(self,parent_window):'''[tortoisehg] view = [hgk | hgview]'''view=ui.ui().config('tortoisehg','view','')ifnotview:msg="You must configure tortoisehg.view in your Mercurial.ini"title="Revision Graph Tool Not Configured"win32ui.MessageBox(msg,title,win32con.MB_OK|win32con.MB_ICONERROR)returntargets=self._filenamesor[self._folder]root=find_root(targets[0])ifview=='hgview':hgviewpath=find_path('hgview')cmd="%s --repository=%s"% \
(shellquote(hgviewpath),shellquote(root))iflen(self._filenames)==1:cmd+=" --file=%s"%shellquote(self._filenames[0])run_program(cmd)else:ifview=='hgk':open_dialog('view',root=root,gui=False)else:msg="Revision graph viewer %s not recognized"%viewtitle="Unknown history tool"win32ui.MessageBox(msg,title,win32con.MB_OK|win32con.MB_ICONERROR)def_history(self,parent_window):self._log(parent_window)def_clone_here(self,parent_window):src=self._filenames[0]dest=self._folderrepo_name=os.path.basename(src)dest_clone=get_clone_repo_name(dest,repo_name)cmdopts="--verbose"repos=[src,dest_clone]open_dialog('clone',cmdopts,cwd=dest,filelist=repos)def_push_here(self,parent_window):src=self._filenames[0]dest=self._foldermsg="Push changes from %s into %s?"%(src,dest)title="Mercurial: push"rv=win32ui.MessageBox(msg,title,win32con.MB_OKCANCEL)ifrv==2:returncmdopts="--verbose"open_dialog('push',cmdopts,root=src,filelist=[dest])def_pull_here(self,parent_window):src=self._filenames[0]dest=self._foldermsg="Pull changes from %s?"%(src)title="Mercurial: pull"rv=win32ui.MessageBox(msg,title,win32con.MB_OKCANCEL)ifrv==2:returncmdopts="--verbose"open_dialog('pull',cmdopts,root=src,filelist=[dest])def_incoming_here(self,parent_window):src=self._filenames[0]dest=self._foldercmdopts="--verbose"open_dialog('incoming',cmdopts,root=src,filelist=[dest])def_outgoing_here(self,parent_window):src=self._filenames[0]dest=self._foldercmdopts="--verbose"open_dialog('outgoing',cmdopts,root=src,filelist=[dest])def_init(self,parent_window):self._run_dialog('init')def_status(self,parent_window):self._run_dialog('status')def_clone(self,parent_window):self._run_dialog('clone',True)def_synch(self,parent_window):self._run_dialog('synch',True)def_synch_here(self,parent_window):self._run_dialog('synch',False)def_pull(self,parent_window):self._run_dialog('pull',True)def_push(self,parent_window):self._run_dialog('push',True)def_incoming(self,parent_window):self._run_dialog('incoming',True)def_outgoing(self,parent_window):self._run_dialog('outgoing',True)def_serve(self,parent_window):self._run_dialog('serve',noargs=True)def_add(self,parent_window):self._run_dialog('add',modal=True)def_remove(self,parent_window):self._run_dialog('remove')def_revert(self,parent_window):self._run_dialog('status')def_tip(self,parent_window):self._run_dialog('tip',True)def_parents(self,parent_window):self._run_dialog('parents',True)def_heads(self,parent_window):self._run_dialog('heads',True)def_log(self,parent_window):self._run_dialog('log',verbose=False)def_show_tags(self,parent_window):self._run_dialog('tags',True,verbose=False)def_add_tag(self,parent_window):self._run_dialog('tag',True,verbose=False)def_diff(self,parent_window):self._run_dialog('diff')def_merge(self,parent_window):self._run_dialog('merge',noargs=True)def_recovery(self,parent_window):self._run_dialog('recovery')def_update(self,parent_window):self._run_dialog('update',noargs=True)def_grep(self,parent_window):# open datamine dialog with no file brings up a search tabself._run_dialog('datamine',noargs=True)def_annotate(self,parent_window):# open datamine dialog with files brings up the annotate# tabs for each fileself._run_dialog('datamine')def_run_dialog(self,hgcmd,noargs=False,verbose=True,modal=False):ifself._folder:cwd=self._folderelifself._filenames:f=self._filenames[0]cwd=os.path.isdir(f)andforos.path.dirname(f)else:win32ui.MessageBox("Can't get cwd!",'Hg ERROR',win32con.MB_OK|win32con.MB_ICONERROR)returntargets=self._filenamesor[self._folder]root=find_root(targets[0])filelist=[]ifnoargs==False:filelist=targetscmdopts="%s"%(verboseand"--verbose"or"")open_dialog(hgcmd,cmdopts,cwd=cwd,root=root,filelist=filelist)def_help(self,parent_window):open_dialog('help','--verbose')def_about(self,parent_window):open_dialog('about')
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.