[PATCH 1 of 2 v2] merge: save merge part labels for later reuse

Pierre-Yves David pierre-yves.david at ens-lyon.org
Sun Mar 27 15:15:54 EDT 2016



On 03/20/2016 05:25 PM, Simon Farnsworth wrote:
> # HG changeset patch
> # User Simon Farnsworth <simonfar at fb.com>
> # Date 1458437830 25200
> #      Sat Mar 19 18:37:10 2016 -0700
> # Node ID 34b91a70655da93c78c82b8fa80fe4fdc4a7d4d9
> # Parent  dfd5a6830ea7cd56909b6667c78ae122cc3a5aa1
> merge: save merge part labels for later reuse
>
> We permit the caller of merge operations to supply labels for the merge
> parts ("local", "other", and optionally "base"). These labels are used in
> conflict markers to reduce confusion; however, the labels were not
> persistent, so 'hg resolve' would lose the labels.
>
> Store the labels in the mergestate.

I've pushed patch 1. Thanks

See feedback on patch 2

>
> diff --git a/mercurial/commands.py b/mercurial/commands.py
> --- a/mercurial/commands.py
> +++ b/mercurial/commands.py
> @@ -2896,6 +2896,14 @@
>
>                   ui.write(('file extras: %s (%s)\n')
>                            % (filename, ', '.join(extrastrings)))
> +            elif rtype == 'l':
> +                labels = record.split('\0', 2)
> +                labels = [l for l in labels if len(l) > 0]
> +                ui.write(('labels:\n'))
> +                ui.write(('  local: %s\n' % labels[0]))
> +                ui.write(('  other: %s\n' % labels[1]))
> +                if len(labels) > 2:
> +                    ui.write(('  base:  %s\n' % labels[2]))
>               else:
>                   ui.write(('unrecognized entry: %s\t%s\n')
>                            % (rtype, record.replace('\0', '\t')))
> @@ -2908,7 +2916,7 @@
>       # sort so that reasonable information is on top
>       v1records = ms._readrecordsv1()
>       v2records = ms._readrecordsv2()
> -    order = 'LOm'
> +    order = 'LOml'
>       def key(r):
>           idx = order.find(r[0])
>           if idx == -1:
> diff --git a/mercurial/merge.py b/mercurial/merge.py
> --- a/mercurial/merge.py
> +++ b/mercurial/merge.py
> @@ -68,6 +68,7 @@
>       f: a (filename, dictonary) tuple of optional values for a given file
>       X: unsupported mandatory record type (used in tests)
>       x: unsupported advisory record type (used in tests)
> +    l: the labels for the parts of the merge.
>
>       Merge driver run states (experimental):
>       u: driver-resolved files unmarked -- needs to be run next time we're about
> @@ -80,11 +81,11 @@
>       statepathv2 = 'merge/state2'
>
>       @staticmethod
> -    def clean(repo, node=None, other=None):
> +    def clean(repo, node=None, other=None, labels=None):
>           """Initialize a brand new merge state, removing any existing state on
>           disk."""
>           ms = mergestate(repo)
> -        ms.reset(node, other)
> +        ms.reset(node, other, labels)
>           return ms
>
>       @staticmethod
> @@ -100,12 +101,14 @@
>           Do not use this directly! Instead call read() or clean()."""
>           self._repo = repo
>           self._dirty = False
> +        self._labels = None
>
> -    def reset(self, node=None, other=None):
> +    def reset(self, node=None, other=None, labels=None):
>           self._state = {}
>           self._stateextras = {}
>           self._local = None
>           self._other = None
> +        self._labels = labels
>           for var in ('localctx', 'otherctx'):
>               if var in vars(self):
>                   delattr(self, var)
> @@ -165,6 +168,9 @@
>                       i += 2
>
>                   self._stateextras[filename] = extras
> +            elif rtype == 'l':
> +                labels = record.split('\0', 2)
> +                self._labels = [l for l in labels if len(l) > 0]
>               elif not rtype.islower():
>                   unsupported.add(rtype)
>           self._results = {}
> @@ -353,6 +359,9 @@
>               rawextras = '\0'.join('%s\0%s' % (k, v) for k, v in
>                                     extras.iteritems())
>               records.append(('f', '%s\0%s' % (filename, rawextras)))
> +        if self._labels is not None:
> +            labels = '\0'.join(self._labels)
> +            records.append(('l', labels))
>           return records
>
>       def _writerecords(self, records):
> @@ -444,7 +453,7 @@
>       def extras(self, filename):
>           return self._stateextras.setdefault(filename, {})
>
> -    def _resolve(self, preresolve, dfile, wctx, labels=None):
> +    def _resolve(self, preresolve, dfile, wctx):
>           """rerun merge process for file path `dfile`"""
>           if self[dfile] in 'rd':
>               return True, 0
> @@ -481,11 +490,11 @@
>                   self._repo.wvfs.unlinkpath(dfile, ignoremissing=True)
>               complete, r, deleted = filemerge.premerge(self._repo, self._local,
>                                                         lfile, fcd, fco, fca,
> -                                                      labels=labels)
> +                                                      labels=self._labels)
>           else:
>               complete, r, deleted = filemerge.filemerge(self._repo, self._local,
>                                                          lfile, fcd, fco, fca,
> -                                                       labels=labels)
> +                                                       labels=self._labels)
>           if r is None:
>               # no real conflict
>               del self._state[dfile]
> @@ -523,17 +532,17 @@
>           else:
>               return ctx[f]
>
> -    def preresolve(self, dfile, wctx, labels=None):
> +    def preresolve(self, dfile, wctx):
>           """run premerge process for dfile
>
>           Returns whether the merge is complete, and the exit code."""
> -        return self._resolve(True, dfile, wctx, labels=labels)
> +        return self._resolve(True, dfile, wctx)
>
> -    def resolve(self, dfile, wctx, labels=None):
> +    def resolve(self, dfile, wctx):
>           """run merge process (assuming premerge was run) for dfile
>
>           Returns the exit code of the merge."""
> -        return self._resolve(False, dfile, wctx, labels=labels)[1]
> +        return self._resolve(False, dfile, wctx)[1]
>
>       def counts(self):
>           """return counts for updated, merged and removed files in this
> @@ -1094,7 +1103,7 @@
>       """
>
>       updated, merged, removed = 0, 0, 0
> -    ms = mergestate.clean(repo, wctx.p1().node(), mctx.node())
> +    ms = mergestate.clean(repo, wctx.p1().node(), mctx.node(), labels)
>       moves = []
>       for m, l in actions.items():
>           l.sort()
> @@ -1247,7 +1256,7 @@
>                                overwrite)
>               continue
>           audit(f)
> -        complete, r = ms.preresolve(f, wctx, labels=labels)
> +        complete, r = ms.preresolve(f, wctx)
>           if not complete:
>               numupdates += 1
>               tocomplete.append((f, args, msg))
> @@ -1257,7 +1266,7 @@
>           repo.ui.debug(" %s: %s -> m (merge)\n" % (f, msg))
>           z += 1
>           progress(_updating, z, item=f, total=numupdates, unit=_files)
> -        ms.resolve(f, wctx, labels=labels)
> +        ms.resolve(f, wctx)
>
>       ms.commit()
>
> diff --git a/tests/test-graft.t b/tests/test-graft.t
> --- a/tests/test-graft.t
> +++ b/tests/test-graft.t
> @@ -452,7 +452,7 @@
>     c
>     =======
>     b
> -  >>>>>>> other: 5d205f8b35b6  - bar: 1
> +  >>>>>>> graft: 5d205f8b35b6  - bar: 1
>     $ echo b > a
>     $ hg resolve -m a
>     (no more unresolved files)
> 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
> @@ -80,6 +80,9 @@
>     * 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)
> @@ -95,6 +98,9 @@
>     * 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 "")
> 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
> @@ -736,6 +736,9 @@
>     * 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 path: file1 (flags "")
> @@ -776,6 +779,9 @@
>     * 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 path: file1 (flags "")
> @@ -814,6 +820,9 @@
>     * 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 path: file1 (flags "")
> @@ -854,6 +863,9 @@
>     * 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 path: file1 (flags "")
> @@ -900,6 +912,9 @@
>     * 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 path: file1 (flags "")
> @@ -947,6 +962,9 @@
>     * 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 path: file1 (flags "")
> 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
> @@ -75,6 +75,9 @@
>     * 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)
> @@ -91,6 +94,9 @@
>     * 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 "")
> _______________________________________________
> Mercurial-devel mailing list
> Mercurial-devel at mercurial-scm.org
> https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
>

-- 
Pierre-Yves David


More information about the Mercurial-devel mailing list