D12442: [RFC] rhg: implement more methods on revlogs
martinvonz created this revision. Herald added a reviewer: hg-reviewers. Herald added a subscriber: mercurial-patches. REPOSITORY rHG Mercurial BRANCH default REVISION DETAIL https://phab.mercurial-scm.org/D12442 AFFECTED FILES rust/hg-core/src/revlog/changelog.rs rust/hg-core/src/revlog/revlog.rs CHANGE DETAILS diff --git a/rust/hg-core/src/revlog/revlog.rs b/rust/hg-core/src/revlog/revlog.rs --- a/rust/hg-core/src/revlog/revlog.rs +++ b/rust/hg-core/src/revlog/revlog.rs @@ -331,6 +331,10 @@ self.rev } +pub fn node(&self) -> &Node { +&self.hash +} + pub fn uncompressed_len(&self) -> Option { u32::try_from(self.uncompressed_len).ok() } @@ -339,6 +343,38 @@ self.p1 != NULL_REVISION } +pub fn p1(&self) -> Result, RevlogError> { +if self.p1 == NULL_REVISION { +Ok(None) +} else { +Ok(Some(self.revlog.get_entry(self.p1)?)) +} +} + +pub fn p2(&self) -> Result, RevlogError> { +if self.p2 == NULL_REVISION { +Ok(None) +} else { +Ok(Some(self.revlog.get_entry(self.p1)?)) +} +} + +pub fn p1_rev(&self) -> Option { +if self.p1 == NULL_REVISION { +None +} else { +Some(self.p1) +} +} + +pub fn p2_rev(&self) -> Option { +if self.p2 == NULL_REVISION { +None +} else { +Some(self.p2) +} +} + pub fn is_cencored(&self) -> bool { (self.flags & REVISION_FLAG_CENSORED) != 0 } diff --git a/rust/hg-core/src/revlog/changelog.rs b/rust/hg-core/src/revlog/changelog.rs --- a/rust/hg-core/src/revlog/changelog.rs +++ b/rust/hg-core/src/revlog/changelog.rs @@ -1,6 +1,6 @@ use crate::errors::HgError; use crate::repo::Repo; -use crate::revlog::revlog::{Revlog, RevlogError}; +use crate::revlog::revlog::{Revlog, RevlogEntry, RevlogError}; use crate::revlog::Revision; use crate::revlog::{Node, NodePrefix}; use crate::utils::hg_path::HgPath; @@ -31,6 +31,15 @@ } /// Return the `ChangelogEntry` of the given revision number. +pub fn entry_for_node( +&self, +node: NodePrefix, +) -> Result { +let rev = self.revlog.rev_from_node(node)?; +self.revlog.get_entry(rev) +} + +/// Return the `ChangelogEntry` of the given revision number. pub fn data_for_rev( &self, rev: Revision, To: martinvonz, #hg-reviewers Cc: mercurial-patches, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D12441: crecord: avoid duplicating lines when reverting noeol->eol change
spectral created this revision. Herald added a reviewer: hg-reviewers. Herald added a subscriber: mercurial-patches. REVISION SUMMARY When reversing a patch that looks like this while using crecord: @@ -301,4 +302,4 @@ zza zzb zzc zzd -zze \ No newline at end of file +zze we would previously reverse the `-zze` line to be an add, encounter the "no newline" line and stop inspecting lines. This caused us to duplicate the line, producing `zzezze` (still without a newline). `break` is the correct action if we know there will be no lines afterwards, as would be the case in an eol -> noeol transition. It is incorrect if there are lines afterward, such as if both sides are missing the newline or if only the lhs is missing the newline. REPOSITORY rHG Mercurial BRANCH default REVISION DETAIL https://phab.mercurial-scm.org/D12441 AFFECTED FILES mercurial/crecord.py tests/test-revert-interactive-curses.t CHANGE DETAILS diff --git a/tests/test-revert-interactive-curses.t b/tests/test-revert-interactive-curses.t --- a/tests/test-revert-interactive-curses.t +++ b/tests/test-revert-interactive-curses.t @@ -68,6 +68,5 @@ $ do_revert reverting a $ cat a - 0 (wdir known-bad-output !) 0 (no-eol) diff --git a/mercurial/crecord.py b/mercurial/crecord.py --- a/mercurial/crecord.py +++ b/mercurial/crecord.py @@ -505,7 +505,7 @@ text = line.linetext if line.linetext == diffhelper.MISSING_NEWLINE_MARKER: noeol = True -break +continue if line.applied: if text.startswith(b'+'): dels.append(text[1:]) To: spectral, #hg-reviewers Cc: mercurial-patches, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D12440: crecord: add test demonstrating issue when reverting noeol->eol change
spectral created this revision. Herald added a reviewer: hg-reviewers. Herald added a subscriber: mercurial-patches. REPOSITORY rHG Mercurial BRANCH default REVISION DETAIL https://phab.mercurial-scm.org/D12440 AFFECTED FILES tests/test-revert-interactive-curses.t CHANGE DETAILS diff --git a/tests/test-revert-interactive-curses.t b/tests/test-revert-interactive-curses.t --- a/tests/test-revert-interactive-curses.t +++ b/tests/test-revert-interactive-curses.t @@ -1,4 +1,5 @@ #require curses +#testcases committed wdir Revert interactive tests with the Curses interface @@ -12,6 +13,22 @@ TODO: Make a curses version of the other tests from test-revert-interactive.t. +#if committed + $ maybe_commit() { + > hg ci "$@" + > } + $ do_revert() { + > hg revert -ir'.^' + > } +#else + $ maybe_commit() { + > true + > } + $ do_revert() { + > hg revert -i + > } +#endif + When a line without EOL is selected during "revert -i" $ hg init $TESTTMP/revert-i-curses-eol @@ -19,7 +36,7 @@ $ echo 0 > a $ hg ci -qAm 0 $ printf 1 >> a - $ hg ci -qAm 1 + $ maybe_commit -qAm 1 $ cat a 0 1 (no-eol) @@ -28,7 +45,7 @@ > c > EOF - $ hg revert -ir'.^' + $ do_revert reverting a $ cat a 0 @@ -40,7 +57,7 @@ $ printf 0 > a $ hg ci -qAm 0 $ echo 0 > a - $ hg ci -qAm 1 + $ maybe_commit -qAm 1 $ cat a 0 @@ -48,8 +65,9 @@ > c > EOF - $ hg revert -ir'.^' + $ do_revert reverting a $ cat a + 0 (wdir known-bad-output !) 0 (no-eol) To: spectral, #hg-reviewers Cc: mercurial-patches, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D12439: [RFC] rhg: start parsing changeset data
martinvonz created this revision. Herald added a reviewer: hg-reviewers. Herald added a subscriber: mercurial-patches. REPOSITORY rHG Mercurial BRANCH default REVISION DETAIL https://phab.mercurial-scm.org/D12439 AFFECTED FILES rust/hg-core/src/revlog/changelog.rs CHANGE DETAILS diff --git a/rust/hg-core/src/revlog/changelog.rs b/rust/hg-core/src/revlog/changelog.rs --- a/rust/hg-core/src/revlog/changelog.rs +++ b/rust/hg-core/src/revlog/changelog.rs @@ -3,6 +3,10 @@ use crate::revlog::revlog::{Revlog, RevlogError}; use crate::revlog::Revision; use crate::revlog::{Node, NodePrefix}; +use crate::utils::hg_path::HgPath; +use std::ascii::escape_default; +use std::fmt::{Debug, Formatter}; +use std::ops::Range; /// A specialized `Revlog` to work with `changelog` data format. pub struct Changelog { @@ -35,7 +39,12 @@ if bytes.is_empty() { Ok(ChangelogRevisionData::null()) } else { -Ok(ChangelogRevisionData::new(bytes)) +Ok(ChangelogRevisionData::new(bytes).ok_or_else(|| { +RevlogError::Other(HgError::CorruptedRepository(format!( +"Invalid changelog data for revision {}", +rev +))) +})?) } } @@ -45,21 +54,66 @@ } /// `Changelog` entry which knows how to interpret the `changelog` data bytes. -#[derive(Debug)] +#[derive(PartialEq)] pub struct ChangelogRevisionData { /// The data bytes of the `changelog` entry. bytes: Vec, +/// The byte range for the hex manifest (not including the newline) +manifest_range: Range, +/// The byte range for the user+email (not including the newline) +user_range: Range, +/// The byte range for the timestamp+timezone+extras (not including the +/// newline) +timestamp_range: Range, +/// The byte range for the file list (including newlines between, but not +/// after) +files_range: Range, +/// The byte range for the description (including newlines) +description_range: Range, } impl ChangelogRevisionData { -fn new(bytes: Vec) -> Self { -Self { bytes } +fn new(bytes: Vec) -> Option { +let mut line_iter = bytes.split(|b| b == &b'\n'); +let manifest_range = 0..line_iter.next().unwrap().len(); +let mut start_pos = manifest_range.end + 1; +let user_slice = line_iter.next()?; +let user_range = start_pos..start_pos + user_slice.len(); +start_pos += user_slice.len() + 1; +let timestamp_slice = line_iter.next()?; +let timestamp_range = start_pos..start_pos + timestamp_slice.len(); +start_pos += timestamp_slice.len() + 1; +let mut files_end_pos = start_pos; +loop { +// This line intentionally returns `None` is the list does not end +// in a newline +let line = line_iter.next()?; +if line.is_empty() { +break; +} +files_end_pos += line.len() + 1; +} +let files_range = start_pos..files_end_pos - 1; +if files_end_pos >= bytes.len() { +return None; +} +let description_range = files_end_pos + 1..bytes.len(); + +Some(Self { +bytes, +manifest_range, +user_range, +timestamp_range, +files_range, +description_range, +}) } fn null() -> Self { Self::new( b"\n\n0 0\n\n".to_vec(), ) +.unwrap() } /// Return an iterator over the lines of the entry. @@ -70,7 +124,92 @@ /// Return the node id of the `manifest` referenced by this `changelog` /// entry. pub fn manifest_node(&self) -> Result { -let manifest_node_hex = self.lines().next().unwrap(); +let manifest_node_hex = &self.bytes[self.manifest_range.clone()]; Node::from_hex_for_repo(manifest_node_hex) } + +/// Return the node id of the `manifest` referenced by this `changelog` +/// entry. +pub fn files(&self) -> impl Iterator { +self.bytes[self.files_range.clone()] +.split(|b| b == &b'\n') +.map(|path| HgPath::new(path)) +} + +/// Return the node id of the `manifest` referenced by this `changelog` +/// entry. +pub fn description(&self) -> &[u8] { +&self.bytes[self.description_range.clone()] +} } + +impl Debug for ChangelogRevisionData { +fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { +f.debug_struct("ChangelogRevisionData") +.field("bytes", &debug_bytes(&self.bytes)) +.field( +"manifest", +&debug_bytes(&self.bytes[self.manifest_range.clone()]), +) +.field("user", &debug_bytes(&self.bytes[self.user_range.clone()])) +.field( +"timestamp", +&de
D12438: rhg: remove special parsing of empty changelog data for null rev
martinvonz created this revision. Herald added a reviewer: hg-reviewers. Herald added a subscriber: mercurial-patches. REVISION SUMMARY For the null revision, `Revlog::get_rev_data()` will return an empty string (of bytes). We currently handle that case in `ChangelogRevisionData::manifest_node()`. However, it's going to be ugly to have special handling for the null revision for each future method on `ChangelogRevisionData`. This patch therefore restructures the code so we instead initialize the struct with valid data for the null revision. REPOSITORY rHG Mercurial BRANCH default REVISION DETAIL https://phab.mercurial-scm.org/D12438 AFFECTED FILES rust/hg-core/src/revlog/changelog.rs CHANGE DETAILS diff --git a/rust/hg-core/src/revlog/changelog.rs b/rust/hg-core/src/revlog/changelog.rs --- a/rust/hg-core/src/revlog/changelog.rs +++ b/rust/hg-core/src/revlog/changelog.rs @@ -1,6 +1,5 @@ use crate::errors::HgError; use crate::repo::Repo; -use crate::revlog::node::NULL_NODE; use crate::revlog::revlog::{Revlog, RevlogError}; use crate::revlog::Revision; use crate::revlog::{Node, NodePrefix}; @@ -33,7 +32,11 @@ rev: Revision, ) -> Result { let bytes = self.revlog.get_rev_data(rev)?.into_owned(); -Ok(ChangelogRevisionData { bytes }) +if bytes.is_empty() { +Ok(ChangelogRevisionData::null()) +} else { +Ok(ChangelogRevisionData::new(bytes)) +} } pub fn node_from_rev(&self, rev: Revision) -> Option<&Node> { @@ -49,6 +52,16 @@ } impl ChangelogRevisionData { +fn new(bytes: Vec) -> Self { +Self { bytes } +} + +fn null() -> Self { +Self::new( +b"\n\n0 0\n\n".to_vec(), +) +} + /// Return an iterator over the lines of the entry. pub fn lines(&self) -> impl Iterator { self.bytes.split(|b| b == &b'\n') @@ -58,10 +71,6 @@ /// entry. pub fn manifest_node(&self) -> Result { let manifest_node_hex = self.lines().next().unwrap(); -if manifest_node_hex.is_empty() { -Ok(NULL_NODE) -} else { -Node::from_hex_for_repo(manifest_node_hex) -} +Node::from_hex_for_repo(manifest_node_hex) } } To: martinvonz, #hg-reviewers Cc: mercurial-patches, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
mercurial-devel | Failed pipeline for branch/default | 32dd1511
Pipeline #46986 has failed! Project: mercurial-devel ( https://foss.heptapod.net/mercurial/mercurial-devel ) Branch: branch/default ( https://foss.heptapod.net/mercurial/mercurial-devel/-/commits/branch/default ) Commit: 32dd1511 ( https://foss.heptapod.net/mercurial/mercurial-devel/-/commit/32dd15116c2cfb79d14eadaa81a2c2d6a1cbf023 ) Commit Message: branching: merge stable into default Commit Author: Raphaël Gomès Pipeline #46986 ( https://foss.heptapod.net/mercurial/mercurial-devel/-/pipelines/46986 ) triggered by Administrator ( https://foss.heptapod.net/root ) had 1 failed job. Job #464882 ( https://foss.heptapod.net/mercurial/mercurial-devel/-/jobs/464882/raw ) Stage: tests Name: test-c -- You're receiving this email because of your account on foss.heptapod.net. ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Re: [PATCH] completion: install completers to conventional locations
It appears that this was queued some days ago. Thanks for the patch! On 3/25/22 04:37, Matthew Martin wrote: I've tested the patch on OpenBSD, but don't have other systems handy. # HG changeset patch # User Matthew Martin # Date 1648175205 18000 # Thu Mar 24 21:26:45 2022 -0500 # Node ID 106bcb6cfb02c00b7e240bb041f6fbab00891a85 # Parent 0590c6c96852a8d05065dde5a757e2a025db2567 completion: install completers to conventional locations Installs the bash and zsh completers to the convential locations so they will automatically be picked up without user intervention. The zsh completer on Debian is still installed to vendor-completions to match their policy. bash: https://github.com/scop/bash-completion#faq zsh: https://github.com/zsh-users/zsh/blob/57305cf245853b8b30895b41a90142dffab97e38/INSTALL#L254 Debian zsh: https://salsa.debian.org/debian/zsh/-/blob/5086b5356abcef8849dc8a09902b7c55f01db3c0/debian/README.Debian#L73 diff -r 0590c6c96852 -r 106bcb6cfb02 Makefile --- a/Makefile Fri Dec 10 17:55:22 2021 -0800 +++ b/Makefile Thu Mar 24 21:26:45 2022 -0500 @@ -238,16 +238,6 @@ # Place a bogon .DS_Store file in the target dir so we can be # sure it doesn't get included in the final package. touch build/mercurial/.DS_Store -# install zsh completions - this location appears to be -# searched by default as of macOS Sierra. - install -d build/mercurial/usr/local/share/zsh/site-functions/ - install -m 0644 contrib/zsh_completion build/mercurial/usr/local/share/zsh/site-functions/_hg -# install bash completions - there doesn't appear to be a -# place that's searched by default for bash, so we'll follow -# the lead of Apple's git install and just put it in a -# location of our own. - install -d build/mercurial/usr/local/hg/contrib/ - install -m 0644 contrib/bash_completion build/mercurial/usr/local/hg/contrib/hg-completion.bash make -C contrib/chg \ HGPATH=/usr/local/bin/hg \ PYTHON=/usr/bin/python2.7 \ diff -r 0590c6c96852 -r 106bcb6cfb02 contrib/packaging/debian/rules --- a/contrib/packaging/debian/rulesFri Dec 10 17:55:22 2021 -0800 +++ b/contrib/packaging/debian/rulesThu Mar 24 21:26:45 2022 -0500 @@ -92,10 +92,8 @@ mkdir -p "$(CURDIR)"/debian/mercurial/etc/mercurial/hgrc.d/ cp contrib/packaging/debian/*.rc "$(CURDIR)"/debian/mercurial/etc/mercurial/hgrc.d/ # completions - mkdir -p "$(CURDIR)"/debian/mercurial/usr/share/bash-completion/completions - cp contrib/bash_completion "$(CURDIR)"/debian/mercurial/usr/share/bash-completion/completions/hg mkdir -p "$(CURDIR)"/debian/mercurial/usr/share/zsh/vendor-completions - cp contrib/zsh_completion "$(CURDIR)"/debian/mercurial/usr/share/zsh/vendor-completions/_hg + mv "$(CURDIR)"/debian/mercurial/usr/share/zsh/site-functions/_hg "$(CURDIR)"/debian/mercurial/usr/share/zsh/vendor-completions/_hg if [ "$(DEB_HG_CHG_BY_DEFAULT)" -eq 1 ]; then \ mkdir -p "$(CURDIR)"/debian/mercurial/usr/lib/mercurial; \ mv "$(CURDIR)"/debian/mercurial/usr/bin/hg "$(CURDIR)"/debian/mercurial/usr/lib/mercurial/hg; \ diff -r 0590c6c96852 -r 106bcb6cfb02 contrib/packaging/hgpackaging/py2exe.py --- a/contrib/packaging/hgpackaging/py2exe.py Fri Dec 10 17:55:22 2021 -0800 +++ b/contrib/packaging/hgpackaging/py2exe.py Thu Mar 24 21:26:45 2022 -0500 @@ -21,7 +21,6 @@ STAGING_RULES = [ -('contrib/bash_completion', 'contrib/'), ('contrib/hgk', 'contrib/hgk.tcl'), ('contrib/hgweb.fcgi', 'contrib/'), ('contrib/hgweb.wsgi', 'contrib/'), @@ -34,7 +33,6 @@ ('contrib/win32/postinstall.txt', 'ReleaseNotes.txt'), ('contrib/win32/ReadMe.html', 'ReadMe.html'), ('contrib/xml.rnc', 'contrib/'), -('contrib/zsh_completion', 'contrib/'), ('dist/hg.exe', './'), ('dist/lib/*.dll', 'lib/'), ('dist/lib/*.pyd', 'lib/'), diff -r 0590c6c96852 -r 106bcb6cfb02 contrib/packaging/hgpackaging/pyoxidizer.py --- a/contrib/packaging/hgpackaging/pyoxidizer.py Fri Dec 10 17:55:22 2021 -0800 +++ b/contrib/packaging/hgpackaging/pyoxidizer.py Thu Mar 24 21:26:45 2022 -0500 @@ -23,7 +23,6 @@ STAGING_RULES_WINDOWS = [ -('contrib/bash_completion', 'contrib/'), ('contrib/hgk', 'contrib/hgk.tcl'), ('contrib/hgweb.fcgi', 'contrib/'), ('contrib/hgweb.wsgi', 'contrib/'), @@ -36,7 +35,6 @@ ('contrib/win32/postinstall.txt', 'ReleaseNotes.txt'), ('contrib/win32/ReadMe.html', 'ReadMe.html'), ('contrib/xml.rnc', 'contrib/'), -('contrib/zsh_completion', 'contrib/'), ('doc/*.html', 'doc/'), ('doc/style.css', 'doc/'), ('COPYING', 'Copying.txt'), diff -r 0590c6c96852 -r 106bcb6cfb02 contrib/packaging/mercurial.spec --- a/contrib/packaging/mercurial.spec Fri Dec 10 17:55:22 2021 -0800 +++ b/contrib/packaging/mercurial.spec Thu Mar 24 21:26:45
mercurial@49005: new changeset
New changeset in mercurial: https://www.mercurial-scm.org/repo/hg/rev/12adf8c695ed changeset: 49005:12adf8c695ed bookmark:@ tag: tip parent: 48997:20c6c9e43397 parent: 49004:9dcfd1d05e6e user:Raphaël Gomès date:Tue Apr 05 11:09:03 2022 +0200 summary: merge: stable into default -- Repository URL: https://www.mercurial-scm.org/repo/hg ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
mercurial-devel | Failed pipeline for branch/default | 2b96a6f9
Pipeline #46972 has failed! Project: mercurial-devel ( https://foss.heptapod.net/mercurial/mercurial-devel ) Branch: branch/default ( https://foss.heptapod.net/mercurial/mercurial-devel/-/commits/branch/default ) Commit: 2b96a6f9 ( https://foss.heptapod.net/mercurial/mercurial-devel/-/commit/2b96a6f9744af283541eeaca8dc2bfe44080ef02 ) Commit Message: merge: stable into default Commit Author: Raphaël Gomès Pipeline #46972 ( https://foss.heptapod.net/mercurial/mercurial-devel/-/pipelines/46972 ) triggered by Administrator ( https://foss.heptapod.net/root ) had 1 failed job. Job #464673 ( https://foss.heptapod.net/mercurial/mercurial-devel/-/jobs/464673/raw ) Stage: tests Name: test-c -- You're receiving this email because of your account on foss.heptapod.net. ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
mercurial@49004: 6 new changesets (6 on stable)
6 new changesets (6 on stable) in mercurial: https://www.mercurial-scm.org/repo/hg/rev/cfd270d83169 changeset: 48999:cfd270d83169 branch: stable user:Raphaël Gomès date:Tue Apr 05 10:55:27 2022 +0200 summary: rust: explain why the current `OwningDirstateMap` is unsound https://www.mercurial-scm.org/repo/hg/rev/dd6b67d5c256 changeset: 49000:dd6b67d5c256 branch: stable user:Raphaël Gomès date:Tue Apr 05 10:55:28 2022 +0200 summary: rust: fix unsound `OwningDirstateMap` https://www.mercurial-scm.org/repo/hg/rev/2593873cda0f changeset: 49001:2593873cda0f branch: stable user:Raphaël Gomès date:Tue Apr 05 10:55:28 2022 +0200 summary: rust-dirstate: panic if the DirstateMap counters go below 0 https://www.mercurial-scm.org/repo/hg/rev/fbc02ccc207e changeset: 49002:fbc02ccc207e branch: stable user:Raphaël Gomès date:Tue Apr 05 10:55:28 2022 +0200 summary: rust-dirstatemap: properly decrement counter for tracked descendants https://www.mercurial-scm.org/repo/hg/rev/ce919b1a1063 changeset: 49003:ce919b1a1063 branch: stable user:Raphaël Gomès date:Tue Apr 05 10:55:28 2022 +0200 summary: rust-dirstatemap: correctly decrement the copies counter https://www.mercurial-scm.org/repo/hg/rev/9dcfd1d05e6e changeset: 49004:9dcfd1d05e6e branch: stable tag: tip user:Raphaël Gomès date:Tue Apr 05 10:55:28 2022 +0200 summary: rust-hgpath: add `repr(transparent)` to `HgPath` -- Repository URL: https://www.mercurial-scm.org/repo/hg ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel