# HG changeset patch # User Martin Geisler # Date 2009-10-28 19:48:24 # Node ID d942e06d7b14a3744881f87a9646cede6172de76 # Parent 1fd9177932698b65d531c0adca79a2ae9896ec88 # Parent 96c803e9018f93493afd90f695178b9495703970 Merge with main diff --git a/contrib/mercurial.spec b/contrib/mercurial.spec --- a/contrib/mercurial.spec +++ b/contrib/mercurial.spec @@ -17,7 +17,7 @@ BuildRoot: %{_tmppath}/%{name}-%{version # python-devel provides an adequate python-dev. The merge tool is a # run-time dependency. # -BuildRequires: python >= 2.4, python-devel, make, gcc, asciidoc, xmlto +BuildRequires: python >= 2.4, python-devel, make, gcc, docutils >= 0.5 Provides: hg = %{version}-%{release} %define pythonver %(python -c 'import sys;print ".".join(map(str, sys.version_info[:2]))') diff --git a/contrib/tcsh_completion b/contrib/tcsh_completion --- a/contrib/tcsh_completion +++ b/contrib/tcsh_completion @@ -2,7 +2,7 @@ # tcsh completion for Mercurial # # This file has been auto-generated by tcsh_completion_build.sh for -# Mercurial Distributed SCM (version 1.1.2) +# Mercurial Distributed SCM (version 1.3.1+269-5d8125bbbbf4) # # Copyright (C) 2005 TK Soh. # @@ -24,7 +24,6 @@ complete hg \ --debugger \ --encoding \ --encodingmode \ - --lsprof \ --traceback \ --time \ --profile \ @@ -33,17 +32,18 @@ complete hg \ 'p/1/(add addremove annotate blame archive \ backout bisect branch branches bundle \ cat clone commit ci copy \ - cp debugancestor debugcheckstate debugcomplete debugdata \ - debugdate debugfsinfo debugindex debugindexdot debuginstall \ - debugrawcommit rawcommit debugrebuildstate debugrename debugsetparents \ - debugstate debugwalk diff export grep \ - heads help identify id import \ - patch incoming in init locate \ - log history manifest merge outgoing \ - out parents paths pull push \ - recover remove rm rename mv \ - resolve revert rollback root serve \ - showconfig debugconfig status st tag \ - tags tip unbundle update up \ - checkout co verify version)/' + cp debugancestor debugcheckstate debugcommands debugcomplete \ + debugdata debugdate debugfsinfo debugindex debugindexdot \ + debuginstall debugrebuildstate debugrename debugsetparents debugstate \ + debugsub debugwalk diff export forget \ + grep heads help identify id \ + import patch incoming in init \ + locate log history manifest merge \ + outgoing out parents paths pull \ + push recover remove rm rename \ + mv resolve revert rollback root \ + serve showconfig debugconfig status st \ + summary sum tag tags tip \ + unbundle update up checkout co \ + verify version)/' diff --git a/contrib/win32/mercurial.iss b/contrib/win32/mercurial.iss --- a/contrib/win32/mercurial.iss +++ b/contrib/win32/mercurial.iss @@ -61,6 +61,7 @@ Source: dist\Microsoft.VC*.MFC.manifest; Source: dist\w9xpopen.exe; DestDir: {app} Source: dist\add_path.exe; DestDir: {app} Source: doc\*.html; DestDir: {app}\Docs +Source: doc\style.css; DestDir: {app}\Docs Source: locale\*.*; DestDir: {app}\locale; Flags: recursesubdirs createallsubdirs Source: templates\*.*; DestDir: {app}\Templates; Flags: recursesubdirs createallsubdirs Source: CONTRIBUTORS; DestDir: {app}; DestName: Contributors.txt diff --git a/help/urls.txt b/help/urls.txt --- a/help/urls.txt +++ b/help/urls.txt @@ -47,7 +47,7 @@ These URLs can all be stored in your hgr ... You can then use the alias for any command that uses a URL (for -example 'hg pull alias1' would pull from the 'alias1' path). +example 'hg pull alias1' will be treated as 'hg pull URL1'). Two path aliases are special because they are used as defaults when you do not provide the URL to a command: diff --git a/hgext/bookmarks.py b/hgext/bookmarks.py --- a/hgext/bookmarks.py +++ b/hgext/bookmarks.py @@ -231,7 +231,7 @@ def strip(oldstrip, ui, repo, node, back write(repo, marks) def reposetup(ui, repo): - if not isinstance(repo, localrepo.localrepository): + if not repo.local(): return # init a bookmark cache as otherwise we would get a infinite reading diff --git a/hgext/churn.py b/hgext/churn.py --- a/hgext/churn.py +++ b/hgext/churn.py @@ -53,14 +53,12 @@ def countrate(ui, repo, amap, *pats, **o if opts.get('date'): df = util.matchdate(opts['date']) - get = util.cachefunc(lambda r: repo[r]) - changeiter, matchfn = cmdutil.walkchangerevs(ui, repo, pats, get, opts) - for st, rev, fns in changeiter: - + m = cmdutil.match(repo, pats, opts) + for st, ctx, fns in cmdutil.walkchangerevs(ui, repo, m, opts): if not st == 'add': continue - ctx = get(rev) + rev = ctx.rev() if df and not df(ctx.date()[0]): # doesn't match date format continue diff --git a/hgext/color.py b/hgext/color.py --- a/hgext/color.py +++ b/hgext/color.py @@ -189,9 +189,25 @@ def colorshowpatch(orig, self, node): finally: self.ui.write = oldwrite +def colordiffstat(orig, s): + lines = s.split('\n') + for i, line in enumerate(lines): + if line and line[-1] in '+-': + name, graph = line.rsplit(' ', 1) + graph = graph.replace('-', + render_effects('-', _diff_effects['deleted'])) + graph = graph.replace('+', + render_effects('+', _diff_effects['inserted'])) + lines[i] = ' '.join([name, graph]) + orig('\n'.join(lines)) + def colordiff(orig, ui, repo, *pats, **opts): '''run the diff command with colored output''' - oldwrite = extensions.wrapfunction(ui, 'write', colorwrap) + if opts.get('stat'): + wrapper = colordiffstat + else: + wrapper = colorwrap + oldwrite = extensions.wrapfunction(ui, 'write', wrapper) try: orig(ui, repo, *pats, **opts) finally: diff --git a/hgext/convert/__init__.py b/hgext/convert/__init__.py --- a/hgext/convert/__init__.py +++ b/hgext/convert/__init__.py @@ -103,7 +103,10 @@ def convert(ui, src, dest=None, revmapfi revision control system whose parents should be modified (same format as a key in .hg/shamap). The values are the revision IDs (in either the source or destination revision control system) that - should be used as the new parents for that node. + should be used as the new parents for that node. For example, if + you have merged "release-1.0" into "trunk", then you should + specify the revision on "trunk" as the first parent and the one on + the "release-1.0" branch as the second. The branchmap is a file that allows you to rename a branch when it is being brought in from whatever external repository. When used in diff --git a/hgext/mq.py b/hgext/mq.py --- a/hgext/mq.py +++ b/hgext/mq.py @@ -420,11 +420,20 @@ class queue(object): def printdiff(self, repo, node1, node2=None, files=None, fp=None, changes=None, opts={}): + stat = opts.get('stat') + if stat: + opts['unified'] = '0' + m = cmdutil.match(repo, files, opts) chunks = patch.diff(repo, node1, node2, m, changes, self.diffopts()) write = fp is None and repo.ui.write or fp.write - for chunk in chunks: - write(chunk) + if stat: + width = self.ui.interactive() and util.termwidth() or 80 + write(patch.diffstat(util.iterlines(chunks), width=width, + git=self.diffopts().git)) + else: + for chunk in chunks: + write(chunk) def mergeone(self, repo, mergeq, head, patch, rev): # first try just applying the patch diff --git a/hgext/patchbomb.py b/hgext/patchbomb.py --- a/hgext/patchbomb.py +++ b/hgext/patchbomb.py @@ -76,11 +76,11 @@ from mercurial import cmdutil, commands, from mercurial.i18n import _ from mercurial.node import bin -def prompt(ui, prompt, default='', rest=': ', empty_ok=False): +def prompt(ui, prompt, default=None, rest=':'): if not ui.interactive(): - if default or empty_ok: + if default is not None: return default - raise util.Abort(_("%sPlease enter a valid value" % (prompt+rest))) + raise util.Abort(_("%s Please enter a valid value" % (prompt+rest))) if default: prompt += ' [%s]' % default prompt += rest @@ -90,8 +90,6 @@ def prompt(ui, prompt, default='', rest= return r if default is not None: return default - if empty_ok: - return r ui.warn(_('Please enter a valid value.\n')) def cdiffstat(ui, summary, patchlines): @@ -99,7 +97,7 @@ def cdiffstat(ui, summary, patchlines): if summary: ui.write(summary, '\n') ui.write(s, '\n') - ans = prompt(ui, _('does the diffstat above look okay? '), 'y') + ans = prompt(ui, _('does the diffstat above look okay?'), 'y') if not ans.lower().startswith('y'): raise util.Abort(_('diffstat rejected')) return s @@ -330,10 +328,11 @@ def patchbomb(ui, repo, *revs, **opts): flag = ' '.join(opts.get('flag')) if flag: - subj = '[PATCH %0*d of %d %s] ' % (tlen, 0, len(patches), flag) + subj = '[PATCH %0*d of %d %s]' % (tlen, 0, len(patches), flag) else: - subj = '[PATCH %0*d of %d] ' % (tlen, 0, len(patches)) - subj += opts.get('subject') or prompt(ui, 'Subject:', rest=subj) + subj = '[PATCH %0*d of %d]' % (tlen, 0, len(patches)) + subj += ' ' + (opts.get('subject') or + prompt(ui, 'Subject: ', rest=subj)) body = '' if opts.get('diffstat'): diff --git a/mercurial/bundlerepo.py b/mercurial/bundlerepo.py --- a/mercurial/bundlerepo.py +++ b/mercurial/bundlerepo.py @@ -50,7 +50,7 @@ class bundlerevlog(revlog.revlog): continue for p in (p1, p2): if not p in self.nodemap: - raise error.LookupError(p1, self.indexfile, + raise error.LookupError(p, self.indexfile, _("unknown parent")) if linkmapper is None: link = n diff --git a/mercurial/cmdutil.py b/mercurial/cmdutil.py --- a/mercurial/cmdutil.py +++ b/mercurial/cmdutil.py @@ -653,8 +653,6 @@ class changeset_printer(object): log = self.repo.changelog date = util.datestr(ctx.date()) - extra = ctx.extra() - branch = extra.get("branch") hexfunc = self.ui.debugflag and hex or short @@ -663,6 +661,7 @@ class changeset_printer(object): self.ui.write(_("changeset: %d:%s\n") % (rev, hexfunc(changenode))) + branch = ctx.branch() # don't show the default branch name if branch != 'default': branch = encoding.tolocal(branch) @@ -691,6 +690,7 @@ class changeset_printer(object): copies = ['%s (%s)' % c for c in copies] self.ui.write(_("copies: %s\n") % ' '.join(copies)) + extra = ctx.extra() if extra and self.ui.debugflag: for key, value in sorted(extra.items()): self.ui.write(_("extra: %s=%s\n") @@ -1024,9 +1024,9 @@ def finddate(ui, repo, date): """Find the tipmost changeset that matches the given date spec""" df = util.matchdate(date) get = util.cachefunc(lambda r: repo[r]) - changeiter, matchfn = walkchangerevs(ui, repo, [], get, {'rev':None}) + m = matchall(repo) results = {} - for st, rev, fns in changeiter: + for st, rev, fns in walkchangerevs(ui, repo, m, get, {'rev':None}): if st == 'add': d = get(rev).date() if df(d[0]): @@ -1039,7 +1039,7 @@ def finddate(ui, repo, date): raise util.Abort(_("revision matching date not found")) -def walkchangerevs(ui, repo, pats, change, opts): +def walkchangerevs(ui, repo, match, opts): '''Iterate over files and the revs in which they changed. Callers most commonly need to iterate backwards over the history @@ -1050,12 +1050,8 @@ def walkchangerevs(ui, repo, pats, chang window, we first walk forwards to gather data, then in the desired order (usually backwards) to display it. - This function returns an (iterator, matchfn) tuple. The iterator - yields 3-tuples. They will be of one of the following forms: - - "window", incrementing, lastrev: stepping through a window, - positive if walking forwards through revs, last rev in the - sequence iterated over - use to reset state for the current window + This function returns an iterator. The iterator yields 3-tuples. + They will be of one of the following forms: "add", rev, fns: out-of-order traversal of the given filenames fns, which changed during revision rev - use to gather data for @@ -1078,11 +1074,10 @@ def walkchangerevs(ui, repo, pats, chang if windowsize < sizelimit: windowsize *= 2 - m = match(repo, pats, opts) follow = opts.get('follow') or opts.get('follow_first') if not len(repo): - return [], m + return [] if follow: defrange = '%s:0' % repo['.'].rev() @@ -1090,10 +1085,11 @@ def walkchangerevs(ui, repo, pats, chang defrange = '-1:0' revs = revrange(repo, opts['rev'] or [defrange]) wanted = set() - slowpath = m.anypats() or (m.files() and opts.get('removed')) + slowpath = match.anypats() or (match.files() and opts.get('removed')) fncache = {} + change = util.cachefunc(repo.changectx) - if not slowpath and not m.files(): + if not slowpath and not match.files(): # No files, no patterns. Display all revs. wanted = set(revs) copies = [] @@ -1117,7 +1113,7 @@ def walkchangerevs(ui, repo, pats, chang if rev[0] < cl_count: yield rev def iterfiles(): - for filename in m.files(): + for filename in match.files(): yield filename, None for filename_node in copies: yield filename_node @@ -1157,7 +1153,7 @@ def walkchangerevs(ui, repo, pats, chang yield change(j) for ctx in changerevgen(): - matches = filter(m, ctx.files()) + matches = filter(match, ctx.files()) if matches: fncache[ctx.rev()] = matches wanted.add(ctx.rev()) @@ -1210,7 +1206,7 @@ def walkchangerevs(ui, repo, pats, chang wanted.discard(x) def iterate(): - if follow and not m.files(): + if follow and not match.files(): ff = followfilter(onlyfirst=opts.get('follow_first')) def want(rev): return ff.match(rev) and rev in wanted @@ -1219,20 +1215,20 @@ def walkchangerevs(ui, repo, pats, chang return rev in wanted for i, window in increasing_windows(0, len(revs)): - yield 'window', revs[0] < revs[-1], revs[-1] nrevs = [rev for rev in revs[i:i+window] if want(rev)] for rev in sorted(nrevs): fns = fncache.get(rev) + ctx = change(rev) if not fns: def fns_generator(): - for f in change(rev).files(): - if m(f): + for f in ctx.files(): + if match(f): yield f fns = fns_generator() - yield 'add', rev, fns + yield 'add', ctx, fns for rev in nrevs: - yield 'iter', rev, None - return iterate(), m + yield 'iter', change(rev), None + return iterate() def commit(ui, repo, commitfunc, pats, opts): '''commit the specified files or all outstanding changes''' diff --git a/mercurial/commands.py b/mercurial/commands.py --- a/mercurial/commands.py +++ b/mercurial/commands.py @@ -1085,6 +1085,7 @@ def diff(ui, repo, *pats, **opts): revs = opts.get('rev') change = opts.get('change') + stat = opts.get('stat') if revs and change: msg = _('cannot specify --rev and --change at the same time') @@ -1095,10 +1096,19 @@ def diff(ui, repo, *pats, **opts): else: node1, node2 = cmdutil.revpair(repo, revs) + if stat: + opts['unified'] = '0' + diffopts = patch.diffopts(ui, opts) + m = cmdutil.match(repo, pats, opts) - it = patch.diff(repo, node1, node2, match=m, opts=patch.diffopts(ui, opts)) - for chunk in it: - ui.write(chunk) + it = patch.diff(repo, node1, node2, match=m, opts=diffopts) + if stat: + width = ui.interactive() and util.termwidth() or 80 + ui.write(patch.diffstat(util.iterlines(it), width=width, + git=diffopts.git)) + else: + for chunk in it: + ui.write(chunk) def export(ui, repo, *changesets, **opts): """dump the header and diffs for one or more changesets @@ -1257,7 +1267,8 @@ def grep(ui, repo, pattern, *pats, **opt for i in xrange(blo, bhi): yield ('+', b[i]) - def display(fn, r, pstates, states): + def display(fn, ctx, pstates, states): + rev = ctx.rev() datefunc = ui.quiet and util.shortdate or util.datestr found = False filerevmatches = {} @@ -1266,17 +1277,17 @@ def grep(ui, repo, pattern, *pats, **opt else: iter = [('', l) for l in states] for change, l in iter: - cols = [fn, str(r)] + cols = [fn, str(rev)] if opts.get('line_number'): cols.append(str(l.linenum)) if opts.get('all'): cols.append(change) if opts.get('user'): - cols.append(ui.shortuser(get(r).user())) + cols.append(ui.shortuser(ctx.user())) if opts.get('date'): - cols.append(datefunc(get(r).date())) + cols.append(datefunc(ctx.date())) if opts.get('files_with_matches'): - c = (fn, r) + c = (fn, rev) if c in filerevmatches: continue filerevmatches[c] = 1 @@ -1288,16 +1299,12 @@ def grep(ui, repo, pattern, *pats, **opt skip = {} revfiles = {} - get = util.cachefunc(lambda r: repo[r]) - changeiter, matchfn = cmdutil.walkchangerevs(ui, repo, pats, get, opts) + matchfn = cmdutil.match(repo, pats, opts) found = False follow = opts.get('follow') - for st, rev, fns in changeiter: - if st == 'window': - matches.clear() - revfiles.clear() - elif st == 'add': - ctx = get(rev) + for st, ctx, fns in cmdutil.walkchangerevs(ui, repo, matchfn, opts): + if st == 'add': + rev = ctx.rev() pctx = ctx.parents()[0] parent = pctx.rev() matches.setdefault(rev, {}) @@ -1331,7 +1338,8 @@ def grep(ui, repo, pattern, *pats, **opt except error.LookupError: pass elif st == 'iter': - parent = get(rev).parents()[0].rev() + rev = ctx.rev() + parent = ctx.parents()[0].rev() for fn in sorted(revfiles.get(rev, [])): states = matches[rev][fn] copy = copies.get(rev, {}).get(fn) @@ -1341,12 +1349,14 @@ def grep(ui, repo, pattern, *pats, **opt continue pstates = matches.get(parent, {}).get(copy or fn, []) if pstates or states: - r = display(fn, rev, pstates, states) + r = display(fn, ctx, pstates, states) found = found or r if r and not opts.get('all'): skip[fn] = True if copy: skip[copy] = True + del matches[rev] + del revfiles[rev] def heads(ui, repo, *branchrevs, **opts): """show current repository heads or show branch heads @@ -1604,7 +1614,7 @@ def help_(ui, name=None, with_version=Fa for title, options in option_lists: opt_output.append(("\n%s" % title, None)) for shortopt, longopt, default, desc in options: - if "DEPRECATED" in desc and not ui.verbose: continue + if _("DEPRECATED") in desc and not ui.verbose: continue opt_output.append(("%2s%s" % (shortopt and "-%s" % shortopt, longopt and " --%s" % longopt), "%s%s" % (desc, @@ -1708,7 +1718,8 @@ def identify(ui, repo, source=None, def import_(ui, repo, patch1, *patches, **opts): """import an ordered set of patches - Import a list of patches and commit them individually. + Import a list of patches and commit them individually (unless + --no-commit is specified). If there are outstanding changes in the working directory, import will abort unless given the -f/--force flag. @@ -1979,9 +1990,7 @@ def log(ui, repo, *pats, **opts): will appear in files:. """ - get = util.cachefunc(lambda r: repo[r]) - changeiter, matchfn = cmdutil.walkchangerevs(ui, repo, pats, get, opts) - + matchfn = cmdutil.match(repo, pats, opts) limit = cmdutil.loglimit(opts) count = 0 @@ -2028,7 +2037,8 @@ def log(ui, repo, *pats, **opts): only_branches = opts.get('only_branch') displayer = cmdutil.show_changeset(ui, repo, opts, True, matchfn) - for st, rev, fns in changeiter: + for st, ctx, fns in cmdutil.walkchangerevs(ui, repo, matchfn, opts): + rev = ctx.rev() if st == 'add': parents = [p for p in repo.changelog.parentrevs(rev) if p != nullrev] @@ -2037,7 +2047,6 @@ def log(ui, repo, *pats, **opts): if opts.get('only_merges') and len(parents) != 2: continue - ctx = get(rev) if only_branches and ctx.branch() not in only_branches: continue @@ -2070,6 +2079,7 @@ def log(ui, repo, *pats, **opts): elif st == 'iter': if count == limit: break + if displayer.flush(rev): count += 1 @@ -2298,6 +2308,8 @@ def pull(ui, repo, source="default", **o raise util.Abort(err) modheads = repo.pull(other, heads=revs, force=opts.get('force')) + if checkout: + checkout = str(repo.changelog.rev(other.lookup(checkout))) return postincoming(ui, repo, modheads, opts.get('update'), checkout) def push(ui, repo, dest=None, **opts): @@ -2433,7 +2445,7 @@ def rename(ui, repo, *pats, **opts): def resolve(ui, repo, *pats, **opts): """retry file merges from a merge or update - This command will cleanly retry unresolved file merges using file + This command can cleanly retry unresolved file merges using file revisions preserved from the last update or merge. To attempt to resolve all unresolved files, use the -a/--all switch. @@ -2451,7 +2463,8 @@ def resolve(ui, repo, *pats, **opts): R = resolved """ - all, mark, unmark, show = [opts.get(o) for o in 'all mark unmark list'.split()] + all, mark, unmark, show, nostatus = \ + [opts.get(o) for o in 'all mark unmark list no_status'.split()] if (show and (mark or unmark)) or (mark and unmark): raise util.Abort(_("too many options specified")) @@ -2467,7 +2480,10 @@ def resolve(ui, repo, *pats, **opts): for f in ms: if m(f): if show: - ui.write("%s %s\n" % (ms[f].upper(), f)) + if nostatus: + ui.write("%s\n" % f) + else: + ui.write("%s %s\n" % (ms[f].upper(), f)) elif mark: ms.mark(f, "r") elif unmark: @@ -3260,7 +3276,8 @@ diffopts2 = [ _('ignore changes in the amount of white space')), ('B', 'ignore-blank-lines', None, _('ignore changes whose lines are all blank')), - ('U', 'unified', '', _('number of lines of context to show')) + ('U', 'unified', '', _('number of lines of context to show')), + ('', 'stat', None, _('output diffstat-style summary of changes')), ] similarityopts = [ @@ -3475,7 +3492,7 @@ table = { ('n', 'newest-first', None, _('show newest record first')), ('', 'bundle', '', _('file to store the bundles into')), ('r', 'rev', [], - _('a specific revision up to which you would like to pull')), + _('a specific remote revision up to which you would like to pull')), ] + logopts + remoteopts, _('[-p] [-n] [-M] [-f] [-r REV]...' ' [--bundle FILENAME] [SOURCE]')), @@ -3543,7 +3560,7 @@ table = { ('f', 'force', None, _('run even when remote repository is unrelated')), ('r', 'rev', [], - _('a specific revision up to which you would like to pull')), + _('a specific remote revision up to which you would like to pull')), ] + remoteopts, _('[-u] [-f] [-r REV]... [-e CMD] [--remotecmd CMD] [SOURCE]')), "^push": @@ -3573,7 +3590,8 @@ table = { [('a', 'all', None, _('remerge all unresolved files')), ('l', 'list', None, _('list state of files needing merge')), ('m', 'mark', None, _('mark files as resolved')), - ('u', 'unmark', None, _('unmark files as resolved'))] + ('u', 'unmark', None, _('unmark files as resolved')), + ('n', 'no-status', None, _('hide status prefix'))] + walkopts, _('[OPTION]... [FILE]...')), "revert": diff --git a/mercurial/patch.py b/mercurial/patch.py --- a/mercurial/patch.py +++ b/mercurial/patch.py @@ -1364,7 +1364,8 @@ def diffstatdata(lines): for line in lines: if line.startswith('diff'): if filename: - yield (filename, adds, removes) + isbinary = adds == 0 and removes == 0 + yield (filename, adds, removes, isbinary) # set numbers to 0 anyway when starting new file adds, removes = 0, 0 if line.startswith('diff --git'): @@ -1377,21 +1378,27 @@ def diffstatdata(lines): elif line.startswith('-') and not line.startswith('---'): removes += 1 if filename: - yield (filename, adds, removes) + isbinary = adds == 0 and removes == 0 + yield (filename, adds, removes, isbinary) -def diffstat(lines, width=80): +def diffstat(lines, width=80, git=False): output = [] stats = list(diffstatdata(lines)) maxtotal, maxname = 0, 0 totaladds, totalremoves = 0, 0 - for filename, adds, removes in stats: + hasbinary = False + for filename, adds, removes, isbinary in stats: totaladds += adds totalremoves += removes maxname = max(maxname, len(filename)) maxtotal = max(maxtotal, adds+removes) + if isbinary: + hasbinary = True countwidth = len(str(maxtotal)) + if hasbinary and countwidth < 3: + countwidth = 3 graphwidth = width - countwidth - maxname - 6 if graphwidth < 10: graphwidth = 10 @@ -1404,11 +1411,15 @@ def diffstat(lines, width=80): # if there were at least some changes. return max(i * graphwidth // maxtotal, int(bool(i))) - for filename, adds, removes in stats: + for filename, adds, removes, isbinary in stats: + if git and isbinary: + count = 'Bin' + else: + count = adds + removes pluses = '+' * scale(adds) minuses = '-' * scale(removes) - output.append(' %-*s | %*.d %s%s\n' % (maxname, filename, countwidth, - adds+removes, pluses, minuses)) + output.append(' %-*s | %*s %s%s\n' % (maxname, filename, countwidth, + count, pluses, minuses)) if stats: output.append(_(' %d files changed, %d insertions(+), %d deletions(-)\n') diff --git a/mercurial/verify.py b/mercurial/verify.py --- a/mercurial/verify.py +++ b/mercurial/verify.py @@ -27,6 +27,7 @@ def _verify(repo): ui = repo.ui cl = repo.changelog mf = repo.manifest + lrugetctx = util.lrucachefunc(repo.changectx) if not repo.cancopy(): raise util.Abort(_("cannot verify bundle or remote repos")) @@ -78,6 +79,13 @@ def _verify(repo): msg = _("rev %d points to unexpected changeset %d") err(None, msg % (i, lr), f) if linkrevs: + if f and len(linkrevs) > 1: + try: + # attempt to filter down to real linkrevs + linkrevs = [l for l in linkrevs + if lrugetctx(l)[f].filenode() == node] + except: + pass warn(_(" (expected %s)") % " ".join(map(str, linkrevs))) lr = None # can't be trusted @@ -136,9 +144,7 @@ def _verify(repo): if not f: err(lr, _("file without name in manifest")) elif f != "/dev/null": - fns = filenodes.setdefault(f, {}) - if fn not in fns: - fns[fn] = i + filenodes.setdefault(f, {}).setdefault(fn, lr) except Exception, inst: exc(lr, _("reading manifest delta %s") % short(n), inst) @@ -173,7 +179,6 @@ def _verify(repo): elif size > 0: storefiles.add(f) - lrugetctx = util.lrucachefunc(repo.changectx) files = sorted(set(filenodes) | set(filelinkrevs)) for f in files: try: @@ -250,7 +255,7 @@ def _verify(repo): # cross-check if f in filenodes: - fns = [(mf.linkrev(l), n) for n,l in filenodes[f].iteritems()] + fns = [(lr, n) for n,lr in filenodes[f].iteritems()] for lr, node in sorted(fns): err(lr, _("%s in manifests not found") % short(node), f) diff --git a/tests/test-convert.out b/tests/test-convert.out --- a/tests/test-convert.out +++ b/tests/test-convert.out @@ -81,7 +81,10 @@ convert a foreign SCM repository to a Me revision ID in the source revision control system whose parents should be modified (same format as a key in .hg/shamap). The values are the revision IDs (in either the source or destination revision control system) that - should be used as the new parents for that node. + should be used as the new parents for that node. For example, if you have + merged "release-1.0" into "trunk", then you should specify the revision on + "trunk" as the first parent and the one on the "release-1.0" branch as the + second. The branchmap is a file that allows you to rename a branch when it is being brought in from whatever external repository. When used in diff --git a/tests/test-debugcomplete.out b/tests/test-debugcomplete.out --- a/tests/test-debugcomplete.out +++ b/tests/test-debugcomplete.out @@ -167,7 +167,7 @@ add: include, exclude, dry-run annotate: rev, follow, text, user, date, number, changeset, line-number, include, exclude clone: noupdate, rev, pull, uncompressed, ssh, remotecmd commit: addremove, close-branch, include, exclude, message, logfile, date, user -diff: rev, change, text, git, nodates, show-function, ignore-all-space, ignore-space-change, ignore-blank-lines, unified, include, exclude +diff: rev, change, text, git, nodates, show-function, ignore-all-space, ignore-space-change, ignore-blank-lines, unified, stat, include, exclude export: output, switch-parent, text, git, nodates forget: include, exclude init: ssh, remotecmd @@ -218,7 +218,7 @@ parents: rev, style, template paths: recover: rename: after, force, include, exclude, dry-run -resolve: all, list, mark, unmark, include, exclude +resolve: all, list, mark, unmark, no-status, include, exclude revert: all, date, rev, no-backup, include, exclude, dry-run rollback: root: diff --git a/tests/test-diff-color b/tests/test-diff-color --- a/tests/test-diff-color +++ b/tests/test-diff-color @@ -35,6 +35,9 @@ hg diff --nodates --color=always echo '% --unified=2' hg diff --nodates -U 2 --color=always +echo '% diffstat' +hg diff --stat --color=always + echo "record=" >> $HGRCPATH echo "[ui]" >> $HGRCPATH echo "interactive=true" >> $HGRCPATH diff --git a/tests/test-diff-color.out b/tests/test-diff-color.out --- a/tests/test-diff-color.out +++ b/tests/test-diff-color.out @@ -23,6 +23,9 @@ adding a +dd a a +% diffstat + a | 2 +- + 1 files changed, 1 insertions(+), 1 deletions(-) % record diff --git a/a b/a old mode 100644 diff --git a/tests/test-diffstat b/tests/test-diffstat new file mode 100755 --- /dev/null +++ b/tests/test-diffstat @@ -0,0 +1,34 @@ +#!/bin/sh + +hg init repo +cd repo +i=0; while [ "$i" -lt 213 ]; do echo a >> a; i=$(($i + 1)); done +hg add a + +echo '% wide diffstat' +hg diff --stat + +echo '% diffstat width' +COLUMNS=24 hg diff --config ui.interactive=true --stat + +hg ci -m adda + +cat >> a < b +hg add b + +echo '% binary diffstat' +hg diff --stat + +echo '% binary git diffstat' +hg diff --stat --git diff --git a/tests/test-diffstat.out b/tests/test-diffstat.out new file mode 100644 --- /dev/null +++ b/tests/test-diffstat.out @@ -0,0 +1,15 @@ +% wide diffstat + a | 213 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + 1 files changed, 213 insertions(+), 0 deletions(-) +% diffstat width + a | 213 ++++++++++++++ + 1 files changed, 213 insertions(+), 0 deletions(-) +% narrow diffstat + a | 3 +++ + 1 files changed, 3 insertions(+), 0 deletions(-) +% binary diffstat + b | 0 + 1 files changed, 0 insertions(+), 0 deletions(-) +% binary git diffstat + b | Bin + 1 files changed, 0 insertions(+), 0 deletions(-) diff --git a/tests/test-help.out b/tests/test-help.out --- a/tests/test-help.out +++ b/tests/test-help.out @@ -241,6 +241,7 @@ options: -b --ignore-space-change ignore changes in the amount of white space -B --ignore-blank-lines ignore changes whose lines are all blank -U --unified number of lines of context to show + --stat output diffstat-style summary of changes -I --include include names matching the given patterns -X --exclude exclude names matching the given patterns diff --git a/tests/test-patchbomb.out b/tests/test-patchbomb.out --- a/tests/test-patchbomb.out +++ b/tests/test-patchbomb.out @@ -1177,7 +1177,7 @@ diff -r eae5fcf795ee -r e317db6a6f28 .hg +ff2c9fa2018b15fa74b33363bda9527323e2a99f two +ff2c9fa2018b15fa74b33363bda9527323e2a99f two.diff -abort: Subject:[PATCH 0 of 2] Please enter a valid value +abort: Subject: [PATCH 0 of 2] Please enter a valid value This patch series consists of 2 patches. This patch series consists of 2 patches.