def overview(ui, repo, source=None, **opts): '''provides a general overview of your repository state This command combines the output of the hg incomng, hg outgoing, hg status, and hg id commands into an easily human-readable explanation of the entire state of your current working repository. ''' if not repo: return originurl = ui.expandpath(source or 'default') targeturl = ui.expandpath(source or 'default-push', source or 'default') origin, hashbranch = parseurl(originurl) origin = hg.repository(remoteui(repo, opts), origin) target, hashbranch = parseurl(targeturl) target = hg.repository(remoteui(repo, opts), target) if originurl == targeturl: ui.status(_('parent repository: %s\n') % url.hidepassword(originurl)) else: ui.status(_('source repository: %s\n') % url.hidepassword(getattr(origin, 'root', origin.url()))) ui.status(_('destination repository: %s\n') % url.hidepassword(getattr(target, 'root', target.url()))) ui.pushbuffer() out = outgoing(repo, target) inc = incoming(repo, origin, filter(bool, [hashbranch])) ui.popbuffer() changed = any(repo.status()) if changed: status = _('uncommitted changes') else: status = _('working copy up-to-date') # grab heads heads = repo.branchheads(None, closed=False) if len(heads) > 1: merge = 'merge required' else: merge = '' ui.status(_('| Remote | << %s | Local | %s\n') % (str(len(out)).center(5), merge)) ui.status(_('| Repository | %s >> | Repository | %s\n') % (str(len(inc)).center(5), status)) if opts['detail']: if len(out) > 0: ui.status(_('\noutgoing changes:\n')) for rev in out: ui.status('%s %s\n' % (repo[rev], repo[rev].description().strip().split('\n')[0])) if len(inc) > 0: ui.status(_('\nincoming changes:\n')) for rev in inc: ui.status('%s %s\n' % (repo[rev], repo[rev].description().strip().split('\n')[0])) if changed: ui.status(_('\nlocal files:\n')) ui.pushbuffer() commands.status(ui, repo, '', **opts) status = ui.popbuffer() for l in status.splitlines(): print ' %s' % l
def goutgoing(ui, repo, dest=None, **opts): """show the outgoing changesets alongside an ASCII revision graph Print the outgoing changesets alongside a revision graph drawn with ASCII characters. Nodes printed as an @ character are parents of the working directory. """ check_unsupported_flags(opts) dest, revs, checkout = hg.parseurl( ui.expandpath(dest or 'default-push', dest or 'default'), opts.get('rev')) if revs: revs = [repo.lookup(rev) for rev in revs] other = hg.repository(cmdutil.remoteui(ui, opts), dest) ui.status(_('comparing with %s\n') % url.hidepassword(dest)) o = repo.findoutgoing(other, force=opts.get('force')) if not o: ui.status(_("no changes found\n")) return o = repo.changelog.nodesbetween(o, revs)[0] revdag = graphrevs(repo, o, opts) fmtdag = asciiformat(ui, repo, revdag, opts) ascii(ui, asciiedges(fmtdag))
def goutgoing(ui, repo, dest=None, **opts): """show the outgoing changesets alongside an ASCII revision graph Print the outgoing changesets alongside a revision graph drawn with ASCII characters. Nodes printed as an @ character are parents of the working directory. """ check_unsupported_flags(opts) dest = ui.expandpath(dest or 'default-push', dest or 'default') dest, branches = hg.parseurl(dest, opts.get('branch')) revs, checkout = hg.addbranchrevs(repo, repo, branches, opts.get('rev')) other = hg.repository(cmdutil.remoteui(ui, opts), dest) if revs: revs = [repo.lookup(rev) for rev in revs] ui.status(_('comparing with %s\n') % url.hidepassword(dest)) o = repo.findoutgoing(other, force=opts.get('force')) if not o: ui.status(_("no changes found\n")) return o = repo.changelog.nodesbetween(o, revs)[0] revdag = graphrevs(repo, o, opts) displayer = show_changeset(ui, repo, opts, buffered=True) showparents = [ctx.node() for ctx in repo[None].parents()] generate(ui, revdag, displayer, showparents, asciiedges)
def incoming(oldincoming, ui, repo, source="default", **opts): if opts.get('bookmarks'): source, branches = hg.parseurl(ui.expandpath(source), opts.get('branch')) other = hg.repository(hg.remoteui(repo, opts), source) ui.status(_('comparing with %s\n') % url.hidepassword(source)) return diffbookmarks(ui, repo, other) else: return oldincoming(ui, repo, source, **opts)
def outgoing(oldoutgoing, ui, repo, dest=None, **opts): if opts.get('bookmarks'): dest = ui.expandpath(dest or 'default-push', dest or 'default') dest, branches = hg.parseurl(dest, opts.get('branch')) other = hg.repository(hg.remoteui(repo, opts), dest) ui.status(_('comparing with %s\n') % url.hidepassword(dest)) return diffbookmarks(ui, other, repo) else: return oldoutgoing(ui, repo, dest, **opts)
def gincoming(ui, repo, source="default", **opts): """show the incoming changesets alongside an ASCII revision graph Print the incoming changesets alongside a revision graph drawn with ASCII characters. Nodes printed as an @ character are parents of the working directory. """ check_unsupported_flags(opts) source, branches = hg.parseurl(ui.expandpath(source), opts.get('branch')) other = hg.repository(cmdutil.remoteui(repo, opts), source) revs, checkout = hg.addbranchrevs(repo, other, branches, opts.get('rev')) ui.status(_('comparing with %s\n') % url.hidepassword(source)) if revs: revs = [other.lookup(rev) for rev in revs] incoming = repo.findincoming(other, heads=revs, force=opts["force"]) if not incoming: try: os.unlink(opts["bundle"]) except: pass ui.status(_("no changes found\n")) return cleanup = None try: fname = opts["bundle"] if fname or not other.local(): # create a bundle (uncompressed if other repo is not local) if revs is None: cg = other.changegroup(incoming, "incoming") else: cg = other.changegroupsubset(incoming, revs, 'incoming') bundletype = other.local() and "HG10BZ" or "HG10UN" fname = cleanup = changegroup.writebundle(cg, fname, bundletype) # keep written bundle? if opts["bundle"]: cleanup = None if not other.local(): # use the created uncompressed bundlerepo other = bundlerepo.bundlerepository(ui, repo.root, fname) chlist = other.changelog.nodesbetween(incoming, revs)[0] revdag = graphrevs(other, chlist, opts) displayer = show_changeset(ui, other, opts, buffered=True) showparents = [ctx.node() for ctx in repo[None].parents()] generate(ui, revdag, displayer, showparents, asciiedges) finally: if hasattr(other, 'close'): other.close() if cleanup: os.unlink(cleanup)
def getoutgoing(dest, revs): '''Return the revisions present locally but not in dest''' dest = ui.expandpath(dest or 'default-push', dest or 'default') dest, branches = hg.parseurl(dest) revs, checkout = hg.addbranchrevs(repo, repo, branches, revs) if revs: revs = [repo.lookup(rev) for rev in revs] other = hg.repository(hg.remoteui(repo, opts), dest) ui.status(_('comparing with %s\n') % url.hidepassword(dest)) o = discovery.findoutgoing(repo, other) if not o: ui.status(_("no changes found\n")) return [] o = repo.changelog.nodesbetween(o, revs)[0] return [str(repo.changelog.rev(r)) for r in o]
def conf_clicked(self, toolbutton, data=None): newpath = hglib.fromutf(self.pathtext.get_text()).strip() for alias, path in self.paths: if newpath in (path, url.hidepassword(path)): newpath = None break dlg = thgconfig.ConfigDialog(True) dlg.show_all() if newpath: dlg.new_path(newpath, 'default') else: dlg.focus_field('tortoisehg.postpull') dlg.run() dlg.hide() self.paths = self.get_paths() self.fill_path_combo() self.update_pull_setting()
def taskspush(orig, ui, repo, dest=None, **opts): ''' Task push Calls custom push command with new custom args''' # all copied from mercurial/commands.py dest, revs, checkout = hg.parseurl( ui.expandpath(dest or 'default-push', dest or 'default'), opts.get('rev')) cmdutil.setremoteconfig(ui, opts) other = hg.repository(ui, dest) ui.status(_('pushing to %s\n') % url.hidepassword(dest)) if revs: revs = [repo.lookup(rev) for rev in revs] # add in our new options r = repo.push(other, opts.get('force'), revs=revs, completed_tasks=opts.get('completed_tasks'), all_tasks=opts.get('all_tasks')) return r == 0
def fetch(ui, repo, source='default', **opts): '''pull changes from a remote repository, merge new changes if needed. This finds all changes from the repository at the specified path or URL and adds them to the local repository. If the pulled changes add a new branch head, the head is automatically merged, and the result of the merge is committed. Otherwise, the working directory is updated to include the new changes. When a merge occurs, the newly pulled changes are assumed to be "authoritative". The head of the new changes is used as the first parent, with local changes as the second. To switch the merge order, use --switch-parent. See 'hg help dates' for a list of formats valid for -d/--date. ''' date = opts.get('date') if date: opts['date'] = util.parsedate(date) parent, p2 = repo.dirstate.parents() branch = repo.dirstate.branch() branchnode = repo.branchtags().get(branch) if parent != branchnode: raise util.Abort(_('working dir not at branch tip ' '(use "hg update" to check out branch tip)')) if p2 != nullid: raise util.Abort(_('outstanding uncommitted merge')) wlock = lock = None try: wlock = repo.wlock() lock = repo.lock() mod, add, rem, del_ = repo.status()[:4] if mod or add or rem: raise util.Abort(_('outstanding uncommitted changes')) if del_: raise util.Abort(_('working directory is missing some files')) bheads = repo.branchheads(branch) bheads = [head for head in bheads if len(repo[head].children()) == 0] if len(bheads) > 1: raise util.Abort(_('multiple heads in this branch ' '(use "hg heads ." and "hg merge" to merge)')) other = hg.repository(cmdutil.remoteui(repo, opts), ui.expandpath(source)) ui.status(_('pulling from %s\n') % url.hidepassword(ui.expandpath(source))) revs = None if opts['rev']: try: revs = [other.lookup(rev) for rev in opts['rev']] except error.CapabilityError: err = _("Other repository doesn't support revision lookup, " "so a rev cannot be specified.") raise util.Abort(err) # Are there any changes at all? modheads = repo.pull(other, heads=revs) if modheads == 0: return 0 # Is this a simple fast-forward along the current branch? newheads = repo.branchheads(branch) newheads = [head for head in newheads if len(repo[head].children()) == 0] newchildren = repo.changelog.nodesbetween([parent], newheads)[2] if len(newheads) == 1: if newchildren[0] != parent: return hg.clean(repo, newchildren[0]) else: return # Are there more than one additional branch heads? newchildren = [n for n in newchildren if n != parent] newparent = parent if newchildren: newparent = newchildren[0] hg.clean(repo, newparent) newheads = [n for n in newheads if n != newparent] if len(newheads) > 1: ui.status(_('not merging with %d other new branch heads ' '(use "hg heads ." and "hg merge" to merge them)\n') % (len(newheads) - 1)) return # Otherwise, let's merge. err = False if newheads: # By default, we consider the repository we're pulling # *from* as authoritative, so we merge our changes into # theirs. if opts['switch_parent']: firstparent, secondparent = newparent, newheads[0] else: firstparent, secondparent = newheads[0], newparent ui.status(_('updating to %d:%s\n') % (repo.changelog.rev(firstparent), short(firstparent))) hg.clean(repo, firstparent) ui.status(_('merging with %d:%s\n') % (repo.changelog.rev(secondparent), short(secondparent))) err = hg.merge(repo, secondparent, remind=False) if not err: # we don't translate commit messages message = (cmdutil.logmessage(opts) or ('Automated merge with %s' % url.removeauth(other.url()))) editor = cmdutil.commiteditor if opts.get('force_editor') or opts.get('edit'): editor = cmdutil.commitforceeditor n = repo.commit(message, opts['user'], opts['date'], editor=editor) ui.status(_('new changeset %d:%s merges remote changes ' 'with local\n') % (repo.changelog.rev(n), short(n))) finally: release(lock, wlock)
def histedit(ui, repo, *parent, **opts): """hg histedit <parent> """ if opts.get('outgoing'): if len(parent) > 1: raise util.Abort('only one repo argument allowed with --outgoing') elif parent: parent = parent[0] dest, revs, checkout = hg.parseurl( ui.expandpath(parent or 'default-push', parent or 'default'), ['tip']) if revs: revs = [repo.lookup(rev) for rev in revs] other = hg.repository(ui, dest) ui.status(_('comparing with %s\n') % url.hidepassword(dest)) parent = repo.findoutgoing(other, force=opts.get('force')) else: if opts.get('force'): raise util.Abort('--force only allowed with --outgoing') if opts.get('continue', False): if len(parent) != 0: raise util.Abort('no arguments allowed with --continue') (parentctxnode, created, replaced, tmpnodes, existing, rules, keep, tip, ) = readstate(repo) currentparent, wantnull = repo.dirstate.parents() parentctx = repo[parentctxnode] # discover any nodes the user has added in the interim newchildren = [c for c in parentctx.children() if c.node() not in existing] action, currentnode = rules.pop(0) while newchildren: if action in ['f', 'fold', ]: tmpnodes.extend([n.node() for n in newchildren]) else: created.extend([n.node() for n in newchildren]) newchildren = filter(lambda x: x.node() not in existing, reduce(lambda x, y: x + y, map(lambda r: r.children(), newchildren))) m, a, r, d = repo.status()[:4] oldctx = repo[currentnode] message = oldctx.description() if action in ('e', 'edit', ): message = ui.edit(message, ui.username()) elif action in ('f', 'fold', ): message = 'fold-temp-revision %s' % currentnode new = None if m or a or r or d: new = repo.commit(text=message, user=oldctx.user(), date=oldctx.date(), extra=oldctx.extra()) if action in ('e', 'edit', 'p', 'pick', ): replaced.append(oldctx.node()) if new: created.append(new) parentctx = repo[new] else: # fold if new: tmpnodes.append(new) else: new = newchildren[-1] (parentctx, created_, replaced_, tmpnodes_, ) = finishfold(ui, repo, parentctx, oldctx, new, opts, newchildren) replaced.extend(replaced_) created.extend(created_) tmpnodes.extend(tmpnodes_) elif opts.get('abort', False): if len(parent) != 0: raise util.Abort('no arguments allowed with --abort') (parentctxnode, created, replaced, tmpnodes, existing, rules, keep, tip, ) = readstate(repo) ui.debug('restore wc to old tip %s\n' % node.hex(tip)) hg.clean(repo, tip) ui.debug('should strip created nodes %s\n' % ', '.join([node.hex(n)[:12] for n in created])) ui.debug('should strip temp nodes %s\n' % ', '.join([node.hex(n)[:12] for n in tmpnodes])) for nodes in (created, tmpnodes, ): for n in reversed(nodes): try: repair.strip(ui, repo, n) except error.LookupError: pass os.unlink(os.path.join(repo.path, 'histedit-state')) return else: cmdutil.bail_if_changed(repo) if os.path.exists(os.path.join(repo.path, 'histedit-state')): raise util.Abort('history edit already in progress, try --continue or --abort') tip, empty = repo.dirstate.parents() if len(parent) != 1: raise util.Abort('requires exactly one parent revision') parent = parent[0] revs = between(repo, parent, tip) ctxs = [repo[r] for r in revs] existing = [r.node() for r in ctxs] rules = '\n'.join([('pick %s %s' % (c.hex()[:12], c.description().splitlines()[0]))[:80] for c in ctxs]) rules += editcomment % (node.hex(parent)[:12], node.hex(tip)[:12], ) rules = ui.edit(rules, ui.username()) parentctx = repo[parent].parents()[0] rules = [l for l in (r.strip() for r in rules.splitlines()) if l and not l[0] == '#'] rules = verifyrules(rules, repo, ctxs) keep = opts.get('keep', False) replaced = [] tmpnodes = [] created = [] while rules: writestate(repo, parentctx.node(), created, replaced, tmpnodes, existing, rules, keep, tip) action, ha = rules.pop(0) (parentctx, created_, replaced_, tmpnodes_, ) = actiontable[action](ui, repo, parentctx, ha, opts) created.extend(created_) replaced.extend(replaced_) tmpnodes.extend(tmpnodes_) hg.update(repo, parentctx.node()) if not keep: ui.debug('should strip replaced nodes %s\n' % ', '.join([node.hex(n)[:12] for n in replaced])) for n in sorted(replaced, lambda x, y: cmp(repo[x].rev(), repo[y].rev())): try: repair.strip(ui, repo, n) except error.LookupError: pass ui.debug('should strip temp nodes %s\n' % ', '.join([node.hex(n)[:12] for n in tmpnodes])) for n in reversed(tmpnodes): try: repair.strip(ui, repo, n) except error.LookupError: pass os.unlink(os.path.join(repo.path, 'histedit-state'))
def overview(ui, repo, source=None, **opts): '''provides a general overview of your repository state This command combines the output of the hg incomng, hg outgoing, hg status, and hg id commands into an easily human-readable explanation of the entire state of your current working repository. ''' if not repo: return originurl = ui.expandpath(source or 'default') targeturl = ui.expandpath(source or 'default-push', source or 'default') origin, hashbranch = parseurl(originurl) origin = hg.repository(remoteui(repo, opts), origin) target, hashbranch = parseurl(targeturl) target = hg.repository(remoteui(repo, opts), target) if originurl == targeturl: ui.status(_('parent repository: %s\n') % url.hidepassword(originurl)) else: ui.status( _('source repository: %s\n') % url.hidepassword(getattr(origin, 'root', origin.url()))) ui.status( _('destination repository: %s\n') % url.hidepassword(getattr(target, 'root', target.url()))) ui.pushbuffer() out = outgoing(repo, target) inc = incoming(repo, origin, filter(bool, [hashbranch])) ui.popbuffer() changed = any(repo.status()) if changed: status = _('uncommitted changes') else: status = _('working copy up-to-date') # grab heads heads = repo.branchheads(None, closed=False) if len(heads) > 1: merge = 'merge required' else: merge = '' ui.status( _('| Remote | << %s | Local | %s\n') % (str(len(out)).center(5), merge)) ui.status( _('| Repository | %s >> | Repository | %s\n') % (str(len(inc)).center(5), status)) if opts['detail']: if len(out) > 0: ui.status(_('\noutgoing changes:\n')) for rev in out: ui.status('%s %s\n' % (repo[rev], repo[rev].description().strip().split('\n')[0])) if len(inc) > 0: ui.status(_('\nincoming changes:\n')) for rev in inc: ui.status('%s %s\n' % (repo[rev], repo[rev].description().strip().split('\n')[0])) if changed: ui.status(_('\nlocal files:\n')) ui.pushbuffer() commands.status(ui, repo, '', **opts) status = ui.popbuffer() for l in status.splitlines(): print ' %s' % l
def fill_path_combo(self): self.pathlist.clear() for alias, path in self.paths: path = url.hidepassword(path) self.pathlist.append([hglib.toutf(path), hglib.toutf(alias)])