Mercurial > hg
changeset 47944:e02f9af7aed1
pathutil: replace the `skip` argument of `dirs` with a boolean
It is ever only used for `r` file. So we make it a boolean this will give use
more versatility later as we will stop storing the state explicitly.
Differential Revision: https://phab.mercurial-scm.org/D11383
author | Pierre-Yves David <pierre-yves.david@octobus.net> |
---|---|
date | Mon, 30 Aug 2021 18:45:54 +0200 |
parents | fea24454f919 |
children | 3337eec29d5b |
files | mercurial/cext/dirs.c mercurial/dirstatemap.py mercurial/pathutil.py rust/hg-core/src/dirstate/dirs_multiset.rs rust/hg-core/src/dirstate/dirstate_map.rs rust/hg-cpython/src/dirstate/dirs_multiset.rs |
diffstat | 6 files changed, 36 insertions(+), 45 deletions(-) [+] |
line wrap: on
line diff
--- a/mercurial/cext/dirs.c Thu Sep 02 00:16:37 2021 +0200 +++ b/mercurial/cext/dirs.c Mon Aug 30 18:45:54 2021 +0200 @@ -161,7 +161,7 @@ return ret; } -static int dirs_fromdict(PyObject *dirs, PyObject *source, char skipchar) +static int dirs_fromdict(PyObject *dirs, PyObject *source, bool only_tracked) { PyObject *key, *value; Py_ssize_t pos = 0; @@ -171,13 +171,13 @@ PyErr_SetString(PyExc_TypeError, "expected string key"); return -1; } - if (skipchar) { + if (only_tracked) { if (!dirstate_tuple_check(value)) { PyErr_SetString(PyExc_TypeError, "expected a dirstate tuple"); return -1; } - if (((dirstateItemObject *)value)->state == skipchar) + if (((dirstateItemObject *)value)->state == 'r') continue; } @@ -218,15 +218,17 @@ * Calculate a refcounted set of directory names for the files in a * dirstate. */ -static int dirs_init(dirsObject *self, PyObject *args) +static int dirs_init(dirsObject *self, PyObject *args, PyObject *kwargs) { PyObject *dirs = NULL, *source = NULL; - char skipchar = 0; + int only_tracked = 0; int ret = -1; + static char *keywords_name[] = {"map", "only_tracked", NULL}; self->dict = NULL; - if (!PyArg_ParseTuple(args, "|Oc:__init__", &source, &skipchar)) + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|Oi:__init__", + keywords_name, &source, &only_tracked)) return -1; dirs = PyDict_New(); @@ -237,10 +239,10 @@ if (source == NULL) ret = 0; else if (PyDict_Check(source)) - ret = dirs_fromdict(dirs, source, skipchar); - else if (skipchar) + ret = dirs_fromdict(dirs, source, (bool)only_tracked); + else if (only_tracked) PyErr_SetString(PyExc_ValueError, - "skip character is only supported " + "`only_tracked` is only supported " "with a dict source"); else ret = dirs_fromiter(dirs, source);
--- a/mercurial/dirstatemap.py Thu Sep 02 00:16:37 2021 +0200 +++ b/mercurial/dirstatemap.py Mon Aug 30 18:45:54 2021 +0200 @@ -377,7 +377,7 @@ @propertycache def _dirs(self): - return pathutil.dirs(self._map, b'r') + return pathutil.dirs(self._map, only_tracked=True) @propertycache def _alldirs(self):
--- a/mercurial/pathutil.py Thu Sep 02 00:16:37 2021 +0200 +++ b/mercurial/pathutil.py Mon Aug 30 18:45:54 2021 +0200 @@ -315,20 +315,19 @@ class dirs(object): '''a multiset of directory names from a set of file paths''' - def __init__(self, map, skip=None): + def __init__(self, map, only_tracked=False): """ a dict map indicates a dirstate while a list indicates a manifest """ self._dirs = {} addpath = self.addpath - if isinstance(map, dict) and skip is not None: + if isinstance(map, dict) and only_tracked: for f, s in pycompat.iteritems(map): - if s.state != skip: + if s.state != b'r': addpath(f) - elif skip is not None: - raise error.ProgrammingError( - b"skip character is only supported with a dict source" - ) + elif only_tracked: + msg = b"`only_tracked` is only supported with a dict source" + raise error.ProgrammingError(msg) else: for f in map: addpath(f)
--- a/rust/hg-core/src/dirstate/dirs_multiset.rs Thu Sep 02 00:16:37 2021 +0200 +++ b/rust/hg-core/src/dirstate/dirs_multiset.rs Mon Aug 30 18:45:54 2021 +0200 @@ -33,7 +33,7 @@ /// If `skip_state` is provided, skips dirstate entries with equal state. pub fn from_dirstate<I, P>( dirstate: I, - skip_state: Option<EntryState>, + only_tracked: bool, ) -> Result<Self, DirstateError> where I: IntoIterator< @@ -48,8 +48,8 @@ let (filename, entry) = item?; let filename = filename.as_ref(); // This `if` is optimized out of the loop - if let Some(skip) = skip_state { - if skip != entry.state { + if only_tracked { + if entry.state != EntryState::Removed { multiset.add_path(filename)?; } } else { @@ -343,7 +343,7 @@ let new = DirsMultiset::from_dirstate( StateMap::default().into_iter().map(Ok), - None, + false, ) .unwrap(); let expected = DirsMultiset { @@ -385,7 +385,7 @@ .map(|(k, v)| (HgPathBuf::from_bytes(k.as_bytes()), *v)) .collect(); - let new = DirsMultiset::from_dirstate(input_map, None).unwrap(); + let new = DirsMultiset::from_dirstate(input_map, false).unwrap(); let expected = DirsMultiset { inner: expected_inner, }; @@ -414,14 +414,12 @@ }); // "a" incremented with "a/c" and "a/d/" - let expected_inner = [("", 1), ("a", 2)] + let expected_inner = [("", 1), ("a", 3)] .iter() .map(|(k, v)| (HgPathBuf::from_bytes(k.as_bytes()), *v)) .collect(); - let new = - DirsMultiset::from_dirstate(input_map, Some(EntryState::Normal)) - .unwrap(); + let new = DirsMultiset::from_dirstate(input_map, true).unwrap(); let expected = DirsMultiset { inner: expected_inner, };
--- a/rust/hg-core/src/dirstate/dirstate_map.rs Thu Sep 02 00:16:37 2021 +0200 +++ b/rust/hg-core/src/dirstate/dirstate_map.rs Mon Aug 30 18:45:54 2021 +0200 @@ -334,7 +334,7 @@ if self.all_dirs.is_none() { self.all_dirs = Some(DirsMultiset::from_dirstate( self.state_map.iter().map(|(k, v)| Ok((k, *v))), - None, + false, )?); } Ok(()) @@ -344,7 +344,7 @@ if self.dirs.is_none() { self.dirs = Some(DirsMultiset::from_dirstate( self.state_map.iter().map(|(k, v)| Ok((k, *v))), - Some(EntryState::Removed), + true, )?); } Ok(())
--- a/rust/hg-cpython/src/dirstate/dirs_multiset.rs Thu Sep 02 00:16:37 2021 +0200 +++ b/rust/hg-cpython/src/dirstate/dirs_multiset.rs Mon Aug 30 18:45:54 2021 +0200 @@ -9,19 +9,16 @@ //! `hg-core` package. use std::cell::RefCell; -use std::convert::TryInto; use cpython::{ - exc, ObjectProtocol, PyBytes, PyClone, PyDict, PyErr, PyObject, PyResult, - Python, UnsafePyLeaked, + exc, ObjectProtocol, PyBool, PyBytes, PyClone, PyDict, PyErr, PyObject, + PyResult, Python, UnsafePyLeaked, }; use crate::dirstate::extract_dirstate; use hg::{ - errors::HgError, utils::hg_path::{HgPath, HgPathBuf}, DirsMultiset, DirsMultisetIter, DirstateError, DirstateMapError, - EntryState, }; py_class!(pub class Dirs |py| { @@ -32,22 +29,17 @@ def __new__( _cls, map: PyObject, - skip: Option<PyObject> = None + only_tracked: Option<PyObject> = None ) -> PyResult<Self> { - let mut skip_state: Option<EntryState> = None; - if let Some(skip) = skip { - skip_state = Some( - skip.extract::<PyBytes>(py)?.data(py)[0] - .try_into() - .map_err(|e: HgError| { - PyErr::new::<exc::ValueError, _>(py, e.to_string()) - })?, - ); - } + let only_tracked_b = if let Some(only_tracked) = only_tracked { + only_tracked.extract::<PyBool>(py)?.is_true() + } else { + false + }; let inner = if let Ok(map) = map.cast_as::<PyDict>(py) { let dirstate = extract_dirstate(py, &map)?; let dirstate = dirstate.iter().map(|(k, v)| Ok((k, *v))); - DirsMultiset::from_dirstate(dirstate, skip_state) + DirsMultiset::from_dirstate(dirstate, only_tracked_b) .map_err(|e: DirstateError| { PyErr::new::<exc::ValueError, _>(py, e.to_string()) })?