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 status(ui, repo, revision='tip', ignore=[]): """Indicates the state of a revision relative to the bugs database. In essence, this function is a wrapper for `hg stat --change x` which strips out changes to the bugs directory. A revision either: * Does not touch the bugs directory: This generally indicates a feature change or other improvement, in any case, b cannot draw any conclusions about the revision. Returns None. * Only touches the bugs directory: This would indicate a new bug report, comment, reassignment, or other internal b housekeeping. No external files were touched, no progress is being made in the rest of repository. Returns an empty list. * Touches the bugs directory, and other areas of the repository: This is assumed to indicate a bug fix, or progress is being made on a bug. Committing unrelated changes to the repository and the bugs database in the same revision should be discouraged. Returns a list of files outside the bugs directory in the given changeset. You may pass a list of Mercurial patterns (see `hg help patterns`) relative to the repository root to exclude from the returned list. """ bugsdir = bugs_dir(ui) ui.pushbuffer() commands.status(ui, repo, change=revision, no_status=True, print0=True) files = ui.popbuffer().split('\0') bug_change = False ret = [] for file in files: if file.strip(): if file.startswith(bugsdir): bug_change = True else: ret.append(file) ui.write(ret if bug_change else None) ui.write('\n')
def push_to_try(ui, repo, server, message=None): nodate = ui.configbool('push-to-try', 'nodate') if not message or 'try:' not in message: ui.status("STOP! A commit message with try syntax is required.\n") return cctx = context.workingctx(repo) status = repo.status() if status.modified + status.added + status.removed: ui.status('The following will be pushed to %s:\n' % server) # TODO: Achieve this by re-using the status call above to avoid the # cost of running it twice. commands.status(ui, repo) preserve_ctx = preservefilectx(cctx) def mk_memfilectx(repo, memctx, path): if path not in status.removed: return preserve_ctx(repo, memctx, path) return None # Invent a temporary commit with our message. ui.status("Creating temporary commit for remote...\n") mctx = context.memctx(repo, repo.dirstate.parents(), message, cctx.files(), mk_memfilectx, date="0 0" if nodate else None) # These messages are expected when we abort our transaction, but aren't # helpful to a user and may be misleading so we surpress them here. filtered_phrases = {_("transaction abort!\n"), _("rollback completed\n")} def filtered_warn(*msgs, **opts): if msgs: filtered = [m for m in msgs if m not in filtered_phrases] if filtered: ui.warn(*filtered, **opts) lock = tr = None try: lock = repo.lock() tr = repo.transaction('push-to-try', report=filtered_warn) m = mctx.commit() # Push to try. commands.push(ui, repo, server, force=True, rev=[repo[m].rev()]) ui.status('push complete\n') # And rollback to the previous state. tr.abort() finally: if tr: tr.release() if lock: lock.release() ui.status("temporary commit removed, repository restored\n")
def check_uncommited_changes(repo): repo.ui.pushbuffer() commands.status(repo.ui, repo) uncommited_changes = repo.ui.popbuffer() if uncommited_changes: do_check = str(raw_input('\nYou have uncommitted changes.\n' 'Checking will be done by the last commited changes.\n' 'If you are not satisfied with this situation,\n' 'commit the latest changes and restart the command (press n to abort) ')).replace('\r', '') if do_check == 'n': sys.exit()
def function(tree, path, opts): path = util.localpath(path) if files: pats = files[tree] else: pats = () if path == top.root: path = '' else: path = relpath(top.root, path) def prefix(output): """This function shims the root in before the filename.""" if opts['no_status']: return os.path.join(path, output) else: prefix, filename = output.split(' ', 1) return ' '.join((prefix, os.path.join(path, filename))) localui = munge_ui(prefix, ui) try: commands.status(localui, tree.repo, *pats, **opts) except RepoError, err: ui.warn(_("skipped: %s\n") % err)
def status(ui,repo,revision='tip',ignore=[]): """Indicates the state of a revision relative to the bugs database. In essence, this function is a wrapper for `hg stat --change x` which strips out changes to the bugs directory. A revision either: * Does not touch the bugs directory: This generally indicates a feature change or other improvement, in any case, b cannot draw any conclusions about the revision. Returns None. * Only touches the bugs directory: This would indicate a new bug report, comment, reassignment, or other internal b housekeeping. No external files were touched, no progress is being made in the rest of repository. Returns an empty list. * Touches the bugs directory, and other areas of the repository: This is assumed to indicate a bug fix, or progress is being made on a bug. Committing unrelated changes to the repository and the bugs database in the same revision should be discouraged. Returns a list of files outside the bugs directory in the given changeset. You may pass a list of Mercurial patterns (see `hg help patterns`) relative to the repository root to exclude from the returned list. """ bugsdir = bugs_dir(ui) ui.pushbuffer() commands.status(ui,repo,change=revision,no_status=True,print0=True) files = ui.popbuffer().split('\0') bug_change = False ret = [] for file in files: if file.strip(): if file.startswith(bugsdir): bug_change = True else: ret.append(file) ui.write(ret if bug_change else None) ui.write('\n')
def readStatus(self, ctx, ctx2, wfile, status): def getstatus(repo, n1, n2, wfile): m = match.exact(repo.root, repo.getcwd(), [wfile]) modified, added, removed = repo.status(n1, n2, match=m)[:3] if wfile in modified: return 'M' if wfile in added: return 'A' if wfile in removed: return 'R' if wfile in ctx: return 'C' return None isbfile = False repo = ctx._repo self.flabel += u'<b>%s</b>' % hglib.tounicode(wfile) if isinstance(ctx, patchctx.patchctx): self.diff = ctx.thgmqpatchdata(wfile) flags = ctx.flags(wfile) if flags == 'x': self.elabel = _( "exec mode has been <font color='red'>set</font>") elif flags == '-': self.elabel = _( "exec mode has been <font color='red'>unset</font>") elif flags == 'l': self.flabel += _(' <i>(is a symlink)</i>') return if ctx2: # If a revision to compare to was provided, we must put it in # the context of the subrepo as well if ctx2._repo.root != ctx._repo.root: wsub2, wfileinsub2, sctx2 = \ hglib.getDeepestSubrepoContainingFile(wfile, ctx2) if wsub2: ctx2 = sctx2 absfile = repo.wjoin(wfile) if (wfile in ctx and 'l' in ctx.flags(wfile)) or \ os.path.islink(absfile): if wfile in ctx: data = ctx[wfile].data() else: data = os.readlink(absfile) self.contents = data self.flabel += _(' <i>(is a symlink)</i>') return if status is None: status = getstatus(repo, ctx.p1().node(), ctx.node(), wfile) if ctx2 is None: ctx2 = ctx.p1() if status == 'S': try: from mercurial import subrepo, commands def genSubrepoRevChangedDescription(subrelpath, sfrom, sto, repo): """Generate a subrepository revision change description""" out = [] def getLog(_ui, srepo, opts): _ui.pushbuffer() try: commands.log(_ui, srepo, **opts) logOutput = _ui.popbuffer() except error.ParseError, e: # Some mercurial versions have a bug that results in # saving a subrepo node id in the .hgsubstate file # which ends with a "+" character. If that is the # case, add a warning to the output, but try to # get the revision information anyway logOutput = '' for n, rev in enumerate(opts['rev']): if rev.endswith('+'): logOutput += _( '[WARNING] Invalid subrepo ' 'revision ID:\n\t%s\n\n') % rev opts['rev'][n] = rev[:-1] commands.log(_ui, srepo, **opts) logOutput += _ui.popbuffer() return logOutput opts = {'date': None, 'user': None, 'rev': [sfrom]} subabspath = os.path.join(repo.root, subrelpath) missingsub = not os.path.isdir(subabspath) incompletesub = False sfromlog = '' def isinitialrevision(rev): return all([el == '0' for el in rev]) if isinitialrevision(sfrom): sfrom = '' if isinitialrevision(sto): sto = '' if not sfrom and not sto: sstatedesc = 'new' out.append( _('Subrepo created and set to initial revision.') + u'\n\n') return out, sstatedesc elif not sfrom: sstatedesc = 'new' out.append( _('Subrepo initialized to revision:') + u'\n\n') elif not sto: sstatedesc = 'removed' out.append( _('Subrepo removed from repository.') + u'\n\n') return out, sstatedesc elif sfrom == sto: sstatedesc = 'unchanged' out.append(_('Subrepo was not changed.') + u'\n\n') out.append(_('Subrepo state is:') + u'\n\n') if missingsub: out.append(_('changeset: %s') % sfrom + u'\n') else: out.append( hglib.tounicode(getLog(_ui, srepo, opts))) return out, sstatedesc else: sstatedesc = 'changed' out.append(_('Revision has changed to:') + u'\n\n') if missingsub: sfromlog = _('changeset: %s') % sfrom + u'\n\n' else: sfromlog = hglib.tounicode(getLog( _ui, srepo, opts)) if not sfromlog: incompletesub = True sfromlog = _('changeset: %s') % sfrom + u'\n\n' sfromlog = _('From:') + u'\n' + sfromlog if missingsub: stolog = _('changeset: %s') % sto + '\n\n' sfromlog += _('Subrepository not found in the working ' 'directory.') + '\n' sfromlog += _( 'Further subrepository revision ' 'information cannot be retrieved.') + '\n' elif incompletesub: stolog = _('changeset: %s') % sto + '\n\n' sfromlog += _('Subrepository is either damaged or ' 'missing some revisions') + '\n' sfromlog += _( 'Further subrepository revision ' 'information cannot be retrieved.') + '\n' sfromlog += _('You may need to open the missing ' 'subrepository and manually\n' 'pull the missing revisions from its ' 'source repository.') + '\n' else: opts['rev'] = [sto] stolog = getLog(_ui, srepo, opts) if not stolog: stolog = _('Initial revision') + u'\n' out.append(hglib.tounicode(stolog)) if sfromlog: out.append(hglib.tounicode(sfromlog)) return out, sstatedesc srev = ctx.substate.get(wfile, subrepo.nullstate)[1] srepo = None try: subabspath = os.path.join(ctx._repo.root, wfile) if not os.path.isdir(subabspath): sactual = '' else: sub = ctx.sub(wfile) if isinstance(sub, subrepo.hgsubrepo): srepo = sub._repo sactual = srepo['.'].hex() else: self.error = _( 'Not a Mercurial subrepo, not previewable') return except (util.Abort, KeyError), e: sactual = '' out = [] _ui = uimod.ui() if srepo is None or ctx.rev() is not None: data = [] else: _ui.pushbuffer() commands.status(_ui, srepo, modified=True, added=True, removed=True, deleted=True) data = _ui.popbuffer() if data: out.append( _('The subrepository is dirty.') + u' ' + _('File Status:') + u'\n') out.append(hglib.tounicode(data)) out.append(u'\n') sstatedesc = 'changed' if ctx.rev() is not None: sparent = ctx.p1().substate.get(wfile, subrepo.nullstate)[1] subrepochange, sstatedesc = \ genSubrepoRevChangedDescription(wfile, sparent, srev, ctx._repo) out += subrepochange else: sstatedesc = 'dirty' if srev != sactual: subrepochange, sstatedesc = \ genSubrepoRevChangedDescription(wfile, srev, sactual, ctx._repo) out += subrepochange if data: sstatedesc += ' and dirty' elif srev and not sactual: sstatedesc = 'removed' self.ucontents = u''.join(out).strip() lbl = { 'changed': _('(is a changed sub-repository)'), 'unchanged': _('(is an unchanged sub-repository)'), 'dirty': _('(is a dirty sub-repository)'), 'new': _('(is a new sub-repository)'), 'removed': _('(is a removed sub-repository)'), 'changed and dirty': _('(is a changed and dirty sub-repository)'), 'new and dirty': _('(is a new and dirty sub-repository)'), 'removed and dirty': _('(is a removed sub-repository)') }[sstatedesc] self.flabel += ' <i>' + lbl + '</i>' if sactual: lbl = _(' <a href="subrepo:%s">open...</a>') self.flabel += lbl % hglib.tounicode(srepo.root)
def push_to_try(ui, repo, server, message=None): nodate = ui.configbool(b'push-to-try', b'nodate') if not server: if b'try' in ui.paths: server = b'try' else: server = b'ssh://hg.mozilla.org/try' if not message: ui.status(b"STOP! A commit message is required.\n") return cctx = context.workingctx(repo) if b'try_task_config.json' not in cctx and b'try:' not in message: ui.status(b"STOP! Either try_task_config.json must be added or the commit " b"message must contain try syntax.\n") return if b'try_task_config.json' in cctx: data = repo.wvfs.tryread(b'try_task_config.json') try: # data could be an empty string if tryread failed, which will # produce a ValueError here. data = json.loads(data) except ValueError as e: ui.status(b"Error reading try_task_config.json: could not decode as JSON\n") return # Invent a temporary commit with our message. ui.status(b"Creating temporary commit for remote...\n") status = repo.status() if status.modified + status.added + status.removed: # TODO: Achieve this by re-using the status call above to avoid the # cost of running it twice. commands.status(ui, repo) preserve_ctx = preservefilectx(cctx) def mk_memfilectx(repo, memctx, path): if path not in status.removed: return preserve_ctx(repo, memctx, path) return None mctx = context.memctx(repo, repo.dirstate.parents(), message, cctx.files(), mk_memfilectx, date=b"0 0" if nodate else None) # These messages are expected when we abort our transaction, but aren't # helpful to a user and may be misleading so we surpress them here. filtered_phrases = {_(b"transaction abort!\n"), _(b"rollback completed\n")} def filtered_warn(*msgs, **opts): if msgs: filtered = [m for m in msgs if m not in filtered_phrases] if filtered: ui.warn(*filtered, **opts) lock = tr = None try: lock = repo.lock() tr = repo.transaction(b'push-to-try', report=filtered_warn) m = mctx.commit() # Push to try. commands.push(ui, repo, server, force=True, rev=[repo[m].rev()]) ui.status(b'push complete\n') # And rollback to the previous state. tr.abort() finally: if tr: tr.release() if lock: lock.release() ui.status(b"temporary commit removed, repository restored\n")
def readStatus(self, ctx, ctx2, wfile, status, changeselect, force): def getstatus(repo, n1, n2, wfile): m = match.exact(repo.root, repo.getcwd(), [wfile]) modified, added, removed = repo.status(n1, n2, match=m)[:3] if wfile in modified: return 'M' if wfile in added: return 'A' if wfile in removed: return 'R' if wfile in ctx: return 'C' return None isbfile = False repo = ctx._repo maxdiff = repo.maxdiff self.flabel += u'<b>%s</b>' % hglib.tounicode(wfile) if isinstance(ctx, patchctx.patchctx): self.diff = ctx.thgmqpatchdata(wfile) flags = ctx.flags(wfile) if flags == 'x': self.elabel = _("exec mode has been <font color='red'>set</font>") elif flags == '-': self.elabel = _("exec mode has been <font color='red'>unset</font>") elif flags == 'l': self.flabel += _(' <i>(is a symlink)</i>') # Do not show patches that are too big or may be binary if not force: p = _('Diff not displayed: ') data = self.diff size = len(data) if (size > maxdiff): self.error = p + _('File is larger than the specified max size.\n' 'maxdiff = %s KB') % (maxdiff // 1024) elif '\0' in data: self.error = p + _('File is binary') elif _exceedsMaxLineLength(data): # it's incredibly slow to render long line by QScintilla self.error = p + \ _('File may be binary (maximum line length exceeded)') if self.error: self.error += u'\n\n' + forcedisplaymsg return if ctx2: # If a revision to compare to was provided, we must put it in # the context of the subrepo as well if ctx2._repo.root != ctx._repo.root: wsub2, wfileinsub2, sctx2 = \ hglib.getDeepestSubrepoContainingFile(wfile, ctx2) if wsub2: ctx2 = sctx2 absfile = repo.wjoin(wfile) if (wfile in ctx and 'l' in ctx.flags(wfile)) or \ os.path.islink(absfile): if wfile in ctx: data = ctx[wfile].data() else: data = os.readlink(absfile) self.contents = data self.flabel += _(' <i>(is a symlink)</i>') return if status is None: status = getstatus(repo, ctx.p1().node(), ctx.node(), wfile) if ctx2 is None: ctx2 = ctx.p1() if status == 'S': try: from mercurial import subrepo, commands def genSubrepoRevChangedDescription(subrelpath, sfrom, sto, repo): """Generate a subrepository revision change description""" out = [] def getLog(_ui, srepo, opts): _ui.pushbuffer() try: commands.log(_ui, srepo, **opts) logOutput = _ui.popbuffer() except error.ParseError, e: # Some mercurial versions have a bug that results in # saving a subrepo node id in the .hgsubstate file # which ends with a "+" character. If that is the # case, add a warning to the output, but try to # get the revision information anyway logOutput = '' for n, rev in enumerate(opts['rev']): if rev.endswith('+'): logOutput += _('[WARNING] Invalid subrepo ' 'revision ID:\n\t%s\n\n') % rev opts['rev'][n] = rev[:-1] commands.log(_ui, srepo, **opts) logOutput += _ui.popbuffer() return logOutput opts = {'date':None, 'user':None, 'rev':[sfrom]} subabspath = os.path.join(repo.root, subrelpath) missingsub = not os.path.isdir(subabspath) incompletesub = False sfromlog = '' def isinitialrevision(rev): return all([el == '0' for el in rev]) if isinitialrevision(sfrom): sfrom = '' if isinitialrevision(sto): sto = '' if not sfrom and not sto: sstatedesc = 'new' out.append(_('Subrepo created and set to initial revision.') + u'\n\n') return out, sstatedesc elif not sfrom: sstatedesc = 'new' out.append(_('Subrepo initialized to revision:') + u'\n\n') elif not sto: sstatedesc = 'removed' out.append(_('Subrepo removed from repository.') + u'\n\n') return out, sstatedesc elif sfrom == sto: sstatedesc = 'unchanged' out.append(_('Subrepo was not changed.') + u'\n\n') out.append(_('Subrepo state is:') + u'\n\n') if missingsub: out.append(_('changeset: %s') % sfrom + u'\n') else: out.append(hglib.tounicode(getLog(_ui, srepo, opts))) return out, sstatedesc else: sstatedesc = 'changed' out.append(_('Revision has changed to:') + u'\n\n') if missingsub: sfromlog = _('changeset: %s') % sfrom + u'\n\n' else: sfromlog = hglib.tounicode(getLog(_ui, srepo, opts)) if not sfromlog: incompletesub = True sfromlog = _('changeset: %s') % sfrom + u'\n\n' sfromlog = _('From:') + u'\n' + sfromlog if missingsub: stolog = _('changeset: %s') % sto + '\n\n' sfromlog += _('Subrepository not found in the working ' 'directory.') + '\n' sfromlog += _('Further subrepository revision ' 'information cannot be retrieved.') + '\n' elif incompletesub: stolog = _('changeset: %s') % sto + '\n\n' sfromlog += _('Subrepository is either damaged or ' 'missing some revisions') + '\n' sfromlog += _('Further subrepository revision ' 'information cannot be retrieved.') + '\n' sfromlog += _('You may need to open the missing ' 'subrepository and manually\n' 'pull the missing revisions from its ' 'source repository.') + '\n' else: opts['rev'] = [sto] stolog = getLog(_ui, srepo, opts) if not stolog: stolog = _('Initial revision') + u'\n' out.append(hglib.tounicode(stolog)) if sfromlog: out.append(hglib.tounicode(sfromlog)) return out, sstatedesc srev = ctx.substate.get(wfile, subrepo.nullstate)[1] srepo = None try: subabspath = os.path.join(ctx._repo.root, wfile) if not os.path.isdir(subabspath): sactual = '' else: sub = ctx.sub(wfile) if isinstance(sub, subrepo.hgsubrepo): srepo = sub._repo sactual = srepo['.'].hex() else: self.error = _('Not a Mercurial subrepo, not previewable') return except (util.Abort, KeyError), e: self.error = (_('Error previewing subrepo: %s') % hglib.tounicode(str(e))) return out = [] _ui = uimod.ui() if srepo is None or ctx.rev() is not None: data = [] else: _ui.pushbuffer() commands.status(_ui, srepo, modified=True, added=True, removed=True, deleted=True) data = _ui.popbuffer() if data: out.append(_('The subrepository is dirty.') + u' ' + _('File Status:') + u'\n') out.append(hglib.tounicode(data)) out.append(u'\n') sstatedesc = 'changed' if ctx.rev() is not None: sparent = ctx.p1().substate.get(wfile, subrepo.nullstate)[1] subrepochange, sstatedesc = \ genSubrepoRevChangedDescription(wfile, sparent, srev, ctx._repo) out += subrepochange else: sstatedesc = 'dirty' if srev != sactual: subrepochange, sstatedesc = \ genSubrepoRevChangedDescription(wfile, srev, sactual, ctx._repo) out += subrepochange if data: sstatedesc += ' and dirty' elif srev and not sactual: sstatedesc = 'removed' self.ucontents = u''.join(out).strip() lbl = { 'changed': _('(is a changed sub-repository)'), 'unchanged': _('(is an unchanged sub-repository)'), 'dirty': _('(is a dirty sub-repository)'), 'new': _('(is a new sub-repository)'), 'removed': _('(is a removed sub-repository)'), 'changed and dirty': _('(is a changed and dirty sub-repository)'), 'new and dirty': _('(is a new and dirty sub-repository)'), 'removed and dirty': _('(is a removed sub-repository)') }[sstatedesc] self.flabel += ' <i>' + lbl + '</i>' if sactual: lbl = ' <a href="repo:%%s">%s</a>' % _('open...') self.flabel += lbl % hglib.tounicode(srepo.root)
% hglib.tounicode(str(e))) + u'\n\n' self.error += _('Subrepo may be damaged or ' 'inaccessible.') return except KeyError, e: # Missing, incomplete or removed subrepo. # Will be handled later as such below pass out = [] _ui = uimod.ui() if srepo is None or ctx.rev() is not None: data = [] else: _ui.pushbuffer() commands.status(_ui, srepo, modified=True, added=True, removed=True, deleted=True) data = _ui.popbuffer() if data: out.append(_('The subrepository is dirty.') + u' ' + _('File Status:') + u'\n') out.append(hglib.tounicode(data)) out.append(u'\n') sstatedesc = 'changed' if ctx.rev() is not None: sparent = ctx2.substate.get(wfile, subrepo.nullstate)[1] subrepochange, sstatedesc = \ genSubrepoRevChangedDescription(wfile, sparent, srev, ctx._repo) out += subrepochange else:
'inaccessible.') return except KeyError, e: # Missing, incomplete or removed subrepo. # Will be handled later as such below pass out = [] # TODO: should be copied from the baseui _ui = hglib.loadui() _ui.setconfig('ui', 'paginate', 'off', 'subrepodata') if srepo is None or ctx.rev() is not None: data = [] else: _ui.pushbuffer() commands.status(_ui, srepo, modified=True, added=True, removed=True, deleted=True) data = _ui.popbuffer() if data: out.append(_('The subrepository is dirty.') + u' ' + _('File Status:') + u'\n') out.append(hglib.tounicode(data)) out.append(u'\n') sstatedesc = 'changed' if ctx.rev() is not None: sparent = ctx2.substate.get(wfile, subrepo.nullstate)[1] subrepochange, sstatedesc = \ genSubrepoRevChangedDescription(wfile, sparent, srev, ctx._repo) out += subrepochange else:
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
localrepo, ui as uimod, ) u = uimod.ui() print('% creating repo') repo = localrepo.localrepository(u, '.', create=True) f = open('test.py', 'w') try: f.write('foo\n') finally: f.close print('% add and commit') commands.add(u, repo, 'test.py') commands.commit(u, repo, message='*') commands.status(u, repo, clean=True) print('% change') f = open('test.py', 'w') try: f.write('bar\n') finally: f.close() # this would return clean instead of changed before the fix commands.status(u, repo, clean=True, modified=True)
from mercurial.ui import ui from mercurial.localrepo import localrepository from mercurial.commands import add, commit, status u = ui() print "% creating repo" repo = localrepository(u, ".", create=True) f = open("test.py", "w") try: f.write("foo\n") finally: f.close print "% add and commit" add(u, repo, "test.py") commit(u, repo, message="*") status(u, repo, clean=True) print "% change" f = open("test.py", "w") try: f.write("bar\n") finally: f.close() # this would return clean instead of changed before the fix status(u, repo, clean=True, modified=True)
# only makes sense to test on os which supports symlinks if not getattr(os, "symlink", False): sys.exit(80) # SKIPPED_STATUS defined in run-tests.py u = ui.ui() # hide outer repo hg.peer(u, {}, '.', create=True) # clone with symlink support hg.clone(u, {}, BUNDLEPATH, 'test0') repo = hg.repository(u, 'test0') # wait a bit, or the status call wont update the dirstate time.sleep(1) commands.status(u, repo) # now disable symlink support -- this is what os.symlink would do on a # non-symlink file system def symlink_failure(src, dst): raise OSError(1, "Operation not permitted") os.symlink = symlink_failure # dereference links as if a Samba server has exported this to a # Windows client for f in 'test0/a.lnk', 'test0/d/b.lnk': os.unlink(f) fp = open(f, 'wb') fp.write(util.readfile(f[:-4])) fp.close()
def sync_hg(hg_interface, local_repo_path, remote_repo_path=None): if remote_repo_path and not os.path.exists(remote_repo_path): #remote_repo_path does not exist #could sync with default source (e.g. github) here remote_repo_path = None #first pull down any changes that may exist on remote repo = hg.repository(hg_interface, local_repo_path) hg_interface.pushbuffer() commands.pull(hg_interface, repo, remote_repo_path) result = hg_interface.popbuffer() #hg_interface won't catch all of the output of a pull #if there were changes in the pull, it gets the line: #(run 'hg update' to get a working copy) # #if not, only has: # pulling from /media/CHARLES/charles #keep track if we find something that changes #so that we can pause at the end #otherwise we should just move on automatically changes = False print("%s" % result) lines = result.splitlines() if len(lines) > 1: #changes = True need_update = False for line in lines: #sometimes might be only 2 lines #sometimes might be 3: #['pulling from /media/charles/CHARLES/moments', 'updating bookmark master', "(run 'hg update' to get a working copy)"] if re.search('hg update', line): print("updating") hg_interface.pushbuffer() commands.update(hg_interface, repo) result = hg_interface.popbuffer() print("%s" % result) response = hg_interface.prompt("everything ok? (ctl-c to exit)", default='y') print("moving on then...") need_update = True if not need_update: #if we didn't update, the lines must be telling us #something else needs to happen... #must be a merge: print(lines) print("merge detected, all yours:") print("cd %s" % local_repo_path) exit() #at this point all changes from remote media should be applied locally #now we should check if we have any changes here: hg_interface.pushbuffer() commands.status(hg_interface, repo) result = hg_interface.popbuffer() if result: print("looks like there are some local changes:") print(result) changes = True new_files = False for line in result.splitlines(): if line.startswith('?'): new_files = True if new_files: print("new files found") response = hg_interface.prompt("would you like to add the new files?", default='y') if response == 'y': commands.add(hg_interface, repo) response = hg_interface.prompt("log (ctl-c to exit):", default='') commands.commit(hg_interface, repo, message=response) #push changes: print("hg push %s" % remote_repo_path) commands.push(hg_interface, repo, remote_repo_path) lines = result.splitlines() if len(lines) > 1: changes = True #only do this if remote repo exists: if remote_repo_path: #on remote repo, remote_repo = hg.repository(hg_interface, remote_repo_path) #update print("updating remote:") hg_interface.pushbuffer() commands.update(hg_interface, remote_repo) result = hg_interface.popbuffer() print("%s" % result) #show remote status commands.status(hg_interface, remote_repo) else: print("skipping remote update: %s" % remote_repo_path) #pass if changes: response = hg_interface.prompt("everything ok? (ctl-c to exit)", default='y')
""" print_(*args, **kwargs) sys.stdout.flush() u = uimod.ui.load() print('% creating repo') repo = localrepo.localrepository(u, b'.', create=True) f = open('test.py', 'w') try: f.write('foo\n') finally: f.close print('% add and commit') commands.add(u, repo, b'test.py') commands.commit(u, repo, message=b'*') commands.status(u, repo, clean=True) print('% change') f = open('test.py', 'w') try: f.write('bar\n') finally: f.close() # this would return clean instead of changed before the fix commands.status(u, repo, clean=True, modified=True)
#!/usr/bin/python from mercurial.ui import ui from mercurial.localrepo import localrepository from mercurial.commands import add, commit, status u = ui() print '% creating repo' repo = localrepository(u, '.', create=True) f = open('test.py', 'w') try: f.write('foo\n') finally: f.close print '% add and commit' add(u, repo, 'test.py') commit(u, repo, message='*') status(u, repo, clean=True) print '% change' f = open('test.py', 'w') try: f.write('bar\n') finally: f.close() # this would return clean instead of changed before the fix status(u, repo, clean=True, modified=True)