D11012: dirstate: add a function to update tracking status while "moving" parent
marmoute created this revision. Herald added a reviewer: hg-reviewers. Herald added a subscriber: mercurial-patches. REVISION SUMMARY The `scmutil.dirstateparent` is moving the dirstate parent without touching the working copy. It isi used by history rewriting operation like amending of folding. The function was doing "low level" computation and dirstate updating itself. All that logic belong to the dirstate and should be moved there. For this purpose we introduce a new function that does just that and use it. REPOSITORY rHG Mercurial BRANCH default REVISION DETAIL https://phab.mercurial-scm.org/D11012 AFFECTED FILES mercurial/dirstate.py mercurial/scmutil.py CHANGE DETAILS diff --git a/mercurial/scmutil.py b/mercurial/scmutil.py --- a/mercurial/scmutil.py +++ b/mercurial/scmutil.py @@ -1485,25 +1485,15 @@ copies = dict(ds.copies()) ds.setparents(newctx.node(), repo.nullid) s = newctx.status(oldctx, match=match) + for f in s.modified: -if ds[f] == b'r': -# modified + removed -> removed -continue -ds.normallookup(f) +ds.update_file_reference(f, p1_tracked=True) for f in s.added: -if ds[f] == b'r': -# added + removed -> unknown -ds.drop(f) -elif ds[f] != b'a': -ds.add(f) +ds.update_file_reference(f, p1_tracked=False) for f in s.removed: -if ds[f] == b'a': -# removed + added -> normal -ds.normallookup(f) -elif ds[f] != b'r': -ds.remove(f) +ds.update_file_reference(f, p1_tracked=True) # Merge old parent and old working dir copies oldcopies = copiesmod.pathcopies(newctx, oldctx, match) diff --git a/mercurial/dirstate.py b/mercurial/dirstate.py --- a/mercurial/dirstate.py +++ b/mercurial/dirstate.py @@ -440,6 +440,49 @@ def copies(self): return self._map.copymap +def update_file_reference( +self, +filename, +p1_tracked, +): +"""Set a file as tracked in the parent (or not) + +Thi is to be called when adjust the dirstate to a new parent after an history +rewriing operation. + +As per its function, it should not be called during a merge (p2 != +nullid) and only withing a `with dirstate.parentchange():` context. +""" +if self._parentwriters <= 0: +msg = ( +b'calling update_file_reference outside' +b' of a parentchange context' +) +raise error.ProgrammingError(msg) +elif self.in_merge: +msg = b'update_file_reference should not be called when merging' +raise error.ProgrammingError(msg) +entry = self._map.get(filename) +if entry is None: +wc_tracked = False +else: +wc_tracked = entry.tracked +if p1_tracked and wc_tracked: +# the underlying reference might have changed, we will have to +# check it. +self.normallookup(filename) +elif not (p1_tracked or wc_tracked): +# the file is no longer relevant to anyone +self.drop(filename) +elif (not p1_tracked) and wc_tracked: +if not entry.added: +self._add(filename) +elif p1_tracked and not wc_tracked: +if entry is None or not entry.removed: +self._remove(filename) +else: +assert False, 'unreachable' + def _addpath( self, f, To: marmoute, #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
D11011: dirstate: introduce and internal `_remove` method
marmoute created this revision. Herald added a reviewer: hg-reviewers. Herald added a subscriber: mercurial-patches. REVISION SUMMARY We want to reserver `dirstate.remove` to `hg remove`-like case and move to a clear API for update of the dirstate coming from update/merge. The first step is to introduce an internal function for this kind of operation. REPOSITORY rHG Mercurial BRANCH default REVISION DETAIL https://phab.mercurial-scm.org/D11011 AFFECTED FILES mercurial/dirstate.py CHANGE DETAILS diff --git a/mercurial/dirstate.py b/mercurial/dirstate.py --- a/mercurial/dirstate.py +++ b/mercurial/dirstate.py @@ -555,10 +555,14 @@ self._map.copymap.pop(filename, None) def remove(self, f): -'''Mark a file removed.''' +'''Mark a file removed''' +self._remove(f) + +def _remove(self, filename): +"""internal function to mark a file removed""" self._dirty = True -self._updatedfiles.add(f) -self._map.removefile(f, in_merge=self.in_merge) +self._updatedfiles.add(filename) +self._map.removefile(filename, in_merge=self.in_merge) def merge(self, f): '''Mark a file merged.''' To: marmoute, #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
D11010: dirstate: introduce and internal `_add` method
marmoute created this revision. Herald added a reviewer: hg-reviewers. Herald added a subscriber: mercurial-patches. REVISION SUMMARY We want to reserver `dirstate.add` to `hg add`-like case and move to a clear API for update of the dirstate coming from update/merge. The first step is to introduce an internal function for this kind of operation. REPOSITORY rHG Mercurial BRANCH default REVISION DETAIL https://phab.mercurial-scm.org/D11010 AFFECTED FILES mercurial/dirstate.py CHANGE DETAILS diff --git a/mercurial/dirstate.py b/mercurial/dirstate.py --- a/mercurial/dirstate.py +++ b/mercurial/dirstate.py @@ -387,7 +387,7 @@ source = self._map.copymap.get(f) if source: copies[f] = source -self.add(f) +self._add(f) return copies def setbranch(self, branch): @@ -547,8 +547,12 @@ def add(self, f): '''Mark a file added.''' -self._addpath(f, added=True) -self._map.copymap.pop(f, None) +self._add(f) + +def _add(self, filename): +"""internal function to mark a file as added""" +self._addpath(filename, added=True) +self._map.copymap.pop(filename, None) def remove(self, f): '''Mark a file removed.''' To: marmoute, #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
D11009: tests: demonstrate crash when common predecessor of divergence is hidden
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/D11009 AFFECTED FILES tests/test-amend.t CHANGE DETAILS diff --git a/tests/test-amend.t b/tests/test-amend.t --- a/tests/test-amend.t +++ b/tests/test-amend.t @@ -250,6 +250,32 @@ [10] $ hg amend -m divergent --config experimental.evolution.allowdivergence=true 2 new content-divergent changesets + +Hidden common predecessor of divergence does not cause crash + +First create C1 as a pruned successor of C + $ hg co C + 1 files updated, 0 files merged, 0 files removed, 0 files unresolved + $ hg amend -m C1 + $ hg tag --local C1 + $ hg debugobsolete $(hg log -T '{node}' -r C1) + 1 new obsolescence markers + obsoleted 1 changesets +Now create C2 as other side of divergence (not actually divergent because C1 is +pruned) + $ hg co C + 0 files updated, 0 files merged, 0 files removed, 0 files unresolved + $ hg amend -m C2 + 1 new orphan changesets +Make the common predecessor (C) pruned + $ hg tag --local --remove C + $ hg co C1 + 0 files updated, 0 files merged, 0 files removed, 0 files unresolved +Try to cause divergence + $ hg amend -m C11 + abort: filtered revision '26805aba1e600a82e93661149f2313866a221a7b' (known-bad-output !) + [255] + [10] #endif Cannot amend public changeset 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
D11006: remotefilelog: stop using RuntimeError for control flow
durin42 created this revision. Herald added a reviewer: hg-reviewers. Herald added a subscriber: mercurial-patches. REVISION SUMMARY We introduce a new exception to handle the various failure categories, rather than relying on RuntimeError. REPOSITORY rHG Mercurial BRANCH default REVISION DETAIL https://phab.mercurial-scm.org/D11006 AFFECTED FILES hgext/remotefilelog/basestore.py hgext/remotefilelog/shallowutil.py tests/test-remotefilelog-corrupt-cache.t CHANGE DETAILS diff --git a/tests/test-remotefilelog-corrupt-cache.t b/tests/test-remotefilelog-corrupt-cache.t --- a/tests/test-remotefilelog-corrupt-cache.t +++ b/tests/test-remotefilelog-corrupt-cache.t @@ -38,7 +38,7 @@ $ chmod u+w $CACHEDIR/master/11/f6ad8ec52a2984abaafd7c3b516503785c2072/1406e74118627694268417491f018a4a883152f0 $ echo x > $CACHEDIR/master/11/f6ad8ec52a2984abaafd7c3b516503785c2072/1406e74118627694268417491f018a4a883152f0 $ hg up tip 2>&1 | egrep "^[^ ].*unexpected remotefilelog" - RuntimeError: unexpected remotefilelog header: illegal format + hgext.remotefilelog.shallowutil.BadRemotefilelogHeader: unexpected remotefilelog header: illegal format Verify detection and remediation when remotefilelog.validatecachelog is set diff --git a/hgext/remotefilelog/shallowutil.py b/hgext/remotefilelog/shallowutil.py --- a/hgext/remotefilelog/shallowutil.py +++ b/hgext/remotefilelog/shallowutil.py @@ -233,6 +233,10 @@ return x +class BadRemotefilelogHeader(error.StorageError): +"""Exception raised when parsing a remotefilelog blob header fails.""" + + def parsesizeflags(raw): """given a remotefilelog blob, return (headersize, rawtextsize, flags) @@ -253,16 +257,20 @@ elif s.startswith(constants.METAKEYFLAG): flags = int(s[len(constants.METAKEYFLAG) :]) else: -raise RuntimeError( +raise BadRemotefilelogHeader( b'unsupported remotefilelog header: %s' % header ) else: # v0, str(int(size)) is the header size = int(header) except ValueError: -raise RuntimeError("unexpected remotefilelog header: illegal format") +raise BadRemotefilelogHeader( +"unexpected remotefilelog header: illegal format" +) if size is None: -raise RuntimeError("unexpected remotefilelog header: no size found") +raise BadRemotefilelogHeader( +"unexpected remotefilelog header: no size found" +) return index + 1, size, flags diff --git a/hgext/remotefilelog/basestore.py b/hgext/remotefilelog/basestore.py --- a/hgext/remotefilelog/basestore.py +++ b/hgext/remotefilelog/basestore.py @@ -308,7 +308,7 @@ # Content matches the intended path return True return False -except (ValueError, RuntimeError): +except (ValueError, shallowutil.BadRemotefilelogHeader): pass return False To: durin42, #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
D11008: shallowutil: dedent code after the previous change
durin42 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/D11008 AFFECTED FILES hgext/remotefilelog/shallowutil.py CHANGE DETAILS diff --git a/hgext/remotefilelog/shallowutil.py b/hgext/remotefilelog/shallowutil.py --- a/hgext/remotefilelog/shallowutil.py +++ b/hgext/remotefilelog/shallowutil.py @@ -251,23 +251,22 @@ raise BadRemotefilelogHeader( "unexpected remotefilelog header: illegal format" ) -if True: -header = raw[:index] -if header.startswith(b'v'): -# v1 and above, header starts with 'v' -if header.startswith(b'v1\n'): -for s in header.split(b'\n'): -if s.startswith(constants.METAKEYSIZE): -size = int(s[len(constants.METAKEYSIZE) :]) -elif s.startswith(constants.METAKEYFLAG): -flags = int(s[len(constants.METAKEYFLAG) :]) -else: -raise BadRemotefilelogHeader( -b'unsupported remotefilelog header: %s' % header -) +header = raw[:index] +if header.startswith(b'v'): +# v1 and above, header starts with 'v' +if header.startswith(b'v1\n'): +for s in header.split(b'\n'): +if s.startswith(constants.METAKEYSIZE): +size = int(s[len(constants.METAKEYSIZE) :]) +elif s.startswith(constants.METAKEYFLAG): +flags = int(s[len(constants.METAKEYFLAG) :]) else: -# v0, str(int(size)) is the header -size = int(header) +raise BadRemotefilelogHeader( +b'unsupported remotefilelog header: %s' % header +) +else: +# v0, str(int(size)) is the header +size = int(header) if size is None: raise BadRemotefilelogHeader( "unexpected remotefilelog header: no size found" To: durin42, #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
D11007: shallowutil: narrow scope of try/except block
durin42 created this revision. Herald added a reviewer: hg-reviewers. Herald added a subscriber: mercurial-patches. REVISION SUMMARY This will make this code easier to understand in the future. REPOSITORY rHG Mercurial BRANCH default REVISION DETAIL https://phab.mercurial-scm.org/D11007 AFFECTED FILES hgext/remotefilelog/shallowutil.py CHANGE DETAILS diff --git a/hgext/remotefilelog/shallowutil.py b/hgext/remotefilelog/shallowutil.py --- a/hgext/remotefilelog/shallowutil.py +++ b/hgext/remotefilelog/shallowutil.py @@ -247,6 +247,11 @@ size = None try: index = raw.index(b'\0') +except ValueError: +raise BadRemotefilelogHeader( +"unexpected remotefilelog header: illegal format" +) +if True: header = raw[:index] if header.startswith(b'v'): # v1 and above, header starts with 'v' @@ -263,10 +268,6 @@ else: # v0, str(int(size)) is the header size = int(header) -except ValueError: -raise BadRemotefilelogHeader( -"unexpected remotefilelog header: illegal format" -) if size is None: raise BadRemotefilelogHeader( "unexpected remotefilelog header: no size found" To: durin42, #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
D11005: remotefilelog: tweak corrupt cache test to grep more flexibly
durin42 created this revision. Herald added a reviewer: hg-reviewers. Herald added a subscriber: mercurial-patches. REVISION SUMMARY I'm about to fix the abuse of RuntimeError here, which breaks the test if I don't do this. REPOSITORY rHG Mercurial BRANCH default REVISION DETAIL https://phab.mercurial-scm.org/D11005 AFFECTED FILES tests/test-remotefilelog-corrupt-cache.t CHANGE DETAILS diff --git a/tests/test-remotefilelog-corrupt-cache.t b/tests/test-remotefilelog-corrupt-cache.t --- a/tests/test-remotefilelog-corrupt-cache.t +++ b/tests/test-remotefilelog-corrupt-cache.t @@ -37,7 +37,7 @@ > EOF $ chmod u+w $CACHEDIR/master/11/f6ad8ec52a2984abaafd7c3b516503785c2072/1406e74118627694268417491f018a4a883152f0 $ echo x > $CACHEDIR/master/11/f6ad8ec52a2984abaafd7c3b516503785c2072/1406e74118627694268417491f018a4a883152f0 - $ hg up tip 2>&1 | egrep "^RuntimeError" + $ hg up tip 2>&1 | egrep "^[^ ].*unexpected remotefilelog" RuntimeError: unexpected remotefilelog header: illegal format Verify detection and remediation when remotefilelog.validatecachelog is set To: durin42, #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
D11001: run-tests: also catch double-escapes for $TESTTMP
Alphare 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/D11001 AFFECTED FILES tests/run-tests.py tests/test-paths.t CHANGE DETAILS diff --git a/tests/test-paths.t b/tests/test-paths.t --- a/tests/test-paths.t +++ b/tests/test-paths.t @@ -98,9 +98,15 @@ expand: $TESTTMP/a/$SOMETHING/bar $ hg log -rnull -T '{get(peerurls, "dupe")}\n' $TESTTMP/b#tip +#if windows + $ hg log -rnull -T '{peerurls % "{urls|json}\n"}' + [{"pushurl": "https://example.com/dupe;, "url": "$TESTTMP\\b#tip"}] + [{"url": "$TESTTMP\\a\\$SOMETHING\\bar"}] +#else $ hg log -rnull -T '{peerurls % "{urls|json}\n"}' [{"pushurl": "https://example.com/dupe;, "url": "$TESTTMP/b#tip"}] [{"url": "$TESTTMP/a/$SOMETHING/bar"}] +#endif (sub options can be populated by map/dot operation) diff --git a/tests/run-tests.py b/tests/run-tests.py --- a/tests/run-tests.py +++ b/tests/run-tests.py @@ -1308,6 +1308,12 @@ (br'\bHG_TXNID=TXN:[a-f0-9]{40}\b', br'HG_TXNID=TXN:$ID$'), ] r.append((self._escapepath(self._testtmp), b'$TESTTMP')) +if os.name == 'nt': +# JSON output escapes backslashes in Windows paths, so also catch a +# double-escape. +r.append( +(self._escapepath(self._testtmp.replace(b'\\', br'\\')), b'$TESTTMP') +) replacementfile = os.path.join(self._testdir, b'common-pattern.py') To: Alphare, #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
D11004: test-run-tests: add missing backslash for Windows
Alphare 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/D11004 AFFECTED FILES tests/test-run-tests.t CHANGE DETAILS diff --git a/tests/test-run-tests.t b/tests/test-run-tests.t --- a/tests/test-run-tests.t +++ b/tests/test-run-tests.t @@ -1406,7 +1406,7 @@ > - \$RUNTESTDIR, in which run-tests.py is placed (expanded at runtime) > > #if windows - > $ test "\$TESTDIR" = "$TESTTMP\anothertests" + > $ test "\$TESTDIR" = "$TESTTMP\\anothertests" > #else > $ test "\$TESTDIR" = "$TESTTMP"/anothertests > #endif To: Alphare, #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
D11003: windows: use cpu-intensive task instead of real time in test
Alphare created this revision. Herald added a reviewer: hg-reviewers. Herald added a subscriber: mercurial-patches. REVISION SUMMARY Windows profiling breaks when using real time instead of cpu, but we need the extension function to show up, so make it do something instead of waiting. I've also duplicated the test cases so that explicit real and CPU times are tested (on platforms other than Windows) REPOSITORY rHG Mercurial BRANCH default REVISION DETAIL https://phab.mercurial-scm.org/D11003 AFFECTED FILES tests/test-profile.t CHANGE DETAILS diff --git a/tests/test-profile.t b/tests/test-profile.t --- a/tests/test-profile.t +++ b/tests/test-profile.t @@ -73,7 +73,9 @@ > command = registrar.command(cmdtable) > @command(b'sleep', [], b'hg sleep') > def sleep_for_at_least_one_stat_cycle(ui, *args, **kwargs): - > time.sleep(0.1) + > t = time.time() # don't use time.sleep because we need CPU time + > while time.time() - t < 0.5: + > pass > EOF $ cat >> $HGRCPATH << EOF @@ -100,10 +102,19 @@ % cumulative self $ cat ../out | statprofran - $ hg --profile --config profiling.statformat=hotpath sleep 2>../out || cat ../out +Windows real time tracking is broken, only use CPU + +#if no-windows + $ hg --profile --config profiling.time-track=real --config profiling.statformat=hotpath sleep 2>../out || cat ../out $ cat ../out | statprofran - $ grep sleepext_with_a_long_filename.py ../out - .* [0-9.]+% [0-9.]+s sleepext_with_a_long_filename.py:\s*sleep_for_at_least_one_stat_cycle, line 7: time\.sleep.* (re) + $ grep sleepext_with_a_long_filename.py ../out | head -n 1 + .* [0-9.]+% [0-9.]+s sleepext_with_a_long_filename.py:\s*sleep_for_at_least_one_stat_cycle, line \d+:\s+(while|pass).* (re) +#endif + + $ hg --profile --config profiling.time-track=cpu --config profiling.statformat=hotpath sleep 2>../out || cat ../out + $ cat ../out | statprofran + $ grep sleepext_with_a_long_filename.py ../out | head -n 1 + .* [0-9.]+% [0-9.]+s sleepext_with_a_long_filename.py:\s*sleep_for_at_least_one_stat_cycle, line \d+:\s+(while|pass).* (re) $ hg --profile --config profiling.statformat=json sleep 2>../out || cat ../out $ cat ../out To: Alphare, #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
D11002: windows: use shell function instead of variable substitution
Alphare created this revision. Herald added a reviewer: hg-reviewers. Herald added a subscriber: mercurial-patches. REVISION SUMMARY This makes it compatible with Windows REPOSITORY rHG Mercurial BRANCH default REVISION DETAIL https://phab.mercurial-scm.org/D11002 AFFECTED FILES tests/test-profile.t CHANGE DETAILS diff --git a/tests/test-profile.t b/tests/test-profile.t --- a/tests/test-profile.t +++ b/tests/test-profile.t @@ -23,27 +23,29 @@ #if lsprof - $ prof='hg --config profiling.type=ls --profile' + $ prof () { + > hg --config profiling.type=ls --profile $@ + > } - $ $prof st 2>../out + $ prof st 2>../out $ grep CallCount ../out > /dev/null || cat ../out - $ $prof --config profiling.output=../out st + $ prof --config profiling.output=../out st $ grep CallCount ../out > /dev/null || cat ../out - $ $prof --config profiling.output=blackbox --config extensions.blackbox= st + $ prof --config profiling.output=blackbox --config extensions.blackbox= st $ grep CallCount .hg/blackbox.log > /dev/null || cat .hg/blackbox.log - $ $prof --config profiling.format=text st 2>../out + $ prof --config profiling.format=text st 2>../out $ grep CallCount ../out > /dev/null || cat ../out $ echo "[profiling]" >> $HGRCPATH $ echo "format=kcachegrind" >> $HGRCPATH - $ $prof st 2>../out + $ prof st 2>../out $ grep 'events: Ticks' ../out > /dev/null || cat ../out - $ $prof --config profiling.output=../out st + $ prof --config profiling.output=../out st $ grep 'events: Ticks' ../out > /dev/null || cat ../out #endif @@ -52,7 +54,7 @@ Profiling of HTTP requests works - $ $prof --config profiling.format=text --config profiling.output=../profile.log serve -d -p $HGPORT --pid-file ../hg.pid -A ../access.log + $ prof --config profiling.format=text --config profiling.output=../profile.log serve -d -p $HGPORT --pid-file ../hg.pid -A ../access.log $ cat ../hg.pid >> $DAEMON_PIDS $ hg -q clone -U http://localhost:$HGPORT ../clone To: Alphare, #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
D11000: windows: add windows behavior on broken pager
Alphare created this revision. Herald added a reviewer: hg-reviewers. Herald added a subscriber: mercurial-patches. REVISION SUMMARY Apparently, Windows has "better" behavior than Unix in this case. This is an edge case that led me down a rabbit hole, only to find a bug in the Python documentation... I am not planning on trying to reproduce the same behavior on Unix systems since it's not really useful, but other people are welcome to! REPOSITORY rHG Mercurial BRANCH default REVISION DETAIL https://phab.mercurial-scm.org/D11000 AFFECTED FILES tests/test-pager.t CHANGE DETAILS diff --git a/tests/test-pager.t b/tests/test-pager.t --- a/tests/test-pager.t +++ b/tests/test-pager.t @@ -219,10 +219,32 @@ #endif A complicated pager command gets worse behavior. Bonus points if you can -improve this. +improve this. Windows apparently does this better? +#if windows $ hg log --limit 3 \ > --config pager.pager='this-command-better-never-exist --seriously' \ > 2>/dev/null || true + \x1b[0;33mchangeset: 10:46106edeeb38\x1b[0m (esc) + tag: tip + user:test + date:Thu Jan 01 00:00:00 1970 + + summary: modify a 10 + + \x1b[0;33mchangeset: 9:6dd8ea7dd621\x1b[0m (esc) + user:test + date:Thu Jan 01 00:00:00 1970 + + summary: modify a 9 + + \x1b[0;33mchangeset: 8:cff05a6312fe\x1b[0m (esc) + user:test + date:Thu Jan 01 00:00:00 1970 + + summary: modify a 8 + +#else + $ hg log --limit 3 \ + > --config pager.pager='this-command-better-never-exist --seriously' \ + > 2>/dev/null || true +#endif Pager works with shell aliases. To: Alphare, #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
D10999: compat: normalise path before comparison in revlog splitting test
Alphare created this revision. Herald added a reviewer: hg-reviewers. Herald added a subscriber: mercurial-patches. REVISION SUMMARY This fixes the test on Window. REPOSITORY rHG Mercurial BRANCH default REVISION DETAIL https://phab.mercurial-scm.org/D10999 AFFECTED FILES tests/test-transaction-rollback-on-revlog-split.t CHANGE DETAILS diff --git a/tests/test-transaction-rollback-on-revlog-split.t b/tests/test-transaction-rollback-on-revlog-split.t --- a/tests/test-transaction-rollback-on-revlog-split.t +++ b/tests/test-transaction-rollback-on-revlog-split.t @@ -10,14 +10,13 @@ > > def extsetup(ui): > def close(orig, *args, **kwargs): - > path = args[0]._atomictempfile__name + > path = util.normpath(args[0]._atomictempfile__name) > if path.endswith(b'/.hg/store/data/file.i'): > os._exit(80) > return orig(*args, **kwargs) > extensions.wrapfunction(util.atomictempfile, 'close', close) > EOF - Test offset computation to correctly factor in the index entries themselve. Also test that the new data size has the correct size if the transaction is aborted after the index has been replaced. To: Alphare, #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
D10998: windows: replicate the normalizing behavior of os.environ
Alphare created this revision. Herald added a reviewer: hg-reviewers. Herald added a subscriber: mercurial-patches. REVISION SUMMARY On Windows, `os.environ` normalizes environment variables to uppercase. Our current bytes-based environ substitution object is a simple dict, so we add the normalization behavior. This changed needed `upper` to be defined higher, I moved `upper` and `lower` together. This fixes test-http-peer.t on Windows. REPOSITORY rHG Mercurial BRANCH default REVISION DETAIL https://phab.mercurial-scm.org/D10998 AFFECTED FILES mercurial/encoding.py CHANGE DETAILS diff --git a/mercurial/encoding.py b/mercurial/encoding.py --- a/mercurial/encoding.py +++ b/mercurial/encoding.py @@ -284,13 +284,73 @@ strmethod = pycompat.identity + +def lower(s): +# type: (bytes) -> bytes +"""best-effort encoding-aware case-folding of local string s""" +try: +return asciilower(s) +except UnicodeDecodeError: +pass +try: +if isinstance(s, localstr): +u = s._utf8.decode("utf-8") +else: +u = s.decode(_sysstr(encoding), _sysstr(encodingmode)) + +lu = u.lower() +if u == lu: +return s # preserve localstring +return lu.encode(_sysstr(encoding)) +except UnicodeError: +return s.lower() # we don't know how to fold this except in ASCII +except LookupError as k: +raise error.Abort(k, hint=b"please check your locale settings") + + +def upper(s): +# type: (bytes) -> bytes +"""best-effort encoding-aware case-folding of local string s""" +try: +return asciiupper(s) +except UnicodeDecodeError: +return upperfallback(s) + + +def upperfallback(s): +# type: (Any) -> Any +try: +if isinstance(s, localstr): +u = s._utf8.decode("utf-8") +else: +u = s.decode(_sysstr(encoding), _sysstr(encodingmode)) + +uu = u.upper() +if u == uu: +return s # preserve localstring +return uu.encode(_sysstr(encoding)) +except UnicodeError: +return s.upper() # we don't know how to fold this except in ASCII +except LookupError as k: +raise error.Abort(k, hint=b"please check your locale settings") + + if not _nativeenviron: # now encoding and helper functions are available, recreate the environ # dict to be exported to other modules -environ = { -tolocal(k.encode('utf-8')): tolocal(v.encode('utf-8')) -for k, v in os.environ.items() # re-exports -} +if pycompat.iswindows and pycompat.ispy3: + +class WindowsEnviron(dict): +"""`os.environ` normalizes environment variables to uppercase on windows""" + +def get(self, key, default=None): +return super().get(upper(key), default) + +environ = WindowsEnviron() + +for k, v in os.environ.items(): # re-exports +environ[tolocal(k.encode('utf-8'))] = tolocal(v.encode('utf-8')) + if pycompat.ispy3: # os.getcwd() on Python 3 returns string, but it has os.getcwdb() which @@ -441,56 +501,6 @@ return ellipsis # no enough room for multi-column characters -def lower(s): -# type: (bytes) -> bytes -"""best-effort encoding-aware case-folding of local string s""" -try: -return asciilower(s) -except UnicodeDecodeError: -pass -try: -if isinstance(s, localstr): -u = s._utf8.decode("utf-8") -else: -u = s.decode(_sysstr(encoding), _sysstr(encodingmode)) - -lu = u.lower() -if u == lu: -return s # preserve localstring -return lu.encode(_sysstr(encoding)) -except UnicodeError: -return s.lower() # we don't know how to fold this except in ASCII -except LookupError as k: -raise error.Abort(k, hint=b"please check your locale settings") - - -def upper(s): -# type: (bytes) -> bytes -"""best-effort encoding-aware case-folding of local string s""" -try: -return asciiupper(s) -except UnicodeDecodeError: -return upperfallback(s) - - -def upperfallback(s): -# type: (Any) -> Any -try: -if isinstance(s, localstr): -u = s._utf8.decode("utf-8") -else: -u = s.decode(_sysstr(encoding), _sysstr(encodingmode)) - -uu = u.upper() -if u == uu: -return s # preserve localstring -return uu.encode(_sysstr(encoding)) -except UnicodeError: -return s.upper() # we don't know how to fold this except in ASCII -except LookupError as k: -raise error.Abort(k, hint=b"please check your locale settings") - - class normcasespecs(object): """what a platform's normcase does to ASCII strings To: Alphare, #hg-reviewers Cc: mercurial-patches, mercurial-devel ___ Mercurial-devel mailing list