D8113: debugcommands: add templated command for reading the merge state for e.g. IDEs

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
11 messages Options
Reply | Threaded
Open this post in threaded view
|

D8113: debugcommands: add templated command for reading the merge state for e.g. IDEs

marmoute (Pierre-Yves David)
martinvonz created this revision.
Herald added a subscriber: mercurial-devel.
Herald added a reviewer: hg-reviewers.

REVISION SUMMARY
  Our IntelliJ team wants to be able to read the merge state in order to
  help the user resolve merge conflicts. They had so far been reading
  file contents from p1() and p2() and their merge base. That is not
  ideal for several reasons (merge base is not necessarily the "graft
  base", renames are not handled, commands like `hg update -m` is not
  handled). It will get especially bad as of my D7827 <https://phab.mercurial-scm.org/D7827>. This patch adds a
  simple templated command for dumping the merge state. I haven't
  bothered to make it complete (e.g. merge driver states are not
  handled), but it's probably good enough as a start.

REPOSITORY
  rHG Mercurial

BRANCH
  default

REVISION DETAIL
  https://phab.mercurial-scm.org/D8113

AFFECTED FILES
  mercurial/debugcommands.py
  tests/test-completion.t
  tests/test-help.t
  tests/test-resolve.t

CHANGE DETAILS

diff --git a/tests/test-resolve.t b/tests/test-resolve.t
--- a/tests/test-resolve.t
+++ b/tests/test-resolve.t
@@ -327,6 +327,20 @@
   R file1
   U file2
 
+test debugmergestatetemplate
+
+  $ hg debugmergestatetemplated
+  abort: template required
+  [255]
+  $ hg debugmergestatetemplated -T json
+  [
+   {
+    "commits": [{"label": "working copy", "name": "local", "node": "57653b9f834a4493f7240b0681efcb9ae7cab745"}, {"label": "merge rev", "name": "other", "node": "dc77451844e37f03f5c559e3b8529b2b48d381d1"}],
+    "files": [{"extras": [{"key": "ancestorlinknode", "value": "99726c03216e233810a2564cbc0adfe395007eac"}], "name": "file1", "state": "r"}, {"ancestor_node": "2ed2a3912a0b24502043eae84ee4b279c18b90dd", "ancestor_path": "file2", "extras": [{"key": "ancestorlinknode", "value": "99726c03216e233810a2564cbc0adfe395007eac"}], "local_flags": "", "local_key": "cb99b709a1978bd205ab9dfd4c5aaa1fc91c7523", "local_path": "file2", "name": "file2", "other_node": "6f4310b00b9a147241b071a60c28a650827fb03d", "other_path": "file2", "state": "u"}]
+   }
+  ]
+
+
 insert unsupported mandatory merge record
 
   $ hg --config extensions.fakemergerecord=$TESTDIR/fakemergerecord.py fakemergerecord -X
diff --git a/tests/test-help.t b/tests/test-help.t
--- a/tests/test-help.t
+++ b/tests/test-help.t
@@ -1022,6 +1022,8 @@
                  cache
    debugmergestate
                  print merge state
+   debugmergestatetemplated
+                 templated output about the merge state
    debugnamecomplete
                  complete "names" - tags, open branch names, bookmark names
    debugnodemap  write and inspect on disk nodemap
diff --git a/tests/test-completion.t b/tests/test-completion.t
--- a/tests/test-completion.t
+++ b/tests/test-completion.t
@@ -106,6 +106,7 @@
   debuglocks
   debugmanifestfulltextcache
   debugmergestate
+  debugmergestatetemplated
   debugnamecomplete
   debugnodemap
   debugobsolete
@@ -290,6 +291,7 @@
   debuglocks: force-lock, force-wlock, set-lock, set-wlock
   debugmanifestfulltextcache: clear, add
   debugmergestate:
+  debugmergestatetemplated: style, template
   debugnamecomplete:
   debugnodemap: dump-new, dump-disk, check, metadata
   debugobsolete: flags, record-parents, rev, exclusive, index, delete, date, user, template
diff --git a/mercurial/debugcommands.py b/mercurial/debugcommands.py
--- a/mercurial/debugcommands.py
+++ b/mercurial/debugcommands.py
@@ -2060,6 +2060,62 @@
             printrecords(2)
 
 
+@command(b'debugmergestatetemplated', [] + cmdutil.templateopts, b'')
+def debugmergestatetemplated(ui, repo, *args, **opts):
+    """templated output about the merge state
+
+    This command requires a template (such as '-T json').
+    """
+
+    opts = pycompat.byteskwargs(opts)
+    if not opts[b'template']:
+        raise error.Abort(_(b'template required'))
+
+    ms = mergemod.mergestate.read(repo)
+    if not ms.active():
+        return
+
+    fm = ui.formatter(b'debugmergestatetemplated', opts)
+    fm.startitem()
+
+    fm_commits = fm.nested(b'commits')
+    for name, node, label_index in (
+        (b'local', ms.local, 0),
+        (b'other', ms.other, 1),
+    ):
+        fm_commits.startitem()
+        fm_commits.data(name=name)
+        fm_commits.data(node=hex(node))
+        if ms._labels and len(ms._labels) > label_index:
+            fm_commits.data(label=ms._labels[label_index])
+    fm_commits.end()
+
+    fm_files = fm.nested(b'files')
+    for f in ms:
+        fm_files.startitem()
+        fm_files.data(name=f)
+        state = ms._state[f]
+        fm_files.data(state=state[0])
+        if state[0] == mergemod.MERGE_RECORD_UNRESOLVED:
+            fm_files.data(local_key=state[1])
+            fm_files.data(local_path=state[2])
+            fm_files.data(ancestor_path=state[3])
+            fm_files.data(ancestor_node=state[4])
+            fm_files.data(other_path=state[5])
+            fm_files.data(other_node=state[6])
+            fm_files.data(local_flags=state[7])
+        fm_extras = fm_files.nested(b'extras')
+        for k, v in ms.extras(f).items():
+            fm_extras.startitem()
+            fm_extras.data(key=k)
+            fm_extras.data(value=v)
+        fm_extras.end()
+
+    fm_files.end()
+
+    fm.end()
+
+
 @command(b'debugnamecomplete', [], _(b'NAME...'))
 def debugnamecomplete(ui, repo, *args):
     '''complete "names" - tags, open branch names, bookmark names'''



To: martinvonz, #hg-reviewers
Cc: mercurial-devel
_______________________________________________
Mercurial-devel mailing list
[hidden email]
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Reply | Threaded
Open this post in threaded view
|

D8113: debugcommands: add templated command for reading the merge state for e.g. IDEs

marmoute (Pierre-Yves David)
durin42 added a comment.


  Why can't we add templater support to `debugmergestate` instead?

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D8113/new/

REVISION DETAIL
  https://phab.mercurial-scm.org/D8113

To: martinvonz, #hg-reviewers
Cc: durin42, mercurial-devel
_______________________________________________
Mercurial-devel mailing list
[hidden email]
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Reply | Threaded
Open this post in threaded view
|

D8113: debugcommands: add templated command for reading the merge state for e.g. IDEs

marmoute (Pierre-Yves David)
In reply to this post by marmoute (Pierre-Yves David)
martinvonz added a comment.


  In D8113#120695 <https://phab.mercurial-scm.org/D8113#120695>, @durin42 wrote:
 
  > Why can't we add templater support to `debugmergestate` instead?
 
  Sorry, I should have explained that in the commit message. The reason I didn't was because the current command seems to try to make the output be true to the on-disk format. Maybe that's not something we care much about, so I can just rewrite it by defining a default template. I'll try that.

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D8113/new/

REVISION DETAIL
  https://phab.mercurial-scm.org/D8113

To: martinvonz, #hg-reviewers
Cc: durin42, mercurial-devel
_______________________________________________
Mercurial-devel mailing list
[hidden email]
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Reply | Threaded
Open this post in threaded view
|

D8113: debugmergestate: make templated

marmoute (Pierre-Yves David)
In reply to this post by marmoute (Pierre-Yves David)
Herald added a reviewer: durin42.
martinvonz edited the summary of this revision.
martinvonz retitled this revision from "debugcommands: add templated command for reading the merge state for e.g. IDEs" to "debugmergestate: make templated".
martinvonz updated this revision to Diff 20202.

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D8113?vs=20180&id=20202

BRANCH
  default

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D8113/new/

REVISION DETAIL
  https://phab.mercurial-scm.org/D8113

AFFECTED FILES
  mercurial/debugcommands.py
  tests/test-backout.t
  tests/test-completion.t
  tests/test-histedit-non-commute-abort.t
  tests/test-merge-changedelete.t
  tests/test-rebase-abort.t
  tests/test-resolve.t

CHANGE DETAILS

diff --git a/tests/test-resolve.t b/tests/test-resolve.t
--- a/tests/test-resolve.t
+++ b/tests/test-resolve.t
@@ -306,48 +306,40 @@
 
   $ hg --config extensions.fakemergerecord=$TESTDIR/fakemergerecord.py fakemergerecord -x
   $ hg debugmergestate
-  * version 2 records
-  local: 57653b9f834a4493f7240b0681efcb9ae7cab745
-  other: dc77451844e37f03f5c559e3b8529b2b48d381d1
-  labels:
-    local: working copy
-    other: merge rev
-  unrecognized entry: x advisory record
-  file extras: file1 (ancestorlinknode = 99726c03216e233810a2564cbc0adfe395007eac)
-  file: file1 (record type "F", state "r", hash 60b27f004e454aca81b0480209cce5081ec52390)
+  local (working copy): 57653b9f834a4493f7240b0681efcb9ae7cab745
+  other (merge rev): dc77451844e37f03f5c559e3b8529b2b48d381d1
+  file: file1 (state "r")
     local path: file1 (flags "")
     ancestor path: file1 (node 2ed2a3912a0b24502043eae84ee4b279c18b90dd)
     other path: file1 (node 6f4310b00b9a147241b071a60c28a650827fb03d)
-  file extras: file2 (ancestorlinknode = 99726c03216e233810a2564cbc0adfe395007eac)
-  file: file2 (record type "F", state "u", hash cb99b709a1978bd205ab9dfd4c5aaa1fc91c7523)
+    extra: ancestorlinknode = 99726c03216e233810a2564cbc0adfe395007eac
+  file: file2 (state "u")
     local path: file2 (flags "")
     ancestor path: file2 (node 2ed2a3912a0b24502043eae84ee4b279c18b90dd)
     other path: file2 (node 6f4310b00b9a147241b071a60c28a650827fb03d)
+    extra: ancestorlinknode = 99726c03216e233810a2564cbc0adfe395007eac
   $ hg resolve -l
   R file1
   U file2
 
+test json output
+
+  $ hg debugmergestate -T json
+  [
+   {
+    "commits": [{"label": "working copy", "name": "local", "node": "57653b9f834a4493f7240b0681efcb9ae7cab745"}, {"label": "merge rev", "name": "other", "node": "dc77451844e37f03f5c559e3b8529b2b48d381d1"}],
+    "files": [{"ancestor_node": "2ed2a3912a0b24502043eae84ee4b279c18b90dd", "ancestor_path": "file1", "extras": [{"key": "ancestorlinknode", "value": "99726c03216e233810a2564cbc0adfe395007eac"}], "local_flags": "", "local_key": "60b27f004e454aca81b0480209cce5081ec52390", "local_path": "file1", "other_node": "6f4310b00b9a147241b071a60c28a650827fb03d", "other_path": "file1", "path": "file1", "state": "r"}, {"ancestor_node": "2ed2a3912a0b24502043eae84ee4b279c18b90dd", "ancestor_path": "file2", "extras": [{"key": "ancestorlinknode", "value": "99726c03216e233810a2564cbc0adfe395007eac"}], "local_flags": "", "local_key": "cb99b709a1978bd205ab9dfd4c5aaa1fc91c7523", "local_path": "file2", "other_node": "6f4310b00b9a147241b071a60c28a650827fb03d", "other_path": "file2", "path": "file2", "state": "u"}]
+   }
+  ]
+
+
 insert unsupported mandatory merge record
 
   $ hg --config extensions.fakemergerecord=$TESTDIR/fakemergerecord.py fakemergerecord -X
   $ hg debugmergestate
-  * version 2 records
-  local: 57653b9f834a4493f7240b0681efcb9ae7cab745
-  other: dc77451844e37f03f5c559e3b8529b2b48d381d1
-  labels:
-    local: working copy
-    other: merge rev
-  file extras: file1 (ancestorlinknode = 99726c03216e233810a2564cbc0adfe395007eac)
-  file: file1 (record type "F", state "r", hash 60b27f004e454aca81b0480209cce5081ec52390)
-    local path: file1 (flags "")
-    ancestor path: file1 (node 2ed2a3912a0b24502043eae84ee4b279c18b90dd)
-    other path: file1 (node 6f4310b00b9a147241b071a60c28a650827fb03d)
-  file extras: file2 (ancestorlinknode = 99726c03216e233810a2564cbc0adfe395007eac)
-  file: file2 (record type "F", state "u", hash cb99b709a1978bd205ab9dfd4c5aaa1fc91c7523)
-    local path: file2 (flags "")
-    ancestor path: file2 (node 2ed2a3912a0b24502043eae84ee4b279c18b90dd)
-    other path: file2 (node 6f4310b00b9a147241b071a60c28a650827fb03d)
-  unrecognized entry: X mandatory record
+  abort: unsupported merge state records: X
+  (see https://mercurial-scm.org/wiki/MergeStateRecords for more information)
+  [255]
   $ hg resolve -l
   abort: unsupported merge state records: X
   (see https://mercurial-scm.org/wiki/MergeStateRecords for more information)
diff --git a/tests/test-rebase-abort.t b/tests/test-rebase-abort.t
--- a/tests/test-rebase-abort.t
+++ b/tests/test-rebase-abort.t
@@ -88,18 +88,13 @@
 
   $ hg --config extensions.fakemergerecord=$TESTDIR/fakemergerecord.py fakemergerecord -x
   $ hg debugmergestate
-  * version 2 records
-  local: 3e046f2ecedb793b97ed32108086edd1a162f8bc
-  other: 46f0b057b5c061d276b91491c22151f78698abd2
-  labels:
-    local: dest
-    other: source
-  unrecognized entry: x advisory record
-  file extras: common (ancestorlinknode = 3163e20567cc93074fbb7a53c8b93312e59dbf2c)
-  file: common (record type "F", state "u", hash 94c8c21d08740f5da9eaa38d1f175c592692f0d1)
+  local (dest): 3e046f2ecedb793b97ed32108086edd1a162f8bc
+  other (source): 46f0b057b5c061d276b91491c22151f78698abd2
+  file: common (state "u")
     local path: common (flags "")
     ancestor path: common (node de0a666fdd9c1a0b0698b90d85064d8bd34f74b6)
     other path: common (node 2f6411de53677f6f1048fef5bf888d67a342e0a5)
+    extra: ancestorlinknode = 3163e20567cc93074fbb7a53c8b93312e59dbf2c
   $ hg resolve -l
   U common
 
@@ -107,18 +102,9 @@
 
   $ hg --config extensions.fakemergerecord=$TESTDIR/fakemergerecord.py fakemergerecord -X
   $ hg debugmergestate
-  * version 2 records
-  local: 3e046f2ecedb793b97ed32108086edd1a162f8bc
-  other: 46f0b057b5c061d276b91491c22151f78698abd2
-  labels:
-    local: dest
-    other: source
-  file extras: common (ancestorlinknode = 3163e20567cc93074fbb7a53c8b93312e59dbf2c)
-  file: common (record type "F", state "u", hash 94c8c21d08740f5da9eaa38d1f175c592692f0d1)
-    local path: common (flags "")
-    ancestor path: common (node de0a666fdd9c1a0b0698b90d85064d8bd34f74b6)
-    other path: common (node 2f6411de53677f6f1048fef5bf888d67a342e0a5)
-  unrecognized entry: X mandatory record
+  abort: unsupported merge state records: X
+  (see https://mercurial-scm.org/wiki/MergeStateRecords for more information)
+  [255]
   $ hg resolve -l
   abort: unsupported merge state records: X
   (see https://mercurial-scm.org/wiki/MergeStateRecords for more information)
diff --git a/tests/test-merge-changedelete.t b/tests/test-merge-changedelete.t
--- a/tests/test-merge-changedelete.t
+++ b/tests/test-merge-changedelete.t
@@ -76,27 +76,23 @@
   U file2
   U file3
   --- debugmergestate ---
-  * version 2 records
-  local: 13910f48cf7bdb2a0ba6e24b4900e4fdd5739dd4
-  other: 10f9a0a634e82080907e62f075ab119cbc565ea6
-  labels:
-    local: working copy
-    other: merge rev
-  file extras: file1 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
-  file: file1 (record type "C", state "u", hash 60b27f004e454aca81b0480209cce5081ec52390)
+  local (working copy): 13910f48cf7bdb2a0ba6e24b4900e4fdd5739dd4
+  other (merge rev): 10f9a0a634e82080907e62f075ab119cbc565ea6
+  file: file1 (state "u")
     local path: file1 (flags "")
     ancestor path: file1 (node b8e02f6433738021a065f94175c7cd23db5f05be)
-    other path: file1 (node null)
-  file extras: file2 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
-  file: file2 (record type "C", state "u", hash null)
+    other path: file1 (node 0000000000000000000000000000000000000000)
+    extra: ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff
+  file: file2 (state "u")
     local path: file2 (flags "")
     ancestor path: file2 (node 5d9299349fc01ddd25d0070d149b124d8f10411e)
     other path: file2 (node e7c1328648519852e723de86c0c0525acd779257)
-  file extras: file3 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
-  file: file3 (record type "F", state "u", hash d5b0a58bc47161b1b8a831084b366f757c4f0b11)
+    extra: ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff
+  file: file3 (state "u")
     local path: file3 (flags "")
     ancestor path: file3 (node 2661d26c649684b482d10f91960cc3db683c38b4)
     other path: file3 (node a2644c43e210356772c7772a8674544a62e06beb)
+    extra: ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff
   --- file1 ---
   1
   changed
@@ -145,27 +141,23 @@
   R file2
   U file3
   --- debugmergestate ---
-  * version 2 records
-  local: 13910f48cf7bdb2a0ba6e24b4900e4fdd5739dd4
-  other: 10f9a0a634e82080907e62f075ab119cbc565ea6
-  labels:
-    local: working copy
-    other: merge rev
-  file extras: file1 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
-  file: file1 (record type "C", state "r", hash 60b27f004e454aca81b0480209cce5081ec52390)
+  local (working copy): 13910f48cf7bdb2a0ba6e24b4900e4fdd5739dd4
+  other (merge rev): 10f9a0a634e82080907e62f075ab119cbc565ea6
+  file: file1 (state "r")
     local path: file1 (flags "")
     ancestor path: file1 (node b8e02f6433738021a065f94175c7cd23db5f05be)
-    other path: file1 (node null)
-  file extras: file2 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
-  file: file2 (record type "C", state "r", hash null)
+    other path: file1 (node 0000000000000000000000000000000000000000)
+    extra: ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff
+  file: file2 (state "r")
     local path: file2 (flags "")
     ancestor path: file2 (node 5d9299349fc01ddd25d0070d149b124d8f10411e)
     other path: file2 (node e7c1328648519852e723de86c0c0525acd779257)
-  file extras: file3 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
-  file: file3 (record type "F", state "u", hash d5b0a58bc47161b1b8a831084b366f757c4f0b11)
+    extra: ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff
+  file: file3 (state "u")
     local path: file3 (flags "")
     ancestor path: file3 (node 2661d26c649684b482d10f91960cc3db683c38b4)
     other path: file3 (node a2644c43e210356772c7772a8674544a62e06beb)
+    extra: ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff
   --- file1 ---
   1
   changed
@@ -227,27 +219,23 @@
   R file2
   U file3
   --- debugmergestate ---
-  * version 2 records
-  local: 13910f48cf7bdb2a0ba6e24b4900e4fdd5739dd4
-  other: 10f9a0a634e82080907e62f075ab119cbc565ea6
-  labels:
-    local: working copy
-    other: merge rev
-  file extras: file1 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
-  file: file1 (record type "C", state "r", hash 60b27f004e454aca81b0480209cce5081ec52390)
+  local (working copy): 13910f48cf7bdb2a0ba6e24b4900e4fdd5739dd4
+  other (merge rev): 10f9a0a634e82080907e62f075ab119cbc565ea6
+  file: file1 (state "r")
     local path: file1 (flags "")
     ancestor path: file1 (node b8e02f6433738021a065f94175c7cd23db5f05be)
-    other path: file1 (node null)
-  file extras: file2 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
-  file: file2 (record type "C", state "r", hash null)
+    other path: file1 (node 0000000000000000000000000000000000000000)
+    extra: ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff
+  file: file2 (state "r")
     local path: file2 (flags "")
     ancestor path: file2 (node 5d9299349fc01ddd25d0070d149b124d8f10411e)
     other path: file2 (node e7c1328648519852e723de86c0c0525acd779257)
-  file extras: file3 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
-  file: file3 (record type "F", state "u", hash d5b0a58bc47161b1b8a831084b366f757c4f0b11)
+    extra: ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff
+  file: file3 (state "u")
     local path: file3 (flags "")
     ancestor path: file3 (node 2661d26c649684b482d10f91960cc3db683c38b4)
     other path: file3 (node a2644c43e210356772c7772a8674544a62e06beb)
+    extra: ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff
   *** file1 does not exist
   --- file2 ---
   2
@@ -293,27 +281,23 @@
   U file2
   U file3
   --- debugmergestate ---
-  * version 2 records
-  local: 13910f48cf7bdb2a0ba6e24b4900e4fdd5739dd4
-  other: 10f9a0a634e82080907e62f075ab119cbc565ea6
-  labels:
-    local: working copy
-    other: merge rev
-  file extras: file1 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
-  file: file1 (record type "C", state "r", hash 60b27f004e454aca81b0480209cce5081ec52390)
+  local (working copy): 13910f48cf7bdb2a0ba6e24b4900e4fdd5739dd4
+  other (merge rev): 10f9a0a634e82080907e62f075ab119cbc565ea6
+  file: file1 (state "r")
     local path: file1 (flags "")
     ancestor path: file1 (node b8e02f6433738021a065f94175c7cd23db5f05be)
-    other path: file1 (node null)
-  file extras: file2 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
-  file: file2 (record type "C", state "u", hash null)
+    other path: file1 (node 0000000000000000000000000000000000000000)
+    extra: ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff
+  file: file2 (state "u")
     local path: file2 (flags "")
     ancestor path: file2 (node 5d9299349fc01ddd25d0070d149b124d8f10411e)
     other path: file2 (node e7c1328648519852e723de86c0c0525acd779257)
-  file extras: file3 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
-  file: file3 (record type "F", state "u", hash d5b0a58bc47161b1b8a831084b366f757c4f0b11)
+    extra: ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff
+  file: file3 (state "u")
     local path: file3 (flags "")
     ancestor path: file3 (node 2661d26c649684b482d10f91960cc3db683c38b4)
     other path: file3 (node a2644c43e210356772c7772a8674544a62e06beb)
+    extra: ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff
   *** file1 does not exist
   --- file2 ---
   2
@@ -346,27 +330,23 @@
   R file2
   R file3
   --- debugmergestate ---
-  * version 2 records
-  local: 13910f48cf7bdb2a0ba6e24b4900e4fdd5739dd4
-  other: 10f9a0a634e82080907e62f075ab119cbc565ea6
-  labels:
-    local: working copy
-    other: merge rev
-  file extras: file1 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
-  file: file1 (record type "C", state "r", hash 60b27f004e454aca81b0480209cce5081ec52390)
+  local (working copy): 13910f48cf7bdb2a0ba6e24b4900e4fdd5739dd4
+  other (merge rev): 10f9a0a634e82080907e62f075ab119cbc565ea6
+  file: file1 (state "r")
     local path: file1 (flags "")
     ancestor path: file1 (node b8e02f6433738021a065f94175c7cd23db5f05be)
-    other path: file1 (node null)
-  file extras: file2 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
-  file: file2 (record type "C", state "r", hash null)
+    other path: file1 (node 0000000000000000000000000000000000000000)
+    extra: ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff
+  file: file2 (state "r")
     local path: file2 (flags "")
     ancestor path: file2 (node 5d9299349fc01ddd25d0070d149b124d8f10411e)
     other path: file2 (node e7c1328648519852e723de86c0c0525acd779257)
-  file extras: file3 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
-  file: file3 (record type "F", state "r", hash d5b0a58bc47161b1b8a831084b366f757c4f0b11)
+    extra: ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff
+  file: file3 (state "r")
     local path: file3 (flags "")
     ancestor path: file3 (node 2661d26c649684b482d10f91960cc3db683c38b4)
     other path: file3 (node a2644c43e210356772c7772a8674544a62e06beb)
+    extra: ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff
   --- file1 ---
   1
   changed
@@ -395,27 +375,23 @@
   R file2
   R file3
   --- debugmergestate ---
-  * version 2 records
-  local: 13910f48cf7bdb2a0ba6e24b4900e4fdd5739dd4
-  other: 10f9a0a634e82080907e62f075ab119cbc565ea6
-  labels:
-    local: working copy
-    other: merge rev
-  file extras: file1 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
-  file: file1 (record type "C", state "r", hash 60b27f004e454aca81b0480209cce5081ec52390)
+  local (working copy): 13910f48cf7bdb2a0ba6e24b4900e4fdd5739dd4
+  other (merge rev): 10f9a0a634e82080907e62f075ab119cbc565ea6
+  file: file1 (state "r")
     local path: file1 (flags "")
     ancestor path: file1 (node b8e02f6433738021a065f94175c7cd23db5f05be)
-    other path: file1 (node null)
-  file extras: file2 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
-  file: file2 (record type "C", state "r", hash null)
+    other path: file1 (node 0000000000000000000000000000000000000000)
+    extra: ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff
+  file: file2 (state "r")
     local path: file2 (flags "")
     ancestor path: file2 (node 5d9299349fc01ddd25d0070d149b124d8f10411e)
     other path: file2 (node e7c1328648519852e723de86c0c0525acd779257)
-  file extras: file3 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
-  file: file3 (record type "F", state "r", hash d5b0a58bc47161b1b8a831084b366f757c4f0b11)
+    extra: ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff
+  file: file3 (state "r")
     local path: file3 (flags "")
     ancestor path: file3 (node 2661d26c649684b482d10f91960cc3db683c38b4)
     other path: file3 (node a2644c43e210356772c7772a8674544a62e06beb)
+    extra: ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff
   *** file1 does not exist
   --- file2 ---
   2
@@ -445,27 +421,23 @@
   U file2
   U file3
   --- debugmergestate ---
-  * version 2 records
-  local: 13910f48cf7bdb2a0ba6e24b4900e4fdd5739dd4
-  other: 10f9a0a634e82080907e62f075ab119cbc565ea6
-  labels:
-    local: working copy
-    other: merge rev
-  file extras: file1 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
-  file: file1 (record type "C", state "u", hash 60b27f004e454aca81b0480209cce5081ec52390)
+  local (working copy): 13910f48cf7bdb2a0ba6e24b4900e4fdd5739dd4
+  other (merge rev): 10f9a0a634e82080907e62f075ab119cbc565ea6
+  file: file1 (state "u")
     local path: file1 (flags "")
     ancestor path: file1 (node b8e02f6433738021a065f94175c7cd23db5f05be)
-    other path: file1 (node null)
-  file extras: file2 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
-  file: file2 (record type "C", state "u", hash null)
+    other path: file1 (node 0000000000000000000000000000000000000000)
+    extra: ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff
+  file: file2 (state "u")
     local path: file2 (flags "")
     ancestor path: file2 (node 5d9299349fc01ddd25d0070d149b124d8f10411e)
     other path: file2 (node e7c1328648519852e723de86c0c0525acd779257)
-  file extras: file3 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
-  file: file3 (record type "F", state "u", hash d5b0a58bc47161b1b8a831084b366f757c4f0b11)
+    extra: ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff
+  file: file3 (state "u")
     local path: file3 (flags "")
     ancestor path: file3 (node 2661d26c649684b482d10f91960cc3db683c38b4)
     other path: file3 (node a2644c43e210356772c7772a8674544a62e06beb)
+    extra: ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff
   --- file1 ---
   1
   changed
@@ -506,27 +478,23 @@
   U file2
   U file3
   --- debugmergestate ---
-  * version 2 records
-  local: 13910f48cf7bdb2a0ba6e24b4900e4fdd5739dd4
-  other: 10f9a0a634e82080907e62f075ab119cbc565ea6
-  labels:
-    local: working copy
-    other: merge rev
-  file extras: file1 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
-  file: file1 (record type "C", state "u", hash 60b27f004e454aca81b0480209cce5081ec52390)
+  local (working copy): 13910f48cf7bdb2a0ba6e24b4900e4fdd5739dd4
+  other (merge rev): 10f9a0a634e82080907e62f075ab119cbc565ea6
+  file: file1 (state "u")
     local path: file1 (flags "")
     ancestor path: file1 (node b8e02f6433738021a065f94175c7cd23db5f05be)
-    other path: file1 (node null)
-  file extras: file2 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
-  file: file2 (record type "C", state "u", hash null)
+    other path: file1 (node 0000000000000000000000000000000000000000)
+    extra: ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff
+  file: file2 (state "u")
     local path: file2 (flags "")
     ancestor path: file2 (node 5d9299349fc01ddd25d0070d149b124d8f10411e)
     other path: file2 (node e7c1328648519852e723de86c0c0525acd779257)
-  file extras: file3 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
-  file: file3 (record type "F", state "u", hash d5b0a58bc47161b1b8a831084b366f757c4f0b11)
+    extra: ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff
+  file: file3 (state "u")
     local path: file3 (flags "")
     ancestor path: file3 (node 2661d26c649684b482d10f91960cc3db683c38b4)
     other path: file3 (node a2644c43e210356772c7772a8674544a62e06beb)
+    extra: ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff
   --- file1 ---
   1
   changed
@@ -569,27 +537,23 @@
   U file2
   U file3
   --- debugmergestate ---
-  * version 2 records
-  local: 13910f48cf7bdb2a0ba6e24b4900e4fdd5739dd4
-  other: 10f9a0a634e82080907e62f075ab119cbc565ea6
-  labels:
-    local: working copy
-    other: merge rev
-  file extras: file1 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
-  file: file1 (record type "C", state "u", hash 60b27f004e454aca81b0480209cce5081ec52390)
+  local (working copy): 13910f48cf7bdb2a0ba6e24b4900e4fdd5739dd4
+  other (merge rev): 10f9a0a634e82080907e62f075ab119cbc565ea6
+  file: file1 (state "u")
     local path: file1 (flags "")
     ancestor path: file1 (node b8e02f6433738021a065f94175c7cd23db5f05be)
-    other path: file1 (node null)
-  file extras: file2 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
-  file: file2 (record type "C", state "u", hash null)
+    other path: file1 (node 0000000000000000000000000000000000000000)
+    extra: ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff
+  file: file2 (state "u")
     local path: file2 (flags "")
     ancestor path: file2 (node 5d9299349fc01ddd25d0070d149b124d8f10411e)
     other path: file2 (node e7c1328648519852e723de86c0c0525acd779257)
-  file extras: file3 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
-  file: file3 (record type "F", state "u", hash d5b0a58bc47161b1b8a831084b366f757c4f0b11)
+    extra: ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff
+  file: file3 (state "u")
     local path: file3 (flags "")
     ancestor path: file3 (node 2661d26c649684b482d10f91960cc3db683c38b4)
     other path: file3 (node a2644c43e210356772c7772a8674544a62e06beb)
+    extra: ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff
   --- file1 ---
   1
   changed
@@ -629,27 +593,23 @@
   U file2
   U file3
   --- debugmergestate ---
-  * version 2 records
-  local: 13910f48cf7bdb2a0ba6e24b4900e4fdd5739dd4
-  other: 10f9a0a634e82080907e62f075ab119cbc565ea6
-  labels:
-    local: working copy
-    other: merge rev
-  file extras: file1 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
-  file: file1 (record type "C", state "u", hash 60b27f004e454aca81b0480209cce5081ec52390)
+  local (working copy): 13910f48cf7bdb2a0ba6e24b4900e4fdd5739dd4
+  other (merge rev): 10f9a0a634e82080907e62f075ab119cbc565ea6
+  file: file1 (state "u")
     local path: file1 (flags "")
     ancestor path: file1 (node b8e02f6433738021a065f94175c7cd23db5f05be)
-    other path: file1 (node null)
-  file extras: file2 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
-  file: file2 (record type "C", state "u", hash null)
+    other path: file1 (node 0000000000000000000000000000000000000000)
+    extra: ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff
+  file: file2 (state "u")
     local path: file2 (flags "")
     ancestor path: file2 (node 5d9299349fc01ddd25d0070d149b124d8f10411e)
     other path: file2 (node e7c1328648519852e723de86c0c0525acd779257)
-  file extras: file3 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
-  file: file3 (record type "F", state "u", hash d5b0a58bc47161b1b8a831084b366f757c4f0b11)
+    extra: ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff
+  file: file3 (state "u")
     local path: file3 (flags "")
     ancestor path: file3 (node 2661d26c649684b482d10f91960cc3db683c38b4)
     other path: file3 (node a2644c43e210356772c7772a8674544a62e06beb)
+    extra: ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff
   --- file1 ---
   1
   changed
@@ -802,22 +762,18 @@
   U file1
   U file2
   --- debugmergestate ---
-  * version 2 records
-  local: ab57bf49aa276a22d35a473592d4c34b5abc3eff
-  other: 10f9a0a634e82080907e62f075ab119cbc565ea6
-  labels:
-    local: working copy
-    other: destination
-  file extras: file1 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
-  file: file1 (record type "C", state "u", hash 60b27f004e454aca81b0480209cce5081ec52390)
+  local (working copy): ab57bf49aa276a22d35a473592d4c34b5abc3eff
+  other (destination): 10f9a0a634e82080907e62f075ab119cbc565ea6
+  file: file1 (state "u")
     local path: file1 (flags "")
     ancestor path: file1 (node b8e02f6433738021a065f94175c7cd23db5f05be)
-    other path: file1 (node null)
-  file extras: file2 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
-  file: file2 (record type "C", state "u", hash null)
+    other path: file1 (node 0000000000000000000000000000000000000000)
+    extra: ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff
+  file: file2 (state "u")
     local path: file2 (flags "")
     ancestor path: file2 (node 5d9299349fc01ddd25d0070d149b124d8f10411e)
     other path: file2 (node e7c1328648519852e723de86c0c0525acd779257)
+    extra: ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff
   --- file1 ---
   1
   changed
@@ -845,22 +801,18 @@
   R file1
   R file2
   --- debugmergestate ---
-  * version 2 records
-  local: ab57bf49aa276a22d35a473592d4c34b5abc3eff
-  other: 10f9a0a634e82080907e62f075ab119cbc565ea6
-  labels:
-    local: working copy
-    other: destination
-  file extras: file1 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
-  file: file1 (record type "C", state "r", hash 60b27f004e454aca81b0480209cce5081ec52390)
+  local (working copy): ab57bf49aa276a22d35a473592d4c34b5abc3eff
+  other (destination): 10f9a0a634e82080907e62f075ab119cbc565ea6
+  file: file1 (state "r")
     local path: file1 (flags "")
     ancestor path: file1 (node b8e02f6433738021a065f94175c7cd23db5f05be)
-    other path: file1 (node null)
-  file extras: file2 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
-  file: file2 (record type "C", state "r", hash null)
+    other path: file1 (node 0000000000000000000000000000000000000000)
+    extra: ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff
+  file: file2 (state "r")
     local path: file2 (flags "")
     ancestor path: file2 (node 5d9299349fc01ddd25d0070d149b124d8f10411e)
     other path: file2 (node e7c1328648519852e723de86c0c0525acd779257)
+    extra: ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff
   --- file1 ---
   1
   changed
@@ -886,22 +838,18 @@
   R file1
   R file2
   --- debugmergestate ---
-  * version 2 records
-  local: ab57bf49aa276a22d35a473592d4c34b5abc3eff
-  other: 10f9a0a634e82080907e62f075ab119cbc565ea6
-  labels:
-    local: working copy
-    other: destination
-  file extras: file1 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
-  file: file1 (record type "C", state "r", hash 60b27f004e454aca81b0480209cce5081ec52390)
+  local (working copy): ab57bf49aa276a22d35a473592d4c34b5abc3eff
+  other (destination): 10f9a0a634e82080907e62f075ab119cbc565ea6
+  file: file1 (state "r")
     local path: file1 (flags "")
     ancestor path: file1 (node b8e02f6433738021a065f94175c7cd23db5f05be)
-    other path: file1 (node null)
-  file extras: file2 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
-  file: file2 (record type "C", state "r", hash null)
+    other path: file1 (node 0000000000000000000000000000000000000000)
+    extra: ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff
+  file: file2 (state "r")
     local path: file2 (flags "")
     ancestor path: file2 (node 5d9299349fc01ddd25d0070d149b124d8f10411e)
     other path: file2 (node e7c1328648519852e723de86c0c0525acd779257)
+    extra: ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff
   *** file1 does not exist
   --- file2 ---
   2
@@ -929,22 +877,18 @@
   U file1
   U file2
   --- debugmergestate ---
-  * version 2 records
-  local: ab57bf49aa276a22d35a473592d4c34b5abc3eff
-  other: 10f9a0a634e82080907e62f075ab119cbc565ea6
-  labels:
-    local: working copy
-    other: destination
-  file extras: file1 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
-  file: file1 (record type "C", state "u", hash 60b27f004e454aca81b0480209cce5081ec52390)
+  local (working copy): ab57bf49aa276a22d35a473592d4c34b5abc3eff
+  other (destination): 10f9a0a634e82080907e62f075ab119cbc565ea6
+  file: file1 (state "u")
     local path: file1 (flags "")
     ancestor path: file1 (node b8e02f6433738021a065f94175c7cd23db5f05be)
-    other path: file1 (node null)
-  file extras: file2 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
-  file: file2 (record type "C", state "u", hash null)
+    other path: file1 (node 0000000000000000000000000000000000000000)
+    extra: ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff
+  file: file2 (state "u")
     local path: file2 (flags "")
     ancestor path: file2 (node 5d9299349fc01ddd25d0070d149b124d8f10411e)
     other path: file2 (node e7c1328648519852e723de86c0c0525acd779257)
+    extra: ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff
   --- file1 ---
   1
   changed
@@ -980,22 +924,18 @@
   U file1
   U file2
   --- debugmergestate ---
-  * version 2 records
-  local: ab57bf49aa276a22d35a473592d4c34b5abc3eff
-  other: 10f9a0a634e82080907e62f075ab119cbc565ea6
-  labels:
-    local: working copy
-    other: destination
-  file extras: file1 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
-  file: file1 (record type "C", state "u", hash 60b27f004e454aca81b0480209cce5081ec52390)
+  local (working copy): ab57bf49aa276a22d35a473592d4c34b5abc3eff
+  other (destination): 10f9a0a634e82080907e62f075ab119cbc565ea6
+  file: file1 (state "u")
     local path: file1 (flags "")
     ancestor path: file1 (node b8e02f6433738021a065f94175c7cd23db5f05be)
-    other path: file1 (node null)
-  file extras: file2 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
-  file: file2 (record type "C", state "u", hash null)
+    other path: file1 (node 0000000000000000000000000000000000000000)
+    extra: ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff
+  file: file2 (state "u")
     local path: file2 (flags "")
     ancestor path: file2 (node 5d9299349fc01ddd25d0070d149b124d8f10411e)
     other path: file2 (node e7c1328648519852e723de86c0c0525acd779257)
+    extra: ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff
   --- file1 ---
   1
   changed
@@ -1032,22 +972,18 @@
   U file1
   U file2
   --- debugmergestate ---
-  * version 2 records
-  local: ab57bf49aa276a22d35a473592d4c34b5abc3eff
-  other: 10f9a0a634e82080907e62f075ab119cbc565ea6
-  labels:
-    local: working copy
-    other: destination
-  file extras: file1 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
-  file: file1 (record type "C", state "u", hash 60b27f004e454aca81b0480209cce5081ec52390)
+  local (working copy): ab57bf49aa276a22d35a473592d4c34b5abc3eff
+  other (destination): 10f9a0a634e82080907e62f075ab119cbc565ea6
+  file: file1 (state "u")
     local path: file1 (flags "")
     ancestor path: file1 (node b8e02f6433738021a065f94175c7cd23db5f05be)
-    other path: file1 (node null)
-  file extras: file2 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
-  file: file2 (record type "C", state "u", hash null)
+    other path: file1 (node 0000000000000000000000000000000000000000)
+    extra: ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff
+  file: file2 (state "u")
     local path: file2 (flags "")
     ancestor path: file2 (node 5d9299349fc01ddd25d0070d149b124d8f10411e)
     other path: file2 (node e7c1328648519852e723de86c0c0525acd779257)
+    extra: ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff
   --- file1 ---
   1
   changed
diff --git a/tests/test-histedit-non-commute-abort.t b/tests/test-histedit-non-commute-abort.t
--- a/tests/test-histedit-non-commute-abort.t
+++ b/tests/test-histedit-non-commute-abort.t
@@ -77,36 +77,22 @@
 insert unsupported advisory merge record
   $ hg --config extensions.fakemergerecord=$TESTDIR/fakemergerecord.py fakemergerecord -x
   $ hg debugmergestate
-  * version 2 records
-  local: 8f7551c7e4a2f2efe0bc8c741baf7f227d65d758
-  other: e860deea161a2f77de56603b340ebbb4536308ae
-  labels:
-    local: local
-    other: histedit
-  unrecognized entry: x advisory record
-  file extras: e (ancestorlinknode = 0000000000000000000000000000000000000000)
-  file: e (record type "F", state "u", hash 58e6b3a414a1e090dfc6029add0f3555ccba127f)
+  local (local): 8f7551c7e4a2f2efe0bc8c741baf7f227d65d758
+  other (histedit): e860deea161a2f77de56603b340ebbb4536308ae
+  file: e (state "u")
     local path: e (flags "")
-    ancestor path: e (node null)
+    ancestor path: e (node 0000000000000000000000000000000000000000)
     other path: e (node 6b67ccefd5ce6de77e7ead4f5292843a0255329f)
+    extra: ancestorlinknode = 0000000000000000000000000000000000000000
   $ hg resolve -l
   U e
 
 insert unsupported mandatory merge record
   $ hg --config extensions.fakemergerecord=$TESTDIR/fakemergerecord.py fakemergerecord -X
   $ hg debugmergestate
-  * version 2 records
-  local: 8f7551c7e4a2f2efe0bc8c741baf7f227d65d758
-  other: e860deea161a2f77de56603b340ebbb4536308ae
-  labels:
-    local: local
-    other: histedit
-  file extras: e (ancestorlinknode = 0000000000000000000000000000000000000000)
-  file: e (record type "F", state "u", hash 58e6b3a414a1e090dfc6029add0f3555ccba127f)
-    local path: e (flags "")
-    ancestor path: e (node null)
-    other path: e (node 6b67ccefd5ce6de77e7ead4f5292843a0255329f)
-  unrecognized entry: X mandatory record
+  abort: unsupported merge state records: X
+  (see https://mercurial-scm.org/wiki/MergeStateRecords for more information)
+  [255]
   $ hg resolve -l
   abort: unsupported merge state records: X
   (see https://mercurial-scm.org/wiki/MergeStateRecords for more information)
diff --git a/tests/test-completion.t b/tests/test-completion.t
--- a/tests/test-completion.t
+++ b/tests/test-completion.t
@@ -289,7 +289,7 @@
   debuglabelcomplete:
   debuglocks: force-lock, force-wlock, set-lock, set-wlock
   debugmanifestfulltextcache: clear, add
-  debugmergestate:
+  debugmergestate: style, template
   debugnamecomplete:
   debugnodemap: dump-new, dump-disk, check, metadata
   debugobsolete: flags, record-parents, rev, exclusive, index, delete, date, user, template
diff --git a/tests/test-backout.t b/tests/test-backout.t
--- a/tests/test-backout.t
+++ b/tests/test-backout.t
@@ -710,22 +710,21 @@
   [1]
   $ hg status
   $ hg debugmergestate
-  * version 2 records
   local: b71750c4b0fdf719734971e3ef90dbeab5919a2d
   other: a30dd8addae3ce71b8667868478542bc417439e6
-  file extras: foo (ancestorlinknode = 91360952243723bd5b1138d5f26bd8c8564cb553)
-  file: foo (record type "F", state "u", hash 0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33)
+  file: foo (state "u")
     local path: foo (flags "")
     ancestor path: foo (node f89532f44c247a0e993d63e3a734dd781ab04708)
     other path: foo (node f50039b486d6fa1a90ae51778388cad161f425ee)
+    extra: ancestorlinknode = 91360952243723bd5b1138d5f26bd8c8564cb553
   $ mv .hg/merge/state2 .hg/merge/state2-moved
   $ hg debugmergestate
-  * version 1 records
   local: b71750c4b0fdf719734971e3ef90dbeab5919a2d
-  file: foo (record type "F", state "u", hash 0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33)
+  other: b71750c4b0fdf719734971e3ef90dbeab5919a2d
+  file: foo (state "u")
     local path: foo (flags "")
     ancestor path: foo (node f89532f44c247a0e993d63e3a734dd781ab04708)
-    other path: foo (node not stored in v1 format)
+    other path:  (node foo)
   $ mv .hg/merge/state2-moved .hg/merge/state2
   $ hg resolve -l  # still unresolved
   U foo
diff --git a/mercurial/debugcommands.py b/mercurial/debugcommands.py
--- a/mercurial/debugcommands.py
+++ b/mercurial/debugcommands.py
@@ -28,7 +28,6 @@
 from .node import (
     bin,
     hex,
-    nullhex,
     nullid,
     nullrev,
     short,
@@ -1944,120 +1943,84 @@
         )
 
 
-@command(b'debugmergestate', [], b'')
-def debugmergestate(ui, repo, *args):
+@command(b'debugmergestate', [] + cmdutil.templateopts, b'')
+def debugmergestate(ui, repo, *args, **opts):
     """print merge state
 
     Use --verbose to print out information about whether v1 or v2 merge state
     was chosen."""
 
-    def _hashornull(h):
-        if h == nullhex:
-            return b'null'
-        else:
-            return h
-
-    def printrecords(version):
-        ui.writenoi18n(b'* version %d records\n' % version)
-        if version == 1:
-            records = v1records
+    if ui.verbose:
+        ms = mergemod.mergestate(repo)
+
+        # sort so that reasonable information is on top
+        v1records = ms._readrecordsv1()
+        v2records = ms._readrecordsv2()
+
+        if not v1records and not v2records:
+            pass
+        elif not v2records:
+            ui.writenoi18n(b'no version 2 merge state\n')
+        elif ms._v1v2match(v1records, v2records):
+            ui.writenoi18n(b'v1 and v2 states match: using v2\n')
         else:
-            records = v2records
-
-        for rtype, record in records:
-            # pretty print some record types
-            if rtype == b'L':
-                ui.writenoi18n(b'local: %s\n' % record)
-            elif rtype == b'O':
-                ui.writenoi18n(b'other: %s\n' % record)
-            elif rtype == b'm':
-                driver, mdstate = record.split(b'\0', 1)
-                ui.writenoi18n(
-                    b'merge driver: %s (state "%s")\n' % (driver, mdstate)
-                )
-            elif rtype in b'FDC':
-                r = record.split(b'\0')
-                f, state, hash, lfile, afile, anode, ofile = r[0:7]
-                if version == 1:
-                    onode = b'not stored in v1 format'
-                    flags = r[7]
-                else:
-                    onode, flags = r[7:9]
-                ui.writenoi18n(
-                    b'file: %s (record type "%s", state "%s", hash %s)\n'
-                    % (f, rtype, state, _hashornull(hash))
-                )
-                ui.writenoi18n(
-                    b'  local path: %s (flags "%s")\n' % (lfile, flags)
-                )
-                ui.writenoi18n(
-                    b'  ancestor path: %s (node %s)\n'
-                    % (afile, _hashornull(anode))
-                )
-                ui.writenoi18n(
-                    b'  other path: %s (node %s)\n'
-                    % (ofile, _hashornull(onode))
-                )
-            elif rtype == b'f':
-                filename, rawextras = record.split(b'\0', 1)
-                extras = rawextras.split(b'\0')
-                i = 0
-                extrastrings = []
-                while i < len(extras):
-                    extrastrings.append(b'%s = %s' % (extras[i], extras[i + 1]))
-                    i += 2
-
-                ui.writenoi18n(
-                    b'file extras: %s (%s)\n'
-                    % (filename, b', '.join(extrastrings))
-                )
-            elif rtype == b'l':
-                labels = record.split(b'\0', 2)
-                labels = [l for l in labels if len(l) > 0]
-                ui.writenoi18n(b'labels:\n')
-                ui.write((b'  local: %s\n' % labels[0]))
-                ui.write((b'  other: %s\n' % labels[1]))
-                if len(labels) > 2:
-                    ui.write((b'  base:  %s\n' % labels[2]))
-            else:
-                ui.writenoi18n(
-                    b'unrecognized entry: %s\t%s\n'
-                    % (rtype, record.replace(b'\0', b'\t'))
-                )
-
-    # Avoid mergestate.read() since it may raise an exception for unsupported
-    # merge state records. We shouldn't be doing this, but this is OK since this
-    # command is pretty low-level.
-    ms = mergemod.mergestate(repo)
-
-    # sort so that reasonable information is on top
-    v1records = ms._readrecordsv1()
-    v2records = ms._readrecordsv2()
-    order = b'LOml'
-
-    def key(r):
-        idx = order.find(r[0])
-        if idx == -1:
-            return (1, r[1])
-        else:
-            return (0, idx)
-
-    v1records.sort(key=key)
-    v2records.sort(key=key)
-
-    if not v1records and not v2records:
-        ui.writenoi18n(b'no merge state found\n')
-    elif not v2records:
-        ui.notenoi18n(b'no version 2 merge state\n')
-        printrecords(1)
-    elif ms._v1v2match(v1records, v2records):
-        ui.notenoi18n(b'v1 and v2 states match: using v2\n')
-        printrecords(2)
-    else:
-        ui.notenoi18n(b'v1 and v2 states mismatch: using v1\n')
-        printrecords(1)
-        if ui.verbose:
-            printrecords(2)
+            ui.writenoi18n(b'v1 and v2 states mismatch: using v1\n')
+
+    opts = pycompat.byteskwargs(opts)
+    if not opts[b'template']:
+        opts[b'template'] = (
+            b'{if(commits, "", "no merge state found\n")}'
+            b'{commits % "{name}{if(label, " ({label})")}: {node}\n"}'
+            b'{files % "file: {path} (state \\"{state}\\")\n'
+            b'  local path: {local_path} (flags \\"{local_flags}\\")\n'
+            b'  ancestor path: {ancestor_path} (node {ancestor_node})\n'
+            b'  other path: {other_path} (node {other_node})\n'
+            b'{extras % "  extra: {key} = {value}\n"}'
+            b'"}'
+        )
+
+    ms = mergemod.mergestate.read(repo)
+
+    fm = ui.formatter(b'debugmergestate', opts)
+    fm.startitem()
+
+    fm_commits = fm.nested(b'commits')
+    if ms.active():
+        for name, node, label_index in (
+            (b'local', ms.local, 0),
+            (b'other', ms.other, 1),
+        ):
+            fm_commits.startitem()
+            fm_commits.data(name=name)
+            fm_commits.data(node=hex(node))
+            if ms._labels and len(ms._labels) > label_index:
+                fm_commits.data(label=ms._labels[label_index])
+    fm_commits.end()
+
+    fm_files = fm.nested(b'files')
+    if ms.active():
+        for f in ms:
+            fm_files.startitem()
+            fm_files.data(path=f)
+            state = ms._state[f]
+            fm_files.data(state=state[0])
+            fm_files.data(local_key=state[1])
+            fm_files.data(local_path=state[2])
+            fm_files.data(ancestor_path=state[3])
+            fm_files.data(ancestor_node=state[4])
+            fm_files.data(other_path=state[5])
+            fm_files.data(other_node=state[6])
+            fm_files.data(local_flags=state[7])
+            fm_extras = fm_files.nested(b'extras')
+            for k, v in ms.extras(f).items():
+                fm_extras.startitem()
+                fm_extras.data(key=k)
+                fm_extras.data(value=v)
+            fm_extras.end()
+
+    fm_files.end()
+
+    fm.end()
 
 
 @command(b'debugnamecomplete', [], _(b'NAME...'))



To: martinvonz, #hg-reviewers, durin42
Cc: durin42, mercurial-devel
_______________________________________________
Mercurial-devel mailing list
[hidden email]
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Reply | Threaded
Open this post in threaded view
|

D8113: debugmergestate: make templated

marmoute (Pierre-Yves David)
In reply to this post by marmoute (Pierre-Yves David)
pulkit added a comment.


  Will be nice to add some release notes either in BC section or in features section stating `debugmergestate` now supports templates and can be used by scripts/editors.

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D8113/new/

REVISION DETAIL
  https://phab.mercurial-scm.org/D8113

To: martinvonz, #hg-reviewers, durin42
Cc: pulkit, durin42, mercurial-devel
_______________________________________________
Mercurial-devel mailing list
[hidden email]
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Reply | Threaded
Open this post in threaded view
|

D8113: debugmergestate: make templated

marmoute (Pierre-Yves David)
In reply to this post by marmoute (Pierre-Yves David)
martinvonz added a comment.


  In D8113#120745 <https://phab.mercurial-scm.org/D8113#120745>, @pulkit wrote:
 
  > Will be nice to add some release notes either in BC section or in features section stating `debugmergestate` now supports templates and can be used by scripts/editors.
 
 
 
    Ah, good point, will do.

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D8113/new/

REVISION DETAIL
  https://phab.mercurial-scm.org/D8113

To: martinvonz, #hg-reviewers, durin42
Cc: pulkit, durin42, mercurial-devel
_______________________________________________
Mercurial-devel mailing list
[hidden email]
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Reply | Threaded
Open this post in threaded view
|

D8113: debugmergestate: make templated

marmoute (Pierre-Yves David)
In reply to this post by marmoute (Pierre-Yves David)
martinvonz added a comment.


  In D8113#120746 <https://phab.mercurial-scm.org/D8113#120746>, @martinvonz wrote:
 
  > In D8113#120745 <https://phab.mercurial-scm.org/D8113#120745>, @pulkit wrote:
  >
  >> Will be nice to add some release notes either in BC section or in features section stating `debugmergestate` now supports templates and can be used by scripts/editors.
  >
  >   Ah, good point, will do.
 
  I did both :)

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D8113/new/

REVISION DETAIL
  https://phab.mercurial-scm.org/D8113

To: martinvonz, #hg-reviewers, durin42
Cc: pulkit, durin42, mercurial-devel
_______________________________________________
Mercurial-devel mailing list
[hidden email]
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Reply | Threaded
Open this post in threaded view
|

D8113: debugmergestate: make templated

marmoute (Pierre-Yves David)
In reply to this post by marmoute (Pierre-Yves David)
martinvonz updated this revision to Diff 20203.

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D8113?vs=20202&id=20203

BRANCH
  default

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D8113/new/

REVISION DETAIL
  https://phab.mercurial-scm.org/D8113

AFFECTED FILES
  mercurial/debugcommands.py
  relnotes/next
  tests/test-backout.t
  tests/test-completion.t
  tests/test-histedit-non-commute-abort.t
  tests/test-merge-changedelete.t
  tests/test-rebase-abort.t
  tests/test-resolve.t

CHANGE DETAILS

diff --git a/tests/test-resolve.t b/tests/test-resolve.t
--- a/tests/test-resolve.t
+++ b/tests/test-resolve.t
@@ -306,48 +306,40 @@
 
   $ hg --config extensions.fakemergerecord=$TESTDIR/fakemergerecord.py fakemergerecord -x
   $ hg debugmergestate
-  * version 2 records
-  local: 57653b9f834a4493f7240b0681efcb9ae7cab745
-  other: dc77451844e37f03f5c559e3b8529b2b48d381d1
-  labels:
-    local: working copy
-    other: merge rev
-  unrecognized entry: x advisory record
-  file extras: file1 (ancestorlinknode = 99726c03216e233810a2564cbc0adfe395007eac)
-  file: file1 (record type "F", state "r", hash 60b27f004e454aca81b0480209cce5081ec52390)
+  local (working copy): 57653b9f834a4493f7240b0681efcb9ae7cab745
+  other (merge rev): dc77451844e37f03f5c559e3b8529b2b48d381d1
+  file: file1 (state "r")
     local path: file1 (flags "")
     ancestor path: file1 (node 2ed2a3912a0b24502043eae84ee4b279c18b90dd)
     other path: file1 (node 6f4310b00b9a147241b071a60c28a650827fb03d)
-  file extras: file2 (ancestorlinknode = 99726c03216e233810a2564cbc0adfe395007eac)
-  file: file2 (record type "F", state "u", hash cb99b709a1978bd205ab9dfd4c5aaa1fc91c7523)
+    extra: ancestorlinknode = 99726c03216e233810a2564cbc0adfe395007eac
+  file: file2 (state "u")
     local path: file2 (flags "")
     ancestor path: file2 (node 2ed2a3912a0b24502043eae84ee4b279c18b90dd)
     other path: file2 (node 6f4310b00b9a147241b071a60c28a650827fb03d)
+    extra: ancestorlinknode = 99726c03216e233810a2564cbc0adfe395007eac
   $ hg resolve -l
   R file1
   U file2
 
+test json output
+
+  $ hg debugmergestate -T json
+  [
+   {
+    "commits": [{"label": "working copy", "name": "local", "node": "57653b9f834a4493f7240b0681efcb9ae7cab745"}, {"label": "merge rev", "name": "other", "node": "dc77451844e37f03f5c559e3b8529b2b48d381d1"}],
+    "files": [{"ancestor_node": "2ed2a3912a0b24502043eae84ee4b279c18b90dd", "ancestor_path": "file1", "extras": [{"key": "ancestorlinknode", "value": "99726c03216e233810a2564cbc0adfe395007eac"}], "local_flags": "", "local_key": "60b27f004e454aca81b0480209cce5081ec52390", "local_path": "file1", "other_node": "6f4310b00b9a147241b071a60c28a650827fb03d", "other_path": "file1", "path": "file1", "state": "r"}, {"ancestor_node": "2ed2a3912a0b24502043eae84ee4b279c18b90dd", "ancestor_path": "file2", "extras": [{"key": "ancestorlinknode", "value": "99726c03216e233810a2564cbc0adfe395007eac"}], "local_flags": "", "local_key": "cb99b709a1978bd205ab9dfd4c5aaa1fc91c7523", "local_path": "file2", "other_node": "6f4310b00b9a147241b071a60c28a650827fb03d", "other_path": "file2", "path": "file2", "state": "u"}]
+   }
+  ]
+
+
 insert unsupported mandatory merge record
 
   $ hg --config extensions.fakemergerecord=$TESTDIR/fakemergerecord.py fakemergerecord -X
   $ hg debugmergestate
-  * version 2 records
-  local: 57653b9f834a4493f7240b0681efcb9ae7cab745
-  other: dc77451844e37f03f5c559e3b8529b2b48d381d1
-  labels:
-    local: working copy
-    other: merge rev
-  file extras: file1 (ancestorlinknode = 99726c03216e233810a2564cbc0adfe395007eac)
-  file: file1 (record type "F", state "r", hash 60b27f004e454aca81b0480209cce5081ec52390)
-    local path: file1 (flags "")
-    ancestor path: file1 (node 2ed2a3912a0b24502043eae84ee4b279c18b90dd)
-    other path: file1 (node 6f4310b00b9a147241b071a60c28a650827fb03d)
-  file extras: file2 (ancestorlinknode = 99726c03216e233810a2564cbc0adfe395007eac)
-  file: file2 (record type "F", state "u", hash cb99b709a1978bd205ab9dfd4c5aaa1fc91c7523)
-    local path: file2 (flags "")
-    ancestor path: file2 (node 2ed2a3912a0b24502043eae84ee4b279c18b90dd)
-    other path: file2 (node 6f4310b00b9a147241b071a60c28a650827fb03d)
-  unrecognized entry: X mandatory record
+  abort: unsupported merge state records: X
+  (see https://mercurial-scm.org/wiki/MergeStateRecords for more information)
+  [255]
   $ hg resolve -l
   abort: unsupported merge state records: X
   (see https://mercurial-scm.org/wiki/MergeStateRecords for more information)
diff --git a/tests/test-rebase-abort.t b/tests/test-rebase-abort.t
--- a/tests/test-rebase-abort.t
+++ b/tests/test-rebase-abort.t
@@ -88,18 +88,13 @@
 
   $ hg --config extensions.fakemergerecord=$TESTDIR/fakemergerecord.py fakemergerecord -x
   $ hg debugmergestate
-  * version 2 records
-  local: 3e046f2ecedb793b97ed32108086edd1a162f8bc
-  other: 46f0b057b5c061d276b91491c22151f78698abd2
-  labels:
-    local: dest
-    other: source
-  unrecognized entry: x advisory record
-  file extras: common (ancestorlinknode = 3163e20567cc93074fbb7a53c8b93312e59dbf2c)
-  file: common (record type "F", state "u", hash 94c8c21d08740f5da9eaa38d1f175c592692f0d1)
+  local (dest): 3e046f2ecedb793b97ed32108086edd1a162f8bc
+  other (source): 46f0b057b5c061d276b91491c22151f78698abd2
+  file: common (state "u")
     local path: common (flags "")
     ancestor path: common (node de0a666fdd9c1a0b0698b90d85064d8bd34f74b6)
     other path: common (node 2f6411de53677f6f1048fef5bf888d67a342e0a5)
+    extra: ancestorlinknode = 3163e20567cc93074fbb7a53c8b93312e59dbf2c
   $ hg resolve -l
   U common
 
@@ -107,18 +102,9 @@
 
   $ hg --config extensions.fakemergerecord=$TESTDIR/fakemergerecord.py fakemergerecord -X
   $ hg debugmergestate
-  * version 2 records
-  local: 3e046f2ecedb793b97ed32108086edd1a162f8bc
-  other: 46f0b057b5c061d276b91491c22151f78698abd2
-  labels:
-    local: dest
-    other: source
-  file extras: common (ancestorlinknode = 3163e20567cc93074fbb7a53c8b93312e59dbf2c)
-  file: common (record type "F", state "u", hash 94c8c21d08740f5da9eaa38d1f175c592692f0d1)
-    local path: common (flags "")
-    ancestor path: common (node de0a666fdd9c1a0b0698b90d85064d8bd34f74b6)
-    other path: common (node 2f6411de53677f6f1048fef5bf888d67a342e0a5)
-  unrecognized entry: X mandatory record
+  abort: unsupported merge state records: X
+  (see https://mercurial-scm.org/wiki/MergeStateRecords for more information)
+  [255]
   $ hg resolve -l
   abort: unsupported merge state records: X
   (see https://mercurial-scm.org/wiki/MergeStateRecords for more information)
diff --git a/tests/test-merge-changedelete.t b/tests/test-merge-changedelete.t
--- a/tests/test-merge-changedelete.t
+++ b/tests/test-merge-changedelete.t
@@ -76,27 +76,23 @@
   U file2
   U file3
   --- debugmergestate ---
-  * version 2 records
-  local: 13910f48cf7bdb2a0ba6e24b4900e4fdd5739dd4
-  other: 10f9a0a634e82080907e62f075ab119cbc565ea6
-  labels:
-    local: working copy
-    other: merge rev
-  file extras: file1 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
-  file: file1 (record type "C", state "u", hash 60b27f004e454aca81b0480209cce5081ec52390)
+  local (working copy): 13910f48cf7bdb2a0ba6e24b4900e4fdd5739dd4
+  other (merge rev): 10f9a0a634e82080907e62f075ab119cbc565ea6
+  file: file1 (state "u")
     local path: file1 (flags "")
     ancestor path: file1 (node b8e02f6433738021a065f94175c7cd23db5f05be)
-    other path: file1 (node null)
-  file extras: file2 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
-  file: file2 (record type "C", state "u", hash null)
+    other path: file1 (node 0000000000000000000000000000000000000000)
+    extra: ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff
+  file: file2 (state "u")
     local path: file2 (flags "")
     ancestor path: file2 (node 5d9299349fc01ddd25d0070d149b124d8f10411e)
     other path: file2 (node e7c1328648519852e723de86c0c0525acd779257)
-  file extras: file3 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
-  file: file3 (record type "F", state "u", hash d5b0a58bc47161b1b8a831084b366f757c4f0b11)
+    extra: ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff
+  file: file3 (state "u")
     local path: file3 (flags "")
     ancestor path: file3 (node 2661d26c649684b482d10f91960cc3db683c38b4)
     other path: file3 (node a2644c43e210356772c7772a8674544a62e06beb)
+    extra: ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff
   --- file1 ---
   1
   changed
@@ -145,27 +141,23 @@
   R file2
   U file3
   --- debugmergestate ---
-  * version 2 records
-  local: 13910f48cf7bdb2a0ba6e24b4900e4fdd5739dd4
-  other: 10f9a0a634e82080907e62f075ab119cbc565ea6
-  labels:
-    local: working copy
-    other: merge rev
-  file extras: file1 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
-  file: file1 (record type "C", state "r", hash 60b27f004e454aca81b0480209cce5081ec52390)
+  local (working copy): 13910f48cf7bdb2a0ba6e24b4900e4fdd5739dd4
+  other (merge rev): 10f9a0a634e82080907e62f075ab119cbc565ea6
+  file: file1 (state "r")
     local path: file1 (flags "")
     ancestor path: file1 (node b8e02f6433738021a065f94175c7cd23db5f05be)
-    other path: file1 (node null)
-  file extras: file2 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
-  file: file2 (record type "C", state "r", hash null)
+    other path: file1 (node 0000000000000000000000000000000000000000)
+    extra: ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff
+  file: file2 (state "r")
     local path: file2 (flags "")
     ancestor path: file2 (node 5d9299349fc01ddd25d0070d149b124d8f10411e)
     other path: file2 (node e7c1328648519852e723de86c0c0525acd779257)
-  file extras: file3 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
-  file: file3 (record type "F", state "u", hash d5b0a58bc47161b1b8a831084b366f757c4f0b11)
+    extra: ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff
+  file: file3 (state "u")
     local path: file3 (flags "")
     ancestor path: file3 (node 2661d26c649684b482d10f91960cc3db683c38b4)
     other path: file3 (node a2644c43e210356772c7772a8674544a62e06beb)
+    extra: ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff
   --- file1 ---
   1
   changed
@@ -227,27 +219,23 @@
   R file2
   U file3
   --- debugmergestate ---
-  * version 2 records
-  local: 13910f48cf7bdb2a0ba6e24b4900e4fdd5739dd4
-  other: 10f9a0a634e82080907e62f075ab119cbc565ea6
-  labels:
-    local: working copy
-    other: merge rev
-  file extras: file1 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
-  file: file1 (record type "C", state "r", hash 60b27f004e454aca81b0480209cce5081ec52390)
+  local (working copy): 13910f48cf7bdb2a0ba6e24b4900e4fdd5739dd4
+  other (merge rev): 10f9a0a634e82080907e62f075ab119cbc565ea6
+  file: file1 (state "r")
     local path: file1 (flags "")
     ancestor path: file1 (node b8e02f6433738021a065f94175c7cd23db5f05be)
-    other path: file1 (node null)
-  file extras: file2 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
-  file: file2 (record type "C", state "r", hash null)
+    other path: file1 (node 0000000000000000000000000000000000000000)
+    extra: ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff
+  file: file2 (state "r")
     local path: file2 (flags "")
     ancestor path: file2 (node 5d9299349fc01ddd25d0070d149b124d8f10411e)
     other path: file2 (node e7c1328648519852e723de86c0c0525acd779257)
-  file extras: file3 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
-  file: file3 (record type "F", state "u", hash d5b0a58bc47161b1b8a831084b366f757c4f0b11)
+    extra: ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff
+  file: file3 (state "u")
     local path: file3 (flags "")
     ancestor path: file3 (node 2661d26c649684b482d10f91960cc3db683c38b4)
     other path: file3 (node a2644c43e210356772c7772a8674544a62e06beb)
+    extra: ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff
   *** file1 does not exist
   --- file2 ---
   2
@@ -293,27 +281,23 @@
   U file2
   U file3
   --- debugmergestate ---
-  * version 2 records
-  local: 13910f48cf7bdb2a0ba6e24b4900e4fdd5739dd4
-  other: 10f9a0a634e82080907e62f075ab119cbc565ea6
-  labels:
-    local: working copy
-    other: merge rev
-  file extras: file1 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
-  file: file1 (record type "C", state "r", hash 60b27f004e454aca81b0480209cce5081ec52390)
+  local (working copy): 13910f48cf7bdb2a0ba6e24b4900e4fdd5739dd4
+  other (merge rev): 10f9a0a634e82080907e62f075ab119cbc565ea6
+  file: file1 (state "r")
     local path: file1 (flags "")
     ancestor path: file1 (node b8e02f6433738021a065f94175c7cd23db5f05be)
-    other path: file1 (node null)
-  file extras: file2 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
-  file: file2 (record type "C", state "u", hash null)
+    other path: file1 (node 0000000000000000000000000000000000000000)
+    extra: ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff
+  file: file2 (state "u")
     local path: file2 (flags "")
     ancestor path: file2 (node 5d9299349fc01ddd25d0070d149b124d8f10411e)
     other path: file2 (node e7c1328648519852e723de86c0c0525acd779257)
-  file extras: file3 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
-  file: file3 (record type "F", state "u", hash d5b0a58bc47161b1b8a831084b366f757c4f0b11)
+    extra: ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff
+  file: file3 (state "u")
     local path: file3 (flags "")
     ancestor path: file3 (node 2661d26c649684b482d10f91960cc3db683c38b4)
     other path: file3 (node a2644c43e210356772c7772a8674544a62e06beb)
+    extra: ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff
   *** file1 does not exist
   --- file2 ---
   2
@@ -346,27 +330,23 @@
   R file2
   R file3
   --- debugmergestate ---
-  * version 2 records
-  local: 13910f48cf7bdb2a0ba6e24b4900e4fdd5739dd4
-  other: 10f9a0a634e82080907e62f075ab119cbc565ea6
-  labels:
-    local: working copy
-    other: merge rev
-  file extras: file1 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
-  file: file1 (record type "C", state "r", hash 60b27f004e454aca81b0480209cce5081ec52390)
+  local (working copy): 13910f48cf7bdb2a0ba6e24b4900e4fdd5739dd4
+  other (merge rev): 10f9a0a634e82080907e62f075ab119cbc565ea6
+  file: file1 (state "r")
     local path: file1 (flags "")
     ancestor path: file1 (node b8e02f6433738021a065f94175c7cd23db5f05be)
-    other path: file1 (node null)
-  file extras: file2 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
-  file: file2 (record type "C", state "r", hash null)
+    other path: file1 (node 0000000000000000000000000000000000000000)
+    extra: ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff
+  file: file2 (state "r")
     local path: file2 (flags "")
     ancestor path: file2 (node 5d9299349fc01ddd25d0070d149b124d8f10411e)
     other path: file2 (node e7c1328648519852e723de86c0c0525acd779257)
-  file extras: file3 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
-  file: file3 (record type "F", state "r", hash d5b0a58bc47161b1b8a831084b366f757c4f0b11)
+    extra: ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff
+  file: file3 (state "r")
     local path: file3 (flags "")
     ancestor path: file3 (node 2661d26c649684b482d10f91960cc3db683c38b4)
     other path: file3 (node a2644c43e210356772c7772a8674544a62e06beb)
+    extra: ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff
   --- file1 ---
   1
   changed
@@ -395,27 +375,23 @@
   R file2
   R file3
   --- debugmergestate ---
-  * version 2 records
-  local: 13910f48cf7bdb2a0ba6e24b4900e4fdd5739dd4
-  other: 10f9a0a634e82080907e62f075ab119cbc565ea6
-  labels:
-    local: working copy
-    other: merge rev
-  file extras: file1 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
-  file: file1 (record type "C", state "r", hash 60b27f004e454aca81b0480209cce5081ec52390)
+  local (working copy): 13910f48cf7bdb2a0ba6e24b4900e4fdd5739dd4
+  other (merge rev): 10f9a0a634e82080907e62f075ab119cbc565ea6
+  file: file1 (state "r")
     local path: file1 (flags "")
     ancestor path: file1 (node b8e02f6433738021a065f94175c7cd23db5f05be)
-    other path: file1 (node null)
-  file extras: file2 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
-  file: file2 (record type "C", state "r", hash null)
+    other path: file1 (node 0000000000000000000000000000000000000000)
+    extra: ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff
+  file: file2 (state "r")
     local path: file2 (flags "")
     ancestor path: file2 (node 5d9299349fc01ddd25d0070d149b124d8f10411e)
     other path: file2 (node e7c1328648519852e723de86c0c0525acd779257)
-  file extras: file3 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
-  file: file3 (record type "F", state "r", hash d5b0a58bc47161b1b8a831084b366f757c4f0b11)
+    extra: ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff
+  file: file3 (state "r")
     local path: file3 (flags "")
     ancestor path: file3 (node 2661d26c649684b482d10f91960cc3db683c38b4)
     other path: file3 (node a2644c43e210356772c7772a8674544a62e06beb)
+    extra: ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff
   *** file1 does not exist
   --- file2 ---
   2
@@ -445,27 +421,23 @@
   U file2
   U file3
   --- debugmergestate ---
-  * version 2 records
-  local: 13910f48cf7bdb2a0ba6e24b4900e4fdd5739dd4
-  other: 10f9a0a634e82080907e62f075ab119cbc565ea6
-  labels:
-    local: working copy
-    other: merge rev
-  file extras: file1 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
-  file: file1 (record type "C", state "u", hash 60b27f004e454aca81b0480209cce5081ec52390)
+  local (working copy): 13910f48cf7bdb2a0ba6e24b4900e4fdd5739dd4
+  other (merge rev): 10f9a0a634e82080907e62f075ab119cbc565ea6
+  file: file1 (state "u")
     local path: file1 (flags "")
     ancestor path: file1 (node b8e02f6433738021a065f94175c7cd23db5f05be)
-    other path: file1 (node null)
-  file extras: file2 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
-  file: file2 (record type "C", state "u", hash null)
+    other path: file1 (node 0000000000000000000000000000000000000000)
+    extra: ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff
+  file: file2 (state "u")
     local path: file2 (flags "")
     ancestor path: file2 (node 5d9299349fc01ddd25d0070d149b124d8f10411e)
     other path: file2 (node e7c1328648519852e723de86c0c0525acd779257)
-  file extras: file3 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
-  file: file3 (record type "F", state "u", hash d5b0a58bc47161b1b8a831084b366f757c4f0b11)
+    extra: ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff
+  file: file3 (state "u")
     local path: file3 (flags "")
     ancestor path: file3 (node 2661d26c649684b482d10f91960cc3db683c38b4)
     other path: file3 (node a2644c43e210356772c7772a8674544a62e06beb)
+    extra: ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff
   --- file1 ---
   1
   changed
@@ -506,27 +478,23 @@
   U file2
   U file3
   --- debugmergestate ---
-  * version 2 records
-  local: 13910f48cf7bdb2a0ba6e24b4900e4fdd5739dd4
-  other: 10f9a0a634e82080907e62f075ab119cbc565ea6
-  labels:
-    local: working copy
-    other: merge rev
-  file extras: file1 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
-  file: file1 (record type "C", state "u", hash 60b27f004e454aca81b0480209cce5081ec52390)
+  local (working copy): 13910f48cf7bdb2a0ba6e24b4900e4fdd5739dd4
+  other (merge rev): 10f9a0a634e82080907e62f075ab119cbc565ea6
+  file: file1 (state "u")
     local path: file1 (flags "")
     ancestor path: file1 (node b8e02f6433738021a065f94175c7cd23db5f05be)
-    other path: file1 (node null)
-  file extras: file2 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
-  file: file2 (record type "C", state "u", hash null)
+    other path: file1 (node 0000000000000000000000000000000000000000)
+    extra: ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff
+  file: file2 (state "u")
     local path: file2 (flags "")
     ancestor path: file2 (node 5d9299349fc01ddd25d0070d149b124d8f10411e)
     other path: file2 (node e7c1328648519852e723de86c0c0525acd779257)
-  file extras: file3 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
-  file: file3 (record type "F", state "u", hash d5b0a58bc47161b1b8a831084b366f757c4f0b11)
+    extra: ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff
+  file: file3 (state "u")
     local path: file3 (flags "")
     ancestor path: file3 (node 2661d26c649684b482d10f91960cc3db683c38b4)
     other path: file3 (node a2644c43e210356772c7772a8674544a62e06beb)
+    extra: ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff
   --- file1 ---
   1
   changed
@@ -569,27 +537,23 @@
   U file2
   U file3
   --- debugmergestate ---
-  * version 2 records
-  local: 13910f48cf7bdb2a0ba6e24b4900e4fdd5739dd4
-  other: 10f9a0a634e82080907e62f075ab119cbc565ea6
-  labels:
-    local: working copy
-    other: merge rev
-  file extras: file1 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
-  file: file1 (record type "C", state "u", hash 60b27f004e454aca81b0480209cce5081ec52390)
+  local (working copy): 13910f48cf7bdb2a0ba6e24b4900e4fdd5739dd4
+  other (merge rev): 10f9a0a634e82080907e62f075ab119cbc565ea6
+  file: file1 (state "u")
     local path: file1 (flags "")
     ancestor path: file1 (node b8e02f6433738021a065f94175c7cd23db5f05be)
-    other path: file1 (node null)
-  file extras: file2 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
-  file: file2 (record type "C", state "u", hash null)
+    other path: file1 (node 0000000000000000000000000000000000000000)
+    extra: ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff
+  file: file2 (state "u")
     local path: file2 (flags "")
     ancestor path: file2 (node 5d9299349fc01ddd25d0070d149b124d8f10411e)
     other path: file2 (node e7c1328648519852e723de86c0c0525acd779257)
-  file extras: file3 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
-  file: file3 (record type "F", state "u", hash d5b0a58bc47161b1b8a831084b366f757c4f0b11)
+    extra: ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff
+  file: file3 (state "u")
     local path: file3 (flags "")
     ancestor path: file3 (node 2661d26c649684b482d10f91960cc3db683c38b4)
     other path: file3 (node a2644c43e210356772c7772a8674544a62e06beb)
+    extra: ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff
   --- file1 ---
   1
   changed
@@ -629,27 +593,23 @@
   U file2
   U file3
   --- debugmergestate ---
-  * version 2 records
-  local: 13910f48cf7bdb2a0ba6e24b4900e4fdd5739dd4
-  other: 10f9a0a634e82080907e62f075ab119cbc565ea6
-  labels:
-    local: working copy
-    other: merge rev
-  file extras: file1 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
-  file: file1 (record type "C", state "u", hash 60b27f004e454aca81b0480209cce5081ec52390)
+  local (working copy): 13910f48cf7bdb2a0ba6e24b4900e4fdd5739dd4
+  other (merge rev): 10f9a0a634e82080907e62f075ab119cbc565ea6
+  file: file1 (state "u")
     local path: file1 (flags "")
     ancestor path: file1 (node b8e02f6433738021a065f94175c7cd23db5f05be)
-    other path: file1 (node null)
-  file extras: file2 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
-  file: file2 (record type "C", state "u", hash null)
+    other path: file1 (node 0000000000000000000000000000000000000000)
+    extra: ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff
+  file: file2 (state "u")
     local path: file2 (flags "")
     ancestor path: file2 (node 5d9299349fc01ddd25d0070d149b124d8f10411e)
     other path: file2 (node e7c1328648519852e723de86c0c0525acd779257)
-  file extras: file3 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
-  file: file3 (record type "F", state "u", hash d5b0a58bc47161b1b8a831084b366f757c4f0b11)
+    extra: ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff
+  file: file3 (state "u")
     local path: file3 (flags "")
     ancestor path: file3 (node 2661d26c649684b482d10f91960cc3db683c38b4)
     other path: file3 (node a2644c43e210356772c7772a8674544a62e06beb)
+    extra: ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff
   --- file1 ---
   1
   changed
@@ -802,22 +762,18 @@
   U file1
   U file2
   --- debugmergestate ---
-  * version 2 records
-  local: ab57bf49aa276a22d35a473592d4c34b5abc3eff
-  other: 10f9a0a634e82080907e62f075ab119cbc565ea6
-  labels:
-    local: working copy
-    other: destination
-  file extras: file1 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
-  file: file1 (record type "C", state "u", hash 60b27f004e454aca81b0480209cce5081ec52390)
+  local (working copy): ab57bf49aa276a22d35a473592d4c34b5abc3eff
+  other (destination): 10f9a0a634e82080907e62f075ab119cbc565ea6
+  file: file1 (state "u")
     local path: file1 (flags "")
     ancestor path: file1 (node b8e02f6433738021a065f94175c7cd23db5f05be)
-    other path: file1 (node null)
-  file extras: file2 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
-  file: file2 (record type "C", state "u", hash null)
+    other path: file1 (node 0000000000000000000000000000000000000000)
+    extra: ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff
+  file: file2 (state "u")
     local path: file2 (flags "")
     ancestor path: file2 (node 5d9299349fc01ddd25d0070d149b124d8f10411e)
     other path: file2 (node e7c1328648519852e723de86c0c0525acd779257)
+    extra: ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff
   --- file1 ---
   1
   changed
@@ -845,22 +801,18 @@
   R file1
   R file2
   --- debugmergestate ---
-  * version 2 records
-  local: ab57bf49aa276a22d35a473592d4c34b5abc3eff
-  other: 10f9a0a634e82080907e62f075ab119cbc565ea6
-  labels:
-    local: working copy
-    other: destination
-  file extras: file1 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
-  file: file1 (record type "C", state "r", hash 60b27f004e454aca81b0480209cce5081ec52390)
+  local (working copy): ab57bf49aa276a22d35a473592d4c34b5abc3eff
+  other (destination): 10f9a0a634e82080907e62f075ab119cbc565ea6
+  file: file1 (state "r")
     local path: file1 (flags "")
     ancestor path: file1 (node b8e02f6433738021a065f94175c7cd23db5f05be)
-    other path: file1 (node null)
-  file extras: file2 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
-  file: file2 (record type "C", state "r", hash null)
+    other path: file1 (node 0000000000000000000000000000000000000000)
+    extra: ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff
+  file: file2 (state "r")
     local path: file2 (flags "")
     ancestor path: file2 (node 5d9299349fc01ddd25d0070d149b124d8f10411e)
     other path: file2 (node e7c1328648519852e723de86c0c0525acd779257)
+    extra: ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff
   --- file1 ---
   1
   changed
@@ -886,22 +838,18 @@
   R file1
   R file2
   --- debugmergestate ---
-  * version 2 records
-  local: ab57bf49aa276a22d35a473592d4c34b5abc3eff
-  other: 10f9a0a634e82080907e62f075ab119cbc565ea6
-  labels:
-    local: working copy
-    other: destination
-  file extras: file1 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
-  file: file1 (record type "C", state "r", hash 60b27f004e454aca81b0480209cce5081ec52390)
+  local (working copy): ab57bf49aa276a22d35a473592d4c34b5abc3eff
+  other (destination): 10f9a0a634e82080907e62f075ab119cbc565ea6
+  file: file1 (state "r")
     local path: file1 (flags "")
     ancestor path: file1 (node b8e02f6433738021a065f94175c7cd23db5f05be)
-    other path: file1 (node null)
-  file extras: file2 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
-  file: file2 (record type "C", state "r", hash null)
+    other path: file1 (node 0000000000000000000000000000000000000000)
+    extra: ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff
+  file: file2 (state "r")
     local path: file2 (flags "")
     ancestor path: file2 (node 5d9299349fc01ddd25d0070d149b124d8f10411e)
     other path: file2 (node e7c1328648519852e723de86c0c0525acd779257)
+    extra: ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff
   *** file1 does not exist
   --- file2 ---
   2
@@ -929,22 +877,18 @@
   U file1
   U file2
   --- debugmergestate ---
-  * version 2 records
-  local: ab57bf49aa276a22d35a473592d4c34b5abc3eff
-  other: 10f9a0a634e82080907e62f075ab119cbc565ea6
-  labels:
-    local: working copy
-    other: destination
-  file extras: file1 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
-  file: file1 (record type "C", state "u", hash 60b27f004e454aca81b0480209cce5081ec52390)
+  local (working copy): ab57bf49aa276a22d35a473592d4c34b5abc3eff
+  other (destination): 10f9a0a634e82080907e62f075ab119cbc565ea6
+  file: file1 (state "u")
     local path: file1 (flags "")
     ancestor path: file1 (node b8e02f6433738021a065f94175c7cd23db5f05be)
-    other path: file1 (node null)
-  file extras: file2 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
-  file: file2 (record type "C", state "u", hash null)
+    other path: file1 (node 0000000000000000000000000000000000000000)
+    extra: ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff
+  file: file2 (state "u")
     local path: file2 (flags "")
     ancestor path: file2 (node 5d9299349fc01ddd25d0070d149b124d8f10411e)
     other path: file2 (node e7c1328648519852e723de86c0c0525acd779257)
+    extra: ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff
   --- file1 ---
   1
   changed
@@ -980,22 +924,18 @@
   U file1
   U file2
   --- debugmergestate ---
-  * version 2 records
-  local: ab57bf49aa276a22d35a473592d4c34b5abc3eff
-  other: 10f9a0a634e82080907e62f075ab119cbc565ea6
-  labels:
-    local: working copy
-    other: destination
-  file extras: file1 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
-  file: file1 (record type "C", state "u", hash 60b27f004e454aca81b0480209cce5081ec52390)
+  local (working copy): ab57bf49aa276a22d35a473592d4c34b5abc3eff
+  other (destination): 10f9a0a634e82080907e62f075ab119cbc565ea6
+  file: file1 (state "u")
     local path: file1 (flags "")
     ancestor path: file1 (node b8e02f6433738021a065f94175c7cd23db5f05be)
-    other path: file1 (node null)
-  file extras: file2 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
-  file: file2 (record type "C", state "u", hash null)
+    other path: file1 (node 0000000000000000000000000000000000000000)
+    extra: ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff
+  file: file2 (state "u")
     local path: file2 (flags "")
     ancestor path: file2 (node 5d9299349fc01ddd25d0070d149b124d8f10411e)
     other path: file2 (node e7c1328648519852e723de86c0c0525acd779257)
+    extra: ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff
   --- file1 ---
   1
   changed
@@ -1032,22 +972,18 @@
   U file1
   U file2
   --- debugmergestate ---
-  * version 2 records
-  local: ab57bf49aa276a22d35a473592d4c34b5abc3eff
-  other: 10f9a0a634e82080907e62f075ab119cbc565ea6
-  labels:
-    local: working copy
-    other: destination
-  file extras: file1 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
-  file: file1 (record type "C", state "u", hash 60b27f004e454aca81b0480209cce5081ec52390)
+  local (working copy): ab57bf49aa276a22d35a473592d4c34b5abc3eff
+  other (destination): 10f9a0a634e82080907e62f075ab119cbc565ea6
+  file: file1 (state "u")
     local path: file1 (flags "")
     ancestor path: file1 (node b8e02f6433738021a065f94175c7cd23db5f05be)
-    other path: file1 (node null)
-  file extras: file2 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
-  file: file2 (record type "C", state "u", hash null)
+    other path: file1 (node 0000000000000000000000000000000000000000)
+    extra: ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff
+  file: file2 (state "u")
     local path: file2 (flags "")
     ancestor path: file2 (node 5d9299349fc01ddd25d0070d149b124d8f10411e)
     other path: file2 (node e7c1328648519852e723de86c0c0525acd779257)
+    extra: ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff
   --- file1 ---
   1
   changed
diff --git a/tests/test-histedit-non-commute-abort.t b/tests/test-histedit-non-commute-abort.t
--- a/tests/test-histedit-non-commute-abort.t
+++ b/tests/test-histedit-non-commute-abort.t
@@ -77,36 +77,22 @@
 insert unsupported advisory merge record
   $ hg --config extensions.fakemergerecord=$TESTDIR/fakemergerecord.py fakemergerecord -x
   $ hg debugmergestate
-  * version 2 records
-  local: 8f7551c7e4a2f2efe0bc8c741baf7f227d65d758
-  other: e860deea161a2f77de56603b340ebbb4536308ae
-  labels:
-    local: local
-    other: histedit
-  unrecognized entry: x advisory record
-  file extras: e (ancestorlinknode = 0000000000000000000000000000000000000000)
-  file: e (record type "F", state "u", hash 58e6b3a414a1e090dfc6029add0f3555ccba127f)
+  local (local): 8f7551c7e4a2f2efe0bc8c741baf7f227d65d758
+  other (histedit): e860deea161a2f77de56603b340ebbb4536308ae
+  file: e (state "u")
     local path: e (flags "")
-    ancestor path: e (node null)
+    ancestor path: e (node 0000000000000000000000000000000000000000)
     other path: e (node 6b67ccefd5ce6de77e7ead4f5292843a0255329f)
+    extra: ancestorlinknode = 0000000000000000000000000000000000000000
   $ hg resolve -l
   U e
 
 insert unsupported mandatory merge record
   $ hg --config extensions.fakemergerecord=$TESTDIR/fakemergerecord.py fakemergerecord -X
   $ hg debugmergestate
-  * version 2 records
-  local: 8f7551c7e4a2f2efe0bc8c741baf7f227d65d758
-  other: e860deea161a2f77de56603b340ebbb4536308ae
-  labels:
-    local: local
-    other: histedit
-  file extras: e (ancestorlinknode = 0000000000000000000000000000000000000000)
-  file: e (record type "F", state "u", hash 58e6b3a414a1e090dfc6029add0f3555ccba127f)
-    local path: e (flags "")
-    ancestor path: e (node null)
-    other path: e (node 6b67ccefd5ce6de77e7ead4f5292843a0255329f)
-  unrecognized entry: X mandatory record
+  abort: unsupported merge state records: X
+  (see https://mercurial-scm.org/wiki/MergeStateRecords for more information)
+  [255]
   $ hg resolve -l
   abort: unsupported merge state records: X
   (see https://mercurial-scm.org/wiki/MergeStateRecords for more information)
diff --git a/tests/test-completion.t b/tests/test-completion.t
--- a/tests/test-completion.t
+++ b/tests/test-completion.t
@@ -289,7 +289,7 @@
   debuglabelcomplete:
   debuglocks: force-lock, force-wlock, set-lock, set-wlock
   debugmanifestfulltextcache: clear, add
-  debugmergestate:
+  debugmergestate: style, template
   debugnamecomplete:
   debugnodemap: dump-new, dump-disk, check, metadata
   debugobsolete: flags, record-parents, rev, exclusive, index, delete, date, user, template
diff --git a/tests/test-backout.t b/tests/test-backout.t
--- a/tests/test-backout.t
+++ b/tests/test-backout.t
@@ -710,22 +710,21 @@
   [1]
   $ hg status
   $ hg debugmergestate
-  * version 2 records
   local: b71750c4b0fdf719734971e3ef90dbeab5919a2d
   other: a30dd8addae3ce71b8667868478542bc417439e6
-  file extras: foo (ancestorlinknode = 91360952243723bd5b1138d5f26bd8c8564cb553)
-  file: foo (record type "F", state "u", hash 0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33)
+  file: foo (state "u")
     local path: foo (flags "")
     ancestor path: foo (node f89532f44c247a0e993d63e3a734dd781ab04708)
     other path: foo (node f50039b486d6fa1a90ae51778388cad161f425ee)
+    extra: ancestorlinknode = 91360952243723bd5b1138d5f26bd8c8564cb553
   $ mv .hg/merge/state2 .hg/merge/state2-moved
   $ hg debugmergestate
-  * version 1 records
   local: b71750c4b0fdf719734971e3ef90dbeab5919a2d
-  file: foo (record type "F", state "u", hash 0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33)
+  other: b71750c4b0fdf719734971e3ef90dbeab5919a2d
+  file: foo (state "u")
     local path: foo (flags "")
     ancestor path: foo (node f89532f44c247a0e993d63e3a734dd781ab04708)
-    other path: foo (node not stored in v1 format)
+    other path:  (node foo)
   $ mv .hg/merge/state2-moved .hg/merge/state2
   $ hg resolve -l  # still unresolved
   U foo
diff --git a/relnotes/next b/relnotes/next
--- a/relnotes/next
+++ b/relnotes/next
@@ -12,6 +12,9 @@
    commits that are being merged, when there are conflicts. Also works
    for conflicts caused by e.g. `hg graft`.
 
+ * `hg debugmergestate` output is now templated, which may be useful
+   e.g. for IDEs that want to help the user resolve merge conflicts.
+
 
 == New Experimental Features ==
 
@@ -26,6 +29,9 @@
    can use the new `conflictparents()` revset for finding the other
    parent during a conflict.
 
+ * `hg debugmergestate` output format changed. Let us know if that is
+   causing you problems and we'll roll it back.
+
 
 == Internal API Changes ==
 
diff --git a/mercurial/debugcommands.py b/mercurial/debugcommands.py
--- a/mercurial/debugcommands.py
+++ b/mercurial/debugcommands.py
@@ -28,7 +28,6 @@
 from .node import (
     bin,
     hex,
-    nullhex,
     nullid,
     nullrev,
     short,
@@ -1944,120 +1943,84 @@
         )
 
 
-@command(b'debugmergestate', [], b'')
-def debugmergestate(ui, repo, *args):
+@command(b'debugmergestate', [] + cmdutil.templateopts, b'')
+def debugmergestate(ui, repo, *args, **opts):
     """print merge state
 
     Use --verbose to print out information about whether v1 or v2 merge state
     was chosen."""
 
-    def _hashornull(h):
-        if h == nullhex:
-            return b'null'
-        else:
-            return h
-
-    def printrecords(version):
-        ui.writenoi18n(b'* version %d records\n' % version)
-        if version == 1:
-            records = v1records
+    if ui.verbose:
+        ms = mergemod.mergestate(repo)
+
+        # sort so that reasonable information is on top
+        v1records = ms._readrecordsv1()
+        v2records = ms._readrecordsv2()
+
+        if not v1records and not v2records:
+            pass
+        elif not v2records:
+            ui.writenoi18n(b'no version 2 merge state\n')
+        elif ms._v1v2match(v1records, v2records):
+            ui.writenoi18n(b'v1 and v2 states match: using v2\n')
         else:
-            records = v2records
-
-        for rtype, record in records:
-            # pretty print some record types
-            if rtype == b'L':
-                ui.writenoi18n(b'local: %s\n' % record)
-            elif rtype == b'O':
-                ui.writenoi18n(b'other: %s\n' % record)
-            elif rtype == b'm':
-                driver, mdstate = record.split(b'\0', 1)
-                ui.writenoi18n(
-                    b'merge driver: %s (state "%s")\n' % (driver, mdstate)
-                )
-            elif rtype in b'FDC':
-                r = record.split(b'\0')
-                f, state, hash, lfile, afile, anode, ofile = r[0:7]
-                if version == 1:
-                    onode = b'not stored in v1 format'
-                    flags = r[7]
-                else:
-                    onode, flags = r[7:9]
-                ui.writenoi18n(
-                    b'file: %s (record type "%s", state "%s", hash %s)\n'
-                    % (f, rtype, state, _hashornull(hash))
-                )
-                ui.writenoi18n(
-                    b'  local path: %s (flags "%s")\n' % (lfile, flags)
-                )
-                ui.writenoi18n(
-                    b'  ancestor path: %s (node %s)\n'
-                    % (afile, _hashornull(anode))
-                )
-                ui.writenoi18n(
-                    b'  other path: %s (node %s)\n'
-                    % (ofile, _hashornull(onode))
-                )
-            elif rtype == b'f':
-                filename, rawextras = record.split(b'\0', 1)
-                extras = rawextras.split(b'\0')
-                i = 0
-                extrastrings = []
-                while i < len(extras):
-                    extrastrings.append(b'%s = %s' % (extras[i], extras[i + 1]))
-                    i += 2
-
-                ui.writenoi18n(
-                    b'file extras: %s (%s)\n'
-                    % (filename, b', '.join(extrastrings))
-                )
-            elif rtype == b'l':
-                labels = record.split(b'\0', 2)
-                labels = [l for l in labels if len(l) > 0]
-                ui.writenoi18n(b'labels:\n')
-                ui.write((b'  local: %s\n' % labels[0]))
-                ui.write((b'  other: %s\n' % labels[1]))
-                if len(labels) > 2:
-                    ui.write((b'  base:  %s\n' % labels[2]))
-            else:
-                ui.writenoi18n(
-                    b'unrecognized entry: %s\t%s\n'
-                    % (rtype, record.replace(b'\0', b'\t'))
-                )
-
-    # Avoid mergestate.read() since it may raise an exception for unsupported
-    # merge state records. We shouldn't be doing this, but this is OK since this
-    # command is pretty low-level.
-    ms = mergemod.mergestate(repo)
-
-    # sort so that reasonable information is on top
-    v1records = ms._readrecordsv1()
-    v2records = ms._readrecordsv2()
-    order = b'LOml'
-
-    def key(r):
-        idx = order.find(r[0])
-        if idx == -1:
-            return (1, r[1])
-        else:
-            return (0, idx)
-
-    v1records.sort(key=key)
-    v2records.sort(key=key)
-
-    if not v1records and not v2records:
-        ui.writenoi18n(b'no merge state found\n')
-    elif not v2records:
-        ui.notenoi18n(b'no version 2 merge state\n')
-        printrecords(1)
-    elif ms._v1v2match(v1records, v2records):
-        ui.notenoi18n(b'v1 and v2 states match: using v2\n')
-        printrecords(2)
-    else:
-        ui.notenoi18n(b'v1 and v2 states mismatch: using v1\n')
-        printrecords(1)
-        if ui.verbose:
-            printrecords(2)
+            ui.writenoi18n(b'v1 and v2 states mismatch: using v1\n')
+
+    opts = pycompat.byteskwargs(opts)
+    if not opts[b'template']:
+        opts[b'template'] = (
+            b'{if(commits, "", "no merge state found\n")}'
+            b'{commits % "{name}{if(label, " ({label})")}: {node}\n"}'
+            b'{files % "file: {path} (state \\"{state}\\")\n'
+            b'  local path: {local_path} (flags \\"{local_flags}\\")\n'
+            b'  ancestor path: {ancestor_path} (node {ancestor_node})\n'
+            b'  other path: {other_path} (node {other_node})\n'
+            b'{extras % "  extra: {key} = {value}\n"}'
+            b'"}'
+        )
+
+    ms = mergemod.mergestate.read(repo)
+
+    fm = ui.formatter(b'debugmergestate', opts)
+    fm.startitem()
+
+    fm_commits = fm.nested(b'commits')
+    if ms.active():
+        for name, node, label_index in (
+            (b'local', ms.local, 0),
+            (b'other', ms.other, 1),
+        ):
+            fm_commits.startitem()
+            fm_commits.data(name=name)
+            fm_commits.data(node=hex(node))
+            if ms._labels and len(ms._labels) > label_index:
+                fm_commits.data(label=ms._labels[label_index])
+    fm_commits.end()
+
+    fm_files = fm.nested(b'files')
+    if ms.active():
+        for f in ms:
+            fm_files.startitem()
+            fm_files.data(path=f)
+            state = ms._state[f]
+            fm_files.data(state=state[0])
+            fm_files.data(local_key=state[1])
+            fm_files.data(local_path=state[2])
+            fm_files.data(ancestor_path=state[3])
+            fm_files.data(ancestor_node=state[4])
+            fm_files.data(other_path=state[5])
+            fm_files.data(other_node=state[6])
+            fm_files.data(local_flags=state[7])
+            fm_extras = fm_files.nested(b'extras')
+            for k, v in ms.extras(f).items():
+                fm_extras.startitem()
+                fm_extras.data(key=k)
+                fm_extras.data(value=v)
+            fm_extras.end()
+
+    fm_files.end()
+
+    fm.end()
 
 
 @command(b'debugnamecomplete', [], _(b'NAME...'))



To: martinvonz, #hg-reviewers, durin42
Cc: pulkit, durin42, mercurial-devel
_______________________________________________
Mercurial-devel mailing list
[hidden email]
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Reply | Threaded
Open this post in threaded view
|

D8113: debugmergestate: make templated

marmoute (Pierre-Yves David)
In reply to this post by marmoute (Pierre-Yves David)
Closed by commit rHG088ab52a04bc: debugmergestate: make templated (authored by martinvonz).
This revision was automatically updated to reflect the committed changes.

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D8113?vs=20203&id=20209

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D8113/new/

REVISION DETAIL
  https://phab.mercurial-scm.org/D8113

AFFECTED FILES
  mercurial/debugcommands.py
  relnotes/next
  tests/test-backout.t
  tests/test-completion.t
  tests/test-histedit-non-commute-abort.t
  tests/test-merge-changedelete.t
  tests/test-rebase-abort.t
  tests/test-resolve.t

CHANGE DETAILS

diff --git a/tests/test-resolve.t b/tests/test-resolve.t
--- a/tests/test-resolve.t
+++ b/tests/test-resolve.t
@@ -306,48 +306,40 @@
 
   $ hg --config extensions.fakemergerecord=$TESTDIR/fakemergerecord.py fakemergerecord -x
   $ hg debugmergestate
-  * version 2 records
-  local: 57653b9f834a4493f7240b0681efcb9ae7cab745
-  other: dc77451844e37f03f5c559e3b8529b2b48d381d1
-  labels:
-    local: working copy
-    other: merge rev
-  unrecognized entry: x advisory record
-  file extras: file1 (ancestorlinknode = 99726c03216e233810a2564cbc0adfe395007eac)
-  file: file1 (record type "F", state "r", hash 60b27f004e454aca81b0480209cce5081ec52390)
+  local (working copy): 57653b9f834a4493f7240b0681efcb9ae7cab745
+  other (merge rev): dc77451844e37f03f5c559e3b8529b2b48d381d1
+  file: file1 (state "r")
     local path: file1 (flags "")
     ancestor path: file1 (node 2ed2a3912a0b24502043eae84ee4b279c18b90dd)
     other path: file1 (node 6f4310b00b9a147241b071a60c28a650827fb03d)
-  file extras: file2 (ancestorlinknode = 99726c03216e233810a2564cbc0adfe395007eac)
-  file: file2 (record type "F", state "u", hash cb99b709a1978bd205ab9dfd4c5aaa1fc91c7523)
+    extra: ancestorlinknode = 99726c03216e233810a2564cbc0adfe395007eac
+  file: file2 (state "u")
     local path: file2 (flags "")
     ancestor path: file2 (node 2ed2a3912a0b24502043eae84ee4b279c18b90dd)
     other path: file2 (node 6f4310b00b9a147241b071a60c28a650827fb03d)
+    extra: ancestorlinknode = 99726c03216e233810a2564cbc0adfe395007eac
   $ hg resolve -l
   R file1
   U file2
 
+test json output
+
+  $ hg debugmergestate -T json
+  [
+   {
+    "commits": [{"label": "working copy", "name": "local", "node": "57653b9f834a4493f7240b0681efcb9ae7cab745"}, {"label": "merge rev", "name": "other", "node": "dc77451844e37f03f5c559e3b8529b2b48d381d1"}],
+    "files": [{"ancestor_node": "2ed2a3912a0b24502043eae84ee4b279c18b90dd", "ancestor_path": "file1", "extras": [{"key": "ancestorlinknode", "value": "99726c03216e233810a2564cbc0adfe395007eac"}], "local_flags": "", "local_key": "60b27f004e454aca81b0480209cce5081ec52390", "local_path": "file1", "other_node": "6f4310b00b9a147241b071a60c28a650827fb03d", "other_path": "file1", "path": "file1", "state": "r"}, {"ancestor_node": "2ed2a3912a0b24502043eae84ee4b279c18b90dd", "ancestor_path": "file2", "extras": [{"key": "ancestorlinknode", "value": "99726c03216e233810a2564cbc0adfe395007eac"}], "local_flags": "", "local_key": "cb99b709a1978bd205ab9dfd4c5aaa1fc91c7523", "local_path": "file2", "other_node": "6f4310b00b9a147241b071a60c28a650827fb03d", "other_path": "file2", "path": "file2", "state": "u"}]
+   }
+  ]
+
+
 insert unsupported mandatory merge record
 
   $ hg --config extensions.fakemergerecord=$TESTDIR/fakemergerecord.py fakemergerecord -X
   $ hg debugmergestate
-  * version 2 records
-  local: 57653b9f834a4493f7240b0681efcb9ae7cab745
-  other: dc77451844e37f03f5c559e3b8529b2b48d381d1
-  labels:
-    local: working copy
-    other: merge rev
-  file extras: file1 (ancestorlinknode = 99726c03216e233810a2564cbc0adfe395007eac)
-  file: file1 (record type "F", state "r", hash 60b27f004e454aca81b0480209cce5081ec52390)
-    local path: file1 (flags "")
-    ancestor path: file1 (node 2ed2a3912a0b24502043eae84ee4b279c18b90dd)
-    other path: file1 (node 6f4310b00b9a147241b071a60c28a650827fb03d)
-  file extras: file2 (ancestorlinknode = 99726c03216e233810a2564cbc0adfe395007eac)
-  file: file2 (record type "F", state "u", hash cb99b709a1978bd205ab9dfd4c5aaa1fc91c7523)
-    local path: file2 (flags "")
-    ancestor path: file2 (node 2ed2a3912a0b24502043eae84ee4b279c18b90dd)
-    other path: file2 (node 6f4310b00b9a147241b071a60c28a650827fb03d)
-  unrecognized entry: X mandatory record
+  abort: unsupported merge state records: X
+  (see https://mercurial-scm.org/wiki/MergeStateRecords for more information)
+  [255]
   $ hg resolve -l
   abort: unsupported merge state records: X
   (see https://mercurial-scm.org/wiki/MergeStateRecords for more information)
diff --git a/tests/test-rebase-abort.t b/tests/test-rebase-abort.t
--- a/tests/test-rebase-abort.t
+++ b/tests/test-rebase-abort.t
@@ -88,18 +88,13 @@
 
   $ hg --config extensions.fakemergerecord=$TESTDIR/fakemergerecord.py fakemergerecord -x
   $ hg debugmergestate
-  * version 2 records
-  local: 3e046f2ecedb793b97ed32108086edd1a162f8bc
-  other: 46f0b057b5c061d276b91491c22151f78698abd2
-  labels:
-    local: dest
-    other: source
-  unrecognized entry: x advisory record
-  file extras: common (ancestorlinknode = 3163e20567cc93074fbb7a53c8b93312e59dbf2c)
-  file: common (record type "F", state "u", hash 94c8c21d08740f5da9eaa38d1f175c592692f0d1)
+  local (dest): 3e046f2ecedb793b97ed32108086edd1a162f8bc
+  other (source): 46f0b057b5c061d276b91491c22151f78698abd2
+  file: common (state "u")
     local path: common (flags "")
     ancestor path: common (node de0a666fdd9c1a0b0698b90d85064d8bd34f74b6)
     other path: common (node 2f6411de53677f6f1048fef5bf888d67a342e0a5)
+    extra: ancestorlinknode = 3163e20567cc93074fbb7a53c8b93312e59dbf2c
   $ hg resolve -l
   U common
 
@@ -107,18 +102,9 @@
 
   $ hg --config extensions.fakemergerecord=$TESTDIR/fakemergerecord.py fakemergerecord -X
   $ hg debugmergestate
-  * version 2 records
-  local: 3e046f2ecedb793b97ed32108086edd1a162f8bc
-  other: 46f0b057b5c061d276b91491c22151f78698abd2
-  labels:
-    local: dest
-    other: source
-  file extras: common (ancestorlinknode = 3163e20567cc93074fbb7a53c8b93312e59dbf2c)
-  file: common (record type "F", state "u", hash 94c8c21d08740f5da9eaa38d1f175c592692f0d1)
-    local path: common (flags "")
-    ancestor path: common (node de0a666fdd9c1a0b0698b90d85064d8bd34f74b6)
-    other path: common (node 2f6411de53677f6f1048fef5bf888d67a342e0a5)
-  unrecognized entry: X mandatory record
+  abort: unsupported merge state records: X
+  (see https://mercurial-scm.org/wiki/MergeStateRecords for more information)
+  [255]
   $ hg resolve -l
   abort: unsupported merge state records: X
   (see https://mercurial-scm.org/wiki/MergeStateRecords for more information)
diff --git a/tests/test-merge-changedelete.t b/tests/test-merge-changedelete.t
--- a/tests/test-merge-changedelete.t
+++ b/tests/test-merge-changedelete.t
@@ -76,27 +76,23 @@
   U file2
   U file3
   --- debugmergestate ---
-  * version 2 records
-  local: 13910f48cf7bdb2a0ba6e24b4900e4fdd5739dd4
-  other: 10f9a0a634e82080907e62f075ab119cbc565ea6
-  labels:
-    local: working copy
-    other: merge rev
-  file extras: file1 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
-  file: file1 (record type "C", state "u", hash 60b27f004e454aca81b0480209cce5081ec52390)
+  local (working copy): 13910f48cf7bdb2a0ba6e24b4900e4fdd5739dd4
+  other (merge rev): 10f9a0a634e82080907e62f075ab119cbc565ea6
+  file: file1 (state "u")
     local path: file1 (flags "")
     ancestor path: file1 (node b8e02f6433738021a065f94175c7cd23db5f05be)
-    other path: file1 (node null)
-  file extras: file2 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
-  file: file2 (record type "C", state "u", hash null)
+    other path: file1 (node 0000000000000000000000000000000000000000)
+    extra: ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff
+  file: file2 (state "u")
     local path: file2 (flags "")
     ancestor path: file2 (node 5d9299349fc01ddd25d0070d149b124d8f10411e)
     other path: file2 (node e7c1328648519852e723de86c0c0525acd779257)
-  file extras: file3 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
-  file: file3 (record type "F", state "u", hash d5b0a58bc47161b1b8a831084b366f757c4f0b11)
+    extra: ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff
+  file: file3 (state "u")
     local path: file3 (flags "")
     ancestor path: file3 (node 2661d26c649684b482d10f91960cc3db683c38b4)
     other path: file3 (node a2644c43e210356772c7772a8674544a62e06beb)
+    extra: ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff
   --- file1 ---
   1
   changed
@@ -145,27 +141,23 @@
   R file2
   U file3
   --- debugmergestate ---
-  * version 2 records
-  local: 13910f48cf7bdb2a0ba6e24b4900e4fdd5739dd4
-  other: 10f9a0a634e82080907e62f075ab119cbc565ea6
-  labels:
-    local: working copy
-    other: merge rev
-  file extras: file1 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
-  file: file1 (record type "C", state "r", hash 60b27f004e454aca81b0480209cce5081ec52390)
+  local (working copy): 13910f48cf7bdb2a0ba6e24b4900e4fdd5739dd4
+  other (merge rev): 10f9a0a634e82080907e62f075ab119cbc565ea6
+  file: file1 (state "r")
     local path: file1 (flags "")
     ancestor path: file1 (node b8e02f6433738021a065f94175c7cd23db5f05be)
-    other path: file1 (node null)
-  file extras: file2 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
-  file: file2 (record type "C", state "r", hash null)
+    other path: file1 (node 0000000000000000000000000000000000000000)
+    extra: ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff
+  file: file2 (state "r")
     local path: file2 (flags "")
     ancestor path: file2 (node 5d9299349fc01ddd25d0070d149b124d8f10411e)
     other path: file2 (node e7c1328648519852e723de86c0c0525acd779257)
-  file extras: file3 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
-  file: file3 (record type "F", state "u", hash d5b0a58bc47161b1b8a831084b366f757c4f0b11)
+    extra: ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff
+  file: file3 (state "u")
     local path: file3 (flags "")
     ancestor path: file3 (node 2661d26c649684b482d10f91960cc3db683c38b4)
     other path: file3 (node a2644c43e210356772c7772a8674544a62e06beb)
+    extra: ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff
   --- file1 ---
   1
   changed
@@ -227,27 +219,23 @@
   R file2
   U file3
   --- debugmergestate ---
-  * version 2 records
-  local: 13910f48cf7bdb2a0ba6e24b4900e4fdd5739dd4
-  other: 10f9a0a634e82080907e62f075ab119cbc565ea6
-  labels:
-    local: working copy
-    other: merge rev
-  file extras: file1 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
-  file: file1 (record type "C", state "r", hash 60b27f004e454aca81b0480209cce5081ec52390)
+  local (working copy): 13910f48cf7bdb2a0ba6e24b4900e4fdd5739dd4
+  other (merge rev): 10f9a0a634e82080907e62f075ab119cbc565ea6
+  file: file1 (state "r")
     local path: file1 (flags "")
     ancestor path: file1 (node b8e02f6433738021a065f94175c7cd23db5f05be)
-    other path: file1 (node null)
-  file extras: file2 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
-  file: file2 (record type "C", state "r", hash null)
+    other path: file1 (node 0000000000000000000000000000000000000000)
+    extra: ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff
+  file: file2 (state "r")
     local path: file2 (flags "")
     ancestor path: file2 (node 5d9299349fc01ddd25d0070d149b124d8f10411e)
     other path: file2 (node e7c1328648519852e723de86c0c0525acd779257)
-  file extras: file3 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
-  file: file3 (record type "F", state "u", hash d5b0a58bc47161b1b8a831084b366f757c4f0b11)
+    extra: ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff
+  file: file3 (state "u")
     local path: file3 (flags "")
     ancestor path: file3 (node 2661d26c649684b482d10f91960cc3db683c38b4)
     other path: file3 (node a2644c43e210356772c7772a8674544a62e06beb)
+    extra: ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff
   *** file1 does not exist
   --- file2 ---
   2
@@ -293,27 +281,23 @@
   U file2
   U file3
   --- debugmergestate ---
-  * version 2 records
-  local: 13910f48cf7bdb2a0ba6e24b4900e4fdd5739dd4
-  other: 10f9a0a634e82080907e62f075ab119cbc565ea6
-  labels:
-    local: working copy
-    other: merge rev
-  file extras: file1 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
-  file: file1 (record type "C", state "r", hash 60b27f004e454aca81b0480209cce5081ec52390)
+  local (working copy): 13910f48cf7bdb2a0ba6e24b4900e4fdd5739dd4
+  other (merge rev): 10f9a0a634e82080907e62f075ab119cbc565ea6
+  file: file1 (state "r")
     local path: file1 (flags "")
     ancestor path: file1 (node b8e02f6433738021a065f94175c7cd23db5f05be)
-    other path: file1 (node null)
-  file extras: file2 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
-  file: file2 (record type "C", state "u", hash null)
+    other path: file1 (node 0000000000000000000000000000000000000000)
+    extra: ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff
+  file: file2 (state "u")
     local path: file2 (flags "")
     ancestor path: file2 (node 5d9299349fc01ddd25d0070d149b124d8f10411e)
     other path: file2 (node e7c1328648519852e723de86c0c0525acd779257)
-  file extras: file3 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
-  file: file3 (record type "F", state "u", hash d5b0a58bc47161b1b8a831084b366f757c4f0b11)
+    extra: ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff
+  file: file3 (state "u")
     local path: file3 (flags "")
     ancestor path: file3 (node 2661d26c649684b482d10f91960cc3db683c38b4)
     other path: file3 (node a2644c43e210356772c7772a8674544a62e06beb)
+    extra: ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff
   *** file1 does not exist
   --- file2 ---
   2
@@ -346,27 +330,23 @@
   R file2
   R file3
   --- debugmergestate ---
-  * version 2 records
-  local: 13910f48cf7bdb2a0ba6e24b4900e4fdd5739dd4
-  other: 10f9a0a634e82080907e62f075ab119cbc565ea6
-  labels:
-    local: working copy
-    other: merge rev
-  file extras: file1 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
-  file: file1 (record type "C", state "r", hash 60b27f004e454aca81b0480209cce5081ec52390)
+  local (working copy): 13910f48cf7bdb2a0ba6e24b4900e4fdd5739dd4
+  other (merge rev): 10f9a0a634e82080907e62f075ab119cbc565ea6
+  file: file1 (state "r")
     local path: file1 (flags "")
     ancestor path: file1 (node b8e02f6433738021a065f94175c7cd23db5f05be)
-    other path: file1 (node null)
-  file extras: file2 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
-  file: file2 (record type "C", state "r", hash null)
+    other path: file1 (node 0000000000000000000000000000000000000000)
+    extra: ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff
+  file: file2 (state "r")
     local path: file2 (flags "")
     ancestor path: file2 (node 5d9299349fc01ddd25d0070d149b124d8f10411e)
     other path: file2 (node e7c1328648519852e723de86c0c0525acd779257)
-  file extras: file3 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
-  file: file3 (record type "F", state "r", hash d5b0a58bc47161b1b8a831084b366f757c4f0b11)
+    extra: ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff
+  file: file3 (state "r")
     local path: file3 (flags "")
     ancestor path: file3 (node 2661d26c649684b482d10f91960cc3db683c38b4)
     other path: file3 (node a2644c43e210356772c7772a8674544a62e06beb)
+    extra: ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff
   --- file1 ---
   1
   changed
@@ -395,27 +375,23 @@
   R file2
   R file3
   --- debugmergestate ---
-  * version 2 records
-  local: 13910f48cf7bdb2a0ba6e24b4900e4fdd5739dd4
-  other: 10f9a0a634e82080907e62f075ab119cbc565ea6
-  labels:
-    local: working copy
-    other: merge rev
-  file extras: file1 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
-  file: file1 (record type "C", state "r", hash 60b27f004e454aca81b0480209cce5081ec52390)
+  local (working copy): 13910f48cf7bdb2a0ba6e24b4900e4fdd5739dd4
+  other (merge rev): 10f9a0a634e82080907e62f075ab119cbc565ea6
+  file: file1 (state "r")
     local path: file1 (flags "")
     ancestor path: file1 (node b8e02f6433738021a065f94175c7cd23db5f05be)
-    other path: file1 (node null)
-  file extras: file2 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
-  file: file2 (record type "C", state "r", hash null)
+    other path: file1 (node 0000000000000000000000000000000000000000)
+    extra: ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff
+  file: file2 (state "r")
     local path: file2 (flags "")
     ancestor path: file2 (node 5d9299349fc01ddd25d0070d149b124d8f10411e)
     other path: file2 (node e7c1328648519852e723de86c0c0525acd779257)
-  file extras: file3 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
-  file: file3 (record type "F", state "r", hash d5b0a58bc47161b1b8a831084b366f757c4f0b11)
+    extra: ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff
+  file: file3 (state "r")
     local path: file3 (flags "")
     ancestor path: file3 (node 2661d26c649684b482d10f91960cc3db683c38b4)
     other path: file3 (node a2644c43e210356772c7772a8674544a62e06beb)
+    extra: ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff
   *** file1 does not exist
   --- file2 ---
   2
@@ -445,27 +421,23 @@
   U file2
   U file3
   --- debugmergestate ---
-  * version 2 records
-  local: 13910f48cf7bdb2a0ba6e24b4900e4fdd5739dd4
-  other: 10f9a0a634e82080907e62f075ab119cbc565ea6
-  labels:
-    local: working copy
-    other: merge rev
-  file extras: file1 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
-  file: file1 (record type "C", state "u", hash 60b27f004e454aca81b0480209cce5081ec52390)
+  local (working copy): 13910f48cf7bdb2a0ba6e24b4900e4fdd5739dd4
+  other (merge rev): 10f9a0a634e82080907e62f075ab119cbc565ea6
+  file: file1 (state "u")
     local path: file1 (flags "")
     ancestor path: file1 (node b8e02f6433738021a065f94175c7cd23db5f05be)
-    other path: file1 (node null)
-  file extras: file2 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
-  file: file2 (record type "C", state "u", hash null)
+    other path: file1 (node 0000000000000000000000000000000000000000)
+    extra: ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff
+  file: file2 (state "u")
     local path: file2 (flags "")
     ancestor path: file2 (node 5d9299349fc01ddd25d0070d149b124d8f10411e)
     other path: file2 (node e7c1328648519852e723de86c0c0525acd779257)
-  file extras: file3 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
-  file: file3 (record type "F", state "u", hash d5b0a58bc47161b1b8a831084b366f757c4f0b11)
+    extra: ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff
+  file: file3 (state "u")
     local path: file3 (flags "")
     ancestor path: file3 (node 2661d26c649684b482d10f91960cc3db683c38b4)
     other path: file3 (node a2644c43e210356772c7772a8674544a62e06beb)
+    extra: ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff
   --- file1 ---
   1
   changed
@@ -506,27 +478,23 @@
   U file2
   U file3
   --- debugmergestate ---
-  * version 2 records
-  local: 13910f48cf7bdb2a0ba6e24b4900e4fdd5739dd4
-  other: 10f9a0a634e82080907e62f075ab119cbc565ea6
-  labels:
-    local: working copy
-    other: merge rev
-  file extras: file1 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
-  file: file1 (record type "C", state "u", hash 60b27f004e454aca81b0480209cce5081ec52390)
+  local (working copy): 13910f48cf7bdb2a0ba6e24b4900e4fdd5739dd4
+  other (merge rev): 10f9a0a634e82080907e62f075ab119cbc565ea6
+  file: file1 (state "u")
     local path: file1 (flags "")
     ancestor path: file1 (node b8e02f6433738021a065f94175c7cd23db5f05be)
-    other path: file1 (node null)
-  file extras: file2 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
-  file: file2 (record type "C", state "u", hash null)
+    other path: file1 (node 0000000000000000000000000000000000000000)
+    extra: ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff
+  file: file2 (state "u")
     local path: file2 (flags "")
     ancestor path: file2 (node 5d9299349fc01ddd25d0070d149b124d8f10411e)
     other path: file2 (node e7c1328648519852e723de86c0c0525acd779257)
-  file extras: file3 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
-  file: file3 (record type "F", state "u", hash d5b0a58bc47161b1b8a831084b366f757c4f0b11)
+    extra: ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff
+  file: file3 (state "u")
     local path: file3 (flags "")
     ancestor path: file3 (node 2661d26c649684b482d10f91960cc3db683c38b4)
     other path: file3 (node a2644c43e210356772c7772a8674544a62e06beb)
+    extra: ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff
   --- file1 ---
   1
   changed
@@ -569,27 +537,23 @@
   U file2
   U file3
   --- debugmergestate ---
-  * version 2 records
-  local: 13910f48cf7bdb2a0ba6e24b4900e4fdd5739dd4
-  other: 10f9a0a634e82080907e62f075ab119cbc565ea6
-  labels:
-    local: working copy
-    other: merge rev
-  file extras: file1 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
-  file: file1 (record type "C", state "u", hash 60b27f004e454aca81b0480209cce5081ec52390)
+  local (working copy): 13910f48cf7bdb2a0ba6e24b4900e4fdd5739dd4
+  other (merge rev): 10f9a0a634e82080907e62f075ab119cbc565ea6
+  file: file1 (state "u")
     local path: file1 (flags "")
     ancestor path: file1 (node b8e02f6433738021a065f94175c7cd23db5f05be)
-    other path: file1 (node null)
-  file extras: file2 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
-  file: file2 (record type "C", state "u", hash null)
+    other path: file1 (node 0000000000000000000000000000000000000000)
+    extra: ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff
+  file: file2 (state "u")
     local path: file2 (flags "")
     ancestor path: file2 (node 5d9299349fc01ddd25d0070d149b124d8f10411e)
     other path: file2 (node e7c1328648519852e723de86c0c0525acd779257)
-  file extras: file3 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
-  file: file3 (record type "F", state "u", hash d5b0a58bc47161b1b8a831084b366f757c4f0b11)
+    extra: ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff
+  file: file3 (state "u")
     local path: file3 (flags "")
     ancestor path: file3 (node 2661d26c649684b482d10f91960cc3db683c38b4)
     other path: file3 (node a2644c43e210356772c7772a8674544a62e06beb)
+    extra: ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff
   --- file1 ---
   1
   changed
@@ -629,27 +593,23 @@
   U file2
   U file3
   --- debugmergestate ---
-  * version 2 records
-  local: 13910f48cf7bdb2a0ba6e24b4900e4fdd5739dd4
-  other: 10f9a0a634e82080907e62f075ab119cbc565ea6
-  labels:
-    local: working copy
-    other: merge rev
-  file extras: file1 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
-  file: file1 (record type "C", state "u", hash 60b27f004e454aca81b0480209cce5081ec52390)
+  local (working copy): 13910f48cf7bdb2a0ba6e24b4900e4fdd5739dd4
+  other (merge rev): 10f9a0a634e82080907e62f075ab119cbc565ea6
+  file: file1 (state "u")
     local path: file1 (flags "")
     ancestor path: file1 (node b8e02f6433738021a065f94175c7cd23db5f05be)
-    other path: file1 (node null)
-  file extras: file2 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
-  file: file2 (record type "C", state "u", hash null)
+    other path: file1 (node 0000000000000000000000000000000000000000)
+    extra: ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff
+  file: file2 (state "u")
     local path: file2 (flags "")
     ancestor path: file2 (node 5d9299349fc01ddd25d0070d149b124d8f10411e)
     other path: file2 (node e7c1328648519852e723de86c0c0525acd779257)
-  file extras: file3 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
-  file: file3 (record type "F", state "u", hash d5b0a58bc47161b1b8a831084b366f757c4f0b11)
+    extra: ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff
+  file: file3 (state "u")
     local path: file3 (flags "")
     ancestor path: file3 (node 2661d26c649684b482d10f91960cc3db683c38b4)
     other path: file3 (node a2644c43e210356772c7772a8674544a62e06beb)
+    extra: ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff
   --- file1 ---
   1
   changed
@@ -802,22 +762,18 @@
   U file1
   U file2
   --- debugmergestate ---
-  * version 2 records
-  local: ab57bf49aa276a22d35a473592d4c34b5abc3eff
-  other: 10f9a0a634e82080907e62f075ab119cbc565ea6
-  labels:
-    local: working copy
-    other: destination
-  file extras: file1 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
-  file: file1 (record type "C", state "u", hash 60b27f004e454aca81b0480209cce5081ec52390)
+  local (working copy): ab57bf49aa276a22d35a473592d4c34b5abc3eff
+  other (destination): 10f9a0a634e82080907e62f075ab119cbc565ea6
+  file: file1 (state "u")
     local path: file1 (flags "")
     ancestor path: file1 (node b8e02f6433738021a065f94175c7cd23db5f05be)
-    other path: file1 (node null)
-  file extras: file2 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
-  file: file2 (record type "C", state "u", hash null)
+    other path: file1 (node 0000000000000000000000000000000000000000)
+    extra: ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff
+  file: file2 (state "u")
     local path: file2 (flags "")
     ancestor path: file2 (node 5d9299349fc01ddd25d0070d149b124d8f10411e)
     other path: file2 (node e7c1328648519852e723de86c0c0525acd779257)
+    extra: ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff
   --- file1 ---
   1
   changed
@@ -845,22 +801,18 @@
   R file1
   R file2
   --- debugmergestate ---
-  * version 2 records
-  local: ab57bf49aa276a22d35a473592d4c34b5abc3eff
-  other: 10f9a0a634e82080907e62f075ab119cbc565ea6
-  labels:
-    local: working copy
-    other: destination
-  file extras: file1 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
-  file: file1 (record type "C", state "r", hash 60b27f004e454aca81b0480209cce5081ec52390)
+  local (working copy): ab57bf49aa276a22d35a473592d4c34b5abc3eff
+  other (destination): 10f9a0a634e82080907e62f075ab119cbc565ea6
+  file: file1 (state "r")
     local path: file1 (flags "")
     ancestor path: file1 (node b8e02f6433738021a065f94175c7cd23db5f05be)
-    other path: file1 (node null)
-  file extras: file2 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
-  file: file2 (record type "C", state "r", hash null)
+    other path: file1 (node 0000000000000000000000000000000000000000)
+    extra: ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff
+  file: file2 (state "r")
     local path: file2 (flags "")
     ancestor path: file2 (node 5d9299349fc01ddd25d0070d149b124d8f10411e)
     other path: file2 (node e7c1328648519852e723de86c0c0525acd779257)
+    extra: ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff
   --- file1 ---
   1
   changed
@@ -886,22 +838,18 @@
   R file1
   R file2
   --- debugmergestate ---
-  * version 2 records
-  local: ab57bf49aa276a22d35a473592d4c34b5abc3eff
-  other: 10f9a0a634e82080907e62f075ab119cbc565ea6
-  labels:
-    local: working copy
-    other: destination
-  file extras: file1 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
-  file: file1 (record type "C", state "r", hash 60b27f004e454aca81b0480209cce5081ec52390)
+  local (working copy): ab57bf49aa276a22d35a473592d4c34b5abc3eff
+  other (destination): 10f9a0a634e82080907e62f075ab119cbc565ea6
+  file: file1 (state "r")
     local path: file1 (flags "")
     ancestor path: file1 (node b8e02f6433738021a065f94175c7cd23db5f05be)
-    other path: file1 (node null)
-  file extras: file2 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
-  file: file2 (record type "C", state "r", hash null)
+    other path: file1 (node 0000000000000000000000000000000000000000)
+    extra: ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff
+  file: file2 (state "r")
     local path: file2 (flags "")
     ancestor path: file2 (node 5d9299349fc01ddd25d0070d149b124d8f10411e)
     other path: file2 (node e7c1328648519852e723de86c0c0525acd779257)
+    extra: ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff
   *** file1 does not exist
   --- file2 ---
   2
@@ -929,22 +877,18 @@
   U file1
   U file2
   --- debugmergestate ---
-  * version 2 records
-  local: ab57bf49aa276a22d35a473592d4c34b5abc3eff
-  other: 10f9a0a634e82080907e62f075ab119cbc565ea6
-  labels:
-    local: working copy
-    other: destination
-  file extras: file1 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
-  file: file1 (record type "C", state "u", hash 60b27f004e454aca81b0480209cce5081ec52390)
+  local (working copy): ab57bf49aa276a22d35a473592d4c34b5abc3eff
+  other (destination): 10f9a0a634e82080907e62f075ab119cbc565ea6
+  file: file1 (state "u")
     local path: file1 (flags "")
     ancestor path: file1 (node b8e02f6433738021a065f94175c7cd23db5f05be)
-    other path: file1 (node null)
-  file extras: file2 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
-  file: file2 (record type "C", state "u", hash null)
+    other path: file1 (node 0000000000000000000000000000000000000000)
+    extra: ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff
+  file: file2 (state "u")
     local path: file2 (flags "")
     ancestor path: file2 (node 5d9299349fc01ddd25d0070d149b124d8f10411e)
     other path: file2 (node e7c1328648519852e723de86c0c0525acd779257)
+    extra: ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff
   --- file1 ---
   1
   changed
@@ -980,22 +924,18 @@
   U file1
   U file2
   --- debugmergestate ---
-  * version 2 records
-  local: ab57bf49aa276a22d35a473592d4c34b5abc3eff
-  other: 10f9a0a634e82080907e62f075ab119cbc565ea6
-  labels:
-    local: working copy
-    other: destination
-  file extras: file1 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
-  file: file1 (record type "C", state "u", hash 60b27f004e454aca81b0480209cce5081ec52390)
+  local (working copy): ab57bf49aa276a22d35a473592d4c34b5abc3eff
+  other (destination): 10f9a0a634e82080907e62f075ab119cbc565ea6
+  file: file1 (state "u")
     local path: file1 (flags "")
     ancestor path: file1 (node b8e02f6433738021a065f94175c7cd23db5f05be)
-    other path: file1 (node null)
-  file extras: file2 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
-  file: file2 (record type "C", state "u", hash null)
+    other path: file1 (node 0000000000000000000000000000000000000000)
+    extra: ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff
+  file: file2 (state "u")
     local path: file2 (flags "")
     ancestor path: file2 (node 5d9299349fc01ddd25d0070d149b124d8f10411e)
     other path: file2 (node e7c1328648519852e723de86c0c0525acd779257)
+    extra: ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff
   --- file1 ---
   1
   changed
@@ -1032,22 +972,18 @@
   U file1
   U file2
   --- debugmergestate ---
-  * version 2 records
-  local: ab57bf49aa276a22d35a473592d4c34b5abc3eff
-  other: 10f9a0a634e82080907e62f075ab119cbc565ea6
-  labels:
-    local: working copy
-    other: destination
-  file extras: file1 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
-  file: file1 (record type "C", state "u", hash 60b27f004e454aca81b0480209cce5081ec52390)
+  local (working copy): ab57bf49aa276a22d35a473592d4c34b5abc3eff
+  other (destination): 10f9a0a634e82080907e62f075ab119cbc565ea6
+  file: file1 (state "u")
     local path: file1 (flags "")
     ancestor path: file1 (node b8e02f6433738021a065f94175c7cd23db5f05be)
-    other path: file1 (node null)
-  file extras: file2 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
-  file: file2 (record type "C", state "u", hash null)
+    other path: file1 (node 0000000000000000000000000000000000000000)
+    extra: ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff
+  file: file2 (state "u")
     local path: file2 (flags "")
     ancestor path: file2 (node 5d9299349fc01ddd25d0070d149b124d8f10411e)
     other path: file2 (node e7c1328648519852e723de86c0c0525acd779257)
+    extra: ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff
   --- file1 ---
   1
   changed
diff --git a/tests/test-histedit-non-commute-abort.t b/tests/test-histedit-non-commute-abort.t
--- a/tests/test-histedit-non-commute-abort.t
+++ b/tests/test-histedit-non-commute-abort.t
@@ -77,36 +77,22 @@
 insert unsupported advisory merge record
   $ hg --config extensions.fakemergerecord=$TESTDIR/fakemergerecord.py fakemergerecord -x
   $ hg debugmergestate
-  * version 2 records
-  local: 8f7551c7e4a2f2efe0bc8c741baf7f227d65d758
-  other: e860deea161a2f77de56603b340ebbb4536308ae
-  labels:
-    local: local
-    other: histedit
-  unrecognized entry: x advisory record
-  file extras: e (ancestorlinknode = 0000000000000000000000000000000000000000)
-  file: e (record type "F", state "u", hash 58e6b3a414a1e090dfc6029add0f3555ccba127f)
+  local (local): 8f7551c7e4a2f2efe0bc8c741baf7f227d65d758
+  other (histedit): e860deea161a2f77de56603b340ebbb4536308ae
+  file: e (state "u")
     local path: e (flags "")
-    ancestor path: e (node null)
+    ancestor path: e (node 0000000000000000000000000000000000000000)
     other path: e (node 6b67ccefd5ce6de77e7ead4f5292843a0255329f)
+    extra: ancestorlinknode = 0000000000000000000000000000000000000000
   $ hg resolve -l
   U e
 
 insert unsupported mandatory merge record
   $ hg --config extensions.fakemergerecord=$TESTDIR/fakemergerecord.py fakemergerecord -X
   $ hg debugmergestate
-  * version 2 records
-  local: 8f7551c7e4a2f2efe0bc8c741baf7f227d65d758
-  other: e860deea161a2f77de56603b340ebbb4536308ae
-  labels:
-    local: local
-    other: histedit
-  file extras: e (ancestorlinknode = 0000000000000000000000000000000000000000)
-  file: e (record type "F", state "u", hash 58e6b3a414a1e090dfc6029add0f3555ccba127f)
-    local path: e (flags "")
-    ancestor path: e (node null)
-    other path: e (node 6b67ccefd5ce6de77e7ead4f5292843a0255329f)
-  unrecognized entry: X mandatory record
+  abort: unsupported merge state records: X
+  (see https://mercurial-scm.org/wiki/MergeStateRecords for more information)
+  [255]
   $ hg resolve -l
   abort: unsupported merge state records: X
   (see https://mercurial-scm.org/wiki/MergeStateRecords for more information)
diff --git a/tests/test-completion.t b/tests/test-completion.t
--- a/tests/test-completion.t
+++ b/tests/test-completion.t
@@ -289,7 +289,7 @@
   debuglabelcomplete:
   debuglocks: force-lock, force-wlock, set-lock, set-wlock
   debugmanifestfulltextcache: clear, add
-  debugmergestate:
+  debugmergestate: style, template
   debugnamecomplete:
   debugnodemap: dump-new, dump-disk, check, metadata
   debugobsolete: flags, record-parents, rev, exclusive, index, delete, date, user, template
diff --git a/tests/test-backout.t b/tests/test-backout.t
--- a/tests/test-backout.t
+++ b/tests/test-backout.t
@@ -710,22 +710,21 @@
   [1]
   $ hg status
   $ hg debugmergestate
-  * version 2 records
   local: b71750c4b0fdf719734971e3ef90dbeab5919a2d
   other: a30dd8addae3ce71b8667868478542bc417439e6
-  file extras: foo (ancestorlinknode = 91360952243723bd5b1138d5f26bd8c8564cb553)
-  file: foo (record type "F", state "u", hash 0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33)
+  file: foo (state "u")
     local path: foo (flags "")
     ancestor path: foo (node f89532f44c247a0e993d63e3a734dd781ab04708)
     other path: foo (node f50039b486d6fa1a90ae51778388cad161f425ee)
+    extra: ancestorlinknode = 91360952243723bd5b1138d5f26bd8c8564cb553
   $ mv .hg/merge/state2 .hg/merge/state2-moved
   $ hg debugmergestate
-  * version 1 records
   local: b71750c4b0fdf719734971e3ef90dbeab5919a2d
-  file: foo (record type "F", state "u", hash 0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33)
+  other: b71750c4b0fdf719734971e3ef90dbeab5919a2d
+  file: foo (state "u")
     local path: foo (flags "")
     ancestor path: foo (node f89532f44c247a0e993d63e3a734dd781ab04708)
-    other path: foo (node not stored in v1 format)
+    other path:  (node foo)
   $ mv .hg/merge/state2-moved .hg/merge/state2
   $ hg resolve -l  # still unresolved
   U foo
diff --git a/relnotes/next b/relnotes/next
--- a/relnotes/next
+++ b/relnotes/next
@@ -12,6 +12,9 @@
    commits that are being merged, when there are conflicts. Also works
    for conflicts caused by e.g. `hg graft`.
 
+ * `hg debugmergestate` output is now templated, which may be useful
+   e.g. for IDEs that want to help the user resolve merge conflicts.
+
 
 == New Experimental Features ==
 
@@ -26,6 +29,9 @@
    can use the new `conflictparents()` revset for finding the other
    parent during a conflict.
 
+ * `hg debugmergestate` output format changed. Let us know if that is
+   causing you problems and we'll roll it back.
+
 
 == Internal API Changes ==
 
diff --git a/mercurial/debugcommands.py b/mercurial/debugcommands.py
--- a/mercurial/debugcommands.py
+++ b/mercurial/debugcommands.py
@@ -28,7 +28,6 @@
 from .node import (
     bin,
     hex,
-    nullhex,
     nullid,
     nullrev,
     short,
@@ -1944,120 +1943,84 @@
         )
 
 
-@command(b'debugmergestate', [], b'')
-def debugmergestate(ui, repo, *args):
+@command(b'debugmergestate', [] + cmdutil.templateopts, b'')
+def debugmergestate(ui, repo, *args, **opts):
     """print merge state
 
     Use --verbose to print out information about whether v1 or v2 merge state
     was chosen."""
 
-    def _hashornull(h):
-        if h == nullhex:
-            return b'null'
-        else:
-            return h
-
-    def printrecords(version):
-        ui.writenoi18n(b'* version %d records\n' % version)
-        if version == 1:
-            records = v1records
+    if ui.verbose:
+        ms = mergemod.mergestate(repo)
+
+        # sort so that reasonable information is on top
+        v1records = ms._readrecordsv1()
+        v2records = ms._readrecordsv2()
+
+        if not v1records and not v2records:
+            pass
+        elif not v2records:
+            ui.writenoi18n(b'no version 2 merge state\n')
+        elif ms._v1v2match(v1records, v2records):
+            ui.writenoi18n(b'v1 and v2 states match: using v2\n')
         else:
-            records = v2records
-
-        for rtype, record in records:
-            # pretty print some record types
-            if rtype == b'L':
-                ui.writenoi18n(b'local: %s\n' % record)
-            elif rtype == b'O':
-                ui.writenoi18n(b'other: %s\n' % record)
-            elif rtype == b'm':
-                driver, mdstate = record.split(b'\0', 1)
-                ui.writenoi18n(
-                    b'merge driver: %s (state "%s")\n' % (driver, mdstate)
-                )
-            elif rtype in b'FDC':
-                r = record.split(b'\0')
-                f, state, hash, lfile, afile, anode, ofile = r[0:7]
-                if version == 1:
-                    onode = b'not stored in v1 format'
-                    flags = r[7]
-                else:
-                    onode, flags = r[7:9]
-                ui.writenoi18n(
-                    b'file: %s (record type "%s", state "%s", hash %s)\n'
-                    % (f, rtype, state, _hashornull(hash))
-                )
-                ui.writenoi18n(
-                    b'  local path: %s (flags "%s")\n' % (lfile, flags)
-                )
-                ui.writenoi18n(
-                    b'  ancestor path: %s (node %s)\n'
-                    % (afile, _hashornull(anode))
-                )
-                ui.writenoi18n(
-                    b'  other path: %s (node %s)\n'
-                    % (ofile, _hashornull(onode))
-                )
-            elif rtype == b'f':
-                filename, rawextras = record.split(b'\0', 1)
-                extras = rawextras.split(b'\0')
-                i = 0
-                extrastrings = []
-                while i < len(extras):
-                    extrastrings.append(b'%s = %s' % (extras[i], extras[i + 1]))
-                    i += 2
-
-                ui.writenoi18n(
-                    b'file extras: %s (%s)\n'
-                    % (filename, b', '.join(extrastrings))
-                )
-            elif rtype == b'l':
-                labels = record.split(b'\0', 2)
-                labels = [l for l in labels if len(l) > 0]
-                ui.writenoi18n(b'labels:\n')
-                ui.write((b'  local: %s\n' % labels[0]))
-                ui.write((b'  other: %s\n' % labels[1]))
-                if len(labels) > 2:
-                    ui.write((b'  base:  %s\n' % labels[2]))
-            else:
-                ui.writenoi18n(
-                    b'unrecognized entry: %s\t%s\n'
-                    % (rtype, record.replace(b'\0', b'\t'))
-                )
-
-    # Avoid mergestate.read() since it may raise an exception for unsupported
-    # merge state records. We shouldn't be doing this, but this is OK since this
-    # command is pretty low-level.
-    ms = mergemod.mergestate(repo)
-
-    # sort so that reasonable information is on top
-    v1records = ms._readrecordsv1()
-    v2records = ms._readrecordsv2()
-    order = b'LOml'
-
-    def key(r):
-        idx = order.find(r[0])
-        if idx == -1:
-            return (1, r[1])
-        else:
-            return (0, idx)
-
-    v1records.sort(key=key)
-    v2records.sort(key=key)
-
-    if not v1records and not v2records:
-        ui.writenoi18n(b'no merge state found\n')
-    elif not v2records:
-        ui.notenoi18n(b'no version 2 merge state\n')
-        printrecords(1)
-    elif ms._v1v2match(v1records, v2records):
-        ui.notenoi18n(b'v1 and v2 states match: using v2\n')
-        printrecords(2)
-    else:
-        ui.notenoi18n(b'v1 and v2 states mismatch: using v1\n')
-        printrecords(1)
-        if ui.verbose:
-            printrecords(2)
+            ui.writenoi18n(b'v1 and v2 states mismatch: using v1\n')
+
+    opts = pycompat.byteskwargs(opts)
+    if not opts[b'template']:
+        opts[b'template'] = (
+            b'{if(commits, "", "no merge state found\n")}'
+            b'{commits % "{name}{if(label, " ({label})")}: {node}\n"}'
+            b'{files % "file: {path} (state \\"{state}\\")\n'
+            b'  local path: {local_path} (flags \\"{local_flags}\\")\n'
+            b'  ancestor path: {ancestor_path} (node {ancestor_node})\n'
+            b'  other path: {other_path} (node {other_node})\n'
+            b'{extras % "  extra: {key} = {value}\n"}'
+            b'"}'
+        )
+
+    ms = mergemod.mergestate.read(repo)
+
+    fm = ui.formatter(b'debugmergestate', opts)
+    fm.startitem()
+
+    fm_commits = fm.nested(b'commits')
+    if ms.active():
+        for name, node, label_index in (
+            (b'local', ms.local, 0),
+            (b'other', ms.other, 1),
+        ):
+            fm_commits.startitem()
+            fm_commits.data(name=name)
+            fm_commits.data(node=hex(node))
+            if ms._labels and len(ms._labels) > label_index:
+                fm_commits.data(label=ms._labels[label_index])
+    fm_commits.end()
+
+    fm_files = fm.nested(b'files')
+    if ms.active():
+        for f in ms:
+            fm_files.startitem()
+            fm_files.data(path=f)
+            state = ms._state[f]
+            fm_files.data(state=state[0])
+            fm_files.data(local_key=state[1])
+            fm_files.data(local_path=state[2])
+            fm_files.data(ancestor_path=state[3])
+            fm_files.data(ancestor_node=state[4])
+            fm_files.data(other_path=state[5])
+            fm_files.data(other_node=state[6])
+            fm_files.data(local_flags=state[7])
+            fm_extras = fm_files.nested(b'extras')
+            for k, v in ms.extras(f).items():
+                fm_extras.startitem()
+                fm_extras.data(key=k)
+                fm_extras.data(value=v)
+            fm_extras.end()
+
+    fm_files.end()
+
+    fm.end()
 
 
 @command(b'debugnamecomplete', [], _(b'NAME...'))



To: martinvonz, #hg-reviewers, durin42, pulkit
Cc: pulkit, durin42, mercurial-devel
_______________________________________________
Mercurial-devel mailing list
[hidden email]
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Reply | Threaded
Open this post in threaded view
|

D8113: debugmergestate: make templated

marmoute (Pierre-Yves David)
In reply to this post by marmoute (Pierre-Yves David)
martinvonz added a comment.


  I was worried that the new version might be crashing in some cases (I specifically worried about indexes out of range in the `state` list). To test that, I added `hg debugmergestate` before every `hg resolve` call in the test suite. That showed two different bugs. Feel free to de-queue this patch or I'll send updates later (maybe tomorrow). Sorry that I didn't think to test that before the patch got accepted.

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D8113/new/

REVISION DETAIL
  https://phab.mercurial-scm.org/D8113

To: martinvonz, #hg-reviewers, durin42, pulkit
Cc: pulkit, durin42, mercurial-devel
_______________________________________________
Mercurial-devel mailing list
[hidden email]
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Reply | Threaded
Open this post in threaded view
|

D8113: debugmergestate: make templated

marmoute (Pierre-Yves David)
In reply to this post by marmoute (Pierre-Yves David)
martinvonz added a comment.


  In D8113#120803 <https://phab.mercurial-scm.org/D8113#120803>, @martinvonz wrote:
 
  > I was worried that the new version might be crashing in some cases (I specifically worried about indexes out of range in the `state` list). To test that, I added `hg debugmergestate` before every `hg resolve` call in the test suite. That showed two different bugs. Feel free to de-queue this patch or I'll send updates later (maybe tomorrow). Sorry that I didn't think to test that before the patch got accepted.
 
  I'll just de-queue the patch myself. I'll send a replacement for this one later.

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D8113/new/

REVISION DETAIL
  https://phab.mercurial-scm.org/D8113

To: martinvonz, #hg-reviewers, durin42, pulkit
Cc: pulkit, durin42, mercurial-devel
_______________________________________________
Mercurial-devel mailing list
[hidden email]
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel