diff --git a/hgext/transplant.py b/hgext/transplant.py --- a/hgext/transplant.py +++ b/hgext/transplant.py @@ -629,8 +629,14 @@ def transplant(ui, repo, *revs, **opts): if sourcerepo: peer = hg.peer(repo, opts, ui.expandpath(sourcerepo)) heads = map(peer.lookup, opts.get('branch', ())) + target = set(heads) + for r in revs: + try: + target.add(peer.lookup(r)) + except error.RepoError: + pass source, csets, cleanupfn = bundlerepo.getremotechanges(ui, repo, peer, - onlyheads=heads, force=True) + onlyheads=sorted(target), force=True) else: source = repo heads = map(source.lookup, opts.get('branch', ())) diff --git a/mercurial/archival.py b/mercurial/archival.py --- a/mercurial/archival.py +++ b/mercurial/archival.py @@ -85,7 +85,6 @@ def buildmetadata(ctx): cmdutil.show_changeset(repo.ui, repo, opts).show(ctx) ltags, dist = repo.ui.popbuffer().split('\n') ltags = ltags.split(':') - # XXX: ctx.rev() needs to be handled differently with wdir() if ctx.rev() is None: changessince = len(repo.revs('only(%d,%s)', ctx.p1(), ltags[0])) + 1 diff --git a/mercurial/changegroup.py b/mercurial/changegroup.py --- a/mercurial/changegroup.py +++ b/mercurial/changegroup.py @@ -585,11 +585,13 @@ def changegroupsubset(repo, roots, heads cl = repo.changelog if not roots: roots = [nullid] - # TODO: remove call to nodesbetween. - csets, roots, heads = cl.nodesbetween(roots, heads) discbases = [] for n in roots: discbases.extend([p for p in cl.parents(n) if p != nullid]) + # TODO: remove call to nodesbetween. + csets, roots, heads = cl.nodesbetween(roots, heads) + included = set(csets) + discbases = [n for n in discbases if n not in included] outgoing = discovery.outgoing(cl, discbases, heads) bundler = packermap[version][0](repo) return getsubset(repo, outgoing, bundler, source, version=version) diff --git a/mercurial/templater.py b/mercurial/templater.py --- a/mercurial/templater.py +++ b/mercurial/templater.py @@ -73,6 +73,41 @@ def tokenize(program, start, end): pos += 1 yield ('integer', program[s:pos], s) pos -= 1 + elif (c == '\\' and program[pos:pos + 2] in (r"\'", r'\"') + or c == 'r' and program[pos:pos + 3] in (r"r\'", r'r\"')): + # handle escaped quoted strings for compatibility with 2.9.2-3.4, + # where some of nested templates were preprocessed as strings and + # then compiled. therefore, \"...\" was allowed. (issue4733) + # + # processing flow of _evalifliteral() at 5ab28a2e9962: + # outer template string -> stringify() -> compiletemplate() + # ------------------------ ------------ ------------------ + # {f("\\\\ {g(\"\\\"\")}"} \\ {g("\"")} [r'\\', {g("\"")}] + # ~~~~~~~~ + # escaped quoted string + if c == 'r': + pos += 1 + token = 'rawstring' + else: + token = 'string' + quote = program[pos:pos + 2] + s = pos = pos + 2 + while pos < end: # find closing escaped quote + if program.startswith('\\\\\\', pos, end): + pos += 4 # skip over double escaped characters + continue + if program.startswith(quote, pos, end): + try: + # interpret as if it were a part of an outer string + data = program[s:pos].decode('string-escape') + except ValueError: # unbalanced escapes + raise error.ParseError(_("syntax error"), s) + yield (token, data, s) + pos += 1 + break + pos += 1 + else: + raise error.ParseError(_("unterminated string"), s) elif c.isalnum() or c in '_': s = pos pos += 1 diff --git a/tests/test-command-template.t b/tests/test-command-template.t --- a/tests/test-command-template.t +++ b/tests/test-command-template.t @@ -2860,6 +2860,16 @@ Test string escaping of quotes: $ hg log -Ra -r0 -T '{r"\\\""}\n' \\\" + + $ hg log -Ra -r0 -T '{"\""}\n' + " + $ hg log -Ra -r0 -T '{"\\\""}\n' + \" + $ hg log -Ra -r0 -T '{r"\""}\n' + \" + $ hg log -Ra -r0 -T '{r"\\\""}\n' + \\\" + Test exception in quoted template. single backslash before quotation mark is stripped before parsing: @@ -2877,6 +2887,47 @@ stripped before parsing: valid $ hg log -r 2 -T esc --config templates.esc="'"'{\'"'"'valid\'"'"'}\n'"'" valid + +Test compatibility with 2.9.2-3.4 of escaped quoted strings in nested +_evalifliteral() templates (issue4733): + + $ hg log -r 2 -T '{if(rev, "\"{rev}")}\n' + "2 + $ hg log -r 2 -T '{if(rev, "{if(rev, \"\\\"{rev}\")}")}\n' + "2 + $ hg log -r 2 -T '{if(rev, "{if(rev, \"{if(rev, \\\"\\\\\\\"{rev}\\\")}\")}")}\n' + "2 + + $ hg log -r 2 -T '{if(rev, "\\\"")}\n' + \" + $ hg log -r 2 -T '{if(rev, "{if(rev, \"\\\\\\\"\")}")}\n' + \" + $ hg log -r 2 -T '{if(rev, "{if(rev, \"{if(rev, \\\"\\\\\\\\\\\\\\\"\\\")}\")}")}\n' + \" + + $ hg log -r 2 -T '{if(rev, r"\\\"")}\n' + \\\" + $ hg log -r 2 -T '{if(rev, "{if(rev, r\"\\\\\\\"\")}")}\n' + \\\" + $ hg log -r 2 -T '{if(rev, "{if(rev, \"{if(rev, r\\\"\\\\\\\\\\\\\\\"\\\")}\")}")}\n' + \\\" + +escaped single quotes and errors: + + $ hg log -r 2 -T "{if(rev, '{if(rev, \'foo\')}')}"'\n' + foo + $ hg log -r 2 -T "{if(rev, '{if(rev, r\'foo\')}')}"'\n' + foo + $ hg log -r 2 -T '{if(rev, "{if(rev, \")}")}\n' + hg: parse error at 11: unterminated string + [255] + $ hg log -r 2 -T '{if(rev, \"\\"")}\n' + hg: parse error at 11: syntax error + [255] + $ hg log -r 2 -T '{if(rev, r\"\\"")}\n' + hg: parse error at 12: syntax error + [255] + $ cd .. Test leading backslashes: diff --git a/tests/test-rebase-conflicts.t b/tests/test-rebase-conflicts.t --- a/tests/test-rebase-conflicts.t +++ b/tests/test-rebase-conflicts.t @@ -272,9 +272,8 @@ Check that the right ancestors is used w removing f1.txt f2.txt: remote created -> g getting f2.txt - 3 changesets found + 2 changesets found list of changesets: - 4c9fbe56a16f30c0d5dcc40ec1a97bbe3325209c e31216eec445e44352c5f01588856059466a24c9 2f2496ddf49d69b5ef23ad8cf9fb2e0e4faf0ac2 saved backup bundle to $TESTTMP/issue4041/.hg/strip-backup/e31216eec445-15f7a814-backup.hg (glob) diff --git a/tests/test-strip.t b/tests/test-strip.t --- a/tests/test-strip.t +++ b/tests/test-strip.t @@ -692,3 +692,137 @@ Verify bundles don't get overwritten: $ ls .hg/strip-backup 3903775176ed-54390173-backup.hg 3903775176ed-e68910bd-backup.hg + $ cd .. + +Test that we only bundle the stripped changesets (issue4736) +------------------------------------------------------------ + +initialisation (previous repo is empty anyway) + + $ hg init issue4736 + $ cd issue4736 + $ echo a > a + $ hg add a + $ hg commit -m commitA + $ echo b > b + $ hg add b + $ hg commit -m commitB + $ echo c > c + $ hg add c + $ hg commit -m commitC + $ hg up 'desc(commitB)' + 0 files updated, 0 files merged, 1 files removed, 0 files unresolved + $ echo d > d + $ hg add d + $ hg commit -m commitD + created new head + $ hg up 'desc(commitC)' + 1 files updated, 0 files merged, 1 files removed, 0 files unresolved + $ hg merge 'desc(commitD)' + 1 files updated, 0 files merged, 0 files removed, 0 files unresolved + (branch merge, don't forget to commit) + $ hg ci -m 'mergeCD' + $ hg log -G + @ changeset: 4:d8db9d137221 + |\ tag: tip + | | parent: 2:5c51d8d6557d + | | parent: 3:6625a5168474 + | | user: test + | | date: Thu Jan 01 00:00:00 1970 +0000 + | | summary: mergeCD + | | + | o changeset: 3:6625a5168474 + | | parent: 1:eca11cf91c71 + | | user: test + | | date: Thu Jan 01 00:00:00 1970 +0000 + | | summary: commitD + | | + o | changeset: 2:5c51d8d6557d + |/ user: test + | date: Thu Jan 01 00:00:00 1970 +0000 + | summary: commitC + | + o changeset: 1:eca11cf91c71 + | user: test + | date: Thu Jan 01 00:00:00 1970 +0000 + | summary: commitB + | + o changeset: 0:105141ef12d0 + user: test + date: Thu Jan 01 00:00:00 1970 +0000 + summary: commitA + + +Check bundle behavior: + + $ hg bundle -r 'desc(mergeCD)' --base 'desc(commitC)' ../issue4736.hg + 2 changesets found + $ hg log -r 'bundle()' -R ../issue4736.hg + changeset: 3:6625a5168474 + parent: 1:eca11cf91c71 + user: test + date: Thu Jan 01 00:00:00 1970 +0000 + summary: commitD + + changeset: 4:d8db9d137221 + tag: tip + parent: 2:5c51d8d6557d + parent: 3:6625a5168474 + user: test + date: Thu Jan 01 00:00:00 1970 +0000 + summary: mergeCD + + +check strip behavior + + $ hg --config extensions.strip= strip 'desc(commitD)' --debug + resolving manifests + branchmerge: False, force: True, partial: False + ancestor: d8db9d137221+, local: d8db9d137221+, remote: eca11cf91c71 + c: other deleted -> r + removing c + d: other deleted -> r + removing d + 0 files updated, 0 files merged, 2 files removed, 0 files unresolved + 2 changesets found + list of changesets: + 6625a516847449b6f0fa3737b9ba56e9f0f3032c + d8db9d1372214336d2b5570f20ee468d2c72fa8b + saved backup bundle to $TESTTMP/issue4736/.hg/strip-backup/6625a5168474-345bb43d-backup.hg (glob) + invalid branchheads cache (served): tip differs + truncating cache/rbc-revs-v1 to 24 + $ hg log -G + o changeset: 2:5c51d8d6557d + | tag: tip + | user: test + | date: Thu Jan 01 00:00:00 1970 +0000 + | summary: commitC + | + @ changeset: 1:eca11cf91c71 + | user: test + | date: Thu Jan 01 00:00:00 1970 +0000 + | summary: commitB + | + o changeset: 0:105141ef12d0 + user: test + date: Thu Jan 01 00:00:00 1970 +0000 + summary: commitA + + +strip backup content + + $ hg log -r 'bundle()' -R .hg/strip-backup/6625a5168474-*-backup.hg + changeset: 3:6625a5168474 + parent: 1:eca11cf91c71 + user: test + date: Thu Jan 01 00:00:00 1970 +0000 + summary: commitD + + changeset: 4:d8db9d137221 + tag: tip + parent: 2:5c51d8d6557d + parent: 3:6625a5168474 + user: test + date: Thu Jan 01 00:00:00 1970 +0000 + summary: mergeCD + diff --git a/tests/test-transplant.t b/tests/test-transplant.t --- a/tests/test-transplant.t +++ b/tests/test-transplant.t @@ -298,7 +298,7 @@ remote transplant with pull updating to branch default 1 files updated, 0 files merged, 0 files removed, 0 files unresolved $ cd ../rp - $ hg transplant -s http://localhost:$HGPORT/ 2 4 + $ hg transplant -s http://localhost:$HGPORT/ 37a1297eb21b a53251cdf717 searching for changes searching for changes adding changesets @@ -313,10 +313,11 @@ remote transplant with pull 0 r1 remote transplant without pull +(It was using "2" and "4" (as the previous transplant used to) which referenced +revision different from one run to another) $ hg pull -q http://localhost:$HGPORT/ - $ hg transplant -s http://localhost:$HGPORT/ 2 4 - searching for changes + $ hg transplant -s http://localhost:$HGPORT/ 8d9279348abb 722f4667af76 skipping already applied revision 2:8d9279348abb applying 722f4667af76 722f4667af76 transplanted to 76e321915884