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.
# history.py - Changelog dialog for TortoiseHg## Copyright 2007 Brad Schick, brad at gmail . com# Copyright 2008 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.importosimportgtkimportgobjectimportpangoimportStringIOfrommercurialimportui,hg,cmdutil,commands,extensions,utilfromthgutil.i18nimport_fromthgutilimporthglib,pathsfromhggtk.logviewimporttreemodelfromhggtk.logview.treeviewimportTreeViewasLogTreeViewfromhggtkimportgdialog,gtklib,hgcmd,datamine,logfilter,gorevfromhggtkimportbackout,status,hgemail,tagadd,update,merge,archivefromhggtkimportchangesetdefcreate_menu(label,callback):menuitem=gtk.MenuItem(label,True)menuitem.connect('activate',callback)menuitem.set_border_width(1)returnmenuitemclassGLog(gdialog.GDialog):'GTK+ based dialog for displaying repository logs'definit(self):self.last_rev=Noneself.filter='all'self.currow=None self.curfile = None
self.origtip = len(self.repo)
self.ready = False
+ self.filterbox = None os.chdir(self.repo.root)
def get_title(self):
returnhglib.toutf(os.path.basename(self.repo.root))+' log'defget_icon(self):return'menulog.ico'defparse_opts(self):# Disable quiet to get full log infoself.ui.quiet=Falsedefget_tbbuttons(self):tbar=[self.make_toolbutton(gtk.STOCK_FIND,_('_DataMine'),self.datamine_clicked,tip=_('Search Repository History')),gtk.SeparatorToolItem(),self.make_toolbutton(gtk.STOCK_JUMP_TO,_('Select Revision'),self.goto_clicked,tip=_('Select revision')),gtk.SeparatorToolItem(),self.make_toolbutton(gtk.STOCK_REFRESH,_('Re_fresh'),self.refresh_clicked,tip=_('Reload revision history')),gtk.SeparatorToolItem(),]+self.changeview.get_tbbuttons()ifnotself.opts.get('from-synch'):self.synctb=self.make_toolbutton(gtk.STOCK_NETWORK,_('Synchronize'),self.synch_clicked,tip=_('Launch synchronize tool'))tbar+=[gtk.SeparatorToolItem(),self.synctb]sep=gtk.SeparatorToolItem()sep.set_expand(True)sep.set_draw(False)self.nextbutton=self.make_toolbutton(gtk.STOCK_GO_DOWN,_('Load more'),self.more_clicked,tip=_('load more revisions'))self.allbutton=self.make_toolbutton(gtk.STOCK_GOTO_BOTTOM,_('Load all'),self.load_all_clicked,menu=self.view_menu(),tip=_('load all revisions'))tbar+=[sep,self.nextbutton,self.allbutton]returntbardefsynch_clicked(self,toolbutton,data):defsync_closed(dialog):self.synctb.set_sensitive(True)defsynch_callback(parents):self.repo.invalidate()newparents=[x.node()forxinself.repo.parents()]iflen(self.repo)!=self.origtip:ifself.newbutton.get_active():self.reload_log()else:self.newbutton.set_active(True)elifnotparents==newparents:self.refresh_model()fromhggtkimportsynchparents=[x.node()forxinself.repo.parents()]dlg=synch.SynchDialog([],False,True)dlg.set_notify_func(synch_callback,parents)dlg.connect('destroy',sync_closed)dlg.show_all()self.synctb.set_sensitive(False)deftoggle_view_column(self,button,property):active=button.get_active()self.graphview.set_property(property,active) if property in ('branch-color') and self.ready:
self.reload_log()
+ def toggle_show_filterbar(self, button, property):+ self.show_filterbar = button.get_active()+ if self.filterbox is not None:+ self.filterbox.set_property('visible', self.show_filterbar)+ def more_clicked(self, button, data=None):
self.graphview.next_revision_batch(self.limit)
defload_all_clicked(self,button,data=None):self.graphview.load_all_revisions()self.nextbutton.set_sensitive(False)self.allbutton.set_sensitive(False)defrevisions_loaded(self,graphview):'Treeview reports log generator has exited'ifnotself.graphview.graphdata:self.changeview._buffer.set_text('')self.changeview._filelist.clear()self.last_rev=Noneself.nextbutton.set_sensitive(False)self.allbutton.set_sensitive(False)defdatamine_clicked(self,toolbutton,data=None):dlg=datamine.DataMineDialog(self.ui,self.repo,self.cwd,[],{})dlg.display()deffilter_help_pressed(self,button,combo):mode=combo.get_active()ifmode==0:# Rev Rangepasselifmode==1:# File Patternspasselifmode==2:# Keywordspasselifmode==3:# Datepassdeffilter_entry_activated(self,entry,combo):'User pressed enter in the filter entry'opts={}mode=combo.get_active()text=entry.get_text()ifmode==0:# Rev Rangetry:opts['revs']=cmdutil.revrange(self.repo,[text])exceptException,e:gdialog.Prompt(_('Invalid revision range'),str(e),self).run()returnelifmode==1:# File Patternsopts['pats']=[w.strip()forwintext.split(',')]elifmode==2:# Keywordsopts['keyword']=[w.strip()forwintext.split(',')]elifmode==3:# Datetry:# return of matchdate not used, just sanity checkingutil.matchdate(text)opts['date']=textexcept(ValueError,util.Abort),e:gdialog.Prompt(_('Invalid date specification'),str(e),self).run()returnelse:returnself.custombutton.set_active(True)self.filter='custom'self.reload_log(**opts)deffilter_selected(self,widget,type):ifnotwidget.get_active():returniftype=='branch':self.select_branch(self.branchcombo)else:self.filter=typeself.reload_log()defview_menu(self):menu=gtk.Menu()button=gtk.CheckMenuItem(_('Show Rev'))button.connect('toggled',self.toggle_view_column,'rev-column-visible')button.set_active(self.showcol.get('rev',True))button.set_draw_as_radio(True)menu.append(button)button=gtk.CheckMenuItem(_('Show ID'))button.connect('toggled',self.toggle_view_column,'id-column-visible')button.set_active(self.showcol.get('id',False))button.set_draw_as_radio(True)menu.append(button)button=gtk.CheckMenuItem(_('Show Local Date'))button.connect('toggled',self.toggle_view_column,'date-column-visible')button.set_active(self.showcol.get('date',True))button.set_draw_as_radio(True)menu.append(button)button=gtk.CheckMenuItem(_('Show UTC Date'))button.connect('toggled',self.toggle_view_column,'utc-column-visible')button.set_active(self.showcol.get('utc',False))button.set_draw_as_radio(True)menu.append(button)button=gtk.CheckMenuItem(_('Show Branch'))button.connect('toggled',self.toggle_view_column,'branch-column-visible')button.set_active(self.showcol.get('branch',False))button.set_draw_as_radio(True)menu.append(button)button=gtk.CheckMenuItem(_('Color by Branch'))button.connect('toggled',self.toggle_view_column,'branch-color') button.set_active(self.branch_color)
button.set_draw_as_radio(True)
menu.append(button)
+ button = gtk.CheckMenuItem(_('Show Filterbar'))+ button.connect('toggled', self.toggle_show_filterbar,+ 'show-filterbar')+ button.set_active(self.show_filterbar)+ button.set_draw_as_radio(True)+ menu.append(button)+ menu.show_all()
return menu
defprepare_display(self):'Called at end of display() method'self.ready=Trueroot=self.repo.rootos.chdir(root)# for paths relative to repo rootifself.opts.get('orig-tip')isnotNone:origtip=self.opts['orig-tip']iforigtip!=len(self.repo):self.origtip=origtipself.graphview.set_property('original-tip-revision',self.origtip)# ignore file patterns that imply repo rootiflen(self.pats)==1andself.pats[0]in(root,root+os.sep,''):self.pats=[]opts=self.optsifopts['filehist']:self.custombutton.set_active(True)self.filter='custom'self.filtercombo.set_active(1)self.filterentry.set_text(opts['filehist'])opts['pats']=[opts['filehist']]elifself.pats:self.custombutton.set_active(True)self.filter='custom'self.filtercombo.set_active(1)self.filterentry.set_text(', '.join(self.pats)) opts['pats'] = self.pats
self.reload_log(**opts)
+ self.filterbox.set_property('visible', self.show_filterbar)+ self.filterbox.set_no_show_all(True)+ def get_graphlimit(self, suggestion):
limit_opt = self.repo.ui.config('tortoisehg', 'graphlimit', '500')
l = 0
forlimitin(suggestion,limit_opt):try:l=int(limit)ifl>0:returnlexcept(TypeError,ValueError):passreturnlor500defsave_settings(self):settings=gdialog.GDialog.save_settings(self) settings['glog-vpane'] = self.vpaned.get_position()
settings['glog-hpane'] = self.hpaned.get_position()
settings['branch-color'] = self.graphview.get_property('branch-color')
+ settings['show-filterbar'] = self.show_filterbar for col in ('rev', 'date', 'id', 'branch', 'utc'):
vis = self.graphview.get_property(col+'-column-visible')
settings['glog-vis-'+col] = vis
returnsettingsdefload_settings(self,settings):'Called at beginning of display() method'# This stuff is here in load_settings in order to have access to# self.changeview when building the toolbar. TODO: clean this upself.stbar=gtklib.StatusBar()self.limit=self.get_graphlimit(None)# Allocate TreeView instance to use internallyifself.opts['limit']:firstlimit=self.get_graphlimit(self.opts['limit'])self.graphview=LogTreeView(self.repo,firstlimit,self.stbar)else:self.graphview=LogTreeView(self.repo,self.limit,self.stbar)# Allocate ChangeSet instance to use internallyself.changeview=changeset.ChangeSet(self.ui,self.repo,self.cwd,[],self.opts,self.stbar)self.changeview.display(False)self.changeview.glog_parent=selfgdialog.GDialog.load_settings(self,settings) self.setting_vpos = -1
self.setting_hpos = -1
self.branch_color = False
+ self.show_filterbar = True self.showcol = {}
try:
self.setting_vpos = settings['glog-vpane']
self.setting_hpos = settings['glog-hpane']
self.branch_color = settings.get('branch-color', False)
+ self.show_filterbar = settings.get('show-filterbar', True) for col in ('rev', 'date', 'id', 'branch', 'utc'):
vis = settings['glog-vis-'+col]
self.showcol[col] = vis
exceptKeyError:passdefrefresh_model(self):'Refresh data in the history model, without reloading graph'ifself.graphview.model:self.graphview.model.refresh()defreload_log(self,**kwopts):'Send refresh event to treeview object'opts={'date':None,'no_merges':False,'only_merges':False,'keyword':[],'branch':None,'pats':[],'filehist':None,'revrange':[],'rev':[],'noheads':False}opts.update(kwopts)self.nextbutton.set_sensitive(True)self.allbutton.set_sensitive(True)self.newbutton.set_sensitive(self.origtip!=len(self.repo))ifself.filter=='branch':branch=opts.get('branch',None)self.graphview.refresh(True,branch,opts)self.set_title(_('%s branch %s')%(self.get_title(),branch))elifself.filter=='custom':self.set_title(self.get_title()+_(' custom filter'))pats=opts.get('pats',[])iflen(pats)==1andnotos.path.isdir(pats[0]):opts['filehist']=pats[0]self.graphview.refresh(True,pats,opts)else:self.graphview.refresh(False,pats,opts)elifself.filter=='all':self.set_title(self.get_title())self.graphview.refresh(True,None,opts)elifself.filter=='new':self.set_title(self.get_title()+_(' new revisions'))assertlen(self.repo)>self.origtipopts['revrange']=[len(self.repo)-1,self.origtip]self.graphview.refresh(True,None,opts)elifself.filter=='only_merges':self.set_title(self.get_title()+_(' only merges'))opts['only_merges']=Trueself.graphview.refresh(False,[],opts)elifself.filter=='ancestry':ifnotself.currow:returnself.set_title(self.get_title()+_(' revision ancestry'))range=[self.currow[treemodel.REVID],0]opts={'noheads':True,'revrange':range}self.graphview.refresh(True,None,opts)elifself.filter=='tagged':self.set_title(self.get_title()+_(' tagged revisions'))tagged=[]fort,rinself.repo.tagslist():hr=self.repo[r].rev()ifhrnotintagged:tagged.insert(0,hr)opts['revs']=taggedself.graphview.refresh(False,[],opts)elifself.filter=='parents':self.set_title(self.get_title()+_(' working parents'))repo_parents=[x.rev()forxinself.repo.parents()]opts['revs']=[str(x)forxinrepo_parents]self.graphview.refresh(False,[],opts)elifself.filter=='heads':self.set_title(self.get_title()+_(' heads'))heads=[self.repo[x].rev()forxinself.repo.heads()]opts['revs']=[str(x)forxinheads]self.graphview.refresh(False,[],opts)deftree_context_menu(self):m=gtk.Menu()m.append(create_menu(_('visualize change'),self.vdiff_change))m.append(create_menu(_('di_splay change'),self.show_status))m.append(create_menu(_('diff to local'),self.vdiff_local))m.append(create_menu(_('_update'),self.checkout))self.cmenu_merge=create_menu(_('_merge with'),self.merge)m.append(self.cmenu_merge)m.append(create_menu(_('_copy hash'),self.copy_hash))m.append(create_menu(_('_export patch'),self.export_patch))m.append(create_menu(_('e_mail patch'),self.email_patch))m.append(create_menu(_('_bundle rev:tip'),self.bundle_rev_to_tip))m.append(create_menu(_('add/remove _tag'),self.add_tag))self.cmenu_backout=create_menu(_('backout revision'),self.backout_rev)m.append(self.cmenu_backout)m.append(create_menu(_('_revert'),self.revert))m.append(create_menu(_('_archive'),self.archive))# Load extension support for commands which need itextensions.loadall(self.ui)# need transplant extension for transplant commandextensions.load(self.ui,'transplant',None)m.append(create_menu(_('transp_lant to local'),self.transplant_rev))# need mq extension for strip commandextensions.load(self.ui,'mq',None)m.append(create_menu(_('strip revision'),self.strip_rev))m.show_all()returnmdefrestore_original_selection(self,widget,*args):self.tree.get_selection().set_mode(gtk.SELECTION_SINGLE)self.tree.get_selection().select_path(self.orig_sel)deftree_diff_context_menu(self):m=gtk.Menu()m.append(create_menu(_('_diff with selected'),self.diff_revs))m.append(create_menu(_('visual diff with selected'),self.vdiff_selected))m.append(create_menu(_('email from here to selected'),self.email_revs))m.append(create_menu(_('bundle from here to selected'),self.bundle_revs))self.cmenu_merge2=create_menu(_('_merge with'),self.merge)m.append(self.cmenu_merge2)# Load extension support for commands which need itextensions.loadall(self.ui)# need transplant extension for transplant commandextensions.load(self.ui,'transplant',None)m.append(create_menu(_('transplant revision range to local'),self.transplant_revs))# need rebase extension for rebase commandextensions.load(self.ui,'rebase',None)m.append(create_menu(_('rebase on top of selected'),self.rebase_selected))m.connect_after('selection-done',self.restore_original_selection)m.show_all()returnmdefget_body(self):self.gorev_dialog=Noneself._menu=self.tree_context_menu()self._menu2=self.tree_diff_context_menu()treeframe=gtk.Frame()treeframe.set_shadow_type(gtk.SHADOW_ETCHED_IN)# PyGtk 2.6 and below did not automatically register typesifgobject.pygtk_version<(2,8,0):gobject.type_register(LogTreeView)self.tree=self.graphview.treeviewself.graphview.connect('revision-selected',self.selection_changed)self.graphview.connect('revisions-loaded',self.revisions_loaded)self.tree.connect('button-press-event',self.tree_button_press)self.tree.connect('row-activated',self.tree_row_act)accelgroup=gtk.AccelGroup()self.add_accel_group(accelgroup)mod=gtklib.get_thg_modifier()key,modifier=gtk.accelerator_parse(mod+'d')self.tree.add_accelerator('thg-diff',accelgroup,key,modifier,gtk.ACCEL_VISIBLE)self.tree.connect('thg-diff',self.thgdiff)key,modifier=gtk.accelerator_parse(mod+'p')self.tree.add_accelerator('thg-parent',accelgroup,key,modifier,gtk.ACCEL_VISIBLE) self.tree.connect('thg-parent', self.thgparent)
self.connect('thg-refresh', self.thgrefresh)
- filterbox = gtk.HBox()+ self.filterbox = gtk.HBox()+ filterbox = self.filterbox all = gtk.RadioButton(None, _('all'))
all.set_active(True)
all.connect('toggled',self.filter_selected,'all')filterbox.pack_start(all,False)self.newbutton=gtk.RadioButton(all,_('new'))self.newbutton.connect('toggled',self.filter_selected,'new')filterbox.pack_start(self.newbutton,False)tagged=gtk.RadioButton(all,_('tagged'))tagged.connect('toggled',self.filter_selected,'tagged')filterbox.pack_start(tagged,False)ancestry=gtk.RadioButton(all,_('ancestry'))ancestry.connect('toggled',self.filter_selected,'ancestry')filterbox.pack_start(ancestry,False)parents=gtk.RadioButton(all,_('parents'))parents.connect('toggled',self.filter_selected,'parents')filterbox.pack_start(parents,False)heads=gtk.RadioButton(all,_('heads'))heads.connect('toggled',self.filter_selected,'heads')filterbox.pack_start(heads,False)merges=gtk.RadioButton(all,_('merges'))merges.connect('toggled',self.filter_selected,'only_merges')filterbox.pack_start(merges,False)branches=gtk.RadioButton(all,_('branch'))branches.connect('toggled',self.filter_selected,'branch')branches.set_sensitive(False)self.branchbutton=branchesfilterbox.pack_start(branches,False)branchcombo=gtk.combo_box_new_text()fornameinself.repo.branchtags().keys():branchcombo.append_text(name)branchcombo.connect('changed',self.select_branch)filterbox.pack_start(branchcombo,False)self.branchcombo=branchcomboself.custombutton=gtk.RadioButton(all,_('custom'))self.custombutton.set_sensitive(False)filterbox.pack_start(self.custombutton,False)filtercombo=gtk.combo_box_new_text()forfin(_('Rev Range'),_('File Patterns'),_('Keywords'),_('Date')):filtercombo.append_text(f)filtercombo.set_active(1)self.filtercombo=filtercombofilterbox.pack_start(filtercombo,False)helpbutton=gtk.Button("?")helpbutton.set_relief(gtk.RELIEF_NONE)helpbutton.connect('pressed',self.filter_help_pressed,filtercombo)filterbox.pack_start(helpbutton,False)entry=gtk.Entry()entry.connect('activate',self.filter_entry_activated,filtercombo)self.filterentry=entryfilterbox.pack_start(entry,True)vbox=gtk.VBox()vbox.pack_start(filterbox,False,False,0)vbox.pack_start(self.graphview,True,True,0)treeframe.add(vbox)treeframe.show_all()# Add ChangeSet instance to bottom half of vpaneself.changeview.graphview=self.graphviewself.hpaned=self.changeview.get_body()self.vpaned=gtk.VPaned()self.vpaned.pack1(treeframe,True,False)self.vpaned.pack2(self.hpaned)gobject.idle_add(self.realize_settings)vbox=gtk.VBox()vbox.pack_start(self.vpaned,True,True)# Append status barvbox.pack_start(gtk.HSeparator(),False,False)vbox.pack_start(self.stbar,False,False)returnvboxdefrealize_settings(self):self.vpaned.set_position(self.setting_vpos)self.hpaned.set_position(self.setting_hpos)defthgdiff(self,treeview):'ctrl-d handler'self.vdiff_change(None)defthgparent(self,treeview):'ctrl-p handler'parent=self.repo['.'].rev()self.graphview.set_revision_id(parent)defgoto_clicked(self,toolbutton,data=None):ifself.gorev_dialog:self.gorev_dialog.show()self.gorev_dialog.present()else:self.show_goto_dialog()defselect_branch(self,combo):row=combo.get_active()ifrow>=0:self.filter='branch'self.branchbutton.set_active(True)self.branchbutton.set_sensitive(True)self.reload_log(branch=combo.get_model()[row][0])else:self.branchbutton.set_sensitive(False)defshow_goto_dialog(self):'Launch a modeless goto revision dialog'defgoto_rev_(rev):self.goto_rev(rev)defresponse_(dialog,response_id):dialog.hide()defdelete_event(dialog,event,data=None):# return True to prevent the dialog from being destroyedreturnTruedlg=gorev.GotoRevDialog(goto_rev_)dlg.connect('response',response_)dlg.connect('delete-event',delete_event)dlg.set_modal(False)dlg.show()self.gorev_dialog=dlgdefgoto_rev(self,revision):rid=self.repo[revision].rev()self.graphview.set_revision_id(rid,load=True)defstrip_rev(self,menuitem):rev=self.currow[treemodel.REVID]res=gdialog.Confirm(_('Confirm Strip Revision(s)'),[],self,_('Remove revision %d and all descendants?')%rev).run()ifres!=gtk.RESPONSE_YES:returncmdline=['hg','strip',str(rev)]dlg=hgcmd.CmdDialog(cmdline)dlg.show_all()dlg.run()dlg.hide()self.repo.invalidate()self.reload_log()self.changeview._buffer.set_text('')self.changeview._filelist.clear()defbackout_rev(self,menuitem):rev=self.currow[treemodel.REVID]rev=str(self.repo[rev])parents=[x.node()forxinself.repo.parents()]dlg=backout.BackoutDialog(rev)dlg.set_transient_for(self)dlg.show_all()dlg.set_notify_func(self.checkout_completed,parents)dlg.present()dlg.set_transient_for(None)defrevert(self,menuitem):rev=self.currow[treemodel.REVID]res=gdialog.Confirm(_('Confirm Revert Revision(s)'),[],self,_('Revert all files to revision %d?\nThis will overwrite your ''local changes')%rev).run()ifres!=gtk.RESPONSE_YES:returncmdline=['hg','revert','--verbose','--all','--rev',str(rev)]dlg=hgcmd.CmdDialog(cmdline)dlg.show_all()dlg.run()dlg.hide()defvdiff_change(self,menuitem,pats=[]):rev=self.currow[treemodel.REVID]self._do_diff(pats,{'change':rev})defvdiff_local(self,menuitem,pats=[]):rev=self.currow[treemodel.REVID]opts={'rev':["%s"%rev]}self._do_diff(pats,opts)defdiff_revs(self,menuitem):rev0,rev1=self.revsstatopts=self.merge_opts(commands.table['^status|st'][1],('include','exclude','git'))statopts['rev']=['%u:%u'%(rev0,rev1)]statopts['modified']=Truestatopts['added']=Truestatopts['removed']=Truedialog=status.GStatus(self.ui,self.repo,self.cwd,self.pats,statopts)dialog.display()returnTruedefvdiff_selected(self,menuitem):strrevs=[str(r)forrinself.revs]self._do_diff(self.pats,{'rev':strrevs})defemail_revs(self,menuitem):revs=list(self.revs)revs.sort()opts=['--rev',str(revs[0])+':'+str(revs[1])]dlg=hgemail.EmailDialog(self.repo.root,opts)dlg.set_transient_for(self)dlg.show_all()dlg.present()dlg.set_transient_for(None)defbundle_revs(self,menuitem):revs=list(self.revs)revs.sort()parent=self.repo[revs[0]].parents()[0].rev()# Special case for revision 0's parent.ifparent==-1:parent='null'filename="%s_rev%d_to_rev%s.hg"%(os.path.basename(self.repo.root),revs[0],revs[1])result=gtklib.NativeSaveFileDialogWrapper(Title=_('Write bundle to'),InitialDir=self.repo.root,FileName=filename).run()ifresult:cmdline=['hg','bundle','--base',str(parent),'--rev',str(revs[1]),result]dlg=hgcmd.CmdDialog(cmdline)dlg.show_all()dlg.run()dlg.hide()defrebase_selected(self,menuitem):"""Rebase revision on top of selection (1st on top of 2nd)."""revs=list(self.revs)res=gdialog.Confirm(_('Confirm Rebase Revision'),[],self,_('Rebase revision %d on top of %d?')%(revs[0],revs[1])).run()ifres!=gtk.RESPONSE_YES:returncmdline=['hg','rebase','--source',str(revs[0]),'--dest',str(revs[1])]dialog=hgcmd.CmdDialog(cmdline)dialog.show_all()dialog.run()dialog.hide()self.repo.invalidate()self.reload_log()self.changeview._buffer.set_text('')self.changeview._filelist.clear()deftransplant_revs(self,menuitem):"""Transplant revision range on top of current revision."""revs=list(self.revs)revs.sort()cmdline=['hg','transplant','%s:%s'%(str(revs[0]),str(revs[1]))]dialog=hgcmd.CmdDialog(cmdline)dialog.show_all()dialog.run()dialog.hide()self.repo.invalidate()self.reload_log()self.changeview._buffer.set_text('')self.changeview._filelist.clear()defadd_tag(self,menuitem):# save tag info for detecting new tags addedoldtags=self.repo.tagslist()oldlen=len(self.repo)rev=self.currow[treemodel.REVID]defrefresh(*args):self.repo.invalidate()iflen(self.repo)!=oldlen:self.reload_log()else:newtags=self.repo.tagslist()ifnewtags!=oldtags:self.refresh_model()dialog=tagadd.TagAddDialog(self.repo.root,rev=str(rev))dialog.set_transient_for(self)dialog.connect('destroy',refresh)dialog.show_all()dialog.present()dialog.set_transient_for(None)defshow_status(self,menuitem):rev=self.currow[treemodel.REVID]statopts={'rev':[str(rev)]}dialog=changeset.ChangeSet(self.ui,self.repo,self.cwd,[],statopts)dialog.display()defcopy_hash(self,menuitem):rev=self.currow[treemodel.REVID]node=str(self.repo[rev])sel=(os.name=='nt')and'CLIPBOARD'or'PRIMARY'clipboard=gtk.Clipboard(selection=sel)clipboard.set_text(node)defexport_patch(self,menuitem):rev=self.currow[treemodel.REVID]filename="%s_rev%s.patch"%(os.path.basename(self.repo.root),rev)result=gtklib.NativeSaveFileDialogWrapper(Title=_('Save patch to'),InitialDir=self.repo.root,FileName=filename).run()ifresult:ifos.path.exists(result):res=gdialog.Confirm(_('Confirm Overwrite'),[],self,_('The file "%s" already exists!\n\n''Do you want to overwrite it?')%result).run()ifres!=gtk.RESPONSE_YES:returnos.remove(result)# In case new export args are added in the future, merge the# hg defaultsexportOpts=self.merge_opts(commands.table['^export'][1],())exportOpts['output']=resultdefdohgexport():commands.export(self.ui,self.repo,str(rev),**exportOpts)success,outtext=self._hg_call_wrapper("Export",dohgexport,False)defbundle_rev_to_tip(self,menuitem):try:rev=int(self.currow[treemodel.REVID])parent=self.repo[rev].parents()[0].rev()# Special case for revision 0's parent.ifparent==-1:parent='null'except(ValueError,hglib.LookupError):returnfilename="%s_rev%d_to_tip.hg"%(os.path.basename(self.repo.root),rev)result=gtklib.NativeSaveFileDialogWrapper(Title=_('Write bundle to'),InitialDir=self.repo.root,FileName=filename).run()ifresult:ifos.path.exists(result):res=gdialog.Confirm(_('Confirm Overwrite'),[],self,_('The file "%s" already exists!\n\n''Do you want to overwrite it?')%result).run()ifres!=gtk.RESPONSE_YES:returnos.remove(result)cmdline=['hg','bundle','--base',str(parent),result]dlg=hgcmd.CmdDialog(cmdline)dlg.show_all()dlg.run()dlg.hide()defemail_patch(self,menuitem):rev=self.currow[treemodel.REVID]dlg=hgemail.EmailDialog(self.repo.root,['--rev',str(rev)])dlg.set_transient_for(self)dlg.show_all()dlg.present()dlg.set_transient_for(None)defcheckout(self,menuitem):rev=self.currow[treemodel.REVID]parents=[x.node()forxinself.repo.parents()]dialog=update.UpdateDialog(rev)dialog.set_transient_for(self)dialog.show_all()dialog.set_notify_func(self.checkout_completed,parents)dialog.present()dialog.set_transient_for(None)defcheckout_completed(self,oldparents):self.repo.invalidate()self.repo.dirstate.invalidate()newparents=[x.node()forxinself.repo.parents()]ifnotoldparents==newparents:self.refresh_model()defmerge(self,menuitem):rev=self.currow[treemodel.REVID]parents=[x.node()forxinself.repo.parents()]ifrev==self.repo.parents()[0].rev():rev=self.revs[1]dialog=merge.MergeDialog(rev)dialog.set_transient_for(self)dialog.show_all()dialog.set_notify_func(self.merge_completed,parents,len(self.repo))dialog.present()dialog.set_transient_for(None)defmerge_completed(self,args):self.repo.invalidate()self.repo.dirstate.invalidate()oldparents,repolen=argsnewparents=[x.node()forxinself.repo.parents()]iflen(self.repo)!=repolen:self.reload_log()elifnotoldparents==newparents:self.refresh_model()defarchive(self,menuitem):rev=self.currow[treemodel.REVID]parents=[x.node()forxinself.repo.parents()]dialog=archive.ArchiveDialog(rev)dialog.set_transient_for(self)dialog.show_all()dialog.present()dialog.set_transient_for(None)deftransplant_rev(self,menuitem):"""Transplant selection on top of current revision."""rev=self.currow[treemodel.REVID]cmdline=['hg','transplant',str(rev)]dialog=hgcmd.CmdDialog(cmdline)dialog.show_all()dialog.run()dialog.hide()self.repo.invalidate()self.reload_log()self.changeview._buffer.set_text('')self.changeview._filelist.clear()defselection_changed(self,treeview):self.currow=self.graphview.get_revision()rev=self.currow[treemodel.REVID]ifrev!=self.last_rev:self.last_rev=revself.changeview.opts['rev']=[str(rev)]self.changeview.load_details(rev)returnFalsedefthgrefresh(self,window):self.reload_log()defrefresh_clicked(self,toolbutton,data=None):self.reload_log()returnTruedeftree_button_press(self,tree,event):ifevent.button==3andnot(event.state&(gtk.gdk.SHIFT_MASK|gtk.gdk.CONTROL_MASK)):path=tree.get_path_at_pos(int(event.x),int(event.y))ifnotpath:returnFalsecrow=path[0](model,pathlist)=tree.get_selection().get_selected_rows()ifpathlist==[]:returnFalsesrow=pathlist[0]ifsrow==crow:self.tree_popup_menu(tree,event.button,event.time)else:tree.get_selection().set_mode(gtk.SELECTION_MULTIPLE)tree.get_selection().select_path(crow)self.orig_sel=srowself.revs=(int(model[srow][treemodel.REVID]),int(model[crow][treemodel.REVID]))self.tree_popup_menu_diff(tree,event.button,event.time)returnTruereturnFalsedeftree_popup_menu(self,treeview,button=0,time=0):selrev=self.currow[treemodel.REVID]# disable/enable menus as requiredparents=[x.rev()forxinself.repo.parents()]can_merge=selrevnotinparentsandlen(parents)<2self.cmenu_merge.set_sensitive(can_merge)op1,op2=self.repo.dirstate.parents()node=self.repo[selrev].node()a=self.repo.changelog.ancestor(op1,node)self.cmenu_backout.set_sensitive(a==node)# display the context menuself._menu.popup(None,None,None,button,time)returnTruedeftree_popup_menu_diff(self,treeview,button=0,time=0):selrev=self.revs[0]# disable/enable menus as requiredparents=[x.rev()forxinself.repo.parents()]can_merge=selrevinparentsandlen(parents)<2self.cmenu_merge2.set_sensitive(can_merge)# display the context menuself._menu2.popup(None,None,None,button,time)returnTruedeftree_row_act(self,tree,path,column):'Default action is the first entry in the context menu'self._menu.get_children()[0].activate()returnTruedefrun(ui,*pats,**opts):cmdoptions={'follow':False,'follow-first':False,'copies':False,'keyword':[],'limit':0,'rev':[],'removed':False,'no_merges':False,'date':None,'only_merges':None,'prune':[],'git':False,'verbose':False,'include':[],'exclude':[],'from-synch':False,'orig-tip':None,'filehist':None,'canonpats':[]}cmdoptions.update(opts)pats=hglib.canonpaths(pats)+cmdoptions['canonpats']returnGLog(ui,None,None,pats,cmdoptions)
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.