def run(ui, *pats, **opts): fname, target = '', '' cwd = os.getcwd() root = paths.find_root(cwd) try: fname = util.canonpath(root, cwd, pats[0]) target = util.canonpath(root, cwd, pats[1]) except util.Abort, e: return gdialog.Prompt(_('Invalid path'), str(e), None)
def graphlog(ui, repo, path=None, **opts): """show revision history alongside an ASCII revision graph Print a revision history alongside a revision graph drawn with ASCII characters. Nodes printed as an @ character are parents of the working directory. """ check_unsupported_flags(opts) limit = cmdutil.loglimit(opts) start, stop = get_revs(repo, opts["rev"]) if start == nullrev: return if path: path = util.canonpath(repo.root, os.getcwd(), path) if path: # could be reset in canonpath revdag = graphmod.filerevs(repo, path, start, stop, limit) else: if limit is not None: stop = max(stop, start - limit + 1) revdag = graphmod.revisions(repo, start, stop) displayer = show_changeset(ui, repo, opts, buffered=True) showparents = [ctx.node() for ctx in repo[None].parents()] generate(ui, revdag, displayer, showparents, asciiedges)
def parsedefinitions(ui, repo, svnroot, exts): """Return (targetdir, revision, source) tuples. Fail if nested targetdirs are detected. source is an svn project URL. """ defs = [] for base in sorted(exts): for line in exts[base]: if not line.strip() or line.lstrip().startswith('#'): # Ignore comments and blank lines continue try: path, rev, source, pegrev, norevline = parsedefinition(line) except BadDefinition: ui.warn(_('ignoring invalid external definition: %r\n' % line)) continue source = resolvesource(ui, svnroot, source) if source is None: continue wpath = hgutil.pconvert(os.path.join(base, path)) wpath = hgutil.canonpath(repo.root, '', wpath) defs.append((wpath, rev, source, pegrev, norevline, base)) # Check target dirs are not nested defs.sort() for i, d in enumerate(defs): for d2 in defs[i+1:]: if d2[0].startswith(d[0] + '/'): raise hgutil.Abort(_('external directories cannot nest:\n%s\n%s') % (d[0], d2[0])) return defs
def parsedefinitions(ui, repo, svnroot, exts): """Return (targetdir, revision, source) tuples. Fail if nested targetdirs are detected. source is an svn project URL. """ defs = [] for base in sorted(exts): for line in exts[base]: try: path, rev, source, pegrev = parsedefinition(line) except BadDefinition: ui.warn(_('ignoring invalid external definition: %r' % line)) continue if re_scheme.search(source): pass elif source.startswith('^/'): source = svnroot + source[1:] else: ui.warn(_('ignoring unsupported non-fully qualified external: %r' % source)) continue wpath = hgutil.pconvert(os.path.join(base, path)) wpath = hgutil.canonpath(repo.root, '', wpath) defs.append((wpath, rev, source, pegrev)) # Check target dirs are not nested defs.sort() for i, d in enumerate(defs): for d2 in defs[i+1:]: if d2[0].startswith(d[0] + '/'): raise hgutil.Abort(_('external directories cannot nest:\n%s\n%s') % (d[0], d2[0])) return defs
def graphlog(ui, repo, path=None, **opts): """show revision history alongside an ASCII revision graph Print a revision history alongside a revision graph drawn with ASCII characters. Nodes printed as an @ character are parents of the working directory. """ check_unsupported_flags(opts) limit = cmdutil.loglimit(opts) start, stop = get_revs(repo, opts["rev"]) stop = max(stop, start - limit + 1) if start == nullrev: return if path: path = util.canonpath(repo.root, os.getcwd(), path) if path: # could be reset in canonpath revdag = graphmod.filerevs(repo, path, start, stop) else: revdag = graphmod.revisions(repo, start, stop) fmtdag = asciiformat(ui, repo, revdag, opts) ascii(ui, asciiedges(fmtdag))
def parsedefinitions(ui, repo, svnroot, exts): """Return (targetdir, revision, source) tuples. Fail if nested targetdirs are detected. source is an svn project URL. """ defs = [] for base in sorted(exts): for line in exts[base]: try: path, rev, source, pegrev, norevline = parsedefinition(line) except BadDefinition: ui.warn(_('ignoring invalid external definition: %r\n' % line)) continue source = resolvesource(ui, svnroot, source) if source is None: continue wpath = hgutil.pconvert(os.path.join(base, path)) wpath = hgutil.canonpath(repo.root, '', wpath) defs.append((wpath, rev, source, pegrev, norevline, base)) # Check target dirs are not nested defs.sort() for i, d in enumerate(defs): for d2 in defs[i + 1:]: if d2[0].startswith(d[0] + '/'): raise hgutil.Abort( _('external directories cannot nest:\n%s\n%s') % (d[0], d2[0])) return defs
def run(root='', cwd='', files=[], **opts): u = ui.ui() u.updateopts(debug=False, traceback=False) repo = hg.repository(u, path=root) 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':[] } dialog = DataMineDialog(u, repo, cwd, files, cmdoptions, True) dialog.display() for f in files: if os.path.isfile(f): cf = util.canonpath(root, cwd, f) dialog.add_annotate_page(cf, '.') elif os.path.isdir(f): Prompt('Invalid path', "Can't annotate directory: %s" % f, dialog).run() if not dialog.notebook.get_n_pages(): dialog.add_search_page() gtk.gdk.threads_init() gtk.gdk.threads_enter() gtk.main() gtk.gdk.threads_leave()
def haskwsource(dest): '''Returns true if dest is a regular file and configured for expansion or a symlink which points to a file configured for expansion. ''' source = repo.dirstate.copied(dest) if 'l' in wctx.flags(source): source = util.canonpath(repo.root, cwd, os.path.realpath(source)) return kwt.match(source)
def setPath(self, path): spath = hglib.fromunicode(path) reporoot = cmdutil.findrepo(os.path.abspath(spath)) if not reporoot: QMessageBox.warning(self, 'Repository Not Found', 'Repository not found for path: %s' % path) repo = hg.repository(ui.ui(), reporoot) canonpath = util.canonpath(repo.root, os.getcwd(), spath) self._plot.plot(repo, canonpath)
def prepare_display(self): root = self.repo.root cf = [] for f in self.pats: try: if os.path.isfile(f): cf.append(util.canonpath(root, self.cwd, f)) elif os.path.isdir(f): for fn in os.listdir(f): fname = os.path.join(f, fn) if not os.path.isfile(fname): continue cf.append(util.canonpath(root, self.cwd, fname)) except util.Abort: pass for f in cf: self.add_annotate_page(f, '.') if not self.notebook.get_n_pages(): self.add_search_page() os.chdir(root)
def _save_file_rev(self, menuitem): file = util.localpath(self.curfile) file, ext = os.path.splitext(os.path.basename(file)) filename = "%s@%d%s" % (file, self.currev, ext) fd = NativeSaveFileDialogWrapper(Title = "Save file to", InitialDir=self.cwd, FileName=filename) result = fd.run() if result: import Queue import hglib q = Queue.Queue() cpath = util.canonpath(self.repo.root, self.cwd, self.curfile) hglib.hgcmd_toq(self.repo.root, q, 'cat', '--rev', str(self.currev), '--output', result, cpath)
def rename_resp(dlg, response): if response != gtk.RESPONSE_OK: dlg.destroy() return try: root = paths.find_root() repo = hg.repository(ui.ui(), root) except (ImportError, error.RepoError): dlg.destroy() return new_name = hglib.fromutf(dlg.entry.get_text()) opts = {} opts['force'] = False # Checkbox? Nah. opts['after'] = True opts['dry_run'] = False saved = sys.stderr errors = cStringIO.StringIO() toquit = False try: sys.stderr = errors repo.ui.pushbuffer() repo.ui.quiet = True try: new_name = util.canonpath(root, root, new_name) targetdir = os.path.dirname(new_name) or '.' if dlg.orig.lower() == new_name.lower() and os.path.isdir(dlg.orig): os.rename(dlg.orig, new_name) else: if not os.path.isdir(targetdir): os.makedirs(targetdir) shutil.move(dlg.orig, new_name) commands.rename(repo.ui, repo, dlg.orig, new_name, **opts) toquit = True except (OSError, IOError, util.Abort, error.RepoError), inst: dialog.error_dialog(None, _('rename error'), str(inst)) toquit = False finally: sys.stderr = saved textout = errors.getvalue() + repo.ui.popbuffer() errors.close() if len(textout) > 1: dialog.error_dialog(None, _('rename error'), textout) elif toquit: dlg.destroy()
def mpatch(ui, rejfile, *pats, **opts): """Attempt to resolve conflicts in a .rej file""" def abort(err): from tortoisehg.hgtk import gdialog gdialog.Prompt(_('mpatch error'), err, None).run() return None if not rejfile or pats or not rejfile.endswith('.rej'): return abort(_('mpatch expects *.rej file argument\n')) if not os.path.exists(rejfile): return abort(_('%s does not exist\n') % rejfile) # Assume patch was made from repo root, and arrange ourselves thusly repo = hg.repository(ui, path=paths.find_root()) rejfile = util.canonpath(repo.root, repo.getcwd(), rejfile) os.chdir(repo.root) source = rejfile[:-4] if not os.path.exists(source): return abort(_('%s does not exist\n') % source) from tortoisehg.util import prej from tortoisehg.hgtk import visdiff prej.run(ui, rejfile, source, visdiff.filemerge)
def makestandin(relpath): return os.path.join(os.path.relpath('.', repo.getcwd()), bfutil.standin(util.canonpath(repo.root, repo.getcwd(), relpath)))
def cleanpath(self, path): path = path.lstrip('/') return util.canonpath(self.repo.root, '', path)
def add_search_page(self): frame = gtk.Frame() frame.set_border_width(10) vbox = gtk.VBox() search_hbox = gtk.HBox() regexp = gtk.Entry() includes = gtk.Entry() if self.cwd.startswith(self.repo.root): try: relpath = util.canonpath(self.repo.root, self.cwd, '.') includes.set_text(relpath) except util.Abort: # Some paths inside root are invalid (.hg/*) pass excludes = gtk.Entry() search = gtk.Button(_('Search')) search_hbox.pack_start(gtk.Label(_('Regexp:')), False, False, 4) search_hbox.pack_start(regexp, True, True, 4) search_hbox.pack_start(gtk.Label(_('Includes:')), False, False, 4) search_hbox.pack_start(includes, True, True, 4) search_hbox.pack_start(gtk.Label(_('Excludes:')), False, False, 4) search_hbox.pack_start(excludes, True, True, 4) search_hbox.pack_start(search, False, False, 4) self.tooltips.set_tip(search, _('Start this search')) self.tooltips.set_tip(regexp, _('Regular expression search pattern')) self.tooltips.set_tip(includes, _('Comma separated list of ' 'inclusion patterns. By default, the entire repository ' 'is searched.')) self.tooltips.set_tip(excludes, _('Comma separated list of ' 'exclusion patterns. Exclusion patterns are applied ' 'after inclusion patterns.')) vbox.pack_start(search_hbox, False, False, 4) hbox = gtk.HBox() follow = gtk.CheckButton(_('Follow copies and renames')) ignorecase = gtk.CheckButton(_('Ignore case')) linenum = gtk.CheckButton(_('Show line numbers')) showall = gtk.CheckButton(_('Show all matching revisions')) hbox.pack_start(follow, False, False, 4) hbox.pack_start(ignorecase, False, False, 4) hbox.pack_start(linenum, False, False, 4) hbox.pack_start(showall, False, False, 4) vbox.pack_start(hbox, False, False, 4) treeview = gtk.TreeView() treeview.get_selection().set_mode(gtk.SELECTION_SINGLE) treeview.set_rules_hint(True) treeview.set_property('fixed-height-mode', True) treeview.connect("cursor-changed", self.grep_selection_changed) treeview.connect('button-release-event', self.grep_button_release) treeview.connect('popup-menu', self.grep_popup_menu) treeview.connect('row-activated', self.grep_row_act) accelgroup = gtk.AccelGroup() self.add_accel_group(accelgroup) mod = gtklib.get_thg_modifier() key, modifier = gtk.accelerator_parse(mod+'d') treeview.add_accelerator('thg-diff', accelgroup, key, modifier, gtk.ACCEL_VISIBLE) treeview.connect('thg-diff', self.grep_thgdiff) results = gtk.ListStore(str, # revision id str, # matched line (utf-8) str, # description (utf-8, escaped) str) # file path (utf-8) treeview.set_model(results) treeview.set_search_equal_func(self.search_in_grep) for title, width, ttype, col, emode in ( (_('Rev'), 10, 'text', GCOL_REVID, pango.ELLIPSIZE_NONE), (_('File'), 25, 'text', GCOL_PATH, pango.ELLIPSIZE_START), (_('Matches'), 80, 'markup', GCOL_LINE, pango.ELLIPSIZE_END)): cell = gtk.CellRendererText() cell.set_property('width-chars', width) cell.set_property('ellipsize', emode) cell.set_property('family', 'Monospace') column = gtk.TreeViewColumn(title) column.set_resizable(True) column.set_sizing(gtk.TREE_VIEW_COLUMN_FIXED) column.set_fixed_width(cell.get_size(treeview)[2]) column.pack_start(cell, expand=True) column.add_attribute(cell, ttype, col) treeview.append_column(column) if hasattr(treeview, 'set_tooltip_column'): treeview.set_tooltip_column(GCOL_DESC) scroller = gtk.ScrolledWindow() scroller.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) scroller.add(treeview) vbox.pack_start(scroller, True, True) frame.add(vbox) frame.show_all() hbox = gtk.HBox() lbl = gtk.Label(_('Search %d') % self.newpagecount) close = self.create_tab_close_button() close.connect('clicked', self.close_page, frame) hbox.pack_start(lbl, True, True, 2) hbox.pack_start(close, False, False) hbox.show_all() num = self.notebook.append_page(frame, hbox) self.newpagecount += 1 objs = (treeview.get_model(), frame, regexp, follow, ignorecase, excludes, includes, linenum, showall, search_hbox) # Clicking 'search' or hitting Enter in any text entry triggers search search.connect('clicked', self.trigger_search, objs) regexp.connect('activate', self.trigger_search, objs) includes.connect('activate', self.trigger_search, objs) excludes.connect('activate', self.trigger_search, objs) # Includes/excludes must disable following copies objs = (includes, excludes, follow) includes.connect('changed', self.update_following_possible, objs) excludes.connect('changed', self.update_following_possible, objs) self.update_following_possible(includes, objs) if hasattr(self.notebook, 'set_tab_reorderable'): self.notebook.set_tab_reorderable(frame, True) self.notebook.set_current_page(num) regexp.grab_focus()
def f(path): cpath = util.canonpath(repo.root, repo.getcwd(), path) return ignfunc(cpath)
sys.stderr.write(_('can not read file "%s". Ignored.\n') % filename) return [] # Convert absolute file paths to repo/cwd canonical cwd = os.getcwd() root = paths.find_root(cwd) if not root: return lines if cwd == root: cwd_rel = '' else: cwd_rel = cwd[len(root+os.sep):] + os.sep files = [] for f in lines: try: cpath = util.canonpath(root, cwd, f) # canonpath will abort on .hg/ paths except util.Abort: continue if cpath.startswith(cwd_rel): cpath = cpath[len(cwd_rel):] files.append(cpath) else: files.append(f) return files def _parse(ui, args): options = {} cmdoptions = {} try:
def cleanpath(repo, path): path = path.lstrip("/") return util.canonpath(repo.root, "", path)
def add_search_page(self): frame = gtk.Frame() frame.set_border_width(10) vbox = gtk.VBox() search_hbox = gtk.HBox() regexp = gtk.Entry() includes = gtk.Entry() if self.cwd.startswith(self.repo.root): includes.set_text(util.canonpath(self.repo.root, self.cwd, '.')) excludes = gtk.Entry() search = gtk.Button('Search') search_hbox.pack_start(gtk.Label('Regexp:'), False, False, 4) search_hbox.pack_start(regexp, True, True, 4) search_hbox.pack_start(gtk.Label('Includes:'), False, False, 4) search_hbox.pack_start(includes, True, True, 4) search_hbox.pack_start(gtk.Label('Excludes:'), False, False, 4) search_hbox.pack_start(excludes, True, True, 4) search_hbox.pack_start(search, False, False) self.tooltips.set_tip(search, 'Start this search') self.tooltips.set_tip(regexp, 'Regular expression search pattern') self.tooltips.set_tip(includes, 'Comma separated list of' ' inclusion patterns. By default, the entire repository' ' is searched.') self.tooltips.set_tip(excludes, 'Comma separated list of' ' exclusion patterns. Exclusion patterns are applied' ' after inclusion patterns.') vbox.pack_start(search_hbox, False, False, 4) hbox = gtk.HBox() follow = gtk.CheckButton('Follow copies and renames') ignorecase = gtk.CheckButton('Ignore case') linenum = gtk.CheckButton('Show line numbers') showall = gtk.CheckButton('Show all matching revisions') hbox.pack_start(follow, False, False, 4) hbox.pack_start(ignorecase, False, False, 4) hbox.pack_start(linenum, False, False, 4) hbox.pack_start(showall, False, False, 4) vbox.pack_start(hbox, False, False, 4) treeview = gtk.TreeView() treeview.get_selection().set_mode(gtk.SELECTION_SINGLE) treeview.set_property('fixed-height-mode', True) treeview.connect("cursor-changed", self._grep_selection_changed) treeview.connect('button-release-event', self._grep_button_release) treeview.connect('popup-menu', self._grep_popup_menu) treeview.connect('row-activated', self._grep_row_act) results = gtk.ListStore(str, str, str, str) treeview.set_model(results) for title, width, col, emode in ( ('Rev', 10, self.COL_REVID, pango.ELLIPSIZE_NONE), ('File', 25, self.COL_PATH, pango.ELLIPSIZE_START), ('Matches', 80, self.COL_TEXT, pango.ELLIPSIZE_END)): cell = gtk.CellRendererText() cell.set_property("width-chars", width) cell.set_property("ellipsize", emode) cell.set_property("family", "Monospace") column = gtk.TreeViewColumn(title) column.set_resizable(True) column.set_sizing(gtk.TREE_VIEW_COLUMN_FIXED) column.set_fixed_width(cell.get_size(treeview)[2]) column.pack_start(cell, expand=True) column.add_attribute(cell, "text", col) treeview.append_column(column) if hasattr(treeview, 'set_tooltip_column'): treeview.set_tooltip_column(self.COL_TOOLTIP) scroller = gtk.ScrolledWindow() scroller.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) scroller.add(treeview) vbox.pack_start(scroller, True, True) frame.add(vbox) frame.show_all() hbox = gtk.HBox() lbl = gtk.Label('Search %d' % self.newpagecount) close = self.create_tab_close_button() close.connect('clicked', self.close_page, frame) hbox.pack_start(lbl, True, True, 2) hbox.pack_start(close, False, False) hbox.show_all() num = self.notebook.append_page(frame, hbox) self.newpagecount += 1 objs = (treeview.get_model(), frame, regexp, follow, ignorecase, excludes, includes, linenum, showall, search_hbox) # Clicking 'search' or hitting Enter in any text entry triggers search search.connect('clicked', self.trigger_search, objs) regexp.connect('activate', self.trigger_search, objs) includes.connect('activate', self.trigger_search, objs) excludes.connect('activate', self.trigger_search, objs) if hasattr(self.notebook, 'set_tab_reorderable'): self.notebook.set_tab_reorderable(frame, True) self.notebook.set_current_page(num) regexp.grab_focus()
def cleanpath(repo, path): path = path.lstrip('/') return util.canonpath(repo.root, '', path)
def graphlog(ui, repo, path=None, **opts): """show revision history alongside an ASCII revision graph Print a revision history alongside a revision graph drawn with ASCII characters. Nodes printed as an @ character are parents of the working directory. """ limit = get_limit(opts["limit"]) (start_rev, stop_rev) = get_revs(repo, opts["rev"]) stop_rev = max(stop_rev, start_rev - limit + 1) if start_rev == nullrev: return cs_printer = show_changeset(ui, repo, opts) if path: cpath = canonpath(repo.root, os.getcwd(), path) grapher = filelog_grapher(repo, cpath, start_rev, stop_rev) else: grapher = revision_grapher(repo, start_rev, stop_rev) repo_parents = repo.dirstate.parents() prev_n_columns_diff = 0 prev_node_index = 0 for (rev, node, node_index, edges, n_columns, n_columns_diff) in grapher: # log_strings is the list of all log strings to draw alongside # the graph. ui.pushbuffer() cs_printer.show(rev, node) log_strings = ui.popbuffer().split("\n")[:-1] if n_columns_diff == -1: # Transform # # | | | | | | # o | | into o---+ # |X / |/ / # | | | | fix_long_right_edges(edges) # add_padding_line says whether to rewrite # # | | | | | | | | # | o---+ into | o---+ # | / / | | | # <--- padding line # o | | | / / # o | | add_padding_line = (len(log_strings) > 2 and n_columns_diff == -1 and [x for (x, y) in edges if x + 1 < y]) # fix_nodeline_tail says whether to rewrite # # | | o | | | | o | | # | | |/ / | | |/ / # | o | | into | o / / # <--- fixed nodeline tail # | |/ / | |/ / # o | | o | | fix_nodeline_tail = len(log_strings) <= 2 and not add_padding_line # nodeline is the line containing the node character (@ or o). nodeline = ["|", " "] * node_index if node in repo_parents: node_ch = "@" else: node_ch = "o" nodeline.extend([node_ch, " "]) nodeline.extend( get_nodeline_edges_tail( node_index, prev_node_index, n_columns, n_columns_diff, prev_n_columns_diff, fix_nodeline_tail)) # shift_interline is the line containing the non-vertical # edges between this entry and the next. shift_interline = ["|", " "] * node_index if n_columns_diff == -1: n_spaces = 1 edge_ch = "/" elif n_columns_diff == 0: n_spaces = 2 edge_ch = "|" else: n_spaces = 3 edge_ch = "\\" shift_interline.extend(n_spaces * [" "]) shift_interline.extend([edge_ch, " "] * (n_columns - node_index - 1)) # Draw edges from the current node to its parents. draw_edges(edges, nodeline, shift_interline) # lines is the list of all graph lines to print. lines = [nodeline] if add_padding_line: lines.append(get_padding_line(node_index, n_columns, edges)) lines.append(shift_interline) # Make sure that there are as many graph lines as there are # log strings. while len(log_strings) < len(lines): log_strings.append("") if len(lines) < len(log_strings): extra_interline = ["|", " "] * (n_columns + n_columns_diff) while len(lines) < len(log_strings): lines.append(extra_interline) # Print lines. indentation_level = max(n_columns, n_columns + n_columns_diff) for (line, logstr) in zip(lines, log_strings): ui.write(format_line(line, indentation_level, logstr)) # ...and start over. prev_node_index = node_index prev_n_columns_diff = n_columns_diff