# HG changeset patch # User Raphaël Gomès # Date 1683624950 -7200 # Node ID f57f5ab0e2207aefe4fde8901f0ea823f11914b9 # Parent e06331275a53fab982cd7fa4885d293c0e340035# Parent 558d08dc7dd462c21c398251f58d15543b7de87e branching: merge stable into default diff -r e06331275a53 -r f57f5ab0e220 .hgsigs --- a/.hgsigs Fri Apr 28 12:12:42 2023 +0200 +++ b/.hgsigs Tue May 09 11:35:50 2023 +0200 @@ -243,3 +243,4 @@ f14864fffdcab725d9eac6d4f4c07be05a35f59a 0 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 diff -r e06331275a53 -r f57f5ab0e220 .hgtags --- a/.hgtags Fri Apr 28 12:12:42 2023 +0200 +++ b/.hgtags Tue May 09 11:35:50 2023 +0200 @@ -259,3 +259,4 @@ f14864fffdcab725d9eac6d4f4c07be05a35f59a 6.4 83ea6ce48b4fd09fb79c4e34cc5750c805699a53 6.4.1 f952be90b0514a576dcc8bbe758ce3847faba9bb 6.4.2 +fc445f8abcf90b33db7c463816a1b3560681767f 6.4.3 diff -r e06331275a53 -r f57f5ab0e220 contrib/chg/chg.c --- a/contrib/chg/chg.c Fri Apr 28 12:12:42 2023 +0200 +++ b/contrib/chg/chg.c Tue May 09 11:35:50 2023 +0200 @@ -31,6 +31,8 @@ #define PATH_MAX 4096 #endif +extern char **environ; + struct cmdserveropts { char sockname[PATH_MAX]; char initsockname[PATH_MAX]; @@ -232,18 +234,12 @@ hgcmd = "hg"; #endif } - /* Set $CHGHG to the path to the seleted hg executable if it wasn't - * already set. This has the effect of ensuring that a new command - * server will be spawned if the existing command server is running from - * an executable at a different path. */ - if (setenv("CHGHG", hgcmd, 1) != 0) - abortmsgerrno("failed to setenv"); return hgcmd; } -static void execcmdserver(const char *hgcmd, const struct cmdserveropts *opts) +static void execcmdserver(const struct cmdserveropts *opts) { - + const char *hgcmd = gethgcmd(); const char *baseargv[] = { hgcmd, "serve", "--no-profile", "--cmdserver", "chgunix", "--address", opts->initsockname, "--daemon-postexec", @@ -380,16 +376,11 @@ debugmsg("start cmdserver at %s", opts->initsockname); - /* Get the path to the hg executable before we fork because this - * function might update the environment, and we want this to be - * reflected in both the parent and child processes. */ - const char *hgcmd = gethgcmd(); - pid_t pid = fork(); if (pid < 0) abortmsg("failed to fork cmdserver process"); if (pid == 0) { - execcmdserver(hgcmd, opts); + execcmdserver(opts); } else { hgc = retryconnectcmdserver(opts, pid); } @@ -523,6 +514,16 @@ } } + /* Set $CHGHG to the path of the hg executable we intend to use. This + * is a no-op if $CHGHG was expliclty specified, but otherwise this + * ensures that we will spawn a new command server if we connect to an + * existing one running from a different executable. This should only + * only be needed when chg is built with HGPATHREL since otherwise the + * hg executable used when CHGHG is absent should be deterministic. + * */ + if (setenv("CHGHG", gethgcmd(), 1) != 0) + abortmsgerrno("failed to setenv"); + hgclient_t *hgc; size_t retry = 0; while (1) { diff -r e06331275a53 -r f57f5ab0e220 hgext/fix.py --- a/hgext/fix.py Fri Apr 28 12:12:42 2023 +0200 +++ b/hgext/fix.py Tue May 09 11:35:50 2023 +0200 @@ -9,6 +9,13 @@ Provides a command that runs configured tools on the contents of modified files, writing back any fixes to the working copy or replacing changesets. +Fixer tools are run in the repository's root directory. This allows them to read +configuration files from the working copy, or even write to the working copy. +The working copy is not updated to match the revision being fixed. In fact, +several revisions may be fixed in parallel. Writes to the working copy are not +amended into the revision being fixed; fixer tools MUST always read content to +be fixed from stdin, and write fixed file content back to stdout. + Here is an example configuration that causes :hg:`fix` to apply automatic formatting fixes to modified lines in C++ code:: @@ -113,13 +120,6 @@ mapping fixer tool names to lists of metadata values returned from executions that modified a file. This aggregates the same metadata previously passed to the "postfixfile" hook. - -Fixer tools are run in the repository's root directory. This allows them to read -configuration files from the working copy, or even write to the working copy. -The working copy is not updated to match the revision being fixed. In fact, -several revisions may be fixed in parallel. Writes to the working copy are not -amended into the revision being fixed; fixer tools should always write fixed -file content back to stdout as documented above. """ @@ -239,7 +239,8 @@ def fix(ui, repo, *pats, **opts): """rewrite file content in changesets or working directory - Runs any configured tools to fix the content of files. Only affects files + Runs any configured tools to fix the content of files. (See + :hg:`help -e fix` for details about configuring tools.) Only affects files with changes, unless file arguments are provided. Only affects changed lines of files, unless the --whole flag is used. Some tools may always affect the whole file regardless of --whole. diff -r e06331275a53 -r f57f5ab0e220 mercurial/configitems.py --- a/mercurial/configitems.py Fri Apr 28 12:12:42 2023 +0200 +++ b/mercurial/configitems.py Tue May 09 11:35:50 2023 +0200 @@ -616,6 +616,10 @@ b'bundle2.debug', default=False, ) +# which kind of delta to put in the bundled changegroup. Possible value +# - '': use default behavior +# - p1: force to always use delta against p1 +# - full: force to always use full content coreconfigitem( b'devel', b'bundle.delta', diff -r e06331275a53 -r f57f5ab0e220 mercurial/revlogutils/deltas.py --- a/mercurial/revlogutils/deltas.py Fri Apr 28 12:12:42 2023 +0200 +++ b/mercurial/revlogutils/deltas.py Tue May 09 11:35:50 2023 +0200 @@ -684,6 +684,15 @@ yield None return + if target_rev is None: + target_rev = len(revlog) + + if not revlog._generaldelta: + # before general delta, there is only one possible delta base + yield (target_rev - 1,) + yield None + return + if ( cachedelta is not None and nullrev == cachedelta[0] @@ -716,9 +725,7 @@ group = [] for rev in temptative: # skip over empty delta (no need to include them in a chain) - while revlog._generaldelta and not ( - rev == nullrev or rev in tested or deltalength(rev) - ): + while not (rev == nullrev or rev in tested or deltalength(rev)): tested.add(rev) rev = deltaparent(rev) # no need to try a delta against nullrev, this will be done as a @@ -901,27 +908,27 @@ The group order aims at providing fast or small candidates first. """ - gdelta = revlog._generaldelta - # gate sparse behind general-delta because of issue6056 - sparse = gdelta and revlog._sparserevlog + # Why search for delta base if we cannot use a delta base ? + assert revlog._generaldelta + # also see issue6056 + sparse = revlog._sparserevlog curr = len(revlog) prev = curr - 1 deltachain = lambda rev: revlog._deltachain(rev)[0] - if gdelta: - # exclude already lazy tested base if any - parents = [p for p in (p1, p2) if p != nullrev] + # exclude already lazy tested base if any + parents = [p for p in (p1, p2) if p != nullrev] - if not revlog._deltabothparents and len(parents) == 2: - parents.sort() - # To minimize the chance of having to build a fulltext, - # pick first whichever parent is closest to us (max rev) - yield (parents[1],) - # then the other one (min rev) if the first did not fit - yield (parents[0],) - elif len(parents) > 0: - # Test all parents (1 or 2), and keep the best candidate - yield parents + if not revlog._deltabothparents and len(parents) == 2: + parents.sort() + # To minimize the chance of having to build a fulltext, + # pick first whichever parent is closest to us (max rev) + yield (parents[1],) + # then the other one (min rev) if the first did not fit + yield (parents[0],) + elif len(parents) > 0: + # Test all parents (1 or 2), and keep the best candidate + yield parents if sparse and parents: if snapshot_cache is None: @@ -1126,7 +1133,7 @@ return delta - def _builddeltainfo(self, revinfo, base, fh): + def _builddeltainfo(self, revinfo, base, fh, target_rev=None): # can we use the cached delta? revlog = self.revlog debug_search = self._write_debug is not None and self._debug_search @@ -1134,6 +1141,13 @@ if revlog._generaldelta: deltabase = base else: + if target_rev is not None and base != target_rev - 1: + msg = ( + b'general delta cannot use delta for something else ' + b'than `prev`: %d<-%d' + ) + msg %= (base, target_rev) + raise error.ProgrammingError(msg) deltabase = chainbase snapshotdepth = None if revlog._sparserevlog and deltabase == nullrev: @@ -1364,7 +1378,12 @@ if debug_search: delta_start = util.timer() - candidatedelta = self._builddeltainfo(revinfo, candidaterev, fh) + candidatedelta = self._builddeltainfo( + revinfo, + candidaterev, + fh, + target_rev=target_rev, + ) if debug_search: delta_end = util.timer() msg = b"DBG-DELTAS-SEARCH: delta-search-time=%f\n" diff -r e06331275a53 -r f57f5ab0e220 mercurial/transaction.py --- a/mercurial/transaction.py Fri Apr 28 12:12:42 2023 +0200 +++ b/mercurial/transaction.py Tue May 09 11:35:50 2023 +0200 @@ -414,6 +414,11 @@ if vfs.exists(file): filepath = vfs.join(file) backuppath = vfs.join(backupfile) + # store encoding may result in different directory here. + # so we have to ensure the destination directory exist + final_dir_name = os.path.dirname(backuppath) + util.makedirs(final_dir_name, mode=vfs.createmode, notindexed=True) + # then we can copy the backup util.copyfile(filepath, backuppath, hardlink=hardlink) else: backupfile = b'' diff -r e06331275a53 -r f57f5ab0e220 mercurial/upgrade_utils/engine.py --- a/mercurial/upgrade_utils/engine.py Fri Apr 28 12:12:42 2023 +0200 +++ b/mercurial/upgrade_utils/engine.py Tue May 09 11:35:50 2023 +0200 @@ -655,9 +655,14 @@ pass assert srcrepo.dirstate._use_dirstate_v2 == (old == b'v2') + use_v2 = new == b'v2' + if use_v2: + # Write the requirements *before* upgrading + scmutil.writereporequirements(srcrepo, upgrade_op.new_requirements) + srcrepo.dirstate._map.preload() - srcrepo.dirstate._use_dirstate_v2 = new == b'v2' - srcrepo.dirstate._map._use_dirstate_v2 = srcrepo.dirstate._use_dirstate_v2 + srcrepo.dirstate._use_dirstate_v2 = use_v2 + srcrepo.dirstate._map._use_dirstate_v2 = use_v2 srcrepo.dirstate._dirty = True try: srcrepo.vfs.unlink(b'dirstate') @@ -667,8 +672,9 @@ pass srcrepo.dirstate.write(None) - - scmutil.writereporequirements(srcrepo, upgrade_op.new_requirements) + if not use_v2: + # Remove the v2 requirement *after* downgrading + scmutil.writereporequirements(srcrepo, upgrade_op.new_requirements) def upgrade_tracked_hint(ui, srcrepo, upgrade_op, add): diff -r e06331275a53 -r f57f5ab0e220 mercurial/vfs.py --- a/mercurial/vfs.py Fri Apr 28 12:12:42 2023 +0200 +++ b/mercurial/vfs.py Tue May 09 11:35:50 2023 +0200 @@ -599,6 +599,10 @@ def __init__(self, vfs: "vfs"): self.vfs = vfs + @property + def createmode(self): + return self.vfs.createmode + def _auditpath(self, path, mode): return self.vfs._auditpath(path, mode) diff -r e06331275a53 -r f57f5ab0e220 relnotes/6.4 --- a/relnotes/6.4 Fri Apr 28 12:12:42 2023 +0200 +++ b/relnotes/6.4 Tue May 09 11:35:50 2023 +0200 @@ -1,3 +1,16 @@ += Mercurial 6.4.3 = + + * chg: declare environ (issue6812) + * chg: set CHGHG before connecting to command server + * delta-find: never do anything fancy when general delta is off + * delta-find: add a simple safeguard to prevent bad non-general-delta + * debug-delta: add minimal documentation for `devel.bundle-delta` option + * fix: highlight the required configuration and behavior of the fixer tools + * rhg: don't print copy source when --no-status is passed + * rhg: correctly relativize copy source path + * repo-upgrade: write new requirement before upgrading the dirstate + * backup: fix issue when the backup end up in a different directory + = Mercurial 6.4.2 = Exceptional bugfix release due to a corruption bug that happens when using diff -r e06331275a53 -r f57f5ab0e220 rust/rhg/src/commands/status.rs --- a/rust/rhg/src/commands/status.rs Fri Apr 28 12:12:42 2023 +0200 +++ b/rust/rhg/src/commands/status.rs Tue May 09 11:35:50 2023 +0200 @@ -552,12 +552,17 @@ // TODO: get the stdout lock once for the whole loop // instead of in each write for StatusPath { path, copy_source } in paths { - let relative; - let path = if let Some(relativize) = &self.relativize { - relative = relativize.relativize(&path); - &*relative + let relative_path; + let relative_source; + let (path, copy_source) = if let Some(relativize) = + &self.relativize + { + relative_path = relativize.relativize(&path); + relative_source = + copy_source.as_ref().map(|s| relativize.relativize(s)); + (&*relative_path, relative_source.as_deref()) } else { - path.as_bytes() + (path.as_bytes(), copy_source.as_ref().map(|s| s.as_bytes())) }; // TODO: Add a way to use `write_bytes!` instead of `format_bytes!` // in order to stream to stdout instead of allocating an @@ -570,10 +575,10 @@ &format_bytes!(b"{}{}", path, linebreak), label, )?; - if let Some(source) = copy_source { + if let Some(source) = copy_source.filter(|_| !self.no_status) { let label = "status.copied"; self.ui.write_stdout_labelled( - &format_bytes!(b" {}{}", source.as_bytes(), linebreak), + &format_bytes!(b" {}{}", source, linebreak), label, )? } diff -r e06331275a53 -r f57f5ab0e220 tests/test-chg.t --- a/tests/test-chg.t Fri Apr 28 12:12:42 2023 +0200 +++ b/tests/test-chg.t Tue May 09 11:35:50 2023 +0200 @@ -553,3 +553,20 @@ $ filteredchg log -r . --no-profile $ filteredchg log -r . Sample count: * (glob) + +chg setting CHGHG itself +------------------------ + +If CHGHG is not set, chg will set it before spawning the command server. + $ hg --kill-chg-daemon + $ HG=$CHGHG CHGHG= CHGDEBUG= hg debugshell -c \ + > 'ui.write(b"CHGHG=%s\n" % ui.environ.get(b"CHGHG"))' 2>&1 \ + > | egrep 'CHGHG|start' + chg: debug: * start cmdserver at * (glob) + CHGHG=/*/install/bin/hg (glob) + +Running the same command a second time shouldn't spawn a new command server. + $ HG=$CHGHG CHGHG= CHGDEBUG= hg debugshell -c \ + > 'ui.write(b"CHGHG=%s\n" % ui.environ.get(b"CHGHG"))' 2>&1 \ + > | egrep 'CHGHG|start' + CHGHG=/*/install/bin/hg (glob) diff -r e06331275a53 -r f57f5ab0e220 tests/test-fix.t --- a/tests/test-fix.t Fri Apr 28 12:12:42 2023 +0200 +++ b/tests/test-fix.t Tue May 09 11:35:50 2023 +0200 @@ -84,10 +84,11 @@ rewrite file content in changesets or working directory - Runs any configured tools to fix the content of files. Only affects files - with changes, unless file arguments are provided. Only affects changed - lines of files, unless the --whole flag is used. Some tools may always - affect the whole file regardless of --whole. + Runs any configured tools to fix the content of files. (See 'hg help -e + fix' for details about configuring tools.) Only affects files with + changes, unless file arguments are provided. Only affects changed lines of + files, unless the --whole flag is used. Some tools may always affect the + whole file regardless of --whole. If --working-dir is used, files with uncommitted changes in the working copy will be fixed. Note that no backup are made. @@ -125,6 +126,13 @@ Provides a command that runs configured tools on the contents of modified files, writing back any fixes to the working copy or replacing changesets. + Fixer tools are run in the repository's root directory. This allows them to + read configuration files from the working copy, or even write to the working + copy. The working copy is not updated to match the revision being fixed. In + fact, several revisions may be fixed in parallel. Writes to the working copy + are not amended into the revision being fixed; fixer tools MUST always read + content to be fixed from stdin, and write fixed file content back to stdout. + Here is an example configuration that causes 'hg fix' to apply automatic formatting fixes to modified lines in C++ code: @@ -231,13 +239,6 @@ executions that modified a file. This aggregates the same metadata previously passed to the "postfixfile" hook. - Fixer tools are run in the repository's root directory. This allows them to - read configuration files from the working copy, or even write to the working - copy. The working copy is not updated to match the revision being fixed. In - fact, several revisions may be fixed in parallel. Writes to the working copy - are not amended into the revision being fixed; fixer tools should always write - fixed file content back to stdout as documented above. - list of commands: fix rewrite file content in changesets or working directory diff -r e06331275a53 -r f57f5ab0e220 tests/test-pullling-to-general-delta.t --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/test-pullling-to-general-delta.t Tue May 09 11:35:50 2023 +0200 @@ -0,0 +1,196 @@ +============================================================================ +Pulling from modern to a non-general delta target (and other related checks) +============================================================================ + +There is various issue that can arise when we update the code with modern +storage in mind while working on delta processing. So this file is meant for +various scenario that might break in the future or have break in the past. + +Setup +===== + +Create a modern server with an older clone + + $ cat << EOF >> $HGRCPATH + > [command-templates] + > log = "{desc} {tags}\n" + > EOF + + $ hg init server + + $ hg clone --quiet --pull server client --config format.usegeneraldelta=no + $ hg debugformat -R client | grep generaldelta + generaldelta: no + +Create some complexe history + + $ cd server + $ hg debugbuilddag -n '.+3:a$.+5:b/a:k$.+7:c/b:l$.+6:d/a:m non-inline transition ---------------------------------------------------------- +We test various file length and naming pattern as this created issue in the +past. + Helper extension to intercept renames and kill process $ cat > $TESTTMP/intercept_before_rename.py << EOF @@ -76,13 +79,30 @@ $ hg init troffset-computation $ cd troffset-computation - $ printf '%20d' '1' > file + $ files=" + > file + > Directory_With,Special%Char/Complex_File.babar + > foo/bar/babar_celeste/foo + > 1234567890/1234567890/1234567890/1234567890/1234567890/1234567890/1234567890/1234567890/1234567890/1234567890/f + > " + $ for f in $files; do + > mkdir -p `dirname $f` + > done + $ for f in $files; do + > printf '%20d' '1' > $f + > done $ hg commit -Aqma - $ printf '%1024d' '1' > file + $ for f in $files; do + > printf '%1024d' '1' > $f + > done $ hg commit -Aqmb - $ printf '%20d' '1' > file + $ for f in $files; do + > printf '%20d' '1' > $f + > done $ hg commit -Aqmc - $ dd if=/dev/zero of=file bs=1k count=128 > /dev/null 2>&1 + $ for f in $files; do + > dd if=/dev/zero of=$f bs=1k count=128 > /dev/null 2>&1 + > done $ hg commit -AqmD --traceback Reference size: @@ -163,7 +183,7 @@ $ f -s .hg/store/data/file* .hg/store/data/file.i: size=1174 $ hg tip - changeset: 1:cfa8d6e60429 + changeset: 1:cc8dfb126534 tag: tip user: test date: Thu Jan 01 00:00:00 1970 +0000 @@ -233,7 +253,7 @@ $ f -s .hg/store/data/file* .hg/store/data/file.i: size=1174 $ hg tip - changeset: 1:cfa8d6e60429 + changeset: 1:cc8dfb126534 tag: tip user: test date: Thu Jan 01 00:00:00 1970 +0000 @@ -297,7 +317,7 @@ $ f -s .hg/store/data/file* .hg/store/data/file.i: size=1174 $ hg tip - changeset: 1:cfa8d6e60429 + changeset: 1:cc8dfb126534 tag: tip user: test date: Thu Jan 01 00:00:00 1970 +0000 @@ -337,7 +357,7 @@ $ hg tip - changeset: 1:cfa8d6e60429 + changeset: 1:cc8dfb126534 tag: tip user: test date: Thu Jan 01 00:00:00 1970 +0000