changeset 48281:96aa3a68d3b5

branching: merge stable into default
author Raphaël Gomès <rgomes@octobus.net>
date Thu, 21 Oct 2021 17:25:41 +0200
parents d86908050375 (current diff) f3e218ae3fd9 (diff)
children fd3d4b7f8e62
files mercurial/merge.py mercurial/revlogutils/rewrite.py rust/hgcli/pyoxidizer.bzl tests/run-tests.py tests/test-chg.t tests/test-persistent-nodemap.t
diffstat 10 files changed, 97 insertions(+), 83 deletions(-) [+]
line wrap: on
line diff
--- a/contrib/heptapod-ci.yml	Thu Oct 21 11:21:21 2021 +0200
+++ b/contrib/heptapod-ci.yml	Thu Oct 21 17:25:41 2021 +0200
@@ -141,7 +141,7 @@
       - $PYTHON -m pip install --user -U pytype==2021.04.15
     variables:
         RUNTEST_ARGS: " --allow-slow-tests tests/test-check-pytype.t"
-        HGTEST_TIMEOUT: "3600"
+        HGTEST_SLOWTIMEOUT: "3600"
         PYTHON: python3
         TEST_HGMODULEPOLICY: "c"
 
--- a/mercurial/merge.py	Thu Oct 21 11:21:21 2021 +0200
+++ b/mercurial/merge.py	Thu Oct 21 17:25:41 2021 +0200
@@ -1714,6 +1714,10 @@
             progress.increment(item=f, total=numupdates)
             ms.resolve(f, wctx)
 
+    except error.InterventionRequired:
+        # If the user has merge.on-failure=halt, catch the error and close the
+        # merge state "properly".
+        pass
     finally:
         ms.commit()
 
--- a/mercurial/revlogutils/rewrite.py	Thu Oct 21 11:21:21 2021 +0200
+++ b/mercurial/revlogutils/rewrite.py	Thu Oct 21 17:25:41 2021 +0200
@@ -589,7 +589,9 @@
     except error.CensoredNodeError:
         # We don't care about censored nodes as they never carry metadata
         return False
-    has_meta = raw_text.startswith(b'\x01\n')
+
+    # raw text can be a `memoryview`, which doesn't implement `startswith`
+    has_meta = bytes(raw_text[:2]) == b'\x01\n'
     if metadata_cache is not None:
         metadata_cache[filerev] = has_meta
     if has_meta:
--- a/rust/hg-cpython/src/revlog.rs	Thu Oct 21 11:21:21 2021 +0200
+++ b/rust/hg-cpython/src/revlog.rs	Thu Oct 21 17:25:41 2021 +0200
@@ -59,22 +59,12 @@
 
     /// Return Revision if found, raises a bare `error.RevlogError`
     /// in case of ambiguity, same as C version does
-    def get_rev(&self, pynode: PyBytes) -> PyResult<Option<Revision>> {
+    def get_rev(&self, node: PyBytes) -> PyResult<Option<Revision>> {
         let opt = self.get_nodetree(py)?.borrow();
         let nt = opt.as_ref().unwrap();
         let idx = &*self.cindex(py).borrow();
-        let node = node_from_py_bytes(py, &pynode)?;
-        match nt.find_bin(idx, node.into())
-        {
-            Ok(None) =>
-                // fallback to C implementation, remove once
-                // https://bz.mercurial-scm.org/show_bug.cgi?id=6554
-                // is fixed (a simple backout should do)
-                self.call_cindex(py, "get_rev", &PyTuple::new(py, &[pynode.into_object()]), None)?
-                .extract(py),
-            Ok(Some(rev)) => Ok(Some(rev)),
-            Err(e) => Err(nodemap_error(py, e)),
-        }
+        let node = node_from_py_bytes(py, &node)?;
+        nt.find_bin(idx, node.into()).map_err(|e| nodemap_error(py, e))
     }
 
     /// same as `get_rev()` but raises a bare `error.RevlogError` if node
@@ -104,34 +94,27 @@
         }
     }
 
-    def partialmatch(&self, pynode: PyObject) -> PyResult<Option<PyBytes>> {
+    def partialmatch(&self, node: PyObject) -> PyResult<Option<PyBytes>> {
         let opt = self.get_nodetree(py)?.borrow();
         let nt = opt.as_ref().unwrap();
         let idx = &*self.cindex(py).borrow();
 
         let node_as_string = if cfg!(feature = "python3-sys") {
-            pynode.cast_as::<PyString>(py)?.to_string(py)?.to_string()
+            node.cast_as::<PyString>(py)?.to_string(py)?.to_string()
         }
         else {
-            let node = pynode.extract::<PyBytes>(py)?;
+            let node = node.extract::<PyBytes>(py)?;
             String::from_utf8_lossy(node.data(py)).to_string()
         };
 
         let prefix = NodePrefix::from_hex(&node_as_string).map_err(|_| PyErr::new::<ValueError, _>(py, "Invalid node or prefix"))?;
 
-        match nt.find_bin(idx, prefix) {
-            Ok(None) =>
-                // fallback to C implementation, remove once
-                // https://bz.mercurial-scm.org/show_bug.cgi?id=6554
-                // is fixed (a simple backout should do)
-                self.call_cindex(
-                    py, "partialmatch",
-                    &PyTuple::new(py, &[pynode]), None
-                )?.extract(py),
-            Ok(Some(rev)) =>
-                Ok(Some(PyBytes::new(py, idx.node(rev).unwrap().as_bytes()))),
-            Err(e) => Err(nodemap_error(py, e)),
-        }
+        nt.find_bin(idx, prefix)
+            // TODO make an inner API returning the node directly
+            .map(|opt| opt.map(
+                |rev| PyBytes::new(py, idx.node(rev).unwrap().as_bytes())))
+            .map_err(|e| nodemap_error(py, e))
+
     }
 
     /// append an index entry
--- a/rust/hgcli/pyoxidizer.bzl	Thu Oct 21 11:21:21 2021 +0200
+++ b/rust/hgcli/pyoxidizer.bzl	Thu Oct 21 17:25:41 2021 +0200
@@ -138,7 +138,7 @@
     )
 
     # Add Mercurial to resources.
-    exe.add_python_resources(exe.pip_install(["--verbose", ROOT]))
+    exe.add_python_resources(exe.pip_install(["--verbose", "--no-use-pep517", ROOT]))
 
     # On Windows, we install extra packages for convenience.
     if IS_WINDOWS:
--- a/tests/basic_test_result.py	Thu Oct 21 11:21:21 2021 +0200
+++ b/tests/basic_test_result.py	Thu Oct 21 17:25:41 2021 +0200
@@ -1,9 +1,15 @@
 from __future__ import absolute_import, print_function
 
+import sys
 import unittest
 
+if sys.version_info[0] < 3:
+    base_class = unittest._TextTestResult
+else:
+    base_class = unittest.TextTestResult
 
-class TestResult(unittest._TextTestResult):
+
+class TestResult(base_class):
     def __init__(self, options, *args, **kwargs):
         super(TestResult, self).__init__(*args, **kwargs)
         self._options = options
--- a/tests/run-tests.py	Thu Oct 21 11:21:21 2021 +0200
+++ b/tests/run-tests.py	Thu Oct 21 17:25:41 2021 +0200
@@ -2235,12 +2235,15 @@
 firstlock = threading.RLock()
 firsterror = False
 
-
-class TestResult(unittest._TextTestResult):
+if PYTHON3:
+    base_class = unittest.TextTestResult
+else:
+    base_class = unittest._TextTestResult
+
+
+class TestResult(base_class):
     """Holds results when executing via unittest."""
 
-    # Don't worry too much about accessing the non-public _TextTestResult.
-    # It is relatively common in Python testing tools.
     def __init__(self, options, *args, **kwargs):
         super(TestResult, self).__init__(*args, **kwargs)
 
--- a/tests/test-chg.t	Thu Oct 21 11:21:21 2021 +0200
+++ b/tests/test-chg.t	Thu Oct 21 17:25:41 2021 +0200
@@ -475,7 +475,7 @@
   $ hg init $TESTTMP/profiling
   $ cd $TESTTMP/profiling
   $ filteredchg() {
-  >   CHGDEBUG=1 chg "$@" 2>&1 | egrep 'Sample count|start cmdserver' || true
+  >   CHGDEBUG=1 chg "$@" 2>&1 | sed -rn 's_^No samples recorded.*$_Sample count: 0_; /Sample count/p; /start cmdserver/p'
   > }
   $ newchg() {
   >   chg --kill-chg-daemon
--- a/tests/test-merge-halt.t	Thu Oct 21 11:21:21 2021 +0200
+++ b/tests/test-merge-halt.t	Thu Oct 21 17:25:41 2021 +0200
@@ -44,7 +44,7 @@
   merging a
   merging b
   merging a failed!
-  merge halted after failed merge (see hg resolve)
+  unresolved conflicts (see 'hg resolve', then 'hg rebase --continue')
   [240]
 
   $ hg resolve --list
@@ -72,7 +72,7 @@
   continue merge operation (yn)? y
   merging b failed!
   continue merge operation (yn)? n
-  merge halted after failed merge (see hg resolve)
+  unresolved conflicts (see 'hg resolve', then 'hg rebase --continue')
   [240]
 
   $ hg resolve --list
@@ -101,7 +101,7 @@
   was merge successful (yn)? n
   merging b failed!
   continue merge operation (yn)? n
-  merge halted after failed merge (see hg resolve)
+  unresolved conflicts (see 'hg resolve', then 'hg rebase --continue')
   [240]
 
   $ hg resolve --list
@@ -124,7 +124,7 @@
   merging a
   merging b
   merging a failed!
-  merge halted after failed merge (see hg resolve)
+  unresolved conflicts (see 'hg resolve', then 'hg rebase --continue')
   [240]
 
   $ hg resolve --list
@@ -145,7 +145,7 @@
   was merge of 'a' successful (yn)? y
   was merge of 'b' successful (yn)? n
   merging b failed!
-  merge halted after failed merge (see hg resolve)
+  unresolved conflicts (see 'hg resolve', then 'hg rebase --continue')
   [240]
 
   $ hg resolve --list
@@ -162,3 +162,59 @@
   merging b
   $TESTTMP/repo/a *a~base* *a~other* (glob)
   $TESTTMP/repo/b *b~base* *b~other* (glob)
+
+Check that unshelve isn't broken by halting the merge
+  $ cat <<EOS >> $HGRCPATH
+  > [extensions]
+  > shelve =
+  > [merge-tools]
+  > false.check=conflicts
+  > false.premerge=false
+  > EOS
+  $ echo foo > shelve_file1
+  $ echo foo > shelve_file2
+  $ hg ci -qAm foo
+  $ echo bar >> shelve_file1
+  $ echo bar >> shelve_file2
+  $ hg shelve --list
+  $ hg shelve
+  shelved as default
+  2 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  $ echo baz >> shelve_file1
+  $ echo baz >> shelve_file2
+  $ hg ci -m baz
+  $ hg unshelve --tool false --config merge-tools.false.premerge=keep
+  unshelving change 'default'
+  rebasing shelved changes
+  merging shelve_file1
+  merging shelve_file2
+  merging shelve_file1 failed!
+  unresolved conflicts (see 'hg resolve', then 'hg unshelve --continue')
+  [240]
+  $ hg status --config commands.status.verbose=True
+  M shelve_file1
+  M shelve_file2
+  ? shelve_file1.orig
+  ? shelve_file2.orig
+  # The repository is in an unfinished *unshelve* state.
+  
+  # Unresolved merge conflicts:
+  # 
+  #     shelve_file1
+  #     shelve_file2
+  # 
+  # To mark files as resolved:  hg resolve --mark FILE
+  
+  # To continue:    hg unshelve --continue
+  # To abort:       hg unshelve --abort
+  
+  $ hg resolve --tool false --all --re-merge
+  merging shelve_file1
+  merging shelve_file2
+  merging shelve_file1 failed!
+  merge halted after failed merge (see hg resolve)
+  [240]
+  $ hg shelve --list
+  default         (* ago)    changes to: foo (glob)
+  $ hg unshelve --abort
+  unshelve of 'default' aborted
--- a/tests/test-persistent-nodemap.t	Thu Oct 21 11:21:21 2021 +0200
+++ b/tests/test-persistent-nodemap.t	Thu Oct 21 17:25:41 2021 +0200
@@ -435,46 +435,6 @@
   data-length: 121088
   data-unused: 0
   data-unused: 0.000%
-
-Sub-case: fallback for corrupted data file
-------------------------------------------
-
-Sabotaging the data file so that nodemap resolutions fail, triggering fallback to
-(non-persistent) C implementation.
-
-
-  $ UUID=`hg debugnodemap --metadata| grep 'uid:' | \
-  > sed 's/uid: //'`
-  $ FILE=.hg/store/00changelog-"${UUID}".nd
-  $ python -c "fobj = open('$FILE', 'r+b'); fobj.write(b'\xff' * 121088); fobj.close()"
-
-The nodemap data file is still considered in sync with the docket. This
-would fail without the fallback to the (non-persistent) C implementation:
-
-  $ hg log -r b355ef8adce0949b8bdf6afc72ca853740d65944 -T '{rev}\n' --traceback
-  5002
-
-The nodemap data file hasn't been fixed, more tests can be inserted:
-
-  $ hg debugnodemap --dump-disk | f --bytes=256 --hexdump --size
-  size=121088
-  0000: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
-  0010: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
-  0020: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
-  0030: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
-  0040: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
-  0050: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
-  0060: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
-  0070: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
-  0080: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
-  0090: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
-  00a0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
-  00b0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
-  00c0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
-  00d0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
-  00e0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
-  00f0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
-
   $ mv ../tmp-data-file $FILE
   $ mv ../tmp-docket .hg/store/00changelog.n