Patchwork [3,of,3,V2] merge: add file ancestor linknode to mergestate

login
register
mail settings
Submitter Durham Goode
Date Feb. 5, 2016, 7:03 p.m.
Message ID <d32dc6274ec43680fb8d.1454699002@dev8486.prn1.facebook.com>
Download mbox | patch
Permalink /patch/13012/
State Accepted
Headers show

Comments

Durham Goode - Feb. 5, 2016, 7:03 p.m.
# HG changeset patch
# User Durham Goode <durham@fb.com>
# Date 1454696534 28800
#      Fri Feb 05 10:22:14 2016 -0800
# Node ID d32dc6274ec43680fb8dfa9883d00175cf4b1c40
# Parent  3f5345de185eaae10a33c8c97afe3d2649b604f6
merge: add file ancestor linknode to mergestate

During a merge, each file has a current commitnode+filenode, an other
commitnode+filenode, and an ancestor commitnode+filenode. The ancestor
commitnode is not stored though, and we rely on the ability for the filectx() to
look up the commitnode by using the filenode's linkrev. In alternative backends
(like remotefilelog), linkrevs may have restriction that prevent arbitrary
linkrev look up given a filenode.

This patch accounts for that by storing the ancestor commitnode in
the merge state so that it is available later at resolve time.

This results in some test changes because the ancestor commitnode we're using at
resolve time changes slightly. Before, we used the linkrev commit, which is the
earliest commit that introduced that particular filenode (which may not be the
latest common ancestor of the commits being merged). Now we use the latest
common ancestor of the merged commits as the commitnode. This is fine though,
because that commit contains the same filenode as the linkrev'd commit.
Martin von Zweigbergk - Feb. 5, 2016, 9:44 p.m.
My comments from v1 have been addressed, so this now looks good to me
(I'm assuming the patch bodies haven't changed). Augie, can I ask you
to queue this since you seem to be set up for queuing patches right
now? :-)

On Fri, Feb 5, 2016 at 11:03 AM, Durham Goode <durham@fb.com> wrote:
> # HG changeset patch
> # User Durham Goode <durham@fb.com>
> # Date 1454696534 28800
> #      Fri Feb 05 10:22:14 2016 -0800
> # Node ID d32dc6274ec43680fb8dfa9883d00175cf4b1c40
> # Parent  3f5345de185eaae10a33c8c97afe3d2649b604f6
> merge: add file ancestor linknode to mergestate
>
> During a merge, each file has a current commitnode+filenode, an other
> commitnode+filenode, and an ancestor commitnode+filenode. The ancestor
> commitnode is not stored though, and we rely on the ability for the filectx() to
> look up the commitnode by using the filenode's linkrev. In alternative backends
> (like remotefilelog), linkrevs may have restriction that prevent arbitrary
> linkrev look up given a filenode.
>
> This patch accounts for that by storing the ancestor commitnode in
> the merge state so that it is available later at resolve time.
>
> This results in some test changes because the ancestor commitnode we're using at
> resolve time changes slightly. Before, we used the linkrev commit, which is the
> earliest commit that introduced that particular filenode (which may not be the
> latest common ancestor of the commits being merged). Now we use the latest
> common ancestor of the merged commits as the commitnode. This is fine though,
> because that commit contains the same filenode as the linkrev'd commit.
>
> diff --git a/mercurial/merge.py b/mercurial/merge.py
> --- a/mercurial/merge.py
> +++ b/mercurial/merge.py
> @@ -405,6 +405,7 @@ class mergestate(object):
>                             fca.path(), hex(fca.filenode()),
>                             fco.path(), hex(fco.filenode()),
>                             fcl.flags()]
> +        self._stateextras[fd] = { 'ancestorlinknode' : hex(fca.node()) }
>          self._dirty = True
>
>      def __contains__(self, dfile):
> @@ -450,10 +451,16 @@ class mergestate(object):
>          stateentry = self._state[dfile]
>          state, hash, lfile, afile, anode, ofile, onode, flags = stateentry
>          octx = self._repo[self._other]
> +        extras = self.extras(dfile)
> +        anccommitnode = extras.get('ancestorlinknode')
> +        if anccommitnode:
> +            actx = self._repo[anccommitnode]
> +        else:
> +            actx = None
>          fcd = self._filectxorabsent(hash, wctx, dfile)
>          fco = self._filectxorabsent(onode, octx, ofile)
>          # TODO: move this to filectxorabsent
> -        fca = self._repo.filectx(afile, fileid=anode)
> +        fca = self._repo.filectx(afile, fileid=anode, changeid=actx)
>          # "premerge" x flags
>          flo = fco.flags()
>          fla = fca.flags()
> diff --git a/tests/test-backout.t b/tests/test-backout.t
> --- a/tests/test-backout.t
> +++ b/tests/test-backout.t
> @@ -686,6 +686,7 @@ Test usage of `hg resolve` in case of co
>    * version 2 records
>    local: b71750c4b0fdf719734971e3ef90dbeab5919a2d
>    other: a30dd8addae3ce71b8667868478542bc417439e6
> +  file extras: foo (ancestorlinknode = 91360952243723bd5b1138d5f26bd8c8564cb553)
>    file: foo (record type "F", state "u", hash 0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33)
>      local path: foo (flags "")
>      ancestor path: foo (node f89532f44c247a0e993d63e3a734dd781ab04708)
> diff --git a/tests/test-graft.t b/tests/test-graft.t
> --- a/tests/test-graft.t
> +++ b/tests/test-graft.t
> @@ -189,10 +189,10 @@ Graft out of order, skipping a merge and
>     e: versions differ -> m (premerge)
>    picked tool ':merge' for e (binary False symlink False changedelete False)
>    merging e
> -  my e@1905859650ec+ other e@9c233e8e184d ancestor e@68795b066622
> +  my e@1905859650ec+ other e@9c233e8e184d ancestor e@4c60f11aa304
>     e: versions differ -> m (merge)
>    picked tool ':merge' for e (binary False symlink False changedelete False)
> -  my e@1905859650ec+ other e@9c233e8e184d ancestor e@68795b066622
> +  my e@1905859650ec+ other e@9c233e8e184d ancestor e@4c60f11aa304
>    warning: conflicts while merging e! (edit, then use 'hg resolve --mark')
>    abort: unresolved conflicts, can't continue
>    (use hg resolve and hg graft --continue --log)
> 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
> @@ -82,6 +82,7 @@ insert unsupported advisory merge record
>    local: 8f7551c7e4a2f2efe0bc8c741baf7f227d65d758
>    other: e860deea161a2f77de56603b340ebbb4536308ae
>    unrecognized entry: x        advisory record
> +  file extras: e (ancestorlinknode = 0000000000000000000000000000000000000000)
>    file: e (record type "F", state "u", hash 58e6b3a414a1e090dfc6029add0f3555ccba127f)
>      local path: e (flags "")
>      ancestor path: e (node null)
> @@ -95,6 +96,7 @@ insert unsupported mandatory merge recor
>    * version 2 records
>    local: 8f7551c7e4a2f2efe0bc8c741baf7f227d65d758
>    other: e860deea161a2f77de56603b340ebbb4536308ae
> +  file extras: e (ancestorlinknode = 0000000000000000000000000000000000000000)
>    file: e (record type "F", state "u", hash 58e6b3a414a1e090dfc6029add0f3555ccba127f)
>      local path: e (flags "")
>      ancestor path: e (node null)
> diff --git a/tests/test-issue672.t b/tests/test-issue672.t
> --- a/tests/test-issue672.t
> +++ b/tests/test-issue672.t
> @@ -68,7 +68,7 @@ https://bz.mercurial-scm.org/672
>     1a: local copied/moved from 1 -> m (premerge)
>    picked tool ':merge' for 1a (binary False symlink False changedelete False)
>    merging 1a and 1 to 1a
> -  my 1a@e327dca35ac8+ other 1@746e9549ea96 ancestor 1@81f4b099af3d
> +  my 1a@e327dca35ac8+ other 1@746e9549ea96 ancestor 1@c64f439569a9
>     premerge successful
>    0 files updated, 1 files merged, 0 files removed, 0 files unresolved
>    (branch merge, don't forget to commit)
> @@ -91,7 +91,7 @@ https://bz.mercurial-scm.org/672
>     1a: remote moved from 1 -> m (premerge)
>    picked tool ':merge' for 1a (binary False symlink False changedelete False)
>    merging 1 and 1a to 1a
> -  my 1a@746e9549ea96+ other 1a@e327dca35ac8 ancestor 1@81f4b099af3d
> +  my 1a@746e9549ea96+ other 1a@e327dca35ac8 ancestor 1@c64f439569a9
>     premerge successful
>    0 files updated, 1 files merged, 0 files removed, 0 files unresolved
>    (branch merge, don't forget to commit)
> 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
> @@ -77,14 +77,17 @@ Non-interactive merge:
>    * version 2 records
>    local: 13910f48cf7bdb2a0ba6e24b4900e4fdd5739dd4
>    other: 10f9a0a634e82080907e62f075ab119cbc565ea6
> +  file extras: file1 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
>    file: file1 (record type "C", state "u", hash 60b27f004e454aca81b0480209cce5081ec52390)
>      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)
>      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)
>      local path: file3 (flags "")
>      ancestor path: file3 (node 2661d26c649684b482d10f91960cc3db683c38b4)
> @@ -136,14 +139,17 @@ Interactive merge:
>    * version 2 records
>    local: 13910f48cf7bdb2a0ba6e24b4900e4fdd5739dd4
>    other: 10f9a0a634e82080907e62f075ab119cbc565ea6
> +  file extras: file1 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
>    file: file1 (record type "C", state "r", hash 60b27f004e454aca81b0480209cce5081ec52390)
>      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)
>      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)
>      local path: file3 (flags "")
>      ancestor path: file3 (node 2661d26c649684b482d10f91960cc3db683c38b4)
> @@ -205,14 +211,17 @@ Interactive merge with bad input:
>    * version 2 records
>    local: 13910f48cf7bdb2a0ba6e24b4900e4fdd5739dd4
>    other: 10f9a0a634e82080907e62f075ab119cbc565ea6
> +  file extras: file1 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
>    file: file1 (record type "C", state "r", hash 60b27f004e454aca81b0480209cce5081ec52390)
>      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)
>      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)
>      local path: file3 (flags "")
>      ancestor path: file3 (node 2661d26c649684b482d10f91960cc3db683c38b4)
> @@ -261,14 +270,17 @@ Interactive merge with not enough input:
>    * version 2 records
>    local: 13910f48cf7bdb2a0ba6e24b4900e4fdd5739dd4
>    other: 10f9a0a634e82080907e62f075ab119cbc565ea6
> +  file extras: file1 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
>    file: file1 (record type "C", state "r", hash 60b27f004e454aca81b0480209cce5081ec52390)
>      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)
>      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)
>      local path: file3 (flags "")
>      ancestor path: file3 (node 2661d26c649684b482d10f91960cc3db683c38b4)
> @@ -306,14 +318,17 @@ Choose local versions of files
>    * version 2 records
>    local: 13910f48cf7bdb2a0ba6e24b4900e4fdd5739dd4
>    other: 10f9a0a634e82080907e62f075ab119cbc565ea6
> +  file extras: file1 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
>    file: file1 (record type "C", state "r", hash 60b27f004e454aca81b0480209cce5081ec52390)
>      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)
>      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)
>      local path: file3 (flags "")
>      ancestor path: file3 (node 2661d26c649684b482d10f91960cc3db683c38b4)
> @@ -347,14 +362,17 @@ Choose other versions of files
>    * version 2 records
>    local: 13910f48cf7bdb2a0ba6e24b4900e4fdd5739dd4
>    other: 10f9a0a634e82080907e62f075ab119cbc565ea6
> +  file extras: file1 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
>    file: file1 (record type "C", state "r", hash 60b27f004e454aca81b0480209cce5081ec52390)
>      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)
>      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)
>      local path: file3 (flags "")
>      ancestor path: file3 (node 2661d26c649684b482d10f91960cc3db683c38b4)
> @@ -389,14 +407,17 @@ Fail
>    * version 2 records
>    local: 13910f48cf7bdb2a0ba6e24b4900e4fdd5739dd4
>    other: 10f9a0a634e82080907e62f075ab119cbc565ea6
> +  file extras: file1 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
>    file: file1 (record type "C", state "u", hash 60b27f004e454aca81b0480209cce5081ec52390)
>      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)
>      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)
>      local path: file3 (flags "")
>      ancestor path: file3 (node 2661d26c649684b482d10f91960cc3db683c38b4)
> @@ -439,14 +460,17 @@ Force prompts with no input (should be s
>    * version 2 records
>    local: 13910f48cf7bdb2a0ba6e24b4900e4fdd5739dd4
>    other: 10f9a0a634e82080907e62f075ab119cbc565ea6
> +  file extras: file1 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
>    file: file1 (record type "C", state "u", hash 60b27f004e454aca81b0480209cce5081ec52390)
>      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)
>      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)
>      local path: file3 (flags "")
>      ancestor path: file3 (node 2661d26c649684b482d10f91960cc3db683c38b4)
> @@ -491,14 +515,17 @@ Force prompts
>    * version 2 records
>    local: 13910f48cf7bdb2a0ba6e24b4900e4fdd5739dd4
>    other: 10f9a0a634e82080907e62f075ab119cbc565ea6
> +  file extras: file1 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
>    file: file1 (record type "C", state "u", hash 60b27f004e454aca81b0480209cce5081ec52390)
>      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)
>      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)
>      local path: file3 (flags "")
>      ancestor path: file3 (node 2661d26c649684b482d10f91960cc3db683c38b4)
> @@ -541,14 +568,17 @@ Choose to merge all files
>    * version 2 records
>    local: 13910f48cf7bdb2a0ba6e24b4900e4fdd5739dd4
>    other: 10f9a0a634e82080907e62f075ab119cbc565ea6
> +  file extras: file1 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
>    file: file1 (record type "C", state "u", hash 60b27f004e454aca81b0480209cce5081ec52390)
>      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)
>      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)
>      local path: file3 (flags "")
>      ancestor path: file3 (node 2661d26c649684b482d10f91960cc3db683c38b4)
> @@ -697,10 +727,12 @@ Non-interactive linear update
>    * version 2 records
>    local: ab57bf49aa276a22d35a473592d4c34b5abc3eff
>    other: 10f9a0a634e82080907e62f075ab119cbc565ea6
> +  file extras: file1 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
>    file: file1 (record type "C", state "u", hash 60b27f004e454aca81b0480209cce5081ec52390)
>      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)
>      local path: file2 (flags "")
>      ancestor path: file2 (node 5d9299349fc01ddd25d0070d149b124d8f10411e)
> @@ -735,10 +767,12 @@ Choose local versions of files
>    * version 2 records
>    local: ab57bf49aa276a22d35a473592d4c34b5abc3eff
>    other: 10f9a0a634e82080907e62f075ab119cbc565ea6
> +  file extras: file1 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
>    file: file1 (record type "C", state "r", hash 60b27f004e454aca81b0480209cce5081ec52390)
>      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)
>      local path: file2 (flags "")
>      ancestor path: file2 (node 5d9299349fc01ddd25d0070d149b124d8f10411e)
> @@ -771,10 +805,12 @@ Choose other versions of files
>    * version 2 records
>    local: ab57bf49aa276a22d35a473592d4c34b5abc3eff
>    other: 10f9a0a634e82080907e62f075ab119cbc565ea6
> +  file extras: file1 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
>    file: file1 (record type "C", state "r", hash 60b27f004e454aca81b0480209cce5081ec52390)
>      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)
>      local path: file2 (flags "")
>      ancestor path: file2 (node 5d9299349fc01ddd25d0070d149b124d8f10411e)
> @@ -809,10 +845,12 @@ Fail
>    * version 2 records
>    local: ab57bf49aa276a22d35a473592d4c34b5abc3eff
>    other: 10f9a0a634e82080907e62f075ab119cbc565ea6
> +  file extras: file1 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
>    file: file1 (record type "C", state "u", hash 60b27f004e454aca81b0480209cce5081ec52390)
>      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)
>      local path: file2 (flags "")
>      ancestor path: file2 (node 5d9299349fc01ddd25d0070d149b124d8f10411e)
> @@ -853,10 +891,12 @@ Force prompts with no input
>    * version 2 records
>    local: ab57bf49aa276a22d35a473592d4c34b5abc3eff
>    other: 10f9a0a634e82080907e62f075ab119cbc565ea6
> +  file extras: file1 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
>    file: file1 (record type "C", state "u", hash 60b27f004e454aca81b0480209cce5081ec52390)
>      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)
>      local path: file2 (flags "")
>      ancestor path: file2 (node 5d9299349fc01ddd25d0070d149b124d8f10411e)
> @@ -898,10 +938,12 @@ Choose to merge all files
>    * version 2 records
>    local: ab57bf49aa276a22d35a473592d4c34b5abc3eff
>    other: 10f9a0a634e82080907e62f075ab119cbc565ea6
> +  file extras: file1 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
>    file: file1 (record type "C", state "u", hash 60b27f004e454aca81b0480209cce5081ec52390)
>      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)
>      local path: file2 (flags "")
>      ancestor path: file2 (node 5d9299349fc01ddd25d0070d149b124d8f10411e)
> diff --git a/tests/test-merge-criss-cross.t b/tests/test-merge-criss-cross.t
> --- a/tests/test-merge-criss-cross.t
> +++ b/tests/test-merge-criss-cross.t
> @@ -85,10 +85,10 @@ Criss cross merging
>     f2: versions differ -> m (premerge)
>    picked tool ':dump' for f2 (binary False symlink False changedelete False)
>    merging f2
> -  my f2@3b08d01b0ab5+ other f2@adfe50279922 ancestor f2@40494bf2444c
> +  my f2@3b08d01b0ab5+ other f2@adfe50279922 ancestor f2@0f6b37dbe527
>     f2: versions differ -> m (merge)
>    picked tool ':dump' for f2 (binary False symlink False changedelete False)
> -  my f2@3b08d01b0ab5+ other f2@adfe50279922 ancestor f2@40494bf2444c
> +  my f2@3b08d01b0ab5+ other f2@adfe50279922 ancestor f2@0f6b37dbe527
>    1 files updated, 0 files merged, 0 files removed, 1 files unresolved
>    use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
>    [1]
> 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
> @@ -76,6 +76,7 @@ Insert unsupported advisory merge record
>    local: 3e046f2ecedb793b97ed32108086edd1a162f8bc
>    other: 46f0b057b5c061d276b91491c22151f78698abd2
>    unrecognized entry: x        advisory record
> +  file extras: common (ancestorlinknode = 3163e20567cc93074fbb7a53c8b93312e59dbf2c)
>    file: common (record type "F", state "u", hash 94c8c21d08740f5da9eaa38d1f175c592692f0d1)
>      local path: common (flags "")
>      ancestor path: common (node de0a666fdd9c1a0b0698b90d85064d8bd34f74b6)
> @@ -90,6 +91,7 @@ Insert unsupported mandatory merge recor
>    * version 2 records
>    local: 3e046f2ecedb793b97ed32108086edd1a162f8bc
>    other: 46f0b057b5c061d276b91491c22151f78698abd2
> +  file extras: common (ancestorlinknode = 3163e20567cc93074fbb7a53c8b93312e59dbf2c)
>    file: common (record type "F", state "u", hash 94c8c21d08740f5da9eaa38d1f175c592692f0d1)
>      local path: common (flags "")
>      ancestor path: common (node de0a666fdd9c1a0b0698b90d85064d8bd34f74b6)
> diff --git a/tests/test-resolve.t b/tests/test-resolve.t
> --- a/tests/test-resolve.t
> +++ b/tests/test-resolve.t
> @@ -263,10 +263,12 @@ insert unsupported advisory merge record
>    local: 57653b9f834a4493f7240b0681efcb9ae7cab745
>    other: dc77451844e37f03f5c559e3b8529b2b48d381d1
>    unrecognized entry: x        advisory record
> +  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)
> @@ -282,10 +284,12 @@ insert unsupported mandatory merge recor
>    * version 2 records
>    local: 57653b9f834a4493f7240b0681efcb9ae7cab745
>    other: dc77451844e37f03f5c559e3b8529b2b48d381d1
> +  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)
> _______________________________________________
> Mercurial-devel mailing list
> Mercurial-devel@mercurial-scm.org
> https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Durham Goode - Feb. 5, 2016, 9:58 p.m.
On 2/5/16 1:44 PM, Martin von Zweigbergk wrote:
> My comments from v1 have been addressed, so this now looks good to me
> (I'm assuming the patch bodies haven't changed). Augie, can I ask you
> to queue this since you seem to be set up for queuing patches right
> now? :-)
The only code change was to sort the list before serializing (as Sid 
requested).
Augie Fackler - Feb. 5, 2016, 10:25 p.m.
On Fri, Feb 05, 2016 at 11:03:22AM -0800, Durham Goode wrote:
> # HG changeset patch
> # User Durham Goode <durham@fb.com>
> # Date 1454696534 28800
> #      Fri Feb 05 10:22:14 2016 -0800
> # Node ID d32dc6274ec43680fb8dfa9883d00175cf4b1c40
> # Parent  3f5345de185eaae10a33c8c97afe3d2649b604f6
> merge: add file ancestor linknode to mergestate

Queued per martinvonz

>
> During a merge, each file has a current commitnode+filenode, an other
> commitnode+filenode, and an ancestor commitnode+filenode. The ancestor
> commitnode is not stored though, and we rely on the ability for the filectx() to
> look up the commitnode by using the filenode's linkrev. In alternative backends
> (like remotefilelog), linkrevs may have restriction that prevent arbitrary
> linkrev look up given a filenode.
>
> This patch accounts for that by storing the ancestor commitnode in
> the merge state so that it is available later at resolve time.
>
> This results in some test changes because the ancestor commitnode we're using at
> resolve time changes slightly. Before, we used the linkrev commit, which is the
> earliest commit that introduced that particular filenode (which may not be the
> latest common ancestor of the commits being merged). Now we use the latest
> common ancestor of the merged commits as the commitnode. This is fine though,
> because that commit contains the same filenode as the linkrev'd commit.
>
> diff --git a/mercurial/merge.py b/mercurial/merge.py
> --- a/mercurial/merge.py
> +++ b/mercurial/merge.py
> @@ -405,6 +405,7 @@ class mergestate(object):
>                             fca.path(), hex(fca.filenode()),
>                             fco.path(), hex(fco.filenode()),
>                             fcl.flags()]
> +        self._stateextras[fd] = { 'ancestorlinknode' : hex(fca.node()) }
>          self._dirty = True
>
>      def __contains__(self, dfile):
> @@ -450,10 +451,16 @@ class mergestate(object):
>          stateentry = self._state[dfile]
>          state, hash, lfile, afile, anode, ofile, onode, flags = stateentry
>          octx = self._repo[self._other]
> +        extras = self.extras(dfile)
> +        anccommitnode = extras.get('ancestorlinknode')
> +        if anccommitnode:
> +            actx = self._repo[anccommitnode]
> +        else:
> +            actx = None
>          fcd = self._filectxorabsent(hash, wctx, dfile)
>          fco = self._filectxorabsent(onode, octx, ofile)
>          # TODO: move this to filectxorabsent
> -        fca = self._repo.filectx(afile, fileid=anode)
> +        fca = self._repo.filectx(afile, fileid=anode, changeid=actx)
>          # "premerge" x flags
>          flo = fco.flags()
>          fla = fca.flags()
> diff --git a/tests/test-backout.t b/tests/test-backout.t
> --- a/tests/test-backout.t
> +++ b/tests/test-backout.t
> @@ -686,6 +686,7 @@ Test usage of `hg resolve` in case of co
>    * version 2 records
>    local: b71750c4b0fdf719734971e3ef90dbeab5919a2d
>    other: a30dd8addae3ce71b8667868478542bc417439e6
> +  file extras: foo (ancestorlinknode = 91360952243723bd5b1138d5f26bd8c8564cb553)
>    file: foo (record type "F", state "u", hash 0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33)
>      local path: foo (flags "")
>      ancestor path: foo (node f89532f44c247a0e993d63e3a734dd781ab04708)
> diff --git a/tests/test-graft.t b/tests/test-graft.t
> --- a/tests/test-graft.t
> +++ b/tests/test-graft.t
> @@ -189,10 +189,10 @@ Graft out of order, skipping a merge and
>     e: versions differ -> m (premerge)
>    picked tool ':merge' for e (binary False symlink False changedelete False)
>    merging e
> -  my e@1905859650ec+ other e@9c233e8e184d ancestor e@68795b066622
> +  my e@1905859650ec+ other e@9c233e8e184d ancestor e@4c60f11aa304
>     e: versions differ -> m (merge)
>    picked tool ':merge' for e (binary False symlink False changedelete False)
> -  my e@1905859650ec+ other e@9c233e8e184d ancestor e@68795b066622
> +  my e@1905859650ec+ other e@9c233e8e184d ancestor e@4c60f11aa304
>    warning: conflicts while merging e! (edit, then use 'hg resolve --mark')
>    abort: unresolved conflicts, can't continue
>    (use hg resolve and hg graft --continue --log)
> 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
> @@ -82,6 +82,7 @@ insert unsupported advisory merge record
>    local: 8f7551c7e4a2f2efe0bc8c741baf7f227d65d758
>    other: e860deea161a2f77de56603b340ebbb4536308ae
>    unrecognized entry: x	advisory record
> +  file extras: e (ancestorlinknode = 0000000000000000000000000000000000000000)
>    file: e (record type "F", state "u", hash 58e6b3a414a1e090dfc6029add0f3555ccba127f)
>      local path: e (flags "")
>      ancestor path: e (node null)
> @@ -95,6 +96,7 @@ insert unsupported mandatory merge recor
>    * version 2 records
>    local: 8f7551c7e4a2f2efe0bc8c741baf7f227d65d758
>    other: e860deea161a2f77de56603b340ebbb4536308ae
> +  file extras: e (ancestorlinknode = 0000000000000000000000000000000000000000)
>    file: e (record type "F", state "u", hash 58e6b3a414a1e090dfc6029add0f3555ccba127f)
>      local path: e (flags "")
>      ancestor path: e (node null)
> diff --git a/tests/test-issue672.t b/tests/test-issue672.t
> --- a/tests/test-issue672.t
> +++ b/tests/test-issue672.t
> @@ -68,7 +68,7 @@ https://bz.mercurial-scm.org/672
>     1a: local copied/moved from 1 -> m (premerge)
>    picked tool ':merge' for 1a (binary False symlink False changedelete False)
>    merging 1a and 1 to 1a
> -  my 1a@e327dca35ac8+ other 1@746e9549ea96 ancestor 1@81f4b099af3d
> +  my 1a@e327dca35ac8+ other 1@746e9549ea96 ancestor 1@c64f439569a9
>     premerge successful
>    0 files updated, 1 files merged, 0 files removed, 0 files unresolved
>    (branch merge, don't forget to commit)
> @@ -91,7 +91,7 @@ https://bz.mercurial-scm.org/672
>     1a: remote moved from 1 -> m (premerge)
>    picked tool ':merge' for 1a (binary False symlink False changedelete False)
>    merging 1 and 1a to 1a
> -  my 1a@746e9549ea96+ other 1a@e327dca35ac8 ancestor 1@81f4b099af3d
> +  my 1a@746e9549ea96+ other 1a@e327dca35ac8 ancestor 1@c64f439569a9
>     premerge successful
>    0 files updated, 1 files merged, 0 files removed, 0 files unresolved
>    (branch merge, don't forget to commit)
> 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
> @@ -77,14 +77,17 @@ Non-interactive merge:
>    * version 2 records
>    local: 13910f48cf7bdb2a0ba6e24b4900e4fdd5739dd4
>    other: 10f9a0a634e82080907e62f075ab119cbc565ea6
> +  file extras: file1 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
>    file: file1 (record type "C", state "u", hash 60b27f004e454aca81b0480209cce5081ec52390)
>      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)
>      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)
>      local path: file3 (flags "")
>      ancestor path: file3 (node 2661d26c649684b482d10f91960cc3db683c38b4)
> @@ -136,14 +139,17 @@ Interactive merge:
>    * version 2 records
>    local: 13910f48cf7bdb2a0ba6e24b4900e4fdd5739dd4
>    other: 10f9a0a634e82080907e62f075ab119cbc565ea6
> +  file extras: file1 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
>    file: file1 (record type "C", state "r", hash 60b27f004e454aca81b0480209cce5081ec52390)
>      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)
>      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)
>      local path: file3 (flags "")
>      ancestor path: file3 (node 2661d26c649684b482d10f91960cc3db683c38b4)
> @@ -205,14 +211,17 @@ Interactive merge with bad input:
>    * version 2 records
>    local: 13910f48cf7bdb2a0ba6e24b4900e4fdd5739dd4
>    other: 10f9a0a634e82080907e62f075ab119cbc565ea6
> +  file extras: file1 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
>    file: file1 (record type "C", state "r", hash 60b27f004e454aca81b0480209cce5081ec52390)
>      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)
>      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)
>      local path: file3 (flags "")
>      ancestor path: file3 (node 2661d26c649684b482d10f91960cc3db683c38b4)
> @@ -261,14 +270,17 @@ Interactive merge with not enough input:
>    * version 2 records
>    local: 13910f48cf7bdb2a0ba6e24b4900e4fdd5739dd4
>    other: 10f9a0a634e82080907e62f075ab119cbc565ea6
> +  file extras: file1 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
>    file: file1 (record type "C", state "r", hash 60b27f004e454aca81b0480209cce5081ec52390)
>      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)
>      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)
>      local path: file3 (flags "")
>      ancestor path: file3 (node 2661d26c649684b482d10f91960cc3db683c38b4)
> @@ -306,14 +318,17 @@ Choose local versions of files
>    * version 2 records
>    local: 13910f48cf7bdb2a0ba6e24b4900e4fdd5739dd4
>    other: 10f9a0a634e82080907e62f075ab119cbc565ea6
> +  file extras: file1 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
>    file: file1 (record type "C", state "r", hash 60b27f004e454aca81b0480209cce5081ec52390)
>      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)
>      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)
>      local path: file3 (flags "")
>      ancestor path: file3 (node 2661d26c649684b482d10f91960cc3db683c38b4)
> @@ -347,14 +362,17 @@ Choose other versions of files
>    * version 2 records
>    local: 13910f48cf7bdb2a0ba6e24b4900e4fdd5739dd4
>    other: 10f9a0a634e82080907e62f075ab119cbc565ea6
> +  file extras: file1 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
>    file: file1 (record type "C", state "r", hash 60b27f004e454aca81b0480209cce5081ec52390)
>      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)
>      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)
>      local path: file3 (flags "")
>      ancestor path: file3 (node 2661d26c649684b482d10f91960cc3db683c38b4)
> @@ -389,14 +407,17 @@ Fail
>    * version 2 records
>    local: 13910f48cf7bdb2a0ba6e24b4900e4fdd5739dd4
>    other: 10f9a0a634e82080907e62f075ab119cbc565ea6
> +  file extras: file1 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
>    file: file1 (record type "C", state "u", hash 60b27f004e454aca81b0480209cce5081ec52390)
>      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)
>      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)
>      local path: file3 (flags "")
>      ancestor path: file3 (node 2661d26c649684b482d10f91960cc3db683c38b4)
> @@ -439,14 +460,17 @@ Force prompts with no input (should be s
>    * version 2 records
>    local: 13910f48cf7bdb2a0ba6e24b4900e4fdd5739dd4
>    other: 10f9a0a634e82080907e62f075ab119cbc565ea6
> +  file extras: file1 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
>    file: file1 (record type "C", state "u", hash 60b27f004e454aca81b0480209cce5081ec52390)
>      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)
>      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)
>      local path: file3 (flags "")
>      ancestor path: file3 (node 2661d26c649684b482d10f91960cc3db683c38b4)
> @@ -491,14 +515,17 @@ Force prompts
>    * version 2 records
>    local: 13910f48cf7bdb2a0ba6e24b4900e4fdd5739dd4
>    other: 10f9a0a634e82080907e62f075ab119cbc565ea6
> +  file extras: file1 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
>    file: file1 (record type "C", state "u", hash 60b27f004e454aca81b0480209cce5081ec52390)
>      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)
>      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)
>      local path: file3 (flags "")
>      ancestor path: file3 (node 2661d26c649684b482d10f91960cc3db683c38b4)
> @@ -541,14 +568,17 @@ Choose to merge all files
>    * version 2 records
>    local: 13910f48cf7bdb2a0ba6e24b4900e4fdd5739dd4
>    other: 10f9a0a634e82080907e62f075ab119cbc565ea6
> +  file extras: file1 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
>    file: file1 (record type "C", state "u", hash 60b27f004e454aca81b0480209cce5081ec52390)
>      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)
>      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)
>      local path: file3 (flags "")
>      ancestor path: file3 (node 2661d26c649684b482d10f91960cc3db683c38b4)
> @@ -697,10 +727,12 @@ Non-interactive linear update
>    * version 2 records
>    local: ab57bf49aa276a22d35a473592d4c34b5abc3eff
>    other: 10f9a0a634e82080907e62f075ab119cbc565ea6
> +  file extras: file1 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
>    file: file1 (record type "C", state "u", hash 60b27f004e454aca81b0480209cce5081ec52390)
>      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)
>      local path: file2 (flags "")
>      ancestor path: file2 (node 5d9299349fc01ddd25d0070d149b124d8f10411e)
> @@ -735,10 +767,12 @@ Choose local versions of files
>    * version 2 records
>    local: ab57bf49aa276a22d35a473592d4c34b5abc3eff
>    other: 10f9a0a634e82080907e62f075ab119cbc565ea6
> +  file extras: file1 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
>    file: file1 (record type "C", state "r", hash 60b27f004e454aca81b0480209cce5081ec52390)
>      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)
>      local path: file2 (flags "")
>      ancestor path: file2 (node 5d9299349fc01ddd25d0070d149b124d8f10411e)
> @@ -771,10 +805,12 @@ Choose other versions of files
>    * version 2 records
>    local: ab57bf49aa276a22d35a473592d4c34b5abc3eff
>    other: 10f9a0a634e82080907e62f075ab119cbc565ea6
> +  file extras: file1 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
>    file: file1 (record type "C", state "r", hash 60b27f004e454aca81b0480209cce5081ec52390)
>      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)
>      local path: file2 (flags "")
>      ancestor path: file2 (node 5d9299349fc01ddd25d0070d149b124d8f10411e)
> @@ -809,10 +845,12 @@ Fail
>    * version 2 records
>    local: ab57bf49aa276a22d35a473592d4c34b5abc3eff
>    other: 10f9a0a634e82080907e62f075ab119cbc565ea6
> +  file extras: file1 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
>    file: file1 (record type "C", state "u", hash 60b27f004e454aca81b0480209cce5081ec52390)
>      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)
>      local path: file2 (flags "")
>      ancestor path: file2 (node 5d9299349fc01ddd25d0070d149b124d8f10411e)
> @@ -853,10 +891,12 @@ Force prompts with no input
>    * version 2 records
>    local: ab57bf49aa276a22d35a473592d4c34b5abc3eff
>    other: 10f9a0a634e82080907e62f075ab119cbc565ea6
> +  file extras: file1 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
>    file: file1 (record type "C", state "u", hash 60b27f004e454aca81b0480209cce5081ec52390)
>      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)
>      local path: file2 (flags "")
>      ancestor path: file2 (node 5d9299349fc01ddd25d0070d149b124d8f10411e)
> @@ -898,10 +938,12 @@ Choose to merge all files
>    * version 2 records
>    local: ab57bf49aa276a22d35a473592d4c34b5abc3eff
>    other: 10f9a0a634e82080907e62f075ab119cbc565ea6
> +  file extras: file1 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
>    file: file1 (record type "C", state "u", hash 60b27f004e454aca81b0480209cce5081ec52390)
>      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)
>      local path: file2 (flags "")
>      ancestor path: file2 (node 5d9299349fc01ddd25d0070d149b124d8f10411e)
> diff --git a/tests/test-merge-criss-cross.t b/tests/test-merge-criss-cross.t
> --- a/tests/test-merge-criss-cross.t
> +++ b/tests/test-merge-criss-cross.t
> @@ -85,10 +85,10 @@ Criss cross merging
>     f2: versions differ -> m (premerge)
>    picked tool ':dump' for f2 (binary False symlink False changedelete False)
>    merging f2
> -  my f2@3b08d01b0ab5+ other f2@adfe50279922 ancestor f2@40494bf2444c
> +  my f2@3b08d01b0ab5+ other f2@adfe50279922 ancestor f2@0f6b37dbe527
>     f2: versions differ -> m (merge)
>    picked tool ':dump' for f2 (binary False symlink False changedelete False)
> -  my f2@3b08d01b0ab5+ other f2@adfe50279922 ancestor f2@40494bf2444c
> +  my f2@3b08d01b0ab5+ other f2@adfe50279922 ancestor f2@0f6b37dbe527
>    1 files updated, 0 files merged, 0 files removed, 1 files unresolved
>    use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
>    [1]
> 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
> @@ -76,6 +76,7 @@ Insert unsupported advisory merge record
>    local: 3e046f2ecedb793b97ed32108086edd1a162f8bc
>    other: 46f0b057b5c061d276b91491c22151f78698abd2
>    unrecognized entry: x	advisory record
> +  file extras: common (ancestorlinknode = 3163e20567cc93074fbb7a53c8b93312e59dbf2c)
>    file: common (record type "F", state "u", hash 94c8c21d08740f5da9eaa38d1f175c592692f0d1)
>      local path: common (flags "")
>      ancestor path: common (node de0a666fdd9c1a0b0698b90d85064d8bd34f74b6)
> @@ -90,6 +91,7 @@ Insert unsupported mandatory merge recor
>    * version 2 records
>    local: 3e046f2ecedb793b97ed32108086edd1a162f8bc
>    other: 46f0b057b5c061d276b91491c22151f78698abd2
> +  file extras: common (ancestorlinknode = 3163e20567cc93074fbb7a53c8b93312e59dbf2c)
>    file: common (record type "F", state "u", hash 94c8c21d08740f5da9eaa38d1f175c592692f0d1)
>      local path: common (flags "")
>      ancestor path: common (node de0a666fdd9c1a0b0698b90d85064d8bd34f74b6)
> diff --git a/tests/test-resolve.t b/tests/test-resolve.t
> --- a/tests/test-resolve.t
> +++ b/tests/test-resolve.t
> @@ -263,10 +263,12 @@ insert unsupported advisory merge record
>    local: 57653b9f834a4493f7240b0681efcb9ae7cab745
>    other: dc77451844e37f03f5c559e3b8529b2b48d381d1
>    unrecognized entry: x	advisory record
> +  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)
> @@ -282,10 +284,12 @@ insert unsupported mandatory merge recor
>    * version 2 records
>    local: 57653b9f834a4493f7240b0681efcb9ae7cab745
>    other: dc77451844e37f03f5c559e3b8529b2b48d381d1
> +  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)
> _______________________________________________
> Mercurial-devel mailing list
> Mercurial-devel@mercurial-scm.org
> https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel

Patch

diff --git a/mercurial/merge.py b/mercurial/merge.py
--- a/mercurial/merge.py
+++ b/mercurial/merge.py
@@ -405,6 +405,7 @@  class mergestate(object):
                            fca.path(), hex(fca.filenode()),
                            fco.path(), hex(fco.filenode()),
                            fcl.flags()]
+        self._stateextras[fd] = { 'ancestorlinknode' : hex(fca.node()) }
         self._dirty = True
 
     def __contains__(self, dfile):
@@ -450,10 +451,16 @@  class mergestate(object):
         stateentry = self._state[dfile]
         state, hash, lfile, afile, anode, ofile, onode, flags = stateentry
         octx = self._repo[self._other]
+        extras = self.extras(dfile)
+        anccommitnode = extras.get('ancestorlinknode')
+        if anccommitnode:
+            actx = self._repo[anccommitnode]
+        else:
+            actx = None
         fcd = self._filectxorabsent(hash, wctx, dfile)
         fco = self._filectxorabsent(onode, octx, ofile)
         # TODO: move this to filectxorabsent
-        fca = self._repo.filectx(afile, fileid=anode)
+        fca = self._repo.filectx(afile, fileid=anode, changeid=actx)
         # "premerge" x flags
         flo = fco.flags()
         fla = fca.flags()
diff --git a/tests/test-backout.t b/tests/test-backout.t
--- a/tests/test-backout.t
+++ b/tests/test-backout.t
@@ -686,6 +686,7 @@  Test usage of `hg resolve` in case of co
   * version 2 records
   local: b71750c4b0fdf719734971e3ef90dbeab5919a2d
   other: a30dd8addae3ce71b8667868478542bc417439e6
+  file extras: foo (ancestorlinknode = 91360952243723bd5b1138d5f26bd8c8564cb553)
   file: foo (record type "F", state "u", hash 0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33)
     local path: foo (flags "")
     ancestor path: foo (node f89532f44c247a0e993d63e3a734dd781ab04708)
diff --git a/tests/test-graft.t b/tests/test-graft.t
--- a/tests/test-graft.t
+++ b/tests/test-graft.t
@@ -189,10 +189,10 @@  Graft out of order, skipping a merge and
    e: versions differ -> m (premerge)
   picked tool ':merge' for e (binary False symlink False changedelete False)
   merging e
-  my e@1905859650ec+ other e@9c233e8e184d ancestor e@68795b066622
+  my e@1905859650ec+ other e@9c233e8e184d ancestor e@4c60f11aa304
    e: versions differ -> m (merge)
   picked tool ':merge' for e (binary False symlink False changedelete False)
-  my e@1905859650ec+ other e@9c233e8e184d ancestor e@68795b066622
+  my e@1905859650ec+ other e@9c233e8e184d ancestor e@4c60f11aa304
   warning: conflicts while merging e! (edit, then use 'hg resolve --mark')
   abort: unresolved conflicts, can't continue
   (use hg resolve and hg graft --continue --log)
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
@@ -82,6 +82,7 @@  insert unsupported advisory merge record
   local: 8f7551c7e4a2f2efe0bc8c741baf7f227d65d758
   other: e860deea161a2f77de56603b340ebbb4536308ae
   unrecognized entry: x	advisory record
+  file extras: e (ancestorlinknode = 0000000000000000000000000000000000000000)
   file: e (record type "F", state "u", hash 58e6b3a414a1e090dfc6029add0f3555ccba127f)
     local path: e (flags "")
     ancestor path: e (node null)
@@ -95,6 +96,7 @@  insert unsupported mandatory merge recor
   * version 2 records
   local: 8f7551c7e4a2f2efe0bc8c741baf7f227d65d758
   other: e860deea161a2f77de56603b340ebbb4536308ae
+  file extras: e (ancestorlinknode = 0000000000000000000000000000000000000000)
   file: e (record type "F", state "u", hash 58e6b3a414a1e090dfc6029add0f3555ccba127f)
     local path: e (flags "")
     ancestor path: e (node null)
diff --git a/tests/test-issue672.t b/tests/test-issue672.t
--- a/tests/test-issue672.t
+++ b/tests/test-issue672.t
@@ -68,7 +68,7 @@  https://bz.mercurial-scm.org/672
    1a: local copied/moved from 1 -> m (premerge)
   picked tool ':merge' for 1a (binary False symlink False changedelete False)
   merging 1a and 1 to 1a
-  my 1a@e327dca35ac8+ other 1@746e9549ea96 ancestor 1@81f4b099af3d
+  my 1a@e327dca35ac8+ other 1@746e9549ea96 ancestor 1@c64f439569a9
    premerge successful
   0 files updated, 1 files merged, 0 files removed, 0 files unresolved
   (branch merge, don't forget to commit)
@@ -91,7 +91,7 @@  https://bz.mercurial-scm.org/672
    1a: remote moved from 1 -> m (premerge)
   picked tool ':merge' for 1a (binary False symlink False changedelete False)
   merging 1 and 1a to 1a
-  my 1a@746e9549ea96+ other 1a@e327dca35ac8 ancestor 1@81f4b099af3d
+  my 1a@746e9549ea96+ other 1a@e327dca35ac8 ancestor 1@c64f439569a9
    premerge successful
   0 files updated, 1 files merged, 0 files removed, 0 files unresolved
   (branch merge, don't forget to commit)
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
@@ -77,14 +77,17 @@  Non-interactive merge:
   * version 2 records
   local: 13910f48cf7bdb2a0ba6e24b4900e4fdd5739dd4
   other: 10f9a0a634e82080907e62f075ab119cbc565ea6
+  file extras: file1 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
   file: file1 (record type "C", state "u", hash 60b27f004e454aca81b0480209cce5081ec52390)
     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)
     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)
     local path: file3 (flags "")
     ancestor path: file3 (node 2661d26c649684b482d10f91960cc3db683c38b4)
@@ -136,14 +139,17 @@  Interactive merge:
   * version 2 records
   local: 13910f48cf7bdb2a0ba6e24b4900e4fdd5739dd4
   other: 10f9a0a634e82080907e62f075ab119cbc565ea6
+  file extras: file1 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
   file: file1 (record type "C", state "r", hash 60b27f004e454aca81b0480209cce5081ec52390)
     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)
     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)
     local path: file3 (flags "")
     ancestor path: file3 (node 2661d26c649684b482d10f91960cc3db683c38b4)
@@ -205,14 +211,17 @@  Interactive merge with bad input:
   * version 2 records
   local: 13910f48cf7bdb2a0ba6e24b4900e4fdd5739dd4
   other: 10f9a0a634e82080907e62f075ab119cbc565ea6
+  file extras: file1 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
   file: file1 (record type "C", state "r", hash 60b27f004e454aca81b0480209cce5081ec52390)
     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)
     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)
     local path: file3 (flags "")
     ancestor path: file3 (node 2661d26c649684b482d10f91960cc3db683c38b4)
@@ -261,14 +270,17 @@  Interactive merge with not enough input:
   * version 2 records
   local: 13910f48cf7bdb2a0ba6e24b4900e4fdd5739dd4
   other: 10f9a0a634e82080907e62f075ab119cbc565ea6
+  file extras: file1 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
   file: file1 (record type "C", state "r", hash 60b27f004e454aca81b0480209cce5081ec52390)
     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)
     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)
     local path: file3 (flags "")
     ancestor path: file3 (node 2661d26c649684b482d10f91960cc3db683c38b4)
@@ -306,14 +318,17 @@  Choose local versions of files
   * version 2 records
   local: 13910f48cf7bdb2a0ba6e24b4900e4fdd5739dd4
   other: 10f9a0a634e82080907e62f075ab119cbc565ea6
+  file extras: file1 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
   file: file1 (record type "C", state "r", hash 60b27f004e454aca81b0480209cce5081ec52390)
     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)
     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)
     local path: file3 (flags "")
     ancestor path: file3 (node 2661d26c649684b482d10f91960cc3db683c38b4)
@@ -347,14 +362,17 @@  Choose other versions of files
   * version 2 records
   local: 13910f48cf7bdb2a0ba6e24b4900e4fdd5739dd4
   other: 10f9a0a634e82080907e62f075ab119cbc565ea6
+  file extras: file1 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
   file: file1 (record type "C", state "r", hash 60b27f004e454aca81b0480209cce5081ec52390)
     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)
     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)
     local path: file3 (flags "")
     ancestor path: file3 (node 2661d26c649684b482d10f91960cc3db683c38b4)
@@ -389,14 +407,17 @@  Fail
   * version 2 records
   local: 13910f48cf7bdb2a0ba6e24b4900e4fdd5739dd4
   other: 10f9a0a634e82080907e62f075ab119cbc565ea6
+  file extras: file1 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
   file: file1 (record type "C", state "u", hash 60b27f004e454aca81b0480209cce5081ec52390)
     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)
     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)
     local path: file3 (flags "")
     ancestor path: file3 (node 2661d26c649684b482d10f91960cc3db683c38b4)
@@ -439,14 +460,17 @@  Force prompts with no input (should be s
   * version 2 records
   local: 13910f48cf7bdb2a0ba6e24b4900e4fdd5739dd4
   other: 10f9a0a634e82080907e62f075ab119cbc565ea6
+  file extras: file1 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
   file: file1 (record type "C", state "u", hash 60b27f004e454aca81b0480209cce5081ec52390)
     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)
     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)
     local path: file3 (flags "")
     ancestor path: file3 (node 2661d26c649684b482d10f91960cc3db683c38b4)
@@ -491,14 +515,17 @@  Force prompts
   * version 2 records
   local: 13910f48cf7bdb2a0ba6e24b4900e4fdd5739dd4
   other: 10f9a0a634e82080907e62f075ab119cbc565ea6
+  file extras: file1 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
   file: file1 (record type "C", state "u", hash 60b27f004e454aca81b0480209cce5081ec52390)
     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)
     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)
     local path: file3 (flags "")
     ancestor path: file3 (node 2661d26c649684b482d10f91960cc3db683c38b4)
@@ -541,14 +568,17 @@  Choose to merge all files
   * version 2 records
   local: 13910f48cf7bdb2a0ba6e24b4900e4fdd5739dd4
   other: 10f9a0a634e82080907e62f075ab119cbc565ea6
+  file extras: file1 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
   file: file1 (record type "C", state "u", hash 60b27f004e454aca81b0480209cce5081ec52390)
     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)
     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)
     local path: file3 (flags "")
     ancestor path: file3 (node 2661d26c649684b482d10f91960cc3db683c38b4)
@@ -697,10 +727,12 @@  Non-interactive linear update
   * version 2 records
   local: ab57bf49aa276a22d35a473592d4c34b5abc3eff
   other: 10f9a0a634e82080907e62f075ab119cbc565ea6
+  file extras: file1 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
   file: file1 (record type "C", state "u", hash 60b27f004e454aca81b0480209cce5081ec52390)
     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)
     local path: file2 (flags "")
     ancestor path: file2 (node 5d9299349fc01ddd25d0070d149b124d8f10411e)
@@ -735,10 +767,12 @@  Choose local versions of files
   * version 2 records
   local: ab57bf49aa276a22d35a473592d4c34b5abc3eff
   other: 10f9a0a634e82080907e62f075ab119cbc565ea6
+  file extras: file1 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
   file: file1 (record type "C", state "r", hash 60b27f004e454aca81b0480209cce5081ec52390)
     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)
     local path: file2 (flags "")
     ancestor path: file2 (node 5d9299349fc01ddd25d0070d149b124d8f10411e)
@@ -771,10 +805,12 @@  Choose other versions of files
   * version 2 records
   local: ab57bf49aa276a22d35a473592d4c34b5abc3eff
   other: 10f9a0a634e82080907e62f075ab119cbc565ea6
+  file extras: file1 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
   file: file1 (record type "C", state "r", hash 60b27f004e454aca81b0480209cce5081ec52390)
     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)
     local path: file2 (flags "")
     ancestor path: file2 (node 5d9299349fc01ddd25d0070d149b124d8f10411e)
@@ -809,10 +845,12 @@  Fail
   * version 2 records
   local: ab57bf49aa276a22d35a473592d4c34b5abc3eff
   other: 10f9a0a634e82080907e62f075ab119cbc565ea6
+  file extras: file1 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
   file: file1 (record type "C", state "u", hash 60b27f004e454aca81b0480209cce5081ec52390)
     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)
     local path: file2 (flags "")
     ancestor path: file2 (node 5d9299349fc01ddd25d0070d149b124d8f10411e)
@@ -853,10 +891,12 @@  Force prompts with no input
   * version 2 records
   local: ab57bf49aa276a22d35a473592d4c34b5abc3eff
   other: 10f9a0a634e82080907e62f075ab119cbc565ea6
+  file extras: file1 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
   file: file1 (record type "C", state "u", hash 60b27f004e454aca81b0480209cce5081ec52390)
     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)
     local path: file2 (flags "")
     ancestor path: file2 (node 5d9299349fc01ddd25d0070d149b124d8f10411e)
@@ -898,10 +938,12 @@  Choose to merge all files
   * version 2 records
   local: ab57bf49aa276a22d35a473592d4c34b5abc3eff
   other: 10f9a0a634e82080907e62f075ab119cbc565ea6
+  file extras: file1 (ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff)
   file: file1 (record type "C", state "u", hash 60b27f004e454aca81b0480209cce5081ec52390)
     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)
     local path: file2 (flags "")
     ancestor path: file2 (node 5d9299349fc01ddd25d0070d149b124d8f10411e)
diff --git a/tests/test-merge-criss-cross.t b/tests/test-merge-criss-cross.t
--- a/tests/test-merge-criss-cross.t
+++ b/tests/test-merge-criss-cross.t
@@ -85,10 +85,10 @@  Criss cross merging
    f2: versions differ -> m (premerge)
   picked tool ':dump' for f2 (binary False symlink False changedelete False)
   merging f2
-  my f2@3b08d01b0ab5+ other f2@adfe50279922 ancestor f2@40494bf2444c
+  my f2@3b08d01b0ab5+ other f2@adfe50279922 ancestor f2@0f6b37dbe527
    f2: versions differ -> m (merge)
   picked tool ':dump' for f2 (binary False symlink False changedelete False)
-  my f2@3b08d01b0ab5+ other f2@adfe50279922 ancestor f2@40494bf2444c
+  my f2@3b08d01b0ab5+ other f2@adfe50279922 ancestor f2@0f6b37dbe527
   1 files updated, 0 files merged, 0 files removed, 1 files unresolved
   use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
   [1]
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
@@ -76,6 +76,7 @@  Insert unsupported advisory merge record
   local: 3e046f2ecedb793b97ed32108086edd1a162f8bc
   other: 46f0b057b5c061d276b91491c22151f78698abd2
   unrecognized entry: x	advisory record
+  file extras: common (ancestorlinknode = 3163e20567cc93074fbb7a53c8b93312e59dbf2c)
   file: common (record type "F", state "u", hash 94c8c21d08740f5da9eaa38d1f175c592692f0d1)
     local path: common (flags "")
     ancestor path: common (node de0a666fdd9c1a0b0698b90d85064d8bd34f74b6)
@@ -90,6 +91,7 @@  Insert unsupported mandatory merge recor
   * version 2 records
   local: 3e046f2ecedb793b97ed32108086edd1a162f8bc
   other: 46f0b057b5c061d276b91491c22151f78698abd2
+  file extras: common (ancestorlinknode = 3163e20567cc93074fbb7a53c8b93312e59dbf2c)
   file: common (record type "F", state "u", hash 94c8c21d08740f5da9eaa38d1f175c592692f0d1)
     local path: common (flags "")
     ancestor path: common (node de0a666fdd9c1a0b0698b90d85064d8bd34f74b6)
diff --git a/tests/test-resolve.t b/tests/test-resolve.t
--- a/tests/test-resolve.t
+++ b/tests/test-resolve.t
@@ -263,10 +263,12 @@  insert unsupported advisory merge record
   local: 57653b9f834a4493f7240b0681efcb9ae7cab745
   other: dc77451844e37f03f5c559e3b8529b2b48d381d1
   unrecognized entry: x	advisory record
+  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)
@@ -282,10 +284,12 @@  insert unsupported mandatory merge recor
   * version 2 records
   local: 57653b9f834a4493f7240b0681efcb9ae7cab745
   other: dc77451844e37f03f5c559e3b8529b2b48d381d1
+  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)