# HG changeset patch # User Boris Feld # Date 1495785937 -7200 # Node ID 590da9c523aec6a3219105ff4786104a6ed92816 # Parent cd4290f923b7e17a04e5ea4709d9f7d2b3853986 template: add successors template The successors templates display the closest visible successors of each changeset, we may have gap, like in this case: A -> B -> C -> D If we display A, C and D but not B, we can't display than B is the closest successor of A because it's not displayed. We display C as the closest successor of A instead. diff -r cd4290f923b7 -r 590da9c523ae README --- a/README Fri May 26 10:05:27 2017 +0200 +++ b/README Fri May 26 10:05:37 2017 +0200 @@ -118,6 +118,7 @@ - olog: add an 'obslog' alias - olog: add an '--all' option to show the whole obsolescence history tree. - template: add a 'precursors' template that display the closests precursors of changesets + - template: add a 'successors' template that display the closests successors of changesets 6.2.2 - in progress ------------------- diff -r cd4290f923b7 -r 590da9c523ae hgext3rd/evolve/templatekw.py --- a/hgext3rd/evolve/templatekw.py Fri May 26 10:05:27 2017 +0200 +++ b/hgext3rd/evolve/templatekw.py Fri May 26 10:05:37 2017 +0200 @@ -74,3 +74,107 @@ # XXX: I think we could returns something close to a "changectx" that would allow template to alter the way we render this. shortnodes = map(node.short, sorted(closestprecursors(repo, ctx.node()))) return ', '.join(shortnodes) + +def closestsuccessors(repo, nodeid): + """ returns the closest visible successors sets instead. + """ + return directsuccessorssets(repo, nodeid) + +@eh.templatekw("successors") +def shownextvisiblesuccessors(repo, ctx, templ, **args): + """Returns a string of sets of successors for a changectx in this format: + [ctx1, ctx2], [ctx3] if ctx has been splitted into ctx1 and ctx2 while + also diverged into ctx3""" + if not ctx.obsolete(): + return '' + + ssets = closestsuccessors(repo, ctx.node()) + + final = [] + for ss in ssets: + final.append('[%s]' % ', '.join(map(node.short, ss))) + + return ', '.join(final) + +# copy from mercurial.obsolete with a small change to stop at first known changeset. + +def directsuccessorssets(repo, initialnode, cache=None): + """return set of all direct successors of initial nodes + """ + + succmarkers = repo.obsstore.successors + + # Stack of nodes we search successors sets for + toproceed = [initialnode] + # set version of above list for fast loop detection + # element added to "toproceed" must be added here + stackedset = set(toproceed) + if cache is None: + cache = {} + while toproceed: + current = toproceed[-1] + if current in cache: + stackedset.remove(toproceed.pop()) + elif current != initialnode and current in repo: + # We have a valid direct successors. + cache[current] = [(current,)] + elif current not in succmarkers: + if current in repo: + # We have a valid last successors. + cache[current] = [(current,)] + else: + # Final obsolete version is unknown locally. + # Do not count that as a valid successors + cache[current] = [] + else: + for mark in sorted(succmarkers[current]): + for suc in mark[1]: + if suc not in cache: + if suc in stackedset: + # cycle breaking + cache[suc] = [] + else: + # case (3) If we have not computed successors sets + # of one of those successors we add it to the + # `toproceed` stack and stop all work for this + # iteration. + toproceed.append(suc) + stackedset.add(suc) + break + else: + continue + break + else: + succssets = [] + for mark in sorted(succmarkers[current]): + # successors sets contributed by this marker + markss = [[]] + for suc in mark[1]: + # cardinal product with previous successors + productresult = [] + for prefix in markss: + for suffix in cache[suc]: + newss = list(prefix) + for part in suffix: + # do not duplicated entry in successors set + # first entry wins. + if part not in newss: + newss.append(part) + productresult.append(newss) + markss = productresult + succssets.extend(markss) + # remove duplicated and subset + seen = [] + final = [] + candidate = sorted(((set(s), s) for s in succssets if s), + key=lambda x: len(x[1]), reverse=True) + for setversion, listversion in candidate: + for seenset in seen: + if setversion.issubset(seenset): + break + else: + final.append(listversion) + seen.append(setversion) + final.reverse() # put small successors set first + cache[current] = final + return cache[initialnode] diff -r cd4290f923b7 -r 590da9c523ae tests/test-evolve-templates.t --- a/tests/test-evolve-templates.t Fri May 26 10:05:27 2017 +0200 +++ b/tests/test-evolve-templates.t Fri May 26 10:05:37 2017 +0200 @@ -12,7 +12,7 @@ > [extensions] > evolve = > [alias] - > tlog = log -G -T '{node|short} Precursors: {precursors}\n' + > tlog = log -G -T '{node|short} Precursors: {precursors} | Successors: {successors}\n' > EOF Test templates on amended commit @@ -26,16 +26,21 @@ $ mkcommit ROOT $ mkcommit A0 $ echo 42 >> A0 - $ hg amend -m "A1 - > - > Better commit message" + $ hg amend -m "A1" + $ hg amend -m "A2" $ hg log --hidden -G - @ changeset: 3:4ae3a4151de9 + @ changeset: 4:d004c8f274b9 | tag: tip | parent: 0:ea207398892e | user: test | date: Thu Jan 01 00:00:00 1970 +0000 - | summary: A1 + | summary: A2 + | + | x changeset: 3:a468dc9b3633 + |/ parent: 0:ea207398892e + | user: test + | date: Thu Jan 01 00:00:00 1970 +0000 + | summary: A1 | | x changeset: 2:f137d23bb3e1 | | user: test @@ -57,36 +62,60 @@ $ hg up 'desc(A0)' --hidden 1 files updated, 0 files merged, 0 files removed, 0 files unresolved working directory parent is obsolete! (471f378eab4c) - (use 'hg evolve' to update to its successor: 4ae3a4151de9) + (use 'hg evolve' to update to its successor: d004c8f274b9) + +Precursors template should show current revision as it is the working copy + $ hg tlog + o d004c8f274b9 Precursors: 471f378eab4c | Successors: + | + | @ 471f378eab4c Precursors: | Successors: [d004c8f274b9] + |/ + o ea207398892e Precursors: | Successors: + + $ hg up 'desc(A1)' --hidden + 1 files updated, 0 files merged, 0 files removed, 0 files unresolved + working directory parent is obsolete! (a468dc9b3633) + (use 'hg evolve' to update to its successor: d004c8f274b9) Precursors template should show current revision as it is the working copy $ hg tlog - o 4ae3a4151de9 Precursors: 471f378eab4c + o d004c8f274b9 Precursors: a468dc9b3633 | Successors: | - | @ 471f378eab4c Precursors: + | @ a468dc9b3633 Precursors: | Successors: [d004c8f274b9] |/ - o ea207398892e Precursors: - - $ hg up 'desc(A1)' - 1 files updated, 0 files merged, 0 files removed, 0 files unresolved - -Precursors template should not show a precursor as it's not displayed in the -log - $ hg tlog - @ 4ae3a4151de9 Precursors: - | - o ea207398892e Precursors: + o ea207398892e Precursors: | Successors: Precursors template should show the precursor as we force its display with ---hidden +--hidden $ hg tlog --hidden - @ 4ae3a4151de9 Precursors: 471f378eab4c + o d004c8f274b9 Precursors: a468dc9b3633 | Successors: | - | x f137d23bb3e1 Precursors: + | @ a468dc9b3633 Precursors: 471f378eab4c | Successors: [d004c8f274b9] + |/ + | x f137d23bb3e1 Precursors: | Successors: | | - | x 471f378eab4c Precursors: + | x 471f378eab4c Precursors: | Successors: [a468dc9b3633] |/ - o ea207398892e Precursors: + o ea207398892e Precursors: | Successors: + + + $ hg up 'desc(A2)' + 0 files updated, 0 files merged, 0 files removed, 0 files unresolved + $ hg tlog + @ d004c8f274b9 Precursors: | Successors: + | + o ea207398892e Precursors: | Successors: + + $ hg tlog --hidden + @ d004c8f274b9 Precursors: a468dc9b3633 | Successors: + | + | x a468dc9b3633 Precursors: 471f378eab4c | Successors: [d004c8f274b9] + |/ + | x f137d23bb3e1 Precursors: | Successors: + | | + | x 471f378eab4c Precursors: | Successors: [a468dc9b3633] + |/ + o ea207398892e Precursors: | Successors: Test templates with splitted commit @@ -181,13 +210,13 @@ Precursors template should show current revision as it is the working copy $ hg tlog - o f257fde29c7a Precursors: 471597cad322 + o f257fde29c7a Precursors: 471597cad322 | Successors: | - o 337fec4d2edc Precursors: 471597cad322 + o 337fec4d2edc Precursors: 471597cad322 | Successors: | - | @ 471597cad322 Precursors: + | @ 471597cad322 Precursors: | Successors: [337fec4d2edc, f257fde29c7a] |/ - o ea207398892e Precursors: + o ea207398892e Precursors: | Successors: $ hg up f257fde29c7a 0 files updated, 0 files merged, 0 files removed, 0 files unresolved @@ -195,22 +224,22 @@ Precursors template should not show a precursor as it's not displayed in the log $ hg tlog - @ f257fde29c7a Precursors: + @ f257fde29c7a Precursors: | Successors: | - o 337fec4d2edc Precursors: + o 337fec4d2edc Precursors: | Successors: | - o ea207398892e Precursors: + o ea207398892e Precursors: | Successors: Precursors template should show the precursor as we force its display with --hidden $ hg tlog --hidden - @ f257fde29c7a Precursors: 471597cad322 + @ f257fde29c7a Precursors: 471597cad322 | Successors: | - o 337fec4d2edc Precursors: 471597cad322 + o 337fec4d2edc Precursors: 471597cad322 | Successors: | - | x 471597cad322 Precursors: + | x 471597cad322 Precursors: | Successors: [337fec4d2edc, f257fde29c7a] |/ - o ea207398892e Precursors: + o ea207398892e Precursors: | Successors: Test templates with folded commit ============================== @@ -276,11 +305,11 @@ Precursors template should show current revision as it is the working copy $ hg tlog - o eb5a0daa2192 Precursors: 471f378eab4c + o eb5a0daa2192 Precursors: 471f378eab4c | Successors: | - | @ 471f378eab4c Precursors: + | @ 471f378eab4c Precursors: | Successors: [eb5a0daa2192] |/ - o ea207398892e Precursors: + o ea207398892e Precursors: | Successors: $ hg up 'desc(B0)' --hidden 1 files updated, 0 files merged, 0 files removed, 0 files unresolved @@ -290,13 +319,13 @@ Precursors template should show both precursors as they should be both displayed $ hg tlog - o eb5a0daa2192 Precursors: 0dec01379d3b, 471f378eab4c + o eb5a0daa2192 Precursors: 0dec01379d3b, 471f378eab4c | Successors: | - | @ 0dec01379d3b Precursors: + | @ 0dec01379d3b Precursors: | Successors: [eb5a0daa2192] | | - | x 471f378eab4c Precursors: + | x 471f378eab4c Precursors: | Successors: [eb5a0daa2192] |/ - o ea207398892e Precursors: + o ea207398892e Precursors: | Successors: $ hg up 'desc(C0)' 0 files updated, 0 files merged, 0 files removed, 0 files unresolved @@ -304,20 +333,20 @@ Precursors template should not show precursors as it's not displayed in the log $ hg tlog - @ eb5a0daa2192 Precursors: + @ eb5a0daa2192 Precursors: | Successors: | - o ea207398892e Precursors: + o ea207398892e Precursors: | Successors: Precursors template should show both precursors as we force its display with --hidden $ hg tlog --hidden - @ eb5a0daa2192 Precursors: 0dec01379d3b, 471f378eab4c + @ eb5a0daa2192 Precursors: 0dec01379d3b, 471f378eab4c | Successors: | - | x 0dec01379d3b Precursors: + | x 0dec01379d3b Precursors: | Successors: [eb5a0daa2192] | | - | x 471f378eab4c Precursors: + | x 471f378eab4c Precursors: | Successors: [eb5a0daa2192] |/ - o ea207398892e Precursors: + o ea207398892e Precursors: | Successors: Test templates with divergence @@ -381,6 +410,8 @@ date: Thu Jan 01 00:00:00 1970 +0000 summary: ROOT + $ hg amend -m 'A3' + Check templates --------------- @@ -391,34 +422,36 @@ Precursors template should show current revision as it is the working copy $ hg tlog - o 65b757b745b9 Precursors: 471f378eab4c + o 019fadeab383 Precursors: 471f378eab4c | Successors: | - | o fdf9bde5129a Precursors: 471f378eab4c + | o fdf9bde5129a Precursors: 471f378eab4c | Successors: |/ - | @ 471f378eab4c Precursors: + | @ 471f378eab4c Precursors: | Successors: [fdf9bde5129a], [019fadeab383] |/ - o ea207398892e Precursors: + o ea207398892e Precursors: | Successors: $ hg up 'desc(A1)' 0 files updated, 0 files merged, 0 files removed, 0 files unresolved Precursors template should not show precursors as it's not displayed in the log $ hg tlog - o 65b757b745b9 Precursors: + o 019fadeab383 Precursors: | Successors: | - | @ fdf9bde5129a Precursors: + | @ fdf9bde5129a Precursors: | Successors: |/ - o ea207398892e Precursors: + o ea207398892e Precursors: | Successors: Precursors template should a precursor as we force its display with --hidden $ hg tlog --hidden - o 65b757b745b9 Precursors: 471f378eab4c + o 019fadeab383 Precursors: 65b757b745b9 | Successors: | - | @ fdf9bde5129a Precursors: 471f378eab4c + | x 65b757b745b9 Precursors: 471f378eab4c | Successors: [019fadeab383] |/ - | x 471f378eab4c Precursors: + | @ fdf9bde5129a Precursors: 471f378eab4c | Successors: |/ - o ea207398892e Precursors: + | x 471f378eab4c Precursors: | Successors: [fdf9bde5129a], [65b757b745b9] + |/ + o ea207398892e Precursors: | Successors: Test templates with amended + folded commit =========================================== @@ -495,55 +528,55 @@ working directory parent is obsolete! (471f378eab4c) (use 'hg evolve' to update to its successor: eb5a0daa2192) $ hg tlog - o eb5a0daa2192 Precursors: 471f378eab4c + o eb5a0daa2192 Precursors: 471f378eab4c | Successors: | - | @ 471f378eab4c Precursors: + | @ 471f378eab4c Precursors: | Successors: [eb5a0daa2192] |/ - o ea207398892e Precursors: + o ea207398892e Precursors: | Successors: $ hg up 'desc(B0)' --hidden 1 files updated, 0 files merged, 0 files removed, 0 files unresolved working directory parent is obsolete! (0dec01379d3b) (use 'hg evolve' to update to its successor: eb5a0daa2192) $ hg tlog - o eb5a0daa2192 Precursors: 0dec01379d3b, 471f378eab4c + o eb5a0daa2192 Precursors: 0dec01379d3b, 471f378eab4c | Successors: | - | @ 0dec01379d3b Precursors: + | @ 0dec01379d3b Precursors: | Successors: [eb5a0daa2192] | | - | x 471f378eab4c Precursors: + | x 471f378eab4c Precursors: | Successors: [eb5a0daa2192] |/ - o ea207398892e Precursors: + o ea207398892e Precursors: | Successors: $ hg up 'desc(B1)' --hidden 0 files updated, 0 files merged, 0 files removed, 0 files unresolved working directory parent is obsolete! (b7ea6d14e664) (use 'hg evolve' to update to its successor: eb5a0daa2192) $ hg tlog - o eb5a0daa2192 Precursors: 471f378eab4c, b7ea6d14e664 + o eb5a0daa2192 Precursors: 471f378eab4c, b7ea6d14e664 | Successors: | - | @ b7ea6d14e664 Precursors: + | @ b7ea6d14e664 Precursors: | Successors: [eb5a0daa2192] | | - | x 471f378eab4c Precursors: + | x 471f378eab4c Precursors: | Successors: [eb5a0daa2192] |/ - o ea207398892e Precursors: + o ea207398892e Precursors: | Successors: $ hg up 'desc(C0)' 0 files updated, 0 files merged, 0 files removed, 0 files unresolved $ hg tlog - @ eb5a0daa2192 Precursors: + @ eb5a0daa2192 Precursors: | Successors: | - o ea207398892e Precursors: + o ea207398892e Precursors: | Successors: $ hg tlog --hidden - @ eb5a0daa2192 Precursors: 471f378eab4c, b7ea6d14e664 + @ eb5a0daa2192 Precursors: 471f378eab4c, b7ea6d14e664 | Successors: | - | x b7ea6d14e664 Precursors: 0dec01379d3b + | x b7ea6d14e664 Precursors: 0dec01379d3b | Successors: [eb5a0daa2192] | | - | | x 0dec01379d3b Precursors: + | | x 0dec01379d3b Precursors: | Successors: [b7ea6d14e664] | |/ - | x 471f378eab4c Precursors: + | x 471f378eab4c Precursors: | Successors: [eb5a0daa2192] |/ - o ea207398892e Precursors: + o ea207398892e Precursors: | Successors: Test template with pushed and pulled obs markers @@ -634,23 +667,23 @@ --------------- $ hg tlog - o 7a230b46bf61 Precursors: 471f378eab4c + o 7a230b46bf61 Precursors: 471f378eab4c | Successors: | - | @ 471f378eab4c Precursors: + | @ 471f378eab4c Precursors: | Successors: [7a230b46bf61] |/ - o ea207398892e Precursors: + o ea207398892e Precursors: | Successors: $ hg up 'desc(A2)' 0 files updated, 0 files merged, 0 files removed, 0 files unresolved $ hg tlog - @ 7a230b46bf61 Precursors: + @ 7a230b46bf61 Precursors: | Successors: | - o ea207398892e Precursors: + o ea207398892e Precursors: | Successors: $ hg tlog --hidden - @ 7a230b46bf61 Precursors: 471f378eab4c + @ 7a230b46bf61 Precursors: 471f378eab4c | Successors: | - | x 471f378eab4c Precursors: + | x 471f378eab4c Precursors: | Successors: [7a230b46bf61] |/ - o ea207398892e Precursors: + o ea207398892e Precursors: | Successors: