Patchwork [4,of,9] template: add minimal obsfate template

login
register
mail settings
Submitter Boris Feld
Date July 6, 2017, 9:50 p.m.
Message ID <7fba236b2b17fd83a6b6.1499377812@FB>
Download mbox | patch
Permalink /patch/22048/
State Changes Requested, archived
Headers show

Comments

Boris Feld - July 6, 2017, 9:50 p.m.
# HG changeset patch
# User Boris Feld <boris.feld@octobus.net>
# Date 1499176225 -7200
#      Tue Jul 04 15:50:25 2017 +0200
# Node ID 7fba236b2b17fd83a6b6446aaa84b14c65820aee
# Parent  7e5752579378680270dd356f4e56fd7795109c5d
# EXP-Topic obsfatetemplate
template: add minimal obsfate template

Obsfate is a template that display each changeset evolved in a clean and
human-readable way.

Introduce an obsfateprinter that display only the successors for the moment.
More informations will be added later.

We don't use _hybrid objects nor the templating engine yet as it introduce much
more complexity and some hacks. The tail of the series will replace
obsfateprinter by _hybrid objects.
Jun Wu - July 7, 2017, 12:05 a.m.
I'm not a big fan of this obsfate template approach. Ideally we could
extract information from an obsmarker using templates. Something like
"{marker.user} {marker.operation} {marker.xxxx}". That's much more flexible
and could work with colors trivially. The current template is binded to a
ctx. We could define some functions or introduce special synctax to make it
bind to an obsmarker.

Excerpts from Boris Feld's message of 2017-07-06 23:50:12 +0200:
> # HG changeset patch
> # User Boris Feld <boris.feld@octobus.net>
> # Date 1499176225 -7200
> #      Tue Jul 04 15:50:25 2017 +0200
> # Node ID 7fba236b2b17fd83a6b6446aaa84b14c65820aee
> # Parent  7e5752579378680270dd356f4e56fd7795109c5d
> # EXP-Topic obsfatetemplate
> template: add minimal obsfate template
> 
> Obsfate is a template that display each changeset evolved in a clean and
> human-readable way.
> 
> Introduce an obsfateprinter that display only the successors for the moment.
> More informations will be added later.
> 
> We don't use _hybrid objects nor the templating engine yet as it introduce much
> more complexity and some hacks. The tail of the series will replace
> obsfateprinter by _hybrid objects.
> 
> diff -r 7e5752579378 -r 7fba236b2b17 mercurial/obsutil.py
> --- a/mercurial/obsutil.py    Mon Jul 03 03:27:58 2017 +0200
> +++ b/mercurial/obsutil.py    Tue Jul 04 15:50:25 2017 +0200
> @@ -8,6 +8,7 @@
>  from __future__ import absolute_import
>  
>  from . import (
> +    node as nodemod,
>      phases,
>  )
>  
> @@ -551,3 +552,46 @@
>                  final.reverse() # put small successors set first
>                  cache[current] = final
>      return cache[initialnode]
> +
> +def preparesuccessorset(successorset, rawmarkers):
> +    """ For a successor set, get all related markers and convert every nodeid
> +    into its hexadecimal form.
> +    """
> +    hex = nodemod.hex
> +
> +    successorset = [hex(n) for n in successorset]
> +
> +    # hex the binary nodes in the markers
> +    markers = []
> +    for m in rawmarkers:
> +        hexprec = hex(m[0])
> +        hexsucs = tuple(hex(n) for n in m[1])
> +        hexparents = None
> +        if m[5] is not None:
> +            hexparents = tuple(hex(n) for n in m[5])
> +        newmarker = (hexprec, hexsucs) + m[2:5] + (hexparents,) + m[6:]
> +        markers.append(newmarker)
> +
> +    # Format basic data
> +    data = {
> +        "successors": sorted(successorset),
> +        "markers": sorted(markers)
> +    }
> +
> +    return data
> +
> +def obsfatedata(repo, ctx):
> +    """compute the raw data needed for computing obsfate
> +    Returns a list of dict, one dict per successors set
> +    """
> +    if not ctx.obsolete():
> +        return None
> +
> +    ssets = successorssets(repo, ctx.node(), closest=True)
> +
> +    values = []
> +    for sset in ssets:
> +        raw = preparesuccessorset(sset, sset.markers)
> +        values.append(raw)
> +
> +    return values
> diff -r 7e5752579378 -r 7fba236b2b17 mercurial/templatekw.py
> --- a/mercurial/templatekw.py    Mon Jul 03 03:27:58 2017 +0200
> +++ b/mercurial/templatekw.py    Tue Jul 04 15:50:25 2017 +0200
> @@ -634,6 +634,57 @@
>      return _hybrid(gen(data), data, lambda x: {'successorset': x},
>                     lambda d: d["successorset"])
>  
> +def _obsfatelineprinter(obsfateline, repo, ui):
> +    """Format and display obsfate related data
> +    """
> +    quiet = ui.quiet
> +    verbose = ui.verbose
> +    normal = not verbose and not quiet
> +
> +    # Build the line step by step
> +    line = []
> +
> +    # Verb
> +    line.append("rewritten")
> +
> +    # Successors
> +    successors = obsfateline["successors"]
> +
> +    if successors:
> +        fmtsuccessors = map(lambda s: _formatrevnode(repo[s]), successors)
> +        line.append(" as %s" % ", ".join(fmtsuccessors))
> +
> +    return "".join(line)
> +
> +def _obsfateprinter(obsfate, repo, ui, prefix=""):
> +    """Generate a human-readable line per successorset of a changeset
> +    """
> +    lines = []
> +    for raw in obsfate:
> +        lines.append(_obsfatelineprinter(raw, repo, ui))
> +
> +    if prefix:
> +        lines = [prefix + line for line in lines]
> +
> +    return "; ".join(lines)
> +
> +@templatekeyword("obsfate")
> +def showobsfate(repo, ctx, **args):
> +    """Returns a string describing how an obsolete changeset has evolved in a
> +    human-readable format.
> +
> +    This line will contains these information:
> +    - The list of closest successors in the log output
> +    """
> +
> +    # Get the needed obsfate data
> +    values = obsutil.obsfatedata(repo, ctx)
> +
> +    if values is None:
> +        return ''
> +
> +    return _obsfateprinter(values, repo, repo.ui)
> +
>  @templatekeyword('p1rev')
>  def showp1rev(repo, ctx, templ, **args):
>      """Integer. The repository-local revision number of the changeset's
> diff -r 7e5752579378 -r 7fba236b2b17 tests/test-obsmarker-template.t
> --- a/tests/test-obsmarker-template.t    Mon Jul 03 03:27:58 2017 +0200
> +++ b/tests/test-obsmarker-template.t    Tue Jul 04 15:50:25 2017 +0200
> @@ -20,6 +20,7 @@
>    >     {if(successorssets, "\n  Successors: {successorssets}")}\
>    >     {if(successorssets, "\n  multi-line: {join(successorssets, "\n  multi-line: ")}")}\
>    >     {if(successorssets, "\n  json: {successorssets|json}")}\n'
> +  > fatelog = log -G -T '{node|short}\n{if(obsfate, "  Obsfate: {obsfate}\n")}'
>    > EOF
>  
>  Test templates on amended commit
> @@ -33,8 +34,8 @@
>    $ mkcommit ROOT
>    $ mkcommit A0
>    $ echo 42 >> A0
> -  $ hg commit --amend -m "A1"
> -  $ hg commit --amend -m "A2"
> +  $ HGUSER=test1 hg commit --amend -m "A1" --config devel.default-date="1234567890 0"
> +  $ HGUSER=test2 hg commit --amend -m "A2" --config devel.default-date="987654321 0"
>  
>    $ hg log --hidden -G
>    @  changeset:   4:d004c8f274b9
> @@ -83,6 +84,27 @@
>    |      json: [["d004c8f274b9ec480a47a93c10dac5eee63adb78"]]
>    o  ea207398892e
>    
> +  $ hg fatelog -q
> +  o  d004c8f274b9
> +  |
> +  | @  471f378eab4c
> +  |/     Obsfate: rewritten as 4:d004c8f274b9
> +  o  ea207398892e
> +  
> +  $ hg fatelog
> +  o  d004c8f274b9
> +  |
> +  | @  471f378eab4c
> +  |/     Obsfate: rewritten as 4:d004c8f274b9
> +  o  ea207398892e
> +  
> +  $ hg fatelog -v
> +  o  d004c8f274b9
> +  |
> +  | @  471f378eab4c
> +  |/     Obsfate: rewritten as 4:d004c8f274b9
> +  o  ea207398892e
> +  
>    $ hg up 'desc(A1)' --hidden
>    1 files updated, 0 files merged, 0 files removed, 0 files unresolved
>  
> @@ -99,6 +121,13 @@
>    |      json: [["d004c8f274b9ec480a47a93c10dac5eee63adb78"]]
>    o  ea207398892e
>    
> +  $ hg fatelog -v
> +  o  d004c8f274b9
> +  |
> +  | @  a468dc9b3633
> +  |/     Obsfate: rewritten as 4:d004c8f274b9
> +  o  ea207398892e
> +  
>  Predecessors template should show all the predecessors as we force their display
>  with --hidden
>    $ hg tlog --hidden
> @@ -123,6 +152,17 @@
>    |      json: [["a468dc9b36338b14fdb7825f55ce3df4e71517ad"]]
>    o  ea207398892e
>    
> +  $ hg fatelog --hidden -q
> +  o  d004c8f274b9
> +  |
> +  | @  a468dc9b3633
> +  |/     Obsfate: rewritten as 4:d004c8f274b9
> +  | x  f137d23bb3e1
> +  | |
> +  | x  471f378eab4c
> +  |/     Obsfate: rewritten as 3:a468dc9b3633
> +  o  ea207398892e
> +  
>  
>  Predecessors template shouldn't show anything as all obsolete commit are not
>  visible.
> @@ -155,6 +195,23 @@
>    |      json: [["a468dc9b36338b14fdb7825f55ce3df4e71517ad"]]
>    o  ea207398892e
>    
> +  $ hg fatelog -v
> +  @  d004c8f274b9
> +  |
> +  o  ea207398892e
> +  
> +
> +  $ hg fatelog -v --hidden
> +  @  d004c8f274b9
> +  |
> +  | x  a468dc9b3633
> +  |/     Obsfate: rewritten as 4:d004c8f274b9
> +  | x  f137d23bb3e1
> +  | |
> +  | x  471f378eab4c
> +  |/     Obsfate: rewritten as 3:a468dc9b3633
> +  o  ea207398892e
> +  
>  
>  Test templates with splitted commit
>  ===================================
> @@ -238,6 +295,16 @@
>    |      json: [["337fec4d2edcf0e7a467e35f818234bc620068b5", "f257fde29c7a847c9b607f6e958656d0df0fb15c"]]
>    o  ea207398892e
>    
> +
> +  $ hg fatelog
> +  o  f257fde29c7a
> +  |
> +  o  337fec4d2edc
> +  |
> +  | @  471597cad322
> +  |/     Obsfate: rewritten as 2:337fec4d2edc, 3:f257fde29c7a
> +  o  ea207398892e
> +  
>    $ hg up f257fde29c7a
>    0 files updated, 0 files merged, 0 files removed, 0 files unresolved
>  
> @@ -269,6 +336,16 @@
>    |      json: [["337fec4d2edcf0e7a467e35f818234bc620068b5", "f257fde29c7a847c9b607f6e958656d0df0fb15c"]]
>    o  ea207398892e
>    
> +
> +  $ hg fatelog --hidden
> +  @  f257fde29c7a
> +  |
> +  o  337fec4d2edc
> +  |
> +  | x  471597cad322
> +  |/     Obsfate: rewritten as 2:337fec4d2edc, 3:f257fde29c7a
> +  o  ea207398892e
> +  
>  Test templates with folded commit
>  =================================
>  
> @@ -351,6 +428,14 @@
>    |      json: [["eb5a0daa21923bbf8caeb2c42085b9e463861fd0"]]
>    o  ea207398892e
>    
> +
> +  $ hg fatelog
> +  o  eb5a0daa2192
> +  |
> +  | @  471f378eab4c
> +  |/     Obsfate: rewritten as 3:eb5a0daa2192
> +  o  ea207398892e
> +  
>    $ hg up 'desc(B0)' --hidden
>    1 files updated, 0 files merged, 0 files removed, 0 files unresolved
>  
> @@ -372,6 +457,16 @@
>    |      json: [["eb5a0daa21923bbf8caeb2c42085b9e463861fd0"]]
>    o  ea207398892e
>    
> +
> +  $ hg fatelog
> +  o  eb5a0daa2192
> +  |
> +  | @  0dec01379d3b
> +  | |    Obsfate: rewritten as 3:eb5a0daa2192
> +  | x  471f378eab4c
> +  |/     Obsfate: rewritten as 3:eb5a0daa2192
> +  o  ea207398892e
> +  
>    $ hg up 'desc(C0)'
>    0 files updated, 0 files merged, 0 files removed, 0 files unresolved
>  
> @@ -401,6 +496,15 @@
>    o  ea207398892e
>    
>  
> +  $ hg fatelog --hidden
> +  @  eb5a0daa2192
> +  |
> +  | x  0dec01379d3b
> +  | |    Obsfate: rewritten as 3:eb5a0daa2192
> +  | x  471f378eab4c
> +  |/     Obsfate: rewritten as 3:eb5a0daa2192
> +  o  ea207398892e
> +  
>  Test templates with divergence
>  ==============================
>  
> @@ -518,6 +622,15 @@
>    |      json: [["fdf9bde5129a28d4548fadd3f62b265cdd3b7a2e"], ["019fadeab383f6699fa83ad7bdb4d82ed2c0e5ab"]]
>    o  ea207398892e
>    
> +  $ hg fatelog
> +  o  019fadeab383
> +  |
> +  | o  fdf9bde5129a
> +  |/
> +  | @  471f378eab4c
> +  |/     Obsfate: rewritten as 2:fdf9bde5129a; rewritten as 4:019fadeab383
> +  o  ea207398892e
> +  
>    $ hg up 'desc(A1)'
>    0 files updated, 0 files merged, 0 files removed, 0 files unresolved
>  
> @@ -530,6 +643,14 @@
>    |/
>    o  ea207398892e
>    
> +
> +  $ hg fatelog
> +  o  019fadeab383
> +  |
> +  | @  fdf9bde5129a
> +  |/
> +  o  ea207398892e
> +  
>  Predecessors template should the predecessors as we force their display with
>  --hidden
>    $ hg tlog --hidden
> @@ -559,6 +680,17 @@
>    o  ea207398892e
>    
>  
> +  $ hg fatelog --hidden
> +  o  019fadeab383
> +  |
> +  | x  65b757b745b9
> +  |/     Obsfate: rewritten as 4:019fadeab383
> +  | @  fdf9bde5129a
> +  |/
> +  | x  471f378eab4c
> +  |/     Obsfate: rewritten as 2:fdf9bde5129a; rewritten as 3:65b757b745b9
> +  o  ea207398892e
> +  
>  Test templates with amended + folded commit
>  ===========================================
>  
> @@ -654,6 +786,14 @@
>    |      json: [["eb5a0daa21923bbf8caeb2c42085b9e463861fd0"]]
>    o  ea207398892e
>    
> +
> +  $ hg fatelog
> +  o  eb5a0daa2192
> +  |
> +  | @  471f378eab4c
> +  |/     Obsfate: rewritten as 4:eb5a0daa2192
> +  o  ea207398892e
> +  
>    $ hg up 'desc(B0)' --hidden
>    1 files updated, 0 files merged, 0 files removed, 0 files unresolved
>  
> @@ -674,6 +814,16 @@
>    |      json: [["eb5a0daa21923bbf8caeb2c42085b9e463861fd0"]]
>    o  ea207398892e
>    
> +
> +  $ hg fatelog
> +  o  eb5a0daa2192
> +  |
> +  | @  0dec01379d3b
> +  | |    Obsfate: rewritten as 4:eb5a0daa2192
> +  | x  471f378eab4c
> +  |/     Obsfate: rewritten as 4:eb5a0daa2192
> +  o  ea207398892e
> +  
>    $ hg up 'desc(B1)' --hidden
>    0 files updated, 0 files merged, 0 files removed, 0 files unresolved
>  
> @@ -694,6 +844,16 @@
>    |      json: [["eb5a0daa21923bbf8caeb2c42085b9e463861fd0"]]
>    o  ea207398892e
>    
> +
> +  $ hg fatelog
> +  o  eb5a0daa2192
> +  |
> +  | @  b7ea6d14e664
> +  | |    Obsfate: rewritten as 4:eb5a0daa2192
> +  | x  471f378eab4c
> +  |/     Obsfate: rewritten as 4:eb5a0daa2192
> +  o  ea207398892e
> +  
>    $ hg up 'desc(C0)'
>    0 files updated, 0 files merged, 0 files removed, 0 files unresolved
>  
> @@ -703,6 +863,12 @@
>    |
>    o  ea207398892e
>    
> +
> +  $ hg fatelog
> +  @  eb5a0daa2192
> +  |
> +  o  ea207398892e
> +  
>  Predecessors template should show all predecessors as we force their display
>  with --hidden
>    $ hg tlog --hidden
> @@ -730,6 +896,17 @@
>    o  ea207398892e
>    
>  
> +  $ hg fatelog --hidden
> +  @  eb5a0daa2192
> +  |
> +  | x  b7ea6d14e664
> +  | |    Obsfate: rewritten as 4:eb5a0daa2192
> +  | | x  0dec01379d3b
> +  | |/     Obsfate: rewritten as 3:b7ea6d14e664
> +  | x  471f378eab4c
> +  |/     Obsfate: rewritten as 4:eb5a0daa2192
> +  o  ea207398892e
> +  
>  Test template with pushed and pulled obs markers
>  ================================================
>  
> @@ -833,6 +1010,14 @@
>    |      json: [["7a230b46bf61e50b30308c6cfd7bd1269ef54702"]]
>    o  ea207398892e
>    
> +
> +  $ hg fatelog
> +  o  7a230b46bf61
> +  |
> +  | @  471f378eab4c
> +  |/     Obsfate: rewritten as 2:7a230b46bf61
> +  o  ea207398892e
> +  
>    $ hg up 'desc(A2)'
>    0 files updated, 0 files merged, 0 files removed, 0 files unresolved
>  
> @@ -842,6 +1027,12 @@
>    |
>    o  ea207398892e
>    
> +
> +  $ hg fatelog
> +  @  7a230b46bf61
> +  |
> +  o  ea207398892e
> +  
>  Predecessors template should show all predecessors as we force their display
>  with --hidden
>    $ hg tlog --hidden
> @@ -857,6 +1048,14 @@
>    o  ea207398892e
>    
>  
> +  $ hg fatelog --hidden
> +  @  7a230b46bf61
> +  |
> +  | x  471f378eab4c
> +  |/     Obsfate: rewritten as 2:7a230b46bf61
> +  o  ea207398892e
> +  
> +
>  Test template with obsmarkers cycle
>  ===================================
>  
> @@ -888,6 +1087,12 @@
>    o  ea207398892e
>    
>  
> +  $ hg fatelog
> +  @  f897c6137566
> +  |
> +  o  ea207398892e
> +  
> +
>    $ hg up -r "desc(B0)" --hidden
>    2 files updated, 0 files merged, 1 files removed, 0 files unresolved
>    $ hg tlog
> @@ -916,6 +1121,16 @@
>    o  ea207398892e
>    
>  
> +  $ hg fatelog
> +  o  f897c6137566
> +  |
> +  | @  0dec01379d3b
> +  | |    Obsfate: rewritten as 3:f897c6137566; rewritten as 1:471f378eab4c
> +  | x  471f378eab4c
> +  |/     Obsfate: rewritten as 2:0dec01379d3b
> +  o  ea207398892e
> +  
> +
>    $ hg up -r "desc(A0)" --hidden
>    0 files updated, 0 files merged, 1 files removed, 0 files unresolved
>    $ hg tlog
> @@ -929,6 +1144,14 @@
>    o  ea207398892e
>    
>  
> +  $ hg fatelog
> +  o  f897c6137566
> +  |
> +  | @  471f378eab4c
> +  |/
> +  o  ea207398892e
> +  
> +
>    $ hg up -r "desc(ROOT)" --hidden
>    0 files updated, 0 files merged, 1 files removed, 0 files unresolved
>    $ hg tlog
> @@ -937,6 +1160,12 @@
>    @  ea207398892e
>    
>  
> +  $ hg fatelog
> +  o  f897c6137566
> +  |
> +  @  ea207398892e
> +  
> +
>    $ hg tlog --hidden
>    o  f897c6137566
>    |    Predecessors: 2:0dec01379d3b
> @@ -1145,6 +1374,21 @@
>    |
>    o  ea207398892e
>    
> +  $ hg fatelog
> +  @  0b997eb7ceee
> +  |
> +  | o  b18bc8331526
> +  |/
> +  | o  ba2ed02b0c9a
> +  | |
> +  | x  4a004186e638
> +  |/     Obsfate: rewritten as 8:b18bc8331526; rewritten as 9:0b997eb7ceee
> +  o  dd800401bd8c
> +  |
> +  o  f897c6137566
> +  |
> +  o  ea207398892e
> +  
>    $ hg tlog --hidden
>    @  0b997eb7ceee
>    |    Predecessors: 6:4a004186e638
> @@ -1203,6 +1447,27 @@
>    |      json: [["0dec01379d3be6318c470ead31b1fe7ae7cb53d5"]]
>    o  ea207398892e
>    
> +  $ hg fatelog --hidden
> +  @  0b997eb7ceee
> +  |
> +  | o  b18bc8331526
> +  |/
> +  | o  ba2ed02b0c9a
> +  | |
> +  | x  4a004186e638
> +  |/     Obsfate: rewritten as 8:b18bc8331526; rewritten as 9:0b997eb7ceee
> +  o  dd800401bd8c
> +  |
> +  | x  9bd10a0775e4
> +  |/     Obsfate: rewritten as 6:4a004186e638, 7:ba2ed02b0c9a, 5:dd800401bd8c
> +  o  f897c6137566
> +  |
> +  | x  0dec01379d3b
> +  | |    Obsfate: rewritten as 3:f897c6137566; rewritten as 1:471f378eab4c
> +  | x  471f378eab4c
> +  |/     Obsfate: rewritten as 2:0dec01379d3b
> +  o  ea207398892e
> +  
>    $ hg up --hidden 4
>    1 files updated, 0 files merged, 0 files removed, 0 files unresolved
>    $ hg rebase -r 7 -d 8 --config extensions.rebase=
> @@ -1237,6 +1502,22 @@
>    |
>    o  ea207398892e
>    
> +
> +  $ hg fatelog
> +  o  eceed8f98ffc
> +  |
> +  | o  0b997eb7ceee
> +  | |
> +  o |  b18bc8331526
> +  |/
> +  o  dd800401bd8c
> +  |
> +  | @  9bd10a0775e4
> +  |/     Obsfate: rewritten as 9:0b997eb7ceee, 5:dd800401bd8c, 10:eceed8f98ffc; rewritten as 8:b18bc8331526, 5:dd800401bd8c, 10:eceed8f98ffc
> +  o  f897c6137566
> +  |
> +  o  ea207398892e
> +  
>  Test templates with pruned commits
>  ==================================
>  
> @@ -1259,3 +1540,13 @@
>    |
>    o  ea207398892e
>    
> +  $ hg fatelog
> +  @  471f378eab4c
> +  |
> +  o  ea207398892e
> +  
> +  $ hg fatelog -v
> +  @  471f378eab4c
> +  |
> +  o  ea207398892e
> +
Sean Farley - July 7, 2017, 1:13 a.m.
Jun Wu <quark@fb.com> writes:

> I'm not a big fan of this obsfate template approach. Ideally we could
> extract information from an obsmarker using templates. Something like
> "{marker.user} {marker.operation} {marker.xxxx}". That's much more flexible
> and could work with colors trivially.

Heh, I was writing almost the same email.

> The current template is binded to a
> ctx. We could define some functions or introduce special synctax to make it
> bind to an obsmarker.

Hmm, maybe. I'm not sure the marker information would be concise enough.
At the very least, I think we could do that in another series as an
experiment.

It might turn out that we need more functionality in the template engine
as well.
Boris Feld - July 7, 2017, 10:28 a.m.
On Thu, 2017-07-06 at 18:13 -0700, Sean Farley wrote:
> Jun Wu <quark@fb.com> writes:
> 
> > I'm not a big fan of this obsfate template approach. Ideally we
> > could
> > extract information from an obsmarker using templates. Something
> > like
> > "{marker.user} {marker.operation} {marker.xxxx}". That's much more
> > flexible
> > and could work with colors trivially.
> 
> Heh, I was writing almost the same email.
> 
> > The current template is binded to a
> > ctx. We could define some functions or introduce special synctax to
> > make it
> > bind to an obsmarker.
> 
> Hmm, maybe. I'm not sure the marker information would be concise
> enough.
> At the very least, I think we could do that in another series as an
> experiment.
> 
> It might turn out that we need more functionality in the template
> engine
> as well.

I've answered to sean email on Patch 9 as it introduce more templating
capabilities, could we merge the two discussion there?

Cheers,

> _______________________________________________
> Mercurial-devel mailing list
> Mercurial-devel@mercurial-scm.org
> https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Yuya Nishihara - July 7, 2017, 12:03 p.m.
On Thu, 6 Jul 2017 17:05:01 -0700, Jun Wu wrote:
> I'm not a big fan of this obsfate template approach. Ideally we could
> extract information from an obsmarker using templates. Something like
> "{marker.user} {marker.operation} {marker.xxxx}".

"{get(marker, 'user')}", perhaps. We could add a syntactic sugar for that.

Patch

diff -r 7e5752579378 -r 7fba236b2b17 mercurial/obsutil.py
--- a/mercurial/obsutil.py	Mon Jul 03 03:27:58 2017 +0200
+++ b/mercurial/obsutil.py	Tue Jul 04 15:50:25 2017 +0200
@@ -8,6 +8,7 @@ 
 from __future__ import absolute_import
 
 from . import (
+    node as nodemod,
     phases,
 )
 
@@ -551,3 +552,46 @@ 
                 final.reverse() # put small successors set first
                 cache[current] = final
     return cache[initialnode]
+
+def preparesuccessorset(successorset, rawmarkers):
+    """ For a successor set, get all related markers and convert every nodeid
+    into its hexadecimal form.
+    """
+    hex = nodemod.hex
+
+    successorset = [hex(n) for n in successorset]
+
+    # hex the binary nodes in the markers
+    markers = []
+    for m in rawmarkers:
+        hexprec = hex(m[0])
+        hexsucs = tuple(hex(n) for n in m[1])
+        hexparents = None
+        if m[5] is not None:
+            hexparents = tuple(hex(n) for n in m[5])
+        newmarker = (hexprec, hexsucs) + m[2:5] + (hexparents,) + m[6:]
+        markers.append(newmarker)
+
+    # Format basic data
+    data = {
+        "successors": sorted(successorset),
+        "markers": sorted(markers)
+    }
+
+    return data
+
+def obsfatedata(repo, ctx):
+    """compute the raw data needed for computing obsfate
+    Returns a list of dict, one dict per successors set
+    """
+    if not ctx.obsolete():
+        return None
+
+    ssets = successorssets(repo, ctx.node(), closest=True)
+
+    values = []
+    for sset in ssets:
+        raw = preparesuccessorset(sset, sset.markers)
+        values.append(raw)
+
+    return values
diff -r 7e5752579378 -r 7fba236b2b17 mercurial/templatekw.py
--- a/mercurial/templatekw.py	Mon Jul 03 03:27:58 2017 +0200
+++ b/mercurial/templatekw.py	Tue Jul 04 15:50:25 2017 +0200
@@ -634,6 +634,57 @@ 
     return _hybrid(gen(data), data, lambda x: {'successorset': x},
                    lambda d: d["successorset"])
 
+def _obsfatelineprinter(obsfateline, repo, ui):
+    """Format and display obsfate related data
+    """
+    quiet = ui.quiet
+    verbose = ui.verbose
+    normal = not verbose and not quiet
+
+    # Build the line step by step
+    line = []
+
+    # Verb
+    line.append("rewritten")
+
+    # Successors
+    successors = obsfateline["successors"]
+
+    if successors:
+        fmtsuccessors = map(lambda s: _formatrevnode(repo[s]), successors)
+        line.append(" as %s" % ", ".join(fmtsuccessors))
+
+    return "".join(line)
+
+def _obsfateprinter(obsfate, repo, ui, prefix=""):
+    """Generate a human-readable line per successorset of a changeset
+    """
+    lines = []
+    for raw in obsfate:
+        lines.append(_obsfatelineprinter(raw, repo, ui))
+
+    if prefix:
+        lines = [prefix + line for line in lines]
+
+    return "; ".join(lines)
+
+@templatekeyword("obsfate")
+def showobsfate(repo, ctx, **args):
+    """Returns a string describing how an obsolete changeset has evolved in a
+    human-readable format.
+
+    This line will contains these information:
+    - The list of closest successors in the log output
+    """
+
+    # Get the needed obsfate data
+    values = obsutil.obsfatedata(repo, ctx)
+
+    if values is None:
+        return ''
+
+    return _obsfateprinter(values, repo, repo.ui)
+
 @templatekeyword('p1rev')
 def showp1rev(repo, ctx, templ, **args):
     """Integer. The repository-local revision number of the changeset's
diff -r 7e5752579378 -r 7fba236b2b17 tests/test-obsmarker-template.t
--- a/tests/test-obsmarker-template.t	Mon Jul 03 03:27:58 2017 +0200
+++ b/tests/test-obsmarker-template.t	Tue Jul 04 15:50:25 2017 +0200
@@ -20,6 +20,7 @@ 
   >     {if(successorssets, "\n  Successors: {successorssets}")}\
   >     {if(successorssets, "\n  multi-line: {join(successorssets, "\n  multi-line: ")}")}\
   >     {if(successorssets, "\n  json: {successorssets|json}")}\n'
+  > fatelog = log -G -T '{node|short}\n{if(obsfate, "  Obsfate: {obsfate}\n")}'
   > EOF
 
 Test templates on amended commit
@@ -33,8 +34,8 @@ 
   $ mkcommit ROOT
   $ mkcommit A0
   $ echo 42 >> A0
-  $ hg commit --amend -m "A1"
-  $ hg commit --amend -m "A2"
+  $ HGUSER=test1 hg commit --amend -m "A1" --config devel.default-date="1234567890 0"
+  $ HGUSER=test2 hg commit --amend -m "A2" --config devel.default-date="987654321 0"
 
   $ hg log --hidden -G
   @  changeset:   4:d004c8f274b9
@@ -83,6 +84,27 @@ 
   |      json: [["d004c8f274b9ec480a47a93c10dac5eee63adb78"]]
   o  ea207398892e
   
+  $ hg fatelog -q
+  o  d004c8f274b9
+  |
+  | @  471f378eab4c
+  |/     Obsfate: rewritten as 4:d004c8f274b9
+  o  ea207398892e
+  
+  $ hg fatelog
+  o  d004c8f274b9
+  |
+  | @  471f378eab4c
+  |/     Obsfate: rewritten as 4:d004c8f274b9
+  o  ea207398892e
+  
+  $ hg fatelog -v
+  o  d004c8f274b9
+  |
+  | @  471f378eab4c
+  |/     Obsfate: rewritten as 4:d004c8f274b9
+  o  ea207398892e
+  
   $ hg up 'desc(A1)' --hidden
   1 files updated, 0 files merged, 0 files removed, 0 files unresolved
 
@@ -99,6 +121,13 @@ 
   |      json: [["d004c8f274b9ec480a47a93c10dac5eee63adb78"]]
   o  ea207398892e
   
+  $ hg fatelog -v
+  o  d004c8f274b9
+  |
+  | @  a468dc9b3633
+  |/     Obsfate: rewritten as 4:d004c8f274b9
+  o  ea207398892e
+  
 Predecessors template should show all the predecessors as we force their display
 with --hidden
   $ hg tlog --hidden
@@ -123,6 +152,17 @@ 
   |      json: [["a468dc9b36338b14fdb7825f55ce3df4e71517ad"]]
   o  ea207398892e
   
+  $ hg fatelog --hidden -q
+  o  d004c8f274b9
+  |
+  | @  a468dc9b3633
+  |/     Obsfate: rewritten as 4:d004c8f274b9
+  | x  f137d23bb3e1
+  | |
+  | x  471f378eab4c
+  |/     Obsfate: rewritten as 3:a468dc9b3633
+  o  ea207398892e
+  
 
 Predecessors template shouldn't show anything as all obsolete commit are not
 visible.
@@ -155,6 +195,23 @@ 
   |      json: [["a468dc9b36338b14fdb7825f55ce3df4e71517ad"]]
   o  ea207398892e
   
+  $ hg fatelog -v
+  @  d004c8f274b9
+  |
+  o  ea207398892e
+  
+
+  $ hg fatelog -v --hidden
+  @  d004c8f274b9
+  |
+  | x  a468dc9b3633
+  |/     Obsfate: rewritten as 4:d004c8f274b9
+  | x  f137d23bb3e1
+  | |
+  | x  471f378eab4c
+  |/     Obsfate: rewritten as 3:a468dc9b3633
+  o  ea207398892e
+  
 
 Test templates with splitted commit
 ===================================
@@ -238,6 +295,16 @@ 
   |      json: [["337fec4d2edcf0e7a467e35f818234bc620068b5", "f257fde29c7a847c9b607f6e958656d0df0fb15c"]]
   o  ea207398892e
   
+
+  $ hg fatelog
+  o  f257fde29c7a
+  |
+  o  337fec4d2edc
+  |
+  | @  471597cad322
+  |/     Obsfate: rewritten as 2:337fec4d2edc, 3:f257fde29c7a
+  o  ea207398892e
+  
   $ hg up f257fde29c7a
   0 files updated, 0 files merged, 0 files removed, 0 files unresolved
 
@@ -269,6 +336,16 @@ 
   |      json: [["337fec4d2edcf0e7a467e35f818234bc620068b5", "f257fde29c7a847c9b607f6e958656d0df0fb15c"]]
   o  ea207398892e
   
+
+  $ hg fatelog --hidden
+  @  f257fde29c7a
+  |
+  o  337fec4d2edc
+  |
+  | x  471597cad322
+  |/     Obsfate: rewritten as 2:337fec4d2edc, 3:f257fde29c7a
+  o  ea207398892e
+  
 Test templates with folded commit
 =================================
 
@@ -351,6 +428,14 @@ 
   |      json: [["eb5a0daa21923bbf8caeb2c42085b9e463861fd0"]]
   o  ea207398892e
   
+
+  $ hg fatelog
+  o  eb5a0daa2192
+  |
+  | @  471f378eab4c
+  |/     Obsfate: rewritten as 3:eb5a0daa2192
+  o  ea207398892e
+  
   $ hg up 'desc(B0)' --hidden
   1 files updated, 0 files merged, 0 files removed, 0 files unresolved
 
@@ -372,6 +457,16 @@ 
   |      json: [["eb5a0daa21923bbf8caeb2c42085b9e463861fd0"]]
   o  ea207398892e
   
+
+  $ hg fatelog
+  o  eb5a0daa2192
+  |
+  | @  0dec01379d3b
+  | |    Obsfate: rewritten as 3:eb5a0daa2192
+  | x  471f378eab4c
+  |/     Obsfate: rewritten as 3:eb5a0daa2192
+  o  ea207398892e
+  
   $ hg up 'desc(C0)'
   0 files updated, 0 files merged, 0 files removed, 0 files unresolved
 
@@ -401,6 +496,15 @@ 
   o  ea207398892e
   
 
+  $ hg fatelog --hidden
+  @  eb5a0daa2192
+  |
+  | x  0dec01379d3b
+  | |    Obsfate: rewritten as 3:eb5a0daa2192
+  | x  471f378eab4c
+  |/     Obsfate: rewritten as 3:eb5a0daa2192
+  o  ea207398892e
+  
 Test templates with divergence
 ==============================
 
@@ -518,6 +622,15 @@ 
   |      json: [["fdf9bde5129a28d4548fadd3f62b265cdd3b7a2e"], ["019fadeab383f6699fa83ad7bdb4d82ed2c0e5ab"]]
   o  ea207398892e
   
+  $ hg fatelog
+  o  019fadeab383
+  |
+  | o  fdf9bde5129a
+  |/
+  | @  471f378eab4c
+  |/     Obsfate: rewritten as 2:fdf9bde5129a; rewritten as 4:019fadeab383
+  o  ea207398892e
+  
   $ hg up 'desc(A1)'
   0 files updated, 0 files merged, 0 files removed, 0 files unresolved
 
@@ -530,6 +643,14 @@ 
   |/
   o  ea207398892e
   
+
+  $ hg fatelog
+  o  019fadeab383
+  |
+  | @  fdf9bde5129a
+  |/
+  o  ea207398892e
+  
 Predecessors template should the predecessors as we force their display with
 --hidden
   $ hg tlog --hidden
@@ -559,6 +680,17 @@ 
   o  ea207398892e
   
 
+  $ hg fatelog --hidden
+  o  019fadeab383
+  |
+  | x  65b757b745b9
+  |/     Obsfate: rewritten as 4:019fadeab383
+  | @  fdf9bde5129a
+  |/
+  | x  471f378eab4c
+  |/     Obsfate: rewritten as 2:fdf9bde5129a; rewritten as 3:65b757b745b9
+  o  ea207398892e
+  
 Test templates with amended + folded commit
 ===========================================
 
@@ -654,6 +786,14 @@ 
   |      json: [["eb5a0daa21923bbf8caeb2c42085b9e463861fd0"]]
   o  ea207398892e
   
+
+  $ hg fatelog
+  o  eb5a0daa2192
+  |
+  | @  471f378eab4c
+  |/     Obsfate: rewritten as 4:eb5a0daa2192
+  o  ea207398892e
+  
   $ hg up 'desc(B0)' --hidden
   1 files updated, 0 files merged, 0 files removed, 0 files unresolved
 
@@ -674,6 +814,16 @@ 
   |      json: [["eb5a0daa21923bbf8caeb2c42085b9e463861fd0"]]
   o  ea207398892e
   
+
+  $ hg fatelog
+  o  eb5a0daa2192
+  |
+  | @  0dec01379d3b
+  | |    Obsfate: rewritten as 4:eb5a0daa2192
+  | x  471f378eab4c
+  |/     Obsfate: rewritten as 4:eb5a0daa2192
+  o  ea207398892e
+  
   $ hg up 'desc(B1)' --hidden
   0 files updated, 0 files merged, 0 files removed, 0 files unresolved
 
@@ -694,6 +844,16 @@ 
   |      json: [["eb5a0daa21923bbf8caeb2c42085b9e463861fd0"]]
   o  ea207398892e
   
+
+  $ hg fatelog
+  o  eb5a0daa2192
+  |
+  | @  b7ea6d14e664
+  | |    Obsfate: rewritten as 4:eb5a0daa2192
+  | x  471f378eab4c
+  |/     Obsfate: rewritten as 4:eb5a0daa2192
+  o  ea207398892e
+  
   $ hg up 'desc(C0)'
   0 files updated, 0 files merged, 0 files removed, 0 files unresolved
 
@@ -703,6 +863,12 @@ 
   |
   o  ea207398892e
   
+
+  $ hg fatelog
+  @  eb5a0daa2192
+  |
+  o  ea207398892e
+  
 Predecessors template should show all predecessors as we force their display
 with --hidden
   $ hg tlog --hidden
@@ -730,6 +896,17 @@ 
   o  ea207398892e
   
 
+  $ hg fatelog --hidden
+  @  eb5a0daa2192
+  |
+  | x  b7ea6d14e664
+  | |    Obsfate: rewritten as 4:eb5a0daa2192
+  | | x  0dec01379d3b
+  | |/     Obsfate: rewritten as 3:b7ea6d14e664
+  | x  471f378eab4c
+  |/     Obsfate: rewritten as 4:eb5a0daa2192
+  o  ea207398892e
+  
 Test template with pushed and pulled obs markers
 ================================================
 
@@ -833,6 +1010,14 @@ 
   |      json: [["7a230b46bf61e50b30308c6cfd7bd1269ef54702"]]
   o  ea207398892e
   
+
+  $ hg fatelog
+  o  7a230b46bf61
+  |
+  | @  471f378eab4c
+  |/     Obsfate: rewritten as 2:7a230b46bf61
+  o  ea207398892e
+  
   $ hg up 'desc(A2)'
   0 files updated, 0 files merged, 0 files removed, 0 files unresolved
 
@@ -842,6 +1027,12 @@ 
   |
   o  ea207398892e
   
+
+  $ hg fatelog
+  @  7a230b46bf61
+  |
+  o  ea207398892e
+  
 Predecessors template should show all predecessors as we force their display
 with --hidden
   $ hg tlog --hidden
@@ -857,6 +1048,14 @@ 
   o  ea207398892e
   
 
+  $ hg fatelog --hidden
+  @  7a230b46bf61
+  |
+  | x  471f378eab4c
+  |/     Obsfate: rewritten as 2:7a230b46bf61
+  o  ea207398892e
+  
+
 Test template with obsmarkers cycle
 ===================================
 
@@ -888,6 +1087,12 @@ 
   o  ea207398892e
   
 
+  $ hg fatelog
+  @  f897c6137566
+  |
+  o  ea207398892e
+  
+
   $ hg up -r "desc(B0)" --hidden
   2 files updated, 0 files merged, 1 files removed, 0 files unresolved
   $ hg tlog
@@ -916,6 +1121,16 @@ 
   o  ea207398892e
   
 
+  $ hg fatelog
+  o  f897c6137566
+  |
+  | @  0dec01379d3b
+  | |    Obsfate: rewritten as 3:f897c6137566; rewritten as 1:471f378eab4c
+  | x  471f378eab4c
+  |/     Obsfate: rewritten as 2:0dec01379d3b
+  o  ea207398892e
+  
+
   $ hg up -r "desc(A0)" --hidden
   0 files updated, 0 files merged, 1 files removed, 0 files unresolved
   $ hg tlog
@@ -929,6 +1144,14 @@ 
   o  ea207398892e
   
 
+  $ hg fatelog
+  o  f897c6137566
+  |
+  | @  471f378eab4c
+  |/
+  o  ea207398892e
+  
+
   $ hg up -r "desc(ROOT)" --hidden
   0 files updated, 0 files merged, 1 files removed, 0 files unresolved
   $ hg tlog
@@ -937,6 +1160,12 @@ 
   @  ea207398892e
   
 
+  $ hg fatelog
+  o  f897c6137566
+  |
+  @  ea207398892e
+  
+
   $ hg tlog --hidden
   o  f897c6137566
   |    Predecessors: 2:0dec01379d3b
@@ -1145,6 +1374,21 @@ 
   |
   o  ea207398892e
   
+  $ hg fatelog
+  @  0b997eb7ceee
+  |
+  | o  b18bc8331526
+  |/
+  | o  ba2ed02b0c9a
+  | |
+  | x  4a004186e638
+  |/     Obsfate: rewritten as 8:b18bc8331526; rewritten as 9:0b997eb7ceee
+  o  dd800401bd8c
+  |
+  o  f897c6137566
+  |
+  o  ea207398892e
+  
   $ hg tlog --hidden
   @  0b997eb7ceee
   |    Predecessors: 6:4a004186e638
@@ -1203,6 +1447,27 @@ 
   |      json: [["0dec01379d3be6318c470ead31b1fe7ae7cb53d5"]]
   o  ea207398892e
   
+  $ hg fatelog --hidden
+  @  0b997eb7ceee
+  |
+  | o  b18bc8331526
+  |/
+  | o  ba2ed02b0c9a
+  | |
+  | x  4a004186e638
+  |/     Obsfate: rewritten as 8:b18bc8331526; rewritten as 9:0b997eb7ceee
+  o  dd800401bd8c
+  |
+  | x  9bd10a0775e4
+  |/     Obsfate: rewritten as 6:4a004186e638, 7:ba2ed02b0c9a, 5:dd800401bd8c
+  o  f897c6137566
+  |
+  | x  0dec01379d3b
+  | |    Obsfate: rewritten as 3:f897c6137566; rewritten as 1:471f378eab4c
+  | x  471f378eab4c
+  |/     Obsfate: rewritten as 2:0dec01379d3b
+  o  ea207398892e
+  
   $ hg up --hidden 4
   1 files updated, 0 files merged, 0 files removed, 0 files unresolved
   $ hg rebase -r 7 -d 8 --config extensions.rebase=
@@ -1237,6 +1502,22 @@ 
   |
   o  ea207398892e
   
+
+  $ hg fatelog
+  o  eceed8f98ffc
+  |
+  | o  0b997eb7ceee
+  | |
+  o |  b18bc8331526
+  |/
+  o  dd800401bd8c
+  |
+  | @  9bd10a0775e4
+  |/     Obsfate: rewritten as 9:0b997eb7ceee, 5:dd800401bd8c, 10:eceed8f98ffc; rewritten as 8:b18bc8331526, 5:dd800401bd8c, 10:eceed8f98ffc
+  o  f897c6137566
+  |
+  o  ea207398892e
+  
 Test templates with pruned commits
 ==================================
 
@@ -1259,3 +1540,13 @@ 
   |
   o  ea207398892e
   
+  $ hg fatelog
+  @  471f378eab4c
+  |
+  o  ea207398892e
+  
+  $ hg fatelog -v
+  @  471f378eab4c
+  |
+  o  ea207398892e
+