# HG changeset patch # User Anton Shestakov # Date 1599342328 -28800 # Node ID c706b96c71d8c6fe15417487834343ce31dbdf02 # Parent 868e7bc03b5f7d1ac498ad757f3d327f6e7f8af1# Parent 6a6f243986868987ba1e3818d2655b4a9705f5aa test-compat: merge mercurial-5.1 into mercurial-5.0 diff -r 868e7bc03b5f -r c706b96c71d8 .hgtags --- a/.hgtags Fri Jul 31 18:54:28 2020 +0800 +++ b/.hgtags Sun Sep 06 05:45:28 2020 +0800 @@ -87,3 +87,4 @@ 583dc6ef3eb21fbf6574021136f32b8a1163506c 9.3.0 8d955635cf457aaa4810d77740721d4275001f74 9.3.1 27d57ca8686590867e62e3d42c96bad84a5f56ef 10.0.0 +fb543438704b73b22023a493c9ef76fc8746b796 10.0.1 diff -r 868e7bc03b5f -r c706b96c71d8 CHANGELOG --- a/CHANGELOG Fri Jul 31 18:54:28 2020 +0800 +++ b/CHANGELOG Sun Sep 06 05:45:28 2020 +0800 @@ -1,7 +1,23 @@ Changelog ========= -10.0.1 - in progress +10.0.2 - in progress +-------------------- + + * py3: use '%d' for formatting revision numbers in stable range cache warning + (issue6390) + + * split: correctly handle discard action after previously splitting changes + into more than one commit + + * uncommit: fix situation where added file would be left in a wrong state + +topic (0.19.2) + + * revset: when processing `topic(REVSET)`, no longer return changesets + without topic from REVSET + +10.0.1 -- 2020-07-31 -------------------- * compatibility with Mercurial 5.5 diff -r 868e7bc03b5f -r c706b96c71d8 debian/changelog --- a/debian/changelog Fri Jul 31 18:54:28 2020 +0800 +++ b/debian/changelog Sun Sep 06 05:45:28 2020 +0800 @@ -1,3 +1,9 @@ +mercurial-evolve (10.0.1-1) unstable; urgency=medium + + * new upstream release + + -- Anton Shestakov Fri, 31 Jul 2020 19:44:25 +0800 + mercurial-evolve (10.0.0-1) unstable; urgency=medium * new upstream release diff -r 868e7bc03b5f -r c706b96c71d8 hgext3rd/evolve/cmdrewrite.py --- a/hgext3rd/evolve/cmdrewrite.py Fri Jul 31 18:54:28 2020 +0800 +++ b/hgext3rd/evolve/cmdrewrite.py Sun Sep 06 05:45:28 2020 +0800 @@ -341,100 +341,49 @@ newid = repo.commitctx(new) return newid -def _uncommitdirstate(repo, oldctx, match, interactive): - """Fix the dirstate after switching the working directory from - oldctx to a copy of oldctx not containing changed files matched by - match. +# TODO: call core's version once we've dropped support for hg <= 4.9 +def movedirstate(repo, newctx, match=None): + """Move the dirstate to newctx and adjust it as necessary. + + A matcher can be provided as an optimization. It is probably a bug to pass + a matcher that doesn't match all the differences between the parent of the + working copy and newctx. """ - ctx = repo[b'.'] + oldctx = repo[b'.'] ds = repo.dirstate - copies = dict(ds.copies()) - if interactive: - # In interactive cases, we will find the status between oldctx and ctx - # and considering only the files which are changed between oldctx and - # ctx, and the status of what changed between oldctx and ctx will help - # us in defining the exact behavior - st = repo.status(oldctx, ctx, match=match) - for f in st.modified: - # These are files which are modified between oldctx and ctx which - # contains two cases: 1) Were modified in oldctx and some - # modifications are uncommitted - # 2) Were added in oldctx but some part is uncommitted (this cannot - # contain the case when added files are uncommitted completely as - # that will result in status as removed not modified.) - # Also any modifications to a removed file will result the status as - # added, so we have only two cases. So in either of the cases, the - # resulting status can be modified or clean. - if ds[f] == b'r': - # But the file is removed in the working directory, leaving that - # as removed - continue + dscopies = dict(ds.copies()) + ds.setparents(newctx.node(), node.nullid) + s = newctx.status(oldctx, match=match) + for f in s.modified: + if ds[f] == b'r': + # modified + removed -> removed + continue + ds.normallookup(f) + + for f in s.added: + if ds[f] == b'r': + # added + removed -> unknown + ds.drop(f) + elif ds[f] != b'a': + ds.add(f) + + for f in s.removed: + if ds[f] == b'a': + # removed + added -> normal ds.normallookup(f) - - for f in st.added: - # These are the files which are added between oldctx and ctx(new - # one), which means the files which were removed in oldctx - # but uncommitted completely while making the ctx - # This file should be marked as removed if the working directory - # does not adds it back. If it's adds it back, we do a normallookup. - # The file can't be removed in working directory, because it was - # removed in oldctx - if ds[f] == b'a': - ds.normallookup(f) - continue + elif ds[f] != b'r': ds.remove(f) - for f in st.removed: - # These are files which are removed between oldctx and ctx, which - # means the files which were added in oldctx and were completely - # uncommitted in ctx. If a added file is partially uncommitted, that - # would have resulted in modified status, not removed. - # So a file added in a commit, and uncommitting that addition must - # result in file being stated as unknown. - if ds[f] == b'r': - # The working directory say it's removed, so lets make the file - # unknown - ds.drop(f) - continue - ds.add(f) - else: - st = repo.status(oldctx.p1(), oldctx, match=match) - for f in st.modified: - if ds[f] == b'r': - # modified + removed -> removed - continue - ds.normallookup(f) - - for f in st.added: - if ds[f] == b'r': - # added + removed -> unknown - ds.drop(f) - elif ds[f] != b'a': - ds.add(f) - - for f in st.removed: - if ds[f] == b'a': - # removed + added -> normal - ds.normallookup(f) - elif ds[f] != b'r': - ds.remove(f) - # Merge old parent and old working dir copies - oldcopies = {} - if interactive: - # Interactive had different meaning of the variables so restoring the - # original meaning to use them - st = repo.status(oldctx.p1(), oldctx, match=match) - for f in (st.modified + st.added): - src = oldctx[f].renamed() - if src: - oldcopies[f] = src[0] - oldcopies.update(copies) - copies = dict((dst, oldcopies.get(src, src)) - for dst, src in oldcopies.items()) + oldcopies = copies.pathcopies(newctx, oldctx, match) + oldcopies.update(dscopies) + newcopies = { + dst: oldcopies.get(src, src) + for dst, src in oldcopies.items() + } # Adjust the dirstate copies - for dst, src in copies.items(): - if (src not in ctx or dst in ctx or ds[dst] != b'a'): + for dst, src in newcopies.items(): + if src not in newctx or dst in newctx or ds[dst] != b'a': src = None ds.copy(src, dst) @@ -567,8 +516,7 @@ hg.updaterepo(repo, newid, True) else: with repo.dirstate.parentchange(), compat.parentchange(repo): - repo.dirstate.setparents(newid, node.nullid) - _uncommitdirstate(repo, old, match, interactive) + movedirstate(repo, repo[newid], match) if not repo[newid].files(): ui.warn(_(b"new changeset is empty\n")) ui.status(_(b"(use 'hg prune .' to remove it)\n")) @@ -1307,7 +1255,13 @@ # diff action or by showing the remaining and # prompting for confirmation ui.status(_(b'discarding remaining changes\n')) - target = newcommits[0] + target = newcommits[-1] + args = [] + kwargs = {} + code = cmdutil.revert.__code__ + # hg <= 5.5 (8c466bcb0879) + if r'parents' in code.co_varnames[:code.co_argcount]: + args.append((target, node.nullid)) if pats: status = repo.status(match=matcher) dirty = set() @@ -1315,12 +1269,10 @@ dirty.update(status.added) dirty.update(status.removed) dirty.update(status.deleted) - dirty = sorted(dirty) - cmdutil.revert(ui, repo, repo[target], - (target, node.nullid), *dirty) + args += sorted(dirty) else: - cmdutil.revert(ui, repo, repo[target], - (target, node.nullid), all=True) + kwargs[r'all'] = True + cmdutil.revert(ui, repo, repo[target], *args, **kwargs) elif nextaction == b'?': nextaction = None ui.write(_(b"y - yes, continue selection\n")) diff -r 868e7bc03b5f -r c706b96c71d8 hgext3rd/evolve/evolvecmd.py --- a/hgext3rd/evolve/evolvecmd.py Fri Jul 31 18:54:28 2020 +0800 +++ b/hgext3rd/evolve/evolvecmd.py Sun Sep 06 05:45:28 2020 +0800 @@ -642,8 +642,7 @@ otherdiv = repo[othernode] with repo.dirstate.parentchange(), compat.parentchange(repo): - repo.dirstate.setparents(publicnode, nodemod.nullid) - dirstatedance(repo, divergent, publicnode, None) + cmdrewrite.movedirstate(repo, repo[publicnode]) # check if node to be committed has changes same as public one s = publicdiv.status() if not (s.added or s.removed or s.deleted or s.modified): @@ -655,9 +654,7 @@ return (True, publicnode) with repo.dirstate.parentchange(), compat.parentchange(repo): - repo.dirstate.setparents(resparent, nodemod.nullid) - - dirstatedance(repo, divergent, resparent, None) + cmdrewrite.movedirstate(repo, repo[resparent]) # merge the branches mergebranches(repo, divergent, other, base) @@ -798,73 +795,6 @@ metadata=metadata, ui=repo.ui) repo.filteredrevcache.clear() -def dirstatedance(repo, oldparent, newparent, match): - """utility function to fix the dirstate when we change parents from - oldparent to newparent with a dirty working directory using - repo.dirstate.setparents() - - Lets refer oldparent as Pold - newparent as Pnew - - Now when we are on oldparent with a dirty working directory, there are three - types of files which we are concerned about. They are files having modified, - added and removed status. - - Lets refer modified files as Fm - added files as Fa - removed files as Fr - - Now, between Pold and Pnew, files can be modified, files can be added, files - can be removed. - - Lets refer modification of a file between Pold to Pnew as Cm - addition of a file between Pold to Pnew as Ca - removal of a file between Pold to Pnew as Cr - - Now let's play combinations and permutations: - - |---------------------------------------------------------------| - | Type of file | Changes between | End status with Pnew as | - | in wdir | Pold -> Pnew | wdir parent | - |--------------|------------------|-----------------------------| - | | | | - | Fm | Cm | Modified or clean | - |--------------|------------------|-----------------------------| - | Fm | Cr | Added | - |--------------|------------------|-----------------------------| - | Fm | Ca | Not possible (1) | - |--------------|------------------|-----------------------------| - | Fa | Ca | Modified or clean | - |--------------|------------------|-----------------------------| - | Fa | Cm | Not possible (2) | - |--------------|------------------|-----------------------------| - | Fa | Cr | Not possible (2) | - |--------------|------------------|-----------------------------| - | Fr | Cr | File should be untracked (3)| - |--------------|------------------|-----------------------------| - | Fr | Ca | Not possible (4) | - |--------------|------------------|-----------------------------| - | Fr | Cm | Removed | - |--------------|------------------|-----------------------------| - - (1): File is modified in wdir, it means file was present in Pold, so - addition of that file between Pold to Pnew is not possible - - (2): File was added in wdir, it means file was not present in Pold, so - deletion or modification of that file from Pold to Pnew is not possible - - (3): File should be dropped from the dirstate, Pnew has it removed, so no - need to mark that removed again - - (4): File was removed in wdir, it means file was present in Pold, so - addition of that file between Pold to Pnew is not possible - - """ - - # falling back to an existing function, in future we should have logic in - # this function only - cmdrewrite._uncommitdirstate(repo, oldparent, match, True) - def mergehook(repo, base, divergent, other): """function which extensions can wrap and merge data introduced by them while resolving content-divergence""" diff -r 868e7bc03b5f -r c706b96c71d8 hgext3rd/evolve/metadata.py --- a/hgext3rd/evolve/metadata.py Fri Jul 31 18:54:28 2020 +0800 +++ b/hgext3rd/evolve/metadata.py Sun Sep 06 05:45:28 2020 +0800 @@ -5,7 +5,7 @@ # This software may be used and distributed according to the terms of the # GNU General Public License version 2 or any later version. -__version__ = b'10.0.1.dev' -testedwith = b'4.6.2 4.7 4.8 4.9 5.0 5.1 5.2 5.3 5.4' +__version__ = b'10.0.2.dev' +testedwith = b'4.6.2 4.7 4.8 4.9 5.0 5.1 5.2 5.3 5.4 5.5' minimumhgversion = b'4.6' buglink = b'https://bz.mercurial-scm.org/' diff -r 868e7bc03b5f -r c706b96c71d8 hgext3rd/evolve/rewind.py --- a/hgext3rd/evolve/rewind.py Fri Jul 31 18:54:28 2020 +0800 +++ b/hgext3rd/evolve/rewind.py Sun Sep 06 05:45:28 2020 +0800 @@ -151,8 +151,14 @@ revertopts = {'no_backup': True, 'all': True, 'rev': oldctx.node()} with ui.configoverride({(b'ui', b'quiet'): True}): - cmdutil.revert(repo.ui, repo, oldctx, - repo.dirstate.parents(), **revertopts) + code = cmdutil.revert.__code__ + # hg <= 5.5 (8c466bcb0879) + if r'parents' in code.co_varnames[:code.co_argcount]: + cmdutil.revert(repo.ui, repo, oldctx, + repo.dirstate.parents(), + **revertopts) + else: + cmdutil.revert(repo.ui, repo, oldctx, **revertopts) else: hg.updaterepo(repo, update_target, False) diff -r 868e7bc03b5f -r c706b96c71d8 hgext3rd/evolve/stablerangecache.py --- a/hgext3rd/evolve/stablerangecache.py Fri Jul 31 18:54:28 2020 +0800 +++ b/hgext3rd/evolve/stablerangecache.py Sun Sep 06 05:45:28 2020 +0800 @@ -335,7 +335,7 @@ # to add. This will confuse sqlite msg = _(b'stable-range cache: skipping write, ' b'database drifted under my feet\n') - hint = _(b'(disk: %s-%s vs mem: %s-%s)\n') + hint = _(b'(disk: %s-%d vs mem: %s-%d)\n') data = (nodemod.hex(meta[2]), meta[1], nodemod.hex(self._ondisktipnode), self._ondisktiprev) repo.ui.warn(msg) diff -r 868e7bc03b5f -r c706b96c71d8 hgext3rd/pullbundle.py --- a/hgext3rd/pullbundle.py Fri Jul 31 18:54:28 2020 +0800 +++ b/hgext3rd/pullbundle.py Sun Sep 06 05:45:28 2020 +0800 @@ -93,9 +93,9 @@ from mercurial.i18n import _ -__version__ = b'0.1.1' -testedwith = b'4.4 4.5 4.6 4.7.1' -minimumhgversion = b'4.4' +__version__ = b'0.1.3.dev' +testedwith = b'4.6.2 4.7 4.8 4.9 5.0 5.1 5.2 5.3 5.4 5.5' +minimumhgversion = b'4.6' buglink = b'https://bz.mercurial-scm.org/' cmdtable = {} diff -r 868e7bc03b5f -r c706b96c71d8 hgext3rd/topic/__init__.py --- a/hgext3rd/topic/__init__.py Fri Jul 31 18:54:28 2020 +0800 +++ b/hgext3rd/topic/__init__.py Sun Sep 06 05:45:28 2020 +0800 @@ -202,9 +202,9 @@ b'topic.active': b'green', } -__version__ = b'0.19.1.dev' +__version__ = b'0.19.2.dev' -testedwith = b'4.6.2 4.7 4.8 4.9 5.0 5.1 5.2 5.3 5.4' +testedwith = b'4.6.2 4.7 4.8 4.9 5.0 5.1 5.2 5.3 5.4 5.5' minimumhgversion = b'4.6' buglink = b'https://bz.mercurial-scm.org/' diff -r 868e7bc03b5f -r c706b96c71d8 hgext3rd/topic/revset.py --- a/hgext3rd/topic/revset.py Fri Jul 31 18:54:28 2020 +0800 +++ b/hgext3rd/topic/revset.py Sun Sep 06 05:45:28 2020 +0800 @@ -67,8 +67,6 @@ topics.discard(b'') def matches(r): - if r in s: - return True topic = repo[r].topic() if not topic: return False diff -r 868e7bc03b5f -r c706b96c71d8 tests/test-split.t --- a/tests/test-split.t Fri Jul 31 18:54:28 2020 +0800 +++ b/tests/test-split.t Sun Sep 06 05:45:28 2020 +0800 @@ -1239,3 +1239,81 @@ @@ -0,0 +1,1 @@ +a + $ cd .. + +Discard after splitting into more than one changeset + + $ hg init discard-after-many + $ cd discard-after-many + + $ echo 0 > num + $ cat > editor.sh << '__EOF__' + > NUM=$(cat num) + > NUM=`expr "$NUM" + 1` + > echo "$NUM" > num + > echo "split$NUM" > "$1" + > __EOF__ + $ export HGEDITOR="\"sh\" \"editor.sh\"" + + $ echo a > a + $ echo b > b + $ echo c > c + $ hg add a b c + $ hg ci -m 'a b c' + +XXX: this shouldn't ask to re-examine changes in b and definitely shouldn't revert b + + $ hg split << EOF + > f + > d + > y + > f + > d + > d + > EOF + 0 files updated, 0 files merged, 3 files removed, 0 files unresolved + adding a + adding b + adding c + diff --git a/a b/a + new file mode 100644 + examine changes to 'a'? [Ynesfdaq?] f + + diff --git a/b b/b + new file mode 100644 + examine changes to 'b'? [Ynesfdaq?] d + + created new head + (consider using topic for lightweight branches. See 'hg help topic') + continue splitting? [Ycdq?] y + diff --git a/b b/b + new file mode 100644 + examine changes to 'b'? [Ynesfdaq?] f + + diff --git a/c b/c + new file mode 100644 + examine changes to 'c'? [Ynesfdaq?] d + + continue splitting? [Ycdq?] d + discarding remaining changes + forgetting c + + $ hg glog -p + @ 2:c2c6f4d8c766 split2 (draft) + | diff --git a/b b/b + | new file mode 100644 + | --- /dev/null + | +++ b/b + | @@ -0,0 +1,1 @@ + | +b + | + o 1:fb91c6249a20 split1 (draft) + diff --git a/a b/a + new file mode 100644 + --- /dev/null + +++ b/a + @@ -0,0 +1,1 @@ + +a + + + $ cd .. diff -r 868e7bc03b5f -r c706b96c71d8 tests/test-topic.t --- a/tests/test-topic.t Fri Jul 31 18:54:28 2020 +0800 +++ b/tests/test-topic.t Sun Sep 06 05:45:28 2020 +0800 @@ -750,12 +750,18 @@ fran (1 changesets) $ hg log -r 'topic(.)' (no output is expected) + + $ hg up 8 + 1 files updated, 0 files merged, 0 files removed, 0 files unresolved + $ echo test > gamma + $ hg ci -m non-topic + $ hg log -r 'topic(.)' + $ hg co fran switching to topic fran - 2 files updated, 0 files merged, 0 files removed, 0 files unresolved + 3 files updated, 0 files merged, 0 files removed, 0 files unresolved $ hg log -r 'topic(.)' changeset: 9:0469d521db49 - tag: tip topic: fran parent: 3:a53952faf762 user: test @@ -801,19 +807,26 @@ created new head (consider using topic for lightweight branches. See 'hg help topic') $ hg log -Gr 'draft()' - @ changeset: 10:4073470c35e1 + @ changeset: 11:4073470c35e1 | tag: tip + | parent: 9:0469d521db49 | user: test | date: Thu Jan 01 00:00:00 1970 +0000 | summary: fran? | - o changeset: 9:0469d521db49 - | topic: fran - | parent: 3:a53952faf762 - | user: test - | date: Thu Jan 01 00:00:00 1970 +0000 - | summary: start on fran - | + | o changeset: 10:de75ec1bdbe8 + | | parent: 8:ae074045b7a7 + | | user: test + | | date: Thu Jan 01 00:00:00 1970 +0000 + | | summary: non-topic + | | + o | changeset: 9:0469d521db49 + | | topic: fran + | | parent: 3:a53952faf762 + | | user: test + | | date: Thu Jan 01 00:00:00 1970 +0000 + | | summary: start on fran + | | $ hg topics fran (1 changesets) diff -r 868e7bc03b5f -r c706b96c71d8 tests/test-uncommit.t --- a/tests/test-uncommit.t Fri Jul 31 18:54:28 2020 +0800 +++ b/tests/test-uncommit.t Sun Sep 06 05:45:28 2020 +0800 @@ -355,6 +355,8 @@ $ hg cat b --rev 0 b: no such file in rev 07f494440405 [1] + $ hg status + A aa $ hg uncommit --rev . b abort: cannot uncommit to parent changeset [255] @@ -362,6 +364,9 @@ $ hg cat b --rev . b: no such file in rev 5b27f6b17da2 [1] + $ hg status + A aa + A b Test uncommiting predecessors @@ -421,9 +426,9 @@ R m R n $ hg status + M b M d A aa - R b $ hg amend --extract j $ hg status --change . M o @@ -438,10 +443,10 @@ R m R n $ hg status + M b M d M j A aa - R b (with all) @@ -450,6 +455,7 @@ (use 'hg prune .' to remove it) $ hg status --change . $ hg status + M b M d M j M o @@ -459,7 +465,6 @@ A h A k A l - R b R c R f R g @@ -472,11 +477,10 @@ $ hg amend $ hg status - ? b $ hg diff -c . --stat aa | 1 + - b | 1 - + b | 1 + c | 1 - d | 1 + e | 1 + @@ -490,7 +494,7 @@ m | 1 - n | 1 - o | 1 + - 15 files changed, 9 insertions(+), 6 deletions(-) + 15 files changed, 10 insertions(+), 5 deletions(-) $ hg uncommit --revert --all new changeset is empty (use 'hg prune .' to remove it)