[Bug 5494] New: resolve --list continues to display results after rebase completes
https://bz.mercurial-scm.org/show_bug.cgi?id=5494 Bug ID: 5494 Summary: resolve --list continues to display results after rebase completes Product: Mercurial Version: 4.1-rc Hardware: All OS: All Status: UNCONFIRMED Severity: bug Priority: wish Component: rebase Assignee: bugzi...@mercurial-scm.org Reporter: r...@fb.com CC: mercurial-devel@mercurial-scm.org In some circumstances after a rebase, the merge state is not properly removed, and `hg resolve --list` continues to show files as "resolved" when there should no longer be a merge state at all. This inside of a test file reproduces the problem: """ $ cat >> $HGRCPATH < [extensions] > rebase= > EOF $ hg init repo $ cd repo $ echo a >> a $ hg commit -qAm base $ echo b >> a $ hg commit -qm b $ hg up .^ 1 files updated, 0 files merged, 0 files removed, 0 files unresolved $ echo c >> a $ hg commit -qm c $ hg rebase -s 1 -d 2 --noninteractive rebasing 1:fdaca8533b86 "b" merging a warning: conflicts while merging a! (edit, then use 'hg resolve --mark') unresolved conflicts (see hg resolve, then hg rebase --continue) [1] $ echo a > a $ echo c >> a $ hg resolve --mark a (no more unresolved files) continue: hg rebase --continue $ hg rebase --continue rebasing 1:fdaca8533b86 "b" note: rebase of 1:fdaca8533b86 created no changes to commit saved backup bundle to $TESTTMP/repo/.hg/strip-backup/fdaca8533b86-7fd70513-backup.hg (glob) $ hg resolve --list R a $ ls .hg/merge 86f7e437faa5a7fce15d1ddcb9eaeaea377667b8 state state2 """ Note that .hg/merge should have been deleted but it wasn't, and that the user-visible error here is that `hg resolve --list` shows a file when there should be no merge state at all. -- You are receiving this mail because: You are on the CC list for the bug. ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Re: [PATCH 1 of 5] transaction: introduce scope
I'm going to drop this series from patchwork. The new dirstate patches is a better fix. Excerpts from Jun Wu's message of 2017-02-27 09:35:25 -0800: > # HG changeset patch > # User Jun Wu > # Date 1488185788 28800 > # Mon Feb 27 00:56:28 2017 -0800 > # Node ID 5dac612ec9a87553fcd329100846bcb01bae9d80 > # Parent b4cb86ab4c719eb615a4308eafd8b1386a511eeb > # Available At https://bitbucket.org/quark-zju/hg-draft > # hg pull https://bitbucket.org/quark-zju/hg-draft -r > 5dac612ec9a8 > transaction: introduce scope > > Previously, transaction tries to cover everything: bookmarks, dirstate, > phaseroots, and branch. It backs them up unconditionally. > > That could be inefficient if we still back up the dirstate in a giant repo, > where the transaction is only intended to change bookmarks. > > This patch introduces "scope" to transactions, which is a set of things that > the transaction should cover. For bookmark-only update, it could avoid > specifying the "dirstate" scope to be more efficient. > > diff --git a/mercurial/transaction.py b/mercurial/transaction.py > --- a/mercurial/transaction.py > +++ b/mercurial/transaction.py > @@ -102,5 +102,6 @@ def _playback(journal, report, opener, v > class transaction(object): > def __init__(self, report, opener, vfsmap, journalname, undoname=None, > - after=None, createmode=None, validator=None, > releasefn=None): > + after=None, createmode=None, validator=None, releasefn=None, > + scope=None): > """Begin a new transaction > > @@ -111,4 +112,5 @@ class transaction(object): > * `createmode`: the mode of the journal file that will be created > * `releasefn`: called after releasing (with transaction and result) > +* `scope`: a set-like, nested transaction's scope must be a subset > """ > self.count = 1 > @@ -171,4 +173,7 @@ class transaction(object): > self._abortcallback = {} > > +# a set indicating what's covered > +self._scope = scope or frozenset() > + > def __del__(self): > if self.journal: > @@ -342,5 +347,10 @@ class transaction(object): > > @active > -def nest(self): > +def nest(self, scope=None): > +scope = scope or frozenset() > +if not scope.issubset(self._scope): > +raise error.ProgrammingError( > +'nested transaction has a superset scope (%s > %s)' > +% (scope, self._scope)) > self.count += 1 > self.usages += 1 > @@ -555,4 +565,7 @@ class transaction(object): > self.releasefn(self, False) # notify failure of transaction > > +def scope(self): > +return self._scope > + > def rollback(opener, vfsmap, file, report): > """Rolls back the transaction contained in the given file ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Re: [PATCH 2 of 2] dirstate: avoid unnecessary load+dump during backup
On 3/1/17 7:08 PM, Jun Wu wrote: # HG changeset patch # User Jun Wu # Date 1488421266 28800 # Wed Mar 01 18:21:06 2017 -0800 # Node ID c1f380ab1539b0dc0bd05f0ef2eb15b827453dbc # Parent 1e74c8187c9b98644ae35902c9e3faddad00f364 # Available At https://urldefense.proofpoint.com/v2/url?u=https-3A__bitbucket.org_quark-2Dzju_hg-2Ddraft&d=DwIGaQ&c=5VD0RTtNlTh3ycd41b3MUw&r=nuarHzhP1wi1T9iURRCj1A&m=Ltv4ypjmHC_b3dl-wNJ14scVlgAc4XjMCbW9vkwrU8s&s=ah37F78Eb6TE15sHQ44HEY-Aa1RpuecRnTgtRLmB_fA&e= # hg pull https://urldefense.proofpoint.com/v2/url?u=https-3A__bitbucket.org_quark-2Dzju_hg-2Ddraft&d=DwIGaQ&c=5VD0RTtNlTh3ycd41b3MUw&r=nuarHzhP1wi1T9iURRCj1A&m=Ltv4ypjmHC_b3dl-wNJ14scVlgAc4XjMCbW9vkwrU8s&s=ah37F78Eb6TE15sHQ44HEY-Aa1RpuecRnTgtRLmB_fA&e= -r c1f380ab1539 dirstate: avoid unnecessary load+dump during backup Previously, dirstate.savebackup unconditionally dumps the dirstate map to disk. It may require loading dirstate first to be able to dump it. Those operations could be expensive if the dirstate is big, and could be avoided if we know the dirstate file is up-to-date. This patch avoids the read and write if the dirstate is clean. In that case, we just do a plain copy without any serialization. This should make commands which use transactions but do not touch dirstate faster. For example, "hg bookmark -r REV NAME". I wish we had macros in emails so I could say: superlike ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
[PATCH] revert: remove set(mf) because it's O(repo)
# HG changeset patch # User Durham Goode # Date 1488426665 28800 # Wed Mar 01 19:51:05 2017 -0800 # Node ID a8458fe51a9d155f1daeaffdcf503e674d4d4588 # Parent b787c41767339158927232ec7a9092196e887453 revert: remove set(mf) because it's O(repo) The revert code had a 'set(manifest)' line in it, which has a runtime equivalent to the size of the working copy. With alternative manifest implementations, like treemanifest, this can be extra expensive. Let's rewrite it to be O(changes) instead of O(working copy size). diff --git a/mercurial/cmdutil.py b/mercurial/cmdutil.py --- a/mercurial/cmdutil.py +++ b/mercurial/cmdutil.py @@ -2977,10 +2977,12 @@ def revert(ui, repo, ctx, parents, *pats modadded = set() # split between files known in target manifest and the others -smf = set(mf) # determine the exact nature of the deleted changesets -deladded = _deleted - smf +deladded = set(_deleted) +for path in _deleted: +if path in mf: +deladded.remove(path) deleted = _deleted - deladded # We need to account for the state of the file in the dirstate, @@ -3024,7 +3026,10 @@ def revert(ui, repo, ctx, parents, *pats # in case of merge, files that are actually added can be reported as # modified, we need to post process the result if p2 != nullid: -mergeadd = dsmodified - smf +mergeadd = set(dsmodified) +for path in dsmodified: +if path in mf: +mergeadd.remove(path) dsadded |= mergeadd dsmodified -= mergeadd ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
[PATCH 1 of 2] dirstate: try to use hardlink to backup dirstate
# HG changeset patch # User Jun Wu # Date 1488419961 28800 # Wed Mar 01 17:59:21 2017 -0800 # Node ID 1e74c8187c9b98644ae35902c9e3faddad00f364 # Parent 0bb3089fe73527c64f1afc40b86ecb8dfe7fd7aa # Available At https://bitbucket.org/quark-zju/hg-draft # hg pull https://bitbucket.org/quark-zju/hg-draft -r 1e74c8187c9b dirstate: try to use hardlink to backup dirstate This should be more efficient once util.copyfile has real hardlink support. diff --git a/mercurial/dirstate.py b/mercurial/dirstate.py --- a/mercurial/dirstate.py +++ b/mercurial/dirstate.py @@ -1225,6 +1225,12 @@ class dirstate(object): tr.registertmp(filename, location='plain') -self._opener.write(prefix + self._filename + suffix, - self._opener.tryread(filename)) +backupname = prefix + self._filename + suffix +assert backupname != filename +if self._opener.exists(backupname): +self._opener.unlink(backupname) +# hardlink backup is okay because _writedirstate is always called +# with an "atomictemp=True" file. +util.copyfile(self._opener.join(filename), + self._opener.join(backupname), hardlink=True) def restorebackup(self, tr, suffix='', prefix=''): diff --git a/tests/test-largefiles-small-disk.t b/tests/test-largefiles-small-disk.t --- a/tests/test-largefiles-small-disk.t +++ b/tests/test-largefiles-small-disk.t @@ -6,5 +6,9 @@ Test how largefiles abort in case the di > # > # this makes the original largefiles code abort: + > _origcopyfileobj = shutil.copyfileobj > def copyfileobj(fsrc, fdst, length=16*1024): + > # allow journal files (used by transaction) to be written + > if 'journal.' in fdst.name: + > return _origcopyfileobj(fsrc, fdst, length) > fdst.write(fsrc.read(4)) > raise IOError(errno.ENOSPC, os.strerror(errno.ENOSPC)) ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
[PATCH 2 of 2] dirstate: avoid unnecessary load+dump during backup
# HG changeset patch # User Jun Wu # Date 1488421266 28800 # Wed Mar 01 18:21:06 2017 -0800 # Node ID c1f380ab1539b0dc0bd05f0ef2eb15b827453dbc # Parent 1e74c8187c9b98644ae35902c9e3faddad00f364 # Available At https://bitbucket.org/quark-zju/hg-draft # hg pull https://bitbucket.org/quark-zju/hg-draft -r c1f380ab1539 dirstate: avoid unnecessary load+dump during backup Previously, dirstate.savebackup unconditionally dumps the dirstate map to disk. It may require loading dirstate first to be able to dump it. Those operations could be expensive if the dirstate is big, and could be avoided if we know the dirstate file is up-to-date. This patch avoids the read and write if the dirstate is clean. In that case, we just do a plain copy without any serialization. This should make commands which use transactions but do not touch dirstate faster. For example, "hg bookmark -r REV NAME". diff --git a/mercurial/dirstate.py b/mercurial/dirstate.py --- a/mercurial/dirstate.py +++ b/mercurial/dirstate.py @@ -1210,6 +1210,7 @@ class dirstate(object): # because the latter omits writing out if transaction is running. # output file will be used to create backup of dirstate at this point. -self._writedirstate(self._opener(filename, "w", atomictemp=True, - checkambig=True)) +if self._dirty or not self._opener.exists(filename): +self._writedirstate(self._opener(filename, "w", atomictemp=True, + checkambig=True)) if tr: ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
[PATCH] help: fix internals.changegroups
# HG changeset patch # User Kyle Lippincott # Date 1488422254 28800 # Wed Mar 01 18:37:34 2017 -0800 # Node ID f39bcd3a0f6d7c2e68948020c243ee53138db7bd # Parent 0bb3089fe73527c64f1afc40b86ecb8dfe7fd7aa help: fix internals.changegroups Add information about tree manifests, copy edit the text and fix up a few ambiguities. The document also contains a few additional fixes from Siddharth Agarwal , who used it to build a parser for changegroups in Rust. diff --git a/mercurial/help/internals/changegroups.txt b/mercurial/help/internals/changegroups.txt --- a/mercurial/help/internals/changegroups.txt +++ b/mercurial/help/internals/changegroups.txt @@ -1,35 +1,49 @@ Changegroups are representations of repository revlog data, specifically -the changelog, manifest, and filelogs. +the changelog data, root/flat manifest data, treemanifest data, and +filelogs. There are 3 versions of changegroups: ``1``, ``2``, and ``3``. From a -high-level, versions ``1`` and ``2`` are almost exactly the same, with -the only difference being a header on entries in the changeset -segment. Version ``3`` adds support for exchanging treemanifests and -includes revlog flags in the delta header. +high-level, versions ``1`` and ``2`` are almost exactly the same, with the +only difference being an additional item in the *delta header*. Version +``3`` adds support for revlog flags in the *delta header* and optionally +exchanging treemanifests (enabled by setting an option on the +``changegroup`` part in the bundle2). -Changegroups consists of 3 logical segments:: +Changegroups when not exchanging treemanifests consist of 3 logical +segments:: +-+ | | | | | changeset | manifest | filelogs | | | | | + | | | | +-+ +When exchanging treemanifests, there are 4 logical segments:: + + +-+ + | | | | | + | changeset | root | treemanifests | filelogs | + | | manifest | | | + | | | | | + +-+ + The principle building block of each segment is a *chunk*. A *chunk* is a framed piece of data:: +---+ | | | | length | data| - | (32 bits) |bytes | + | (4 bytes) | ( bytes)| | | | +---+ -Each chunk starts with a 32-bit big-endian signed integer indicating -the length of the raw data that follows. +All integers are big-endian signed integers. Each chunk starts with a 32-bit +integer indicating the length of the entire chunk (including the length field +itself). -There is a special case chunk that has 0 length (``0x``). We -call this an *empty chunk*. +There is a special case chunk that has a value of 0 for the length +(``0x``). We call this an *empty chunk*. Delta Groups @@ -43,26 +57,27 @@ to signal the end of the delta group:: ++ || | | | | | chunk0 length | chunk0 data | chunk1 length | chunk1 data |0x0| - | (32 bits)| (various) | (32 bits) | (various) | (32 bits) | + | (4 bytes)| (various) | (4 bytes) | (various) | (4 bytes) | || | | | | - ++---+ + ++ Each *chunk*'s data consists of the following:: - +-+ - | | | | - | delta header | mdiff header | delta | - | (various) | (12 bytes) | (various) | - | | | | - +-+ + +---+ + || | + | delta header | delta data | + | (various by version) | (various) | + || | + +---+ -The *length* field is the byte length of the remaining 3 logical pieces -of data. The *delta* is a diff from an existing entry in the changelog. +The *delta data* is a series of *delta*s that describe a diff from an existing +entry (either that the recipient already has, or previously specified in the +bundlei/changegroup). The *delta header* is different between versions ``1``, ``2``, and ``3`` of the changegroup format. -Version 1:: +Version 1 (headerlen=80)::
Re: [PATCH 11 of 11 V5] update: allow setting default update check to "noconflict"
I've reviwed the rest of the series and it looks good to me. On 3/1/17 12:41 PM, Martin von Zweigbergk wrote: On Wed, Mar 1, 2017 at 11:54 AM, Ryan McElroy wrote: I'm a very big +1 on this direction -- this is a huge usability improvment. Facebook currently adds a "--nocheck" flag and turns on "check" by default in our "tweakdefaults" extension, but this direction is strictly better than that and we will definitely switch over to this "noconflict" functionality once it gets into core. I even volunteer to do the work to remove the "nocheck" stuff from tweakdefaults and all that. Thanks a ton for working on this Martin! Great to hear it will be sufficient to replace that part of tweakdefaults. On 2/27/17 4:31 PM, Martin von Zweigbergk via Mercurial-devel wrote: # HG changeset patch # User Martin von Zweigbergk # Date 1486973155 28800 # Mon Feb 13 00:05:55 2017 -0800 # Node ID c88aa4bc36ee81b0837d2949501d6b4fcf825c38 # Parent ae37f4578e3af6fd4cb7c29c9ab06ad0efd726da update: allow setting default update check to "noconflict" The new value allows update (linear or not) as long as they don't result in file merges. I'm hoping that this value can some day become the default. diff -r ae37f4578e3a -r c88aa4bc36ee mercurial/hg.py --- a/mercurial/hg.py Mon Feb 13 16:03:05 2017 -0800 +++ b/mercurial/hg.py Mon Feb 13 00:05:55 2017 -0800 @@ -733,12 +733,13 @@ * none: don't check (merge working directory changes into destination) * linear: check that update is linear before merging working directory changes into destination + * noconflict: check that the update does not result in file merges This returns whether conflict is detected at updating or not. """ if updatecheck is None: updatecheck = ui.config('experimental', 'updatecheck') -if updatecheck not in ('abort', 'none', 'linear'): +if updatecheck not in ('abort', 'none', 'linear', 'noconflict'): # If not configured, or invalid value configured updatecheck = 'linear' with repo.wlock(): diff -r ae37f4578e3a -r c88aa4bc36ee mercurial/merge.py --- a/mercurial/merge.pyMon Feb 13 16:03:05 2017 -0800 +++ b/mercurial/merge.pyMon Feb 13 00:05:55 2017 -0800 @@ -1465,21 +1465,27 @@ The table below shows all the behaviors of the update command given the -c and -C or no options, whether the working directory is dirty, whether a revision is specified, and the relationship of -the parent rev to the target rev (linear or not). Match from top first. +the parent rev to the target rev (linear or not). Match from top first. The +-n option doesn't exist on the command line, but represents the +experimental.updatecheck=noconflict option. This logic is tested by test-update-branches.t. --c -C -m dirty rev linear | result - y y ** * * |(1) - y * y* * * |(1) - * y y* * * |(1) - * * ** n n | x - * * *n * * |ok - n n ny * y | merge - n n ny y n |(2) - n n yy * * | merge - n y ny * * | discard - y n ny * * |(3) +-c -C -n -m dirty rev linear | result + y y * ** * * |(1) + y * y ** * * |(1) + y * * y* * * |(1) + * y y ** * * |(1) + * y * y* * * |(1) + * * y y* * * |(1) + * * * ** n n | x + * * * *n * * |ok + n n n ny * y | merge + n n n ny y n |(2) + n n n yy * * | merge + n n y ny * * | merge if no conflict + n y n ny * * | discard + y n n ny * * |(3) x = can't happen * = don't-care @@ -1499,7 +1505,7 @@ # updatecheck='abort' to better suppport some of these callers. if updatecheck is None: updatecheck = 'linear' -assert updatecheck in ('none', 'linear') +assert updatecheck in ('none', 'linear', 'noconflict') # If we're doing a partial update, we need to skip updating # the dirstate, so make a note of any partial-ness to the # update here. @@ -1593,6 +1599,13 @@ repo, wc, p2, pas, branchmerge, force, mergeancestor, followcopies, matcher=matcher, mergeforce=mergeforce) +if updatecheck == 'noconflict': +for f, (m, args, msg) in actionbyfile.iteritems(): +if m not in ('g', 'k', 'r'): +msg = _("uncommitted changes")
Re: [PATCH] transaction: enable hardlink backups for non-windows systems
According to https://bz.mercurial-scm.org/show_bug.cgi?id=4546: Testing with mercurial 3.2 and 3.3 to a Linux samba server worked without issue in the few tests I've done. This suggests the most likely cause is an NTFS/Windows based file server? So I think at least we can have a whitelist (instead of a blacklist) that allows Linux to use real hardlinks. Just ignore OS X or Windows for now. I want hardlinks :) Excerpts from Jeroen Vaelen's message of 2017-02-15 20:34:32 +: > Sorry for the delay in reply. > > Confidence in stable posix implementations could come from: > > - hardlink backups being the default for nearly 10 years before the previously > mentioned patch disabled them after a series of bug reports coming > exclusively from Windows users. > - generally more dependencies on hardlinks on such systems by different > tools which make cache coherency bugs (theory) like issue 4546 less > likely. > > Getting a repro for this bug has been tough. Do you have any ideas for > alternative directions here? > > Excerpts from Augie Fackler's message of 2017-02-14 10:39:00 -0500: > > On Tue, Feb 14, 2017 at 01:31:02AM -0800, Jeroen Vaelen wrote: > > > # HG changeset patch > > > # User Jeroen Vaelen > > > # Date 1487064458 28800 > > > # Tue Feb 14 01:27:38 2017 -0800 > > > # Node ID c7fb7ac39a12c8683518bb7db7e1a93346e017e0 > > > # Parent a0e3d808690d57d1c9dff840e0b8ee099526397b > > > transaction: enable hardlink backups for non-windows systems > > > > > > 07a92bbd02e5 disabled hardlink backups entirely because they can cause > > > trouble > > > with CIFS on Windows (see issue 4546). This changeset limits that > > > restriction > > > to Windows systems. Ideally we check for CIFS, because e.g. NTFS does > > > support > > > hardlinks. But this at least gives us cheaper transactional backups for > > > posix, > > > which is a step forward. > > > > I'm hesitant to take this because as of 10.12 macOS is pushing people > > towards CIFS instead of AFP, so this issue feels more likely to come > > up there. Also, isn't it possible to mount CIFS volumes in the > > filesystem space on Linux? Do we have any reason for confidence this > > is only a problem in the Windows CIFS client, and not a problem in the > > server? > > > > Thanks! > > > > > > > > Note: the test changes were originally introduced in 07a92bbd02e5. > > > > > > diff --git a/mercurial/util.py b/mercurial/util.py > > > --- a/mercurial/util.py > > > +++ b/mercurial/util.py > > > @@ -1084,9 +1084,9 @@ > > > if checkambig: > > > oldstat = checkambig and filestat(dest) > > > unlink(dest) > > > -# hardlinks are problematic on CIFS, quietly ignore this flag > > > -# until we find a way to work around it cleanly (issue4546) > > > -if False and hardlink: > > > +# quietly ignore the hardlink flag on Windows due to CIFS limitations > > > +# (see discussion on issue 4546) > > > +if hardlink and pycompat.osname != 'nt': > > > try: > > > oslink(src, dest) > > > return > > > diff --git a/tests/test-hardlinks.t b/tests/test-hardlinks.t > > > --- a/tests/test-hardlinks.t > > > +++ b/tests/test-hardlinks.t > > > @@ -166,7 +166,7 @@ > > >1 r2/.hg/store/00manifest.i > > >1 r2/.hg/store/data/d1/f2.i > > >2 r2/.hg/store/data/f1.i > > > - 1 r2/.hg/store/fncache > > > + 2 r2/.hg/store/fncache > > > > > >$ hg -R r2 verify > > >checking changesets > > > @@ -191,7 +191,7 @@ > > >1 r2/.hg/store/00manifest.i > > >1 r2/.hg/store/data/d1/f2.i > > >1 r2/.hg/store/data/f1.i > > > - 1 r2/.hg/store/fncache > > > + 2 r2/.hg/store/fncache > > > > > > > > >$ cd r3 > > > https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Re: [PATCH RFC] similar: allow similarity detection to use sha256 for digesting file contents
On Wed, Mar 1, 2017 at 4:46 PM, Mike Hommey wrote: > On Wed, Mar 01, 2017 at 04:34:43PM -0800, Gregory Szorc wrote: > > On Wed, Mar 1, 2017 at 7:02 AM, FUJIWARA Katsunori < > fo...@lares.dti.ne.jp> > > wrote: > > > > > # HG changeset patch > > > # User FUJIWARA Katsunori > > > # Date 1488380487 -32400 > > > # Thu Mar 02 00:01:27 2017 +0900 > > > # Node ID 018d9759cb93f116007d4640341a82db6cf2d45c > > > # Parent 0bb3089fe73527c64f1afc40b86ecb8dfe7fd7aa > > > similar: allow similarity detection to use sha256 for digesting file > > > contents > > > > > > Before this patch, similarity detection logic (used for addremove and > > > automv) uses SHA-1 digesting. But this cause incorrect rename > > > detection, if: > > > > > > - removing file A and adding file B occur at same committing, and > > > - SHA-1 hash values of file A and B are same > > > > > > This may prevent security experts from managing sample files for > > > SHAttered issue in Mercurial repository, for example. > > > > > > https://security.googleblog.com/2017/02/announcing-first- > > > sha1-collision.html > > > https://shattered.it/ > > > > > > Hash collision itself isn't so serious for core repository > > > functionality of Mercurial, described by mpm as below, though. > > > > > > https://www.mercurial-scm.org/wiki/mpm/SHA1 > > > > > > HOW ABOUT: > > > > > > - which should we use default algorithm SHA-1, SHA-256 or SHA-512 ? > > > > > > > SHA-512 should be faster than SHA-256 on 64-bit hardware. So, there's > > likely no good reason to use SHA-256 for simple identity checks. > > > > > > > > > > ease (handling problematic files safely by default) or > > > performance? > > > > > > > > > On my Skylake at 4.0 GHz, SHA-1 is capable of running at ~975 MB/s and > > SHA-512 at ~700 MB/s. Both are fast enough that for simple one-time > content > > identity checks, hashing shouldn't be a bottleneck, at least not for most > > repos. > > > > So I think it is fine to change this function from SHA-1 to SHA-512 > > assuming the hashes don't "leak" into storage. If they end up being > stored > > or used for something other than identity checks, then we need to bloat > > scope to discuss our general hashing future. And that needs its own > thread > > ;) > > With hashing, there is *always* the risk of collision. It might be tiny, > but it still exists. Why not just compare the contents when the hash > match? Then it doesn't really matter what the hash is. The hash is just > a shortcut to avoid comparing full contents in a O(n^2) fashion. > > There aren't going to be that many hash matches anyways, comparing the > content then should not make a significant difference in speed, but > would guarantee that the "similarity" is real. > Yeah, the objects will already be in memory. Under the hood bytes.__eq__ just looks at the buffer length then falls back to memcmp, which should be on the order of 10 GB/s. So using __eq__ here seems reasonable. > > (BTW, interestingly, in terms of similarity detection, while the > SHAttered PDFs are not 100% identical, they are 80%+ similar) > > Mike > ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Re: [PATCH RFC] similar: allow similarity detection to use sha256 for digesting file contents
On Wed, Mar 01, 2017 at 04:34:43PM -0800, Gregory Szorc wrote: > On Wed, Mar 1, 2017 at 7:02 AM, FUJIWARA Katsunori > wrote: > > > # HG changeset patch > > # User FUJIWARA Katsunori > > # Date 1488380487 -32400 > > # Thu Mar 02 00:01:27 2017 +0900 > > # Node ID 018d9759cb93f116007d4640341a82db6cf2d45c > > # Parent 0bb3089fe73527c64f1afc40b86ecb8dfe7fd7aa > > similar: allow similarity detection to use sha256 for digesting file > > contents > > > > Before this patch, similarity detection logic (used for addremove and > > automv) uses SHA-1 digesting. But this cause incorrect rename > > detection, if: > > > > - removing file A and adding file B occur at same committing, and > > - SHA-1 hash values of file A and B are same > > > > This may prevent security experts from managing sample files for > > SHAttered issue in Mercurial repository, for example. > > > > https://security.googleblog.com/2017/02/announcing-first- > > sha1-collision.html > > https://shattered.it/ > > > > Hash collision itself isn't so serious for core repository > > functionality of Mercurial, described by mpm as below, though. > > > > https://www.mercurial-scm.org/wiki/mpm/SHA1 > > > > HOW ABOUT: > > > > - which should we use default algorithm SHA-1, SHA-256 or SHA-512 ? > > > > SHA-512 should be faster than SHA-256 on 64-bit hardware. So, there's > likely no good reason to use SHA-256 for simple identity checks. > > > > > > ease (handling problematic files safely by default) or > > performance? > > > > > On my Skylake at 4.0 GHz, SHA-1 is capable of running at ~975 MB/s and > SHA-512 at ~700 MB/s. Both are fast enough that for simple one-time content > identity checks, hashing shouldn't be a bottleneck, at least not for most > repos. > > So I think it is fine to change this function from SHA-1 to SHA-512 > assuming the hashes don't "leak" into storage. If they end up being stored > or used for something other than identity checks, then we need to bloat > scope to discuss our general hashing future. And that needs its own thread > ;) With hashing, there is *always* the risk of collision. It might be tiny, but it still exists. Why not just compare the contents when the hash match? Then it doesn't really matter what the hash is. The hash is just a shortcut to avoid comparing full contents in a O(n^2) fashion. There aren't going to be that many hash matches anyways, comparing the content then should not make a significant difference in speed, but would guarantee that the "similarity" is real. (BTW, interestingly, in terms of similarity detection, while the SHAttered PDFs are not 100% identical, they are 80%+ similar) Mike ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
[PATCH] manifest: remove _repo from manifestctx objects
# HG changeset patch # User Durham Goode # Date 1488415188 28800 # Wed Mar 01 16:39:48 2017 -0800 # Node ID b787c41767339158927232ec7a9092196e887453 # Parent 0bb3089fe73527c64f1afc40b86ecb8dfe7fd7aa manifest: remove _repo from manifestctx objects We were storing the repo on the manifestctx objects so that they could access the manifestlog via repo.manifestlog, which would refresh the structure if it became out of date. This caused probems however when we want to have multiple manifest logs in memory at once, like when transitioning to tree manifest from flat manifests, since a tree manifest would try to access sub-trees via repo.manifestlog[node], which was the flat manifest. The solution is to just not store the repo, and instead store the manifestlog that created this context. This removes the invalidation when the in memory manifestlog becomes out of date, but people should probably not be keeping ctx's around that long anyway. diff --git a/mercurial/manifest.py b/mercurial/manifest.py --- a/mercurial/manifest.py +++ b/mercurial/manifest.py @@ -1252,8 +1252,6 @@ class manifestlog(object): class do not care about the implementation details of the actual manifests they receive (i.e. tree or flat or lazily loaded, etc).""" def __init__(self, opener, repo): -self._repo = repo - usetreemanifest = False cachesize = 4 @@ -1300,7 +1298,7 @@ class manifestlog(object): if node not in dirlog.nodemap: raise LookupError(node, dirlog.indexfile, _('no node')) -m = treemanifestctx(self._repo, dir, node) +m = treemanifestctx(self, dir, node) else: raise error.Abort( _("cannot ask for manifest directory '%s' in a flat " @@ -1311,9 +1309,9 @@ class manifestlog(object): raise LookupError(node, self._revlog.indexfile, _('no node')) if self._treeinmem: -m = treemanifestctx(self._repo, '', node) +m = treemanifestctx(self, '', node) else: -m = manifestctx(self._repo, node) +m = manifestctx(self, node) if node != revlog.nullid: mancache = self._dirmancache.get(dir) @@ -1328,18 +1326,18 @@ class manifestlog(object): self._revlog.clearcaches() class memmanifestctx(object): -def __init__(self, repo): -self._repo = repo +def __init__(self, manifestlog): +self._manifestlog = manifestlog self._manifestdict = manifestdict() def _revlog(self): -return self._repo.manifestlog._revlog +return self._manifestlog._revlog def new(self): -return memmanifestctx(self._repo) +return memmanifestctx(self._manifestlog) def copy(self): -memmf = memmanifestctx(self._repo) +memmf = memmanifestctx(self._manifestlog) memmf._manifestdict = self.read().copy() return memmf @@ -1354,8 +1352,8 @@ class manifestctx(object): """A class representing a single revision of a manifest, including its contents, its parent revs, and its linkrev. """ -def __init__(self, repo, node): -self._repo = repo +def __init__(self, manifestlog, node): +self._manifestlog = manifestlog self._data = None self._node = node @@ -1368,16 +1366,16 @@ class manifestctx(object): #self.linkrev = revlog.linkrev(rev) def _revlog(self): -return self._repo.manifestlog._revlog +return self._manifestlog._revlog def node(self): return self._node def new(self): -return memmanifestctx(self._repo) +return memmanifestctx(self._manifestlog) def copy(self): -memmf = memmanifestctx(self._repo) +memmf = memmanifestctx(self._manifestlog) memmf._manifestdict = self.read().copy() return memmf @@ -1422,7 +1420,7 @@ class manifestctx(object): if revlog._usemanifestv2: # Need to perform a slow delta r0 = revlog.deltaparent(revlog.rev(self._node)) -m0 = self._repo.manifestlog[revlog.node(r0)].read() +m0 = self._manifestlog[revlog.node(r0)].read() m1 = self.read() md = manifestdict() for f, ((n0, fl0), (n1, fl1)) in m0.diff(m1).iteritems(): @@ -1440,19 +1438,19 @@ class manifestctx(object): return self.read().find(key) class memtreemanifestctx(object): -def __init__(self, repo, dir=''): -self._repo = repo +def __init__(self, manifestlog, dir=''): +self._manifestlog = manifestlog self._dir = dir self._treemanifest = treemanifest() def _revlog(self): -return self._repo.manifestlog._revlog +return self._manifestlog._revlog def new(self, dir='
[PATCH 2 of 2 V3] treemanifest: make node reuse match flat manifest behavior
# HG changeset patch # User Durham Goode # Date 1488413981 28800 # Wed Mar 01 16:19:41 2017 -0800 # Node ID f99c019063bea8a0b5f66c1e79dbd0b98b1326d8 # Parent 9c89185b63f574cad1d4009f6c9dd511a2cba986 treemanifest: make node reuse match flat manifest behavior In a flat manifest, a node with the same content but different parents is still considered a new node. In the current tree manifests however, if the content is the same, we ignore the parents entirely and just reuse the existing node. In our external treemanifest extension, we want to allow having one treemanifest for every flat manifests, as a way of easeing the migration to treemanifests. To make this possible, let's change the root node treemanifest behavior to match the behavior for flat manifests, so we can have a 1:1 relationship. While this sounds like a BC breakage, it's not actually a state users can normally get in because: A) you can't make empty commits, and B) even if you try to make an empty commit (by making a commit then amending it's changes away), the higher level commit logic in localrepo.commitctx() forces the commit to use the original p1 manifest node if no files were changed. So this would only affect extensions and automation that reached passed the normal localrepo.commit() logic straight into the manifest logic. diff --git a/mercurial/manifest.py b/mercurial/manifest.py --- a/mercurial/manifest.py +++ b/mercurial/manifest.py @@ -1233,7 +1233,7 @@ class manifestrevlog(revlog.revlog): def _addtree(self, m, transaction, link, m1, m2, readtree): # If the manifest is unchanged compared to one parent, # don't write a new revision -if m.unmodifiedsince(m1) or m.unmodifiedsince(m2): +if self._dir != '' and (m.unmodifiedsince(m1) or m.unmodifiedsince(m2)): return m.node() def writesubtree(subm, subp1, subp2): sublog = self.dirlog(subm.dir()) @@ -1241,13 +1241,17 @@ class manifestrevlog(revlog.revlog): readtree=readtree) m.writesubtrees(m1, m2, writesubtree) text = m.dirtext(self._usemanifestv2) -# Double-check whether contents are unchanged to one parent -if text == m1.dirtext(self._usemanifestv2): -n = m1.node() -elif text == m2.dirtext(self._usemanifestv2): -n = m2.node() -else: +n = None +if self._dir != '': +# Double-check whether contents are unchanged to one parent +if text == m1.dirtext(self._usemanifestv2): +n = m1.node() +elif text == m2.dirtext(self._usemanifestv2): +n = m2.node() + +if not n: n = self.addrevision(text, transaction, link, m1.node(), m2.node()) + # Save nodeid so parent manifest can calculate its nodeid m.setnode(n) return n diff --git a/tests/test-treemanifest.t b/tests/test-treemanifest.t --- a/tests/test-treemanifest.t +++ b/tests/test-treemanifest.t @@ -825,3 +825,13 @@ other branch added 1 changesets with 1 changes to 1 files (+1 heads) (run 'hg heads' to see heads, 'hg merge' to merge) +Committing a empty commit does not duplicate root treemanifest + $ echo z >> z + $ hg commit -Aqm 'pre-empty commit' + $ hg rm z + $ hg commit --amend -m 'empty commit' + saved backup bundle to $TESTTMP/grafted-dir-repo-clone/.hg/strip-backup/cb99d5717cea-de37743b-amend-backup.hg (glob) + $ hg log -r 'tip + tip^' -T '{manifest}\n' + 1:678d3574b88c + 1:678d3574b88c + $ hg --config extensions.strip= strip -r . -q ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
[PATCH 1 of 2 V3] manifest: allow specifying the revlog filename
# HG changeset patch # User Durham Goode # Date 1488414957 28800 # Wed Mar 01 16:35:57 2017 -0800 # Node ID 9c89185b63f574cad1d4009f6c9dd511a2cba986 # Parent 0bb3089fe73527c64f1afc40b86ecb8dfe7fd7aa manifest: allow specifying the revlog filename Previously we had hardcoded the manifest filename to be 00manifest.i. In our external treemanifest extension, we want to allow writing a treemanifest side by side with a flat manifest, so we need to be able to store the root revisions at a different location (in our extension we use 00manifesttree.i). This patches moves the revlog name to a parameter so we can adjust it. diff --git a/mercurial/manifest.py b/mercurial/manifest.py --- a/mercurial/manifest.py +++ b/mercurial/manifest.py @@ -1132,7 +1132,12 @@ class manifestrevlog(revlog.revlog): '''A revlog that stores manifest texts. This is responsible for caching the full-text manifest contents. ''' -def __init__(self, opener, dir='', dirlogcache=None): +def __init__(self, opener, dir='', dirlogcache=None, indexfile=None): +"""Constructs a new manifest revlog + +`indexfile` - used by extensions to have two manifests at once, like +when transitioning between flatmanifeset and treemanifests. +""" # During normal operations, we expect to deal with not more than four # revs at a time (such as during commit --amend). When rebasing large # stacks of commits, the number can go up, hence the config knob below. @@ -1150,12 +1155,16 @@ class manifestrevlog(revlog.revlog): self._fulltextcache = util.lrucachedict(cachesize) -indexfile = "00manifest.i" if dir: assert self._treeondisk, 'opts is %r' % opts if not dir.endswith('/'): dir = dir + '/' -indexfile = "meta/" + dir + "00manifest.i" + +if indexfile is None: +indexfile = '00manifest.i' +if dir: +indexfile = "meta/" + dir + indexfile + self._dir = dir # The dirlogcache is kept on the root manifest log if dir: ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Re: [PATCH RFC] similar: allow similarity detection to use sha256 for digesting file contents
On Wed, Mar 1, 2017 at 7:02 AM, FUJIWARA Katsunori wrote: > # HG changeset patch > # User FUJIWARA Katsunori > # Date 1488380487 -32400 > # Thu Mar 02 00:01:27 2017 +0900 > # Node ID 018d9759cb93f116007d4640341a82db6cf2d45c > # Parent 0bb3089fe73527c64f1afc40b86ecb8dfe7fd7aa > similar: allow similarity detection to use sha256 for digesting file > contents > > Before this patch, similarity detection logic (used for addremove and > automv) uses SHA-1 digesting. But this cause incorrect rename > detection, if: > > - removing file A and adding file B occur at same committing, and > - SHA-1 hash values of file A and B are same > > This may prevent security experts from managing sample files for > SHAttered issue in Mercurial repository, for example. > > https://security.googleblog.com/2017/02/announcing-first- > sha1-collision.html > https://shattered.it/ > > Hash collision itself isn't so serious for core repository > functionality of Mercurial, described by mpm as below, though. > > https://www.mercurial-scm.org/wiki/mpm/SHA1 > > HOW ABOUT: > > - which should we use default algorithm SHA-1, SHA-256 or SHA-512 ? > SHA-512 should be faster than SHA-256 on 64-bit hardware. So, there's likely no good reason to use SHA-256 for simple identity checks. > > ease (handling problematic files safely by default) or > performance? > On my Skylake at 4.0 GHz, SHA-1 is capable of running at ~975 MB/s and SHA-512 at ~700 MB/s. Both are fast enough that for simple one-time content identity checks, hashing shouldn't be a bottleneck, at least not for most repos. So I think it is fine to change this function from SHA-1 to SHA-512 assuming the hashes don't "leak" into storage. If they end up being stored or used for something other than identity checks, then we need to bloat scope to discuss our general hashing future. And that needs its own thread ;) > > - what name of config knob is reasonable to control digesting algorithm ? > > or should we fully switch to more secure digest alrgorithm ? > > BTW, almost all of SHA-1 clients in Mercurial source tree applies it > on other than file contents (e.g. list of parent hash ids, file path, > URL, and so on). But some SHA-1 clients below apply it on file > contents. > > - patch.trydiff() > > SHA-1 is applied on "blob SIZE\0" header + file content (only if > experimental.extendedheader.index is enabled) > > - largefiles > > The former should be less serious. > > On the other hand, the latter causes unintentional unification between > largefiles, which cause same SHA-1 hash value, at checking files out. > > > diff --git a/mercurial/similar.py b/mercurial/similar.py > --- a/mercurial/similar.py > +++ b/mercurial/similar.py > @@ -12,9 +12,15 @@ import hashlib > from .i18n import _ > from . import ( > bdiff, > +error, > mdiff, > ) > > +DIGESTERS = { > +'sha1': hashlib.sha1, > +'sha256': hashlib.sha256, > +} > + > def _findexactmatches(repo, added, removed): > '''find renamed files that have no changes > > @@ -23,19 +29,25 @@ def _findexactmatches(repo, added, remov > ''' > numfiles = len(added) + len(removed) > > +digest = repo.ui.config('ui', 'similaritydigest', 'sha256') > +if digest not in DIGESTERS: > +raise error.ConfigError(_("ui.similaritydigest value is invalid: > %s") > +% digest) > +digester = DIGESTERS[digest] > + > # Get hashes of removed files. > hashes = {} > for i, fctx in enumerate(removed): > repo.ui.progress(_('searching for exact renames'), i, > total=numfiles, > unit=_('files')) > -h = hashlib.sha1(fctx.data()).digest() > +h = digester(fctx.data()).digest() > hashes[h] = fctx > > # For each added file, see if it corresponds to a removed file. > for i, fctx in enumerate(added): > repo.ui.progress(_('searching for exact renames'), i + > len(removed), > total=numfiles, unit=_('files')) > -h = hashlib.sha1(fctx.data()).digest() > +h = digester(fctx.data()).digest() > if h in hashes: > yield (hashes[h], fctx) > > ___ > Mercurial-devel mailing list > Mercurial-devel@mercurial-scm.org > https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel > ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
[PATCH] phases: remove experimental.nativephaseskillswitch
# HG changeset patch # User Jun Wu # Date 1488412201 28800 # Wed Mar 01 15:50:01 2017 -0800 # Node ID 85e43415eb995e9096feb3d8b543320dd0b891c5 # Parent 0bb3089fe73527c64f1afc40b86ecb8dfe7fd7aa # Available At https://bitbucket.org/quark-zju/hg-draft # hg pull https://bitbucket.org/quark-zju/hg-draft -r 85e43415eb99 phases: remove experimental.nativephaseskillswitch The native code has been used for a long time. Therefore drop the experimental config option. diff --git a/mercurial/phases.py b/mercurial/phases.py --- a/mercurial/phases.py +++ b/mercurial/phases.py @@ -225,10 +225,6 @@ class phasecache(object): if self._phaserevs is None: try: -if repo.ui.configbool('experimental', - 'nativephaseskillswitch'): -self._computephaserevspure(repo) -else: -res = self._getphaserevsnative(repo) -self._phaserevs, self._phasesets = res +res = self._getphaserevsnative(repo) +self._phaserevs, self._phasesets = res except AttributeError: self._computephaserevspure(repo) diff --git a/tests/test-phases.t b/tests/test-phases.t --- a/tests/test-phases.t +++ b/tests/test-phases.t @@ -480,10 +480,6 @@ move changeset backward -move changeset forward and backward and test kill switch +move changeset forward and backward - $ cat <> $HGRCPATH - > [experimental] - > nativephaseskillswitch = true - > EOF $ hg phase --draft --force 1::4 $ hg log -G --template "{rev} {phase} {desc}\n" @@ -506,8 +502,4 @@ move changeset forward and backward and test partial failure - $ cat <> $HGRCPATH - > [experimental] - > nativephaseskillswitch = false - > EOF $ hg phase --public 7 $ hg phase --draft '5 or 7' ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Re: [PATCH 11 of 11 V5] update: allow setting default update check to "noconflict"
On Wed, Mar 1, 2017 at 11:54 AM, Ryan McElroy wrote: > I'm a very big +1 on this direction -- this is a huge usability improvment. > > Facebook currently adds a "--nocheck" flag and turns on "check" by default > in our "tweakdefaults" extension, but this direction is strictly better than > that and we will definitely switch over to this "noconflict" functionality > once it gets into core. I even volunteer to do the work to remove the > "nocheck" stuff from tweakdefaults and all that. > > Thanks a ton for working on this Martin! Great to hear it will be sufficient to replace that part of tweakdefaults. > > > > > On 2/27/17 4:31 PM, Martin von Zweigbergk via Mercurial-devel wrote: >> >> # HG changeset patch >> # User Martin von Zweigbergk >> # Date 1486973155 28800 >> # Mon Feb 13 00:05:55 2017 -0800 >> # Node ID c88aa4bc36ee81b0837d2949501d6b4fcf825c38 >> # Parent ae37f4578e3af6fd4cb7c29c9ab06ad0efd726da >> update: allow setting default update check to "noconflict" >> >> The new value allows update (linear or not) as long as they don't >> result in file merges. >> >> I'm hoping that this value can some day become the default. >> >> diff -r ae37f4578e3a -r c88aa4bc36ee mercurial/hg.py >> --- a/mercurial/hg.py Mon Feb 13 16:03:05 2017 -0800 >> +++ b/mercurial/hg.py Mon Feb 13 00:05:55 2017 -0800 >> @@ -733,12 +733,13 @@ >>* none: don't check (merge working directory changes into >> destination) >>* linear: check that update is linear before merging working >> directory >> changes into destination >> + * noconflict: check that the update does not result in file merges >> This returns whether conflict is detected at updating or not. >> """ >> if updatecheck is None: >> updatecheck = ui.config('experimental', 'updatecheck') >> -if updatecheck not in ('abort', 'none', 'linear'): >> +if updatecheck not in ('abort', 'none', 'linear', 'noconflict'): >> # If not configured, or invalid value configured >> updatecheck = 'linear' >> with repo.wlock(): >> diff -r ae37f4578e3a -r c88aa4bc36ee mercurial/merge.py >> --- a/mercurial/merge.pyMon Feb 13 16:03:05 2017 -0800 >> +++ b/mercurial/merge.pyMon Feb 13 00:05:55 2017 -0800 >> @@ -1465,21 +1465,27 @@ >> The table below shows all the behaviors of the update command >> given the -c and -C or no options, whether the working directory >> is dirty, whether a revision is specified, and the relationship of >> -the parent rev to the target rev (linear or not). Match from top >> first. >> +the parent rev to the target rev (linear or not). Match from top >> first. The >> +-n option doesn't exist on the command line, but represents the >> +experimental.updatecheck=noconflict option. >> This logic is tested by test-update-branches.t. >> --c -C -m dirty rev linear | result >> - y y ** * * |(1) >> - y * y* * * |(1) >> - * y y* * * |(1) >> - * * ** n n | x >> - * * *n * * |ok >> - n n ny * y | merge >> - n n ny y n |(2) >> - n n yy * * | merge >> - n y ny * * | discard >> - y n ny * * |(3) >> +-c -C -n -m dirty rev linear | result >> + y y * ** * * |(1) >> + y * y ** * * |(1) >> + y * * y* * * |(1) >> + * y y ** * * |(1) >> + * y * y* * * |(1) >> + * * y y* * * |(1) >> + * * * ** n n | x >> + * * * *n * * |ok >> + n n n ny * y | merge >> + n n n ny y n |(2) >> + n n n yy * * | merge >> + n n y ny * * | merge if no conflict >> + n y n ny * * | discard >> + y n n ny * * |(3) >> x = can't happen >> * = don't-care >> @@ -1499,7 +1505,7 @@ >> # updatecheck='abort' to better suppport some of these callers. >> if updatecheck is None: >> updatecheck = 'linear' >> -assert updatecheck in ('none', 'linear') >> +assert updatecheck in ('none', 'linear', 'noconflict') >> # If we're doing a partial update, we need to skip updating >> # the dirstate, so make a note of any partial-ness to the >> # update here. >> @@ -1593,6 +1599,13 @@ >> repo, wc, p2, pas, branchmerge, force, mergeancestor, >> followcopies, matcher=matcher, mergeforce=mergeforce) >> +if updatecheck == 'noconflict': >> +for f,
Re: [PATCH 2 of 4 V2] chgcache: report repo paths from worker to master
Excerpts from Yuya Nishihara's message of 2017-02-28 23:04:52 +0900: > Perhaps this is related to the baselocalrepostiroy-vs-repostorage story. > Maybe we'll have to settle it first? > > My view is that there will be a repostorage object, which will be looked > up at dispatch layer and be injected into a localrepository object. So > localrepo can ideally go without knowing chgcache. > > dispatch (or hook carried by req object) cached_storage = > chgcache.lookup(root) attach_storage_in_some_way(repo, cached_storage) > > In this view, it makes sense to record the repo path here. I think the repostorage refactoring is relatively separate from chgcache, and it could be a big project (partially because of compatibility with existing extensions), so I'd prefer avoiding it for now. My understanding about chgcache is: - It's low-level, like a key-value storage (ex. memcache) - Its repo stuff is just to make it easier to write preloading code. - It does not have to be used together with repo. For example, if I just want revlogs, I can send "revlog path" and preload them. Revlog is not a good example but you get the idea. A real user of this may be remotefilelog's packfiles. - The core only has minimal support code. i.e. "chgcache" won't be everywhere in "mercurial/". - Most chgcache users are expected to be extensions touching random areas. If chg's preloading ability has to be exposed via a "chgrepostorage", it's less flexible, and increases the overhead of code touching storage - they may have to wrap both chgrepostorage and the original storage class. Since I have already moved the most troublesome logic (loading extensions) out of localrepository [1]. I'd like to just go ahead with a chgpreloadrepo class inherited from localrepository with some key functions disabled. In that way, it seems easier and better compatible with others. [1]: https://www.mercurial-scm.org/pipermail/mercurial-devel/2017-February/093173.html ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Re: [PATCH 11 of 11 V5] update: allow setting default update check to "noconflict"
I'm a very big +1 on this direction -- this is a huge usability improvment. Facebook currently adds a "--nocheck" flag and turns on "check" by default in our "tweakdefaults" extension, but this direction is strictly better than that and we will definitely switch over to this "noconflict" functionality once it gets into core. I even volunteer to do the work to remove the "nocheck" stuff from tweakdefaults and all that. Thanks a ton for working on this Martin! On 2/27/17 4:31 PM, Martin von Zweigbergk via Mercurial-devel wrote: # HG changeset patch # User Martin von Zweigbergk # Date 1486973155 28800 # Mon Feb 13 00:05:55 2017 -0800 # Node ID c88aa4bc36ee81b0837d2949501d6b4fcf825c38 # Parent ae37f4578e3af6fd4cb7c29c9ab06ad0efd726da update: allow setting default update check to "noconflict" The new value allows update (linear or not) as long as they don't result in file merges. I'm hoping that this value can some day become the default. diff -r ae37f4578e3a -r c88aa4bc36ee mercurial/hg.py --- a/mercurial/hg.py Mon Feb 13 16:03:05 2017 -0800 +++ b/mercurial/hg.py Mon Feb 13 00:05:55 2017 -0800 @@ -733,12 +733,13 @@ * none: don't check (merge working directory changes into destination) * linear: check that update is linear before merging working directory changes into destination + * noconflict: check that the update does not result in file merges This returns whether conflict is detected at updating or not. """ if updatecheck is None: updatecheck = ui.config('experimental', 'updatecheck') -if updatecheck not in ('abort', 'none', 'linear'): +if updatecheck not in ('abort', 'none', 'linear', 'noconflict'): # If not configured, or invalid value configured updatecheck = 'linear' with repo.wlock(): diff -r ae37f4578e3a -r c88aa4bc36ee mercurial/merge.py --- a/mercurial/merge.pyMon Feb 13 16:03:05 2017 -0800 +++ b/mercurial/merge.pyMon Feb 13 00:05:55 2017 -0800 @@ -1465,21 +1465,27 @@ The table below shows all the behaviors of the update command given the -c and -C or no options, whether the working directory is dirty, whether a revision is specified, and the relationship of -the parent rev to the target rev (linear or not). Match from top first. +the parent rev to the target rev (linear or not). Match from top first. The +-n option doesn't exist on the command line, but represents the +experimental.updatecheck=noconflict option. This logic is tested by test-update-branches.t. --c -C -m dirty rev linear | result - y y ** * * |(1) - y * y* * * |(1) - * y y* * * |(1) - * * ** n n | x - * * *n * * |ok - n n ny * y | merge - n n ny y n |(2) - n n yy * * | merge - n y ny * * | discard - y n ny * * |(3) +-c -C -n -m dirty rev linear | result + y y * ** * * |(1) + y * y ** * * |(1) + y * * y* * * |(1) + * y y ** * * |(1) + * y * y* * * |(1) + * * y y* * * |(1) + * * * ** n n | x + * * * *n * * |ok + n n n ny * y | merge + n n n ny y n |(2) + n n n yy * * | merge + n n y ny * * | merge if no conflict + n y n ny * * | discard + y n n ny * * |(3) x = can't happen * = don't-care @@ -1499,7 +1505,7 @@ # updatecheck='abort' to better suppport some of these callers. if updatecheck is None: updatecheck = 'linear' -assert updatecheck in ('none', 'linear') +assert updatecheck in ('none', 'linear', 'noconflict') # If we're doing a partial update, we need to skip updating # the dirstate, so make a note of any partial-ness to the # update here. @@ -1593,6 +1599,13 @@ repo, wc, p2, pas, branchmerge, force, mergeancestor, followcopies, matcher=matcher, mergeforce=mergeforce) +if updatecheck == 'noconflict': +for f, (m, args, msg) in actionbyfile.iteritems(): +if m not in ('g', 'k', 'r'): +msg = _("uncommitted changes") I'd make this message more specific/correct -- something like "conflicting changes", or perhaps more pedantically, "working copy changes conflict with update changes". I bring this up because "uncommitted changes" is true but doesn't really explain why w
Re: [PATCH 6 of 7] help: use 'churn' instead of 'color' as an example extension
On 03/01/2017 03:10 PM, Augie Fackler wrote: On Feb 28, 2017, at 14:25, Pierre-Yves David wrote: # HG changeset patch # User Pierre-Yves David # Date 1487714018 -3600 # Tue Feb 21 22:53:38 2017 +0100 # Node ID 9fffdf9b71de54fba36d3efd581aa660ab8076d1 # Parent 63ff941fd53a11b8e295db36f3787f60ef0c9ceb # EXP-Topic color help: use 'churn' instead of 'color' as an example extension The 'color' extensions is now deprecated. diff --git a/mercurial/help/config.txt b/mercurial/help/config.txt --- a/mercurial/help/config.txt +++ b/mercurial/help/config.txt @@ -728,8 +728,8 @@ or ``foo = !`` when path is not supplied Example for ``~/.hgrc``:: [extensions] - # (the color extension will get loaded from Mercurial's path) - color = + # (the churn extension will get loaded from Mercurial's path) + churn = nit: Would purge be a better thing to advertise here? 'purge' can eat user data without backups. So I think we tried to keep an air gap between purge and clueless user that copy past thing without much thinking (I think it is also why it is still an extension) Just trying to think of something that's likely to be of immediate interest to a typical user. I'm happy to send a follow-up if we've got any consensus. In the area of "harmless" (but less useful) I can see 'scheme' or 'blackbox'. I seems like we are running low on extensions "so useful we want to push all user to enable it by default", that is probably a good sign overall. (I would have said shelve, but I think I'd like to wait on that one until the implementation is a bit more robust) I agree, "share" would also have been a good candidate is more solid. Cheers, -- Pierre-Yves David ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Re: [PATCH] config: add extension point for extracting all included files
On 11-02-17 10:52, Yuya Nishihara wrote: On Tue, 7 Feb 2017 15:31:02 +, De Mare, Mathias (Nokia - BE) wrote: On Feb 3, 2017, at 09:56, Mathias De Maré wrote: # HG changeset patch # User Mathias De Mare # Date 1486132049 -3600 # Fri Feb 03 15:27:29 2017 +0100 # Node ID ea2e95febfeff39377c878fa05cc853832bc3b2a # Parent eb78ec9e97b70310e2944f72c29463bedfc21442 config: add extension point for extracting all included files Hmm... for those of us who haven't been paying close attention, can you say more about why this is desirable? Generally we don't add an extension point unless at least an in-tree extension uses it. (It's possible there are historical exceptions to this.) Pierre-Yves and myself spent some time working on an extension that would allow users to share their configuration with a server and allow a server to send configuration suggestions to a client. The work so far is available at https://bitbucket.org/Mathiasdm/hg-configexpress/overview One of the possible suggestions to clients would be to add specific includes, and this extension point allows checking if these includes are present. Can it be done by using/extending config._source dict? I don't think hooking config method is a good idea because config object may be used to parse template maps, .hgsub, etc. config._source can't be used as it is (as it stores the absolute paths, while config includes could be include with a relative path). I guess one possible alternative would be to create a config._relsource containing the relative paths, but that would require signature changes to some of the config methods. Another option would be for hg-configexpress to implement parsing of configfiles itself (only the 'includes' part), but that seems a bit redundant. Finally, it would be possible to add 2 additional keyword arguments to the 'include' function that's called inside config.config.parse, so it would be something like: include(inc, remap=remap, sections=sections, base=base, expanded=expanded) I quite like the last option, but it would require changing the subrepo code as well (like you mentioned). (Sorry, I appear to have missed this mail due to my holidays.) Greetings, Mathias ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Re: [PATCH RFC] similar: allow similarity detection to use sha256 for digesting file contents
On Wed, Mar 1, 2017 at 7:02 AM, FUJIWARA Katsunori wrote: > # HG changeset patch > # User FUJIWARA Katsunori > # Date 1488380487 -32400 > # Thu Mar 02 00:01:27 2017 +0900 > # Node ID 018d9759cb93f116007d4640341a82db6cf2d45c > # Parent 0bb3089fe73527c64f1afc40b86ecb8dfe7fd7aa > similar: allow similarity detection to use sha256 for digesting file contents > > Before this patch, similarity detection logic (used for addremove and > automv) uses SHA-1 digesting. But this cause incorrect rename > detection, if: > > - removing file A and adding file B occur at same committing, and > - SHA-1 hash values of file A and B are same If rename detection in this very special case is all that's lost, I don't think the extra complexity (code and config) is worth it. > > This may prevent security experts from managing sample files for > SHAttered issue in Mercurial repository, for example. > > https://security.googleblog.com/2017/02/announcing-first-sha1-collision.html > https://shattered.it/ > > Hash collision itself isn't so serious for core repository > functionality of Mercurial, described by mpm as below, though. > > https://www.mercurial-scm.org/wiki/mpm/SHA1 > > HOW ABOUT: > > - which should we use default algorithm SHA-1, SHA-256 or SHA-512 ? > > ease (handling problematic files safely by default) or > performance? > > - what name of config knob is reasonable to control digesting algorithm ? > > or should we fully switch to more secure digest alrgorithm ? Yes, I'd rather wait until we do that. > > BTW, almost all of SHA-1 clients in Mercurial source tree applies it > on other than file contents (e.g. list of parent hash ids, file path, > URL, and so on). But some SHA-1 clients below apply it on file > contents. > > - patch.trydiff() > > SHA-1 is applied on "blob SIZE\0" header + file content (only if > experimental.extendedheader.index is enabled) > > - largefiles > > The former should be less serious. > > On the other hand, the latter causes unintentional unification between > largefiles, which cause same SHA-1 hash value, at checking files out. > > diff --git a/mercurial/similar.py b/mercurial/similar.py > --- a/mercurial/similar.py > +++ b/mercurial/similar.py > @@ -12,9 +12,15 @@ import hashlib > from .i18n import _ > from . import ( > bdiff, > +error, > mdiff, > ) > > +DIGESTERS = { > +'sha1': hashlib.sha1, > +'sha256': hashlib.sha256, > +} > + > def _findexactmatches(repo, added, removed): > '''find renamed files that have no changes > > @@ -23,19 +29,25 @@ def _findexactmatches(repo, added, remov > ''' > numfiles = len(added) + len(removed) > > +digest = repo.ui.config('ui', 'similaritydigest', 'sha256') > +if digest not in DIGESTERS: > +raise error.ConfigError(_("ui.similaritydigest value is invalid: %s") > +% digest) > +digester = DIGESTERS[digest] > + > # Get hashes of removed files. > hashes = {} > for i, fctx in enumerate(removed): > repo.ui.progress(_('searching for exact renames'), i, total=numfiles, > unit=_('files')) > -h = hashlib.sha1(fctx.data()).digest() > +h = digester(fctx.data()).digest() > hashes[h] = fctx > > # For each added file, see if it corresponds to a removed file. > for i, fctx in enumerate(added): > repo.ui.progress(_('searching for exact renames'), i + len(removed), > total=numfiles, unit=_('files')) > -h = hashlib.sha1(fctx.data()).digest() > +h = digester(fctx.data()).digest() > if h in hashes: > yield (hashes[h], fctx) > > ___ > Mercurial-devel mailing list > Mercurial-devel@mercurial-scm.org > https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Re: [PATCH 3 of 4 V2] chgcache: implement the background preloading thread
Excerpts from Yuya Nishihara's message of 2017-03-01 21:56:08 +0900: > On Wed, 22 Feb 2017 18:16:10 -0800, Jun Wu wrote: > > # HG changeset patch > > # User Jun Wu > > # Date 1487813979 28800 > > # Wed Feb 22 17:39:39 2017 -0800 > > # Node ID 28571825744fb4f4b424385f55afa9484532ef43 > > # Parent 630457e88fa0485bce7822345ea640b5cdcb9b8e > > # Available At https://bitbucket.org/quark-zju/hg-draft > > # hg pull https://bitbucket.org/quark-zju/hg-draft -r > > 28571825744f > > chgcache: implement the background preloading thread > > > > The background preloading thread is meant to used by chg master, and it sets > > up the IPC channel. > > > +def _preloadloop(self, interval=0.5): > > +while not self._shouldexit.is_set(): > > +try: > > +atimestr, path = self._ipc.recv().split(' ', 1) > > +atime = float(atimestr) > > +except Exception: # ignore errors > > +pass > > +else: > > +if path in _repocaches and _repocaches[path][0] >= atime: > > +# this repocache is up-to-date, no need to update > > +continue > > +now = time.time() > > +# TODO update repocache properly > > Another concern just came up. Do you know what will happen if the process > is fork()ed while the preloader thread is actively loading cache? > > Only the main thread (which called fork()) would be copied, so the preloader > would stop. That should be okay, but the other resources such as files and > mutexes (if any) would be copied. Right. It's possible to leak some fds, where I think it's probably fine. I guess Python will deal with mutexes created by Python code. ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Re: [PATCH 8 of 8 V2] hgweb: add a "followlines" link to hover-box in annotate
Yuya Nishihara a écrit : On Tue, 28 Feb 2017 16:00:44 -0800, Gregory Szorc wrote: Also, the page it links to showing the revisions with links to a line range filtered diff is good but not great. I imagine developers will complain that it requires too many clicks to go to what they want (the actual line content). IMO it would be *really* useful if there were a single page showing multiple changesets and line range data for either/and a) raw line content b) annotate view c) diff view. That way, developers could scroll and see all versions of that line range. If you were looking at say the history of a function, this would be *extremely* useful compared to loading N pages. This improvement could be done as a follow-up and doesn't need to block this series. When the page gets more dynamically rendered, will we still need the mdiff filtering function? I guess filtering will be handled by js, and we'll need to label all chunks instead of filtering them on server side. I think the mdiff and patch.diff() APIs are the most controversial part in this series. If we can go without them, that would be nice. Maybe filtering can occur in webutil.diffs only, but I seems to me that this would imply parsing diff headers (@@ +start,count -start,count @@). I think that filtering in mdiff/patch.diff is cleaner but I agree that the API is not nice. Also, working on mdiff/patch.diff side will probably be necessary when implementing the command-line version of this feature. ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Re: [PATCH 5 of 8 V2] hgweb: handle "linerange" request parameter in filediff command
Yuya Nishihara a écrit : I got a strange error. Can you take a look? 1. run "hg serve" in mercurial repo 2. open http://localhost:8000/annotate/tip/mercurial/cmdutil.py 3. scroll down to the bottom 4. click "follow lines" link of the last chunk http://localhost:8000/log/ed4d06f180b8/mercurial/cmdutil.py?linerange=3439:3475 We might use a wrong fctx/linerange pair. Indeed, there's a problem in patch 8. This works better: diff --git a/mercurial/hgweb/webcommands.py b/mercurial/hgweb/webcommands.py --- a/mercurial/hgweb/webcommands.py +++ b/mercurial/hgweb/webcommands.py @@ -905,7 +905,7 @@ def annotate(web, req, tmpl): def addlinerange(lines): if lines: linerange = webutil.formatlinerange( -lines[0]['lineno'] - 1, lines[-1]['lineno']) +lines[0]['targetline'] - 1, lines[-1]['targetline']) for l in lines: l['linerange'] = linerange yield l ("lineno" refers to the currently viewed fctx and "targetline" refers to the one we link to) ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Re: [PATCH 1 of 8 V2] revset: factor out linerange processing into a utility function
On Sat, 25 Feb 2017 10:05:58 +0100, Denis Laxalde wrote: > # HG changeset patch > # User Denis Laxalde > # Date 1487957948 -3600 > # Fri Feb 24 18:39:08 2017 +0100 > # Node ID 17c6195ce42f3cbb47cee53aeb4e6a4e5074878a > # Parent abb92b3d370e116b29eba4d2e3154e9691c8edbb > # Available At https://hg.logilab.org/users/dlaxalde/hg > # hg pull https://hg.logilab.org/users/dlaxalde/hg -r > 17c6195ce42f > # EXP-Topic linerange-log/hgweb-filelog > revset: factor out linerange processing into a utility function > diff --git a/mercurial/util.py b/mercurial/util.py > --- a/mercurial/util.py > +++ b/mercurial/util.py > @@ -2122,6 +2122,27 @@ def unitcountfn(*unittable): > > return go > > +def processlinerange(fromline, toline): > +"""Check that linerange : makes sense and return a > +0-based range. > + > +>>> processlinerange(10, 20) > +(9, 20) > +>>> processlinerange(2, 1) > +Traceback (most recent call last): > +... > +ValueError: line range must be positive > +>>> processlinerange(0, 5) > +Traceback (most recent call last): > +... > +ValueError: fromline must be strictly positive > +""" > +if toline - fromline < 0: > +raise ValueError(_("line range must be positive")) > +if fromline < 1: > +raise ValueError(_("fromline must be strictly positive")) > +return fromline - 1, toline Just a nit. Can we just raise ParseError? Carrying non-ascii bytes over Python's standard exception might get surprising in future since the message should be unicode on Python 3. ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
[PATCH RFC] similar: allow similarity detection to use sha256 for digesting file contents
# HG changeset patch # User FUJIWARA Katsunori # Date 1488380487 -32400 # Thu Mar 02 00:01:27 2017 +0900 # Node ID 018d9759cb93f116007d4640341a82db6cf2d45c # Parent 0bb3089fe73527c64f1afc40b86ecb8dfe7fd7aa similar: allow similarity detection to use sha256 for digesting file contents Before this patch, similarity detection logic (used for addremove and automv) uses SHA-1 digesting. But this cause incorrect rename detection, if: - removing file A and adding file B occur at same committing, and - SHA-1 hash values of file A and B are same This may prevent security experts from managing sample files for SHAttered issue in Mercurial repository, for example. https://security.googleblog.com/2017/02/announcing-first-sha1-collision.html https://shattered.it/ Hash collision itself isn't so serious for core repository functionality of Mercurial, described by mpm as below, though. https://www.mercurial-scm.org/wiki/mpm/SHA1 HOW ABOUT: - which should we use default algorithm SHA-1, SHA-256 or SHA-512 ? ease (handling problematic files safely by default) or performance? - what name of config knob is reasonable to control digesting algorithm ? or should we fully switch to more secure digest alrgorithm ? BTW, almost all of SHA-1 clients in Mercurial source tree applies it on other than file contents (e.g. list of parent hash ids, file path, URL, and so on). But some SHA-1 clients below apply it on file contents. - patch.trydiff() SHA-1 is applied on "blob SIZE\0" header + file content (only if experimental.extendedheader.index is enabled) - largefiles The former should be less serious. On the other hand, the latter causes unintentional unification between largefiles, which cause same SHA-1 hash value, at checking files out. diff --git a/mercurial/similar.py b/mercurial/similar.py --- a/mercurial/similar.py +++ b/mercurial/similar.py @@ -12,9 +12,15 @@ import hashlib from .i18n import _ from . import ( bdiff, +error, mdiff, ) +DIGESTERS = { +'sha1': hashlib.sha1, +'sha256': hashlib.sha256, +} + def _findexactmatches(repo, added, removed): '''find renamed files that have no changes @@ -23,19 +29,25 @@ def _findexactmatches(repo, added, remov ''' numfiles = len(added) + len(removed) +digest = repo.ui.config('ui', 'similaritydigest', 'sha256') +if digest not in DIGESTERS: +raise error.ConfigError(_("ui.similaritydigest value is invalid: %s") +% digest) +digester = DIGESTERS[digest] + # Get hashes of removed files. hashes = {} for i, fctx in enumerate(removed): repo.ui.progress(_('searching for exact renames'), i, total=numfiles, unit=_('files')) -h = hashlib.sha1(fctx.data()).digest() +h = digester(fctx.data()).digest() hashes[h] = fctx # For each added file, see if it corresponds to a removed file. for i, fctx in enumerate(added): repo.ui.progress(_('searching for exact renames'), i + len(removed), total=numfiles, unit=_('files')) -h = hashlib.sha1(fctx.data()).digest() +h = digester(fctx.data()).digest() if h in hashes: yield (hashes[h], fctx) ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Re: [PATCH 5 of 8 V2] hgweb: handle "linerange" request parameter in filediff command
On Sat, 25 Feb 2017 10:06:02 +0100, Denis Laxalde wrote: > # HG changeset patch > # User Denis Laxalde > # Date 1484922599 -3600 > # Fri Jan 20 15:29:59 2017 +0100 > # Node ID 7fbe70c91d65683ab3984f7c80edc85f5c02860c > # Parent 6625dfbecf264f51748a96aa7203fc09bee597e9 > # Available At https://hg.logilab.org/users/dlaxalde/hg > # hg pull https://hg.logilab.org/users/dlaxalde/hg -r > 7fbe70c91d65 > # EXP-Topic linerange-log/hgweb-filelog > hgweb: handle "linerange" request parameter in filediff command > diff --git a/mercurial/hgweb/webcommands.py b/mercurial/hgweb/webcommands.py > --- a/mercurial/hgweb/webcommands.py > +++ b/mercurial/hgweb/webcommands.py > @@ -762,7 +762,24 @@ def filediff(web, req, tmpl): > if 'style' in req.form: > style = req.form['style'][0] > > -diffs = webutil.diffs(web.repo, tmpl, ctx, basectx, [path], parity, > style) > +lineranges = {} > +linerange = webutil.linerange(req) > +if linerange is not None: > +assert fctx is not None > +lineranges = {fctx: linerange} > +ancestors = context.blockancestors(fctx, *linerange, > followfirst=True) > +try: > +next(ancestors) # first iteration returns fctx > +p, plinerange = next(ancestors) > +except StopIteration: > +pass > +else: > +lineranges[p] = plinerange > +basectx = p.changectx() > +linerange = webutil.formatlinerange(*linerange) > + > +diffs = webutil.diffs(web.repo, tmpl, ctx, basectx, [path], parity, > style, > + lineranges) > if fctx is not None: > rename = webutil.renamelink(fctx) > ctx = fctx > @@ -774,6 +791,7 @@ def filediff(web, req, tmpl): > symrev=webutil.symrevorshortnode(req, ctx), > rename=rename, > diff=diffs, > +linerange=linerange, > **webutil.commonentry(web.repo, ctx)) I got a strange error. Can you take a look? 1. run "hg serve" in mercurial repo 2. open http://localhost:8000/annotate/tip/mercurial/cmdutil.py 3. scroll down to the bottom 4. click "follow lines" link of the last chunk http://localhost:8000/log/ed4d06f180b8/mercurial/cmdutil.py?linerange=3439:3475 We might use a wrong fctx/linerange pair. ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Re: [PATCH 8 of 8 V2] hgweb: add a "followlines" link to hover-box in annotate
On Tue, 28 Feb 2017 16:00:44 -0800, Gregory Szorc wrote: > Also, the page it links to showing the revisions with links to a line range > filtered diff is good but not great. I imagine developers will complain > that it requires too many clicks to go to what they want (the actual line > content). IMO it would be *really* useful if there were a single page > showing multiple changesets and line range data for either/and a) raw line > content b) annotate view c) diff view. That way, developers could scroll > and see all versions of that line range. If you were looking at say the > history of a function, this would be *extremely* useful compared to loading > N pages. This improvement could be done as a follow-up and doesn't need to > block this series. When the page gets more dynamically rendered, will we still need the mdiff filtering function? I guess filtering will be handled by js, and we'll need to label all chunks instead of filtering them on server side. I think the mdiff and patch.diff() APIs are the most controversial part in this series. If we can go without them, that would be nice. ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Re: [PATCH 4 of 7] color: update main documentation
On Wed, 1 Mar 2017 15:08:32 +0100, Pierre-Yves David wrote: > On 03/01/2017 02:39 PM, Yuya Nishihara wrote: > > On Tue, 28 Feb 2017 20:25:44 +0100, Pierre-Yves David wrote: > >> # HG changeset patch > >> # User Pierre-Yves David > >> # Date 1487703895 -3600 > >> # Tue Feb 21 20:04:55 2017 +0100 > >> # Node ID 84cd9b720b92c6bab764bc172b8cf2795f8e8600 > >> # Parent c65f0cd7a22844c071c888cdd10c2cd625e766c5 > >> # EXP-Topic color > >> color: update main documentation > > > > This needs to update the help table. Should I fix it in flight? > > Good catch ☺ Maybe we need a test (as we have with the wix). > > You can fix it inflight if you want but I can also submit a new patches. > Just let me know. I lost the acceptance race, so please send a followup. ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
mercurial@31128: 16 new changesets (2 on stable)
16 new changesets (2 on stable) in mercurial: https://www.mercurial-scm.org/repo/hg/rev/268caf97c38f changeset: 31113:268caf97c38f user:Pierre-Yves David date:Sat Feb 25 15:00:51 2017 +0100 summary: color: move the dict with terminfo parameters on the ui object https://www.mercurial-scm.org/repo/hg/rev/1613c55ad3d6 changeset: 31114:1613c55ad3d6 user:Pierre-Yves David date:Sun Nov 06 20:10:53 2016 +0100 summary: color: pass 'ui' to 'win32print' https://www.mercurial-scm.org/repo/hg/rev/f5131d4f512a changeset: 31115:f5131d4f512a user:Pierre-Yves David date:Sun Nov 06 20:16:01 2016 +0100 summary: color: move 'styles' definition on the 'ui' object https://www.mercurial-scm.org/repo/hg/rev/6483e49204ee changeset: 31116:6483e49204ee user:Pierre-Yves David date:Sun Nov 06 20:16:54 2016 +0100 summary: color: rename '_styles' to '_defaultstyles' for clarity https://www.mercurial-scm.org/repo/hg/rev/92bca12328d1 changeset: 31117:92bca12328d1 branch: stable parent: 31065:7074589cf22a user:Yuya Nishihara date:Sat Feb 25 12:33:37 2017 +0900 summary: worker: add basic test to ensure child processes are managed well https://www.mercurial-scm.org/repo/hg/rev/a91c62752d08 changeset: 31118:a91c62752d08 branch: stable user:Yuya Nishihara date:Sat Feb 25 12:48:50 2017 +0900 summary: worker: flush messages written by child processes before exit https://www.mercurial-scm.org/repo/hg/rev/13bbcd56c57a changeset: 31119:13bbcd56c57a parent: 31116:6483e49204ee parent: 31118:a91c62752d08 user:Martin von Zweigbergk date:Tue Feb 28 11:13:25 2017 -0800 summary: merge with stable https://www.mercurial-scm.org/repo/hg/rev/c4e8fa2b1c40 changeset: 31120:c4e8fa2b1c40 user:Pierre-Yves David date:Tue Feb 21 18:41:37 2017 +0100 summary: color: move 'debugcolor' into the 'debugcommands' modules https://www.mercurial-scm.org/repo/hg/rev/8fc55bbd2235 changeset: 31121:8fc55bbd2235 user:Pierre-Yves David date:Sat Feb 25 19:43:14 2017 +0100 summary: color: cleanup 'debugcolor' logic https://www.mercurial-scm.org/repo/hg/rev/53a60e95f154 changeset: 31122:53a60e95f154 user:Pierre-Yves David date:Tue Feb 28 20:12:08 2017 +0100 summary: pager: drop the 'color' dependant code https://www.mercurial-scm.org/repo/hg/rev/df0a0734304a changeset: 31123:df0a0734304a user:Pierre-Yves David date:Tue Feb 21 20:04:55 2017 +0100 summary: color: update main documentation https://www.mercurial-scm.org/repo/hg/rev/791ea883fc44 changeset: 31124:791ea883fc44 user:Pierre-Yves David date:Tue Feb 21 22:17:33 2017 +0100 summary: config: suggest the 'ui.color' instead of the 'color' extension https://www.mercurial-scm.org/repo/hg/rev/01a0ea04c372 changeset: 31125:01a0ea04c372 user:Pierre-Yves David date:Tue Feb 21 22:53:38 2017 +0100 summary: help: use 'churn' instead of 'color' as an example extension https://www.mercurial-scm.org/repo/hg/rev/1b065fa21b00 changeset: 31126:1b065fa21b00 user:Pierre-Yves David date:Tue Feb 28 20:23:10 2017 +0100 summary: config: update the Windows example config file https://www.mercurial-scm.org/repo/hg/rev/90fb0193f187 changeset: 31127:90fb0193f187 user:Yuya Nishihara date:Sat Feb 18 17:37:52 2017 +0900 summary: smartset: reorder initialization of baseset in more intuitive way https://www.mercurial-scm.org/repo/hg/rev/0bb3089fe735 changeset: 31128:0bb3089fe735 bookmark:@ tag: tip user:Yuya Nishihara date:Sat Feb 25 14:09:55 2017 +0900 summary: ui: remove superfluous indent in _write() -- 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
Re: [PATCH 6 of 7] help: use 'churn' instead of 'color' as an example extension
> On Feb 28, 2017, at 14:25, Pierre-Yves David > wrote: > > # HG changeset patch > # User Pierre-Yves David > # Date 1487714018 -3600 > # Tue Feb 21 22:53:38 2017 +0100 > # Node ID 9fffdf9b71de54fba36d3efd581aa660ab8076d1 > # Parent 63ff941fd53a11b8e295db36f3787f60ef0c9ceb > # EXP-Topic color > help: use 'churn' instead of 'color' as an example extension > > The 'color' extensions is now deprecated. > > diff --git a/mercurial/help/config.txt b/mercurial/help/config.txt > --- a/mercurial/help/config.txt > +++ b/mercurial/help/config.txt > @@ -728,8 +728,8 @@ or ``foo = !`` when path is not supplied > Example for ``~/.hgrc``:: > > [extensions] > - # (the color extension will get loaded from Mercurial's path) > - color = > + # (the churn extension will get loaded from Mercurial's path) > + churn = nit: Would purge be a better thing to advertise here? Just trying to think of something that's likely to be of immediate interest to a typical user. I'm happy to send a follow-up if we've got any consensus. (I would have said shelve, but I think I'd like to wait on that one until the implementation is a bit more robust) > # (this extension will get loaded from the file specified) > myfeature = ~/.hgext/myfeature.py > > ___ > Mercurial-devel mailing list > Mercurial-devel@mercurial-scm.org > https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Re: [PATCH 4 of 7] color: update main documentation
On 03/01/2017 02:39 PM, Yuya Nishihara wrote: On Tue, 28 Feb 2017 20:25:44 +0100, Pierre-Yves David wrote: # HG changeset patch # User Pierre-Yves David # Date 1487703895 -3600 # Tue Feb 21 20:04:55 2017 +0100 # Node ID 84cd9b720b92c6bab764bc172b8cf2795f8e8600 # Parent c65f0cd7a22844c071c888cdd10c2cd625e766c5 # EXP-Topic color color: update main documentation This needs to update the help table. Should I fix it in flight? Good catch ☺ Maybe we need a test (as we have with the wix). You can fix it inflight if you want but I can also submit a new patches. Just let me know. diff --git a/mercurial/help.py b/mercurial/help.py --- a/mercurial/help.py +++ b/mercurial/help.py @@ -208,6 +208,7 @@ def internalshelp(ui): return ''.join(lines) helptable = sorted([ +(['color'], _("Colorizing Outputs"), loaddoc('color')), (["config", "hgrc"], _("Configuration Files"), loaddoc('config')), (["dates"], _("Date Formats"), loaddoc('dates')), (["patterns"], _("File Name Patterns"), loaddoc('patterns')), -- Pierre-Yves David ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
[Bug 5493] New: ISAPI_WSGI module not work anymore in 4.1 version
https://bz.mercurial-scm.org/show_bug.cgi?id=5493 Bug ID: 5493 Summary: ISAPI_WSGI module not work anymore in 4.1 version Product: Mercurial Version: stable branch Hardware: PC OS: Windows Status: UNCONFIRMED Severity: bug Priority: wish Component: hgweb Assignee: bugzi...@mercurial-scm.org Reporter: vbolsha...@gmail.com CC: mercurial-devel@mercurial-scm.org ISAPI_WSGI module build from 4.1 version not starting with this message: Internal Extension Error: Failed to import callback module 'hgwebdir_wsgi' Traceback (most recent call last): File "D:\Mercurial\NEW\hgwebdir_wsgi.py", line 27, in from mercurial.hgweb.hgwebdir_mod import hgwebdir File "D:\AppPython\hg\Lib\site-packages\mercurial-4.1-py2.7-win-amd64.egg\mercurial\hgweb\__init__.py", line 13, in from ..i18n import _ File "D:\AppPython\hg\Lib\site-packages\mercurial-4.1-py2.7-win-amd64.egg\mercurial\i18n.py", line 15, in from . import ( File "D:\AppPython\hg\Lib\site-packages\mercurial-4.1-py2.7-win-amd64.egg\mercurial\encoding.py", line 15, in from . import ( File "D:\AppPython\hg\Lib\site-packages\mercurial-4.1-py2.7-win-amd64.egg\mercurial\pycompat.py", line 168, in sysargv = sys.argv AttributeError: 'module' object has no attribute 'argv' Same ISAPI_WSGI module build from 4.0.2 version work without any problems. -- You are receiving this mail because: You are on the CC list for the bug. ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Re: [PATCH 4 of 7] color: update main documentation
On Tue, 28 Feb 2017 20:25:44 +0100, Pierre-Yves David wrote: > # HG changeset patch > # User Pierre-Yves David > # Date 1487703895 -3600 > # Tue Feb 21 20:04:55 2017 +0100 > # Node ID 84cd9b720b92c6bab764bc172b8cf2795f8e8600 > # Parent c65f0cd7a22844c071c888cdd10c2cd625e766c5 > # EXP-Topic color > color: update main documentation This needs to update the help table. Should I fix it in flight? diff --git a/mercurial/help.py b/mercurial/help.py --- a/mercurial/help.py +++ b/mercurial/help.py @@ -208,6 +208,7 @@ def internalshelp(ui): return ''.join(lines) helptable = sorted([ +(['color'], _("Colorizing Outputs"), loaddoc('color')), (["config", "hgrc"], _("Configuration Files"), loaddoc('config')), (["dates"], _("Date Formats"), loaddoc('dates')), (["patterns"], _("File Name Patterns"), loaddoc('patterns')), ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Re: [PATCH 3 of 4 V2] chgcache: implement the background preloading thread
On Wed, 22 Feb 2017 18:16:10 -0800, Jun Wu wrote: > # HG changeset patch > # User Jun Wu > # Date 1487813979 28800 > # Wed Feb 22 17:39:39 2017 -0800 > # Node ID 28571825744fb4f4b424385f55afa9484532ef43 > # Parent 630457e88fa0485bce7822345ea640b5cdcb9b8e > # Available At https://bitbucket.org/quark-zju/hg-draft > # hg pull https://bitbucket.org/quark-zju/hg-draft -r > 28571825744f > chgcache: implement the background preloading thread > > The background preloading thread is meant to used by chg master, and it sets > up the IPC channel. > +def _preloadloop(self, interval=0.5): > +while not self._shouldexit.is_set(): > +try: > +atimestr, path = self._ipc.recv().split(' ', 1) > +atime = float(atimestr) > +except Exception: # ignore errors > +pass > +else: > +if path in _repocaches and _repocaches[path][0] >= atime: > +# this repocache is up-to-date, no need to update > +continue > +now = time.time() > +# TODO update repocache properly Another concern just came up. Do you know what will happen if the process is fork()ed while the preloader thread is actively loading cache? Only the main thread (which called fork()) would be copied, so the preloader would stop. That should be okay, but the other resources such as files and mutexes (if any) would be copied. ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Re: [PATCH 2 of 7] color: initialize color for local peer ui
On Tue, 28 Feb 2017 16:44:36 +0100, Pierre-Yves David wrote: > On 02/28/2017 03:29 PM, Yuya Nishihara wrote: > > On Tue, 28 Feb 2017 11:35:03 +0100, Pierre-Yves David wrote: > >> On 02/28/2017 11:24 AM, Pierre-Yves David wrote: > >>> On 02/28/2017 07:57 AM, Martin von Zweigbergk wrote: > On Mon, Feb 27, 2017 at 6:59 AM, Pierre-Yves David > wrote: > > # HG changeset patch > > # User Pierre-Yves David > > # Date 1488044041 -3600 > > # Sat Feb 25 18:34:01 2017 +0100 > > # Node ID c3224694bdae9cdb7530f952e2c767e419b7f280 > > # Parent 92526381242cd381375a465d5a800446916d2d7b > > # EXP-Topic color > > color: initialize color for local peer ui > > > > The local peer > > "local peer" or "localrepository"? The patch seems to be in "class > localrepository". > >>> > >>> hum, good catch. Things seems clowner than I expected. It looks like we > >>> don't use the "lui" (local ui, goes through uisetup) to create the > >>> repository but the "baseui" (does not goes through uisetup). > >>> > >>> Let me grab a shovel and go bad into that code. > >> > >> Okay so in short "ui initialisation business is not simple". That > >> description should be: > >> > >> color: initialize color for the localrepo ui > >> > >> The 'ui' object dedicated to a 'localrepo' is independant from the one > >> available in dispatch (and 'uisetup'). In addition, it is created from > >> the 'baseui' (for good reason apparently). For this reason, we need to > >> run the color setup on it after the local repository config is read. > > > > Maybe we can move color.setup() to ui.fixconfig(), where ui attributes are > > updated reflecting to config changes. > > I considered it but it did not seemed appropriate. Fixconfig is run > quite often and the setup function is erasing most internal state > related to color. I was not confident make that change. I'm not saying > it is entirely impossible but that requires a careful review of the > setup process and other fixconfig related thing. So I would rather not > go this route for now. In particular, running during 'fixconfig' would > mean running it 'too early' before the extensions are loaded (they might > change the default style. Good point and agreed. It would be nice if we can get rid of the color dependency from localrepo in future. ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
mercurial@31112: 4 new changesets
4 new changesets in mercurial: https://www.mercurial-scm.org/repo/hg/rev/53230c5bb273 changeset: 31109:53230c5bb273 user:Pierre-Yves David date:Tue Feb 28 11:42:07 2017 +0100 summary: color: reinvent dictionary https://www.mercurial-scm.org/repo/hg/rev/7fec37746417 changeset: 31110:7fec37746417 user:Pierre-Yves David date:Sat Feb 25 19:44:23 2017 +0100 summary: color: add a 'ui.color' option to control color behavior https://www.mercurial-scm.org/repo/hg/rev/95ec3ad62f62 changeset: 3:95ec3ad62f62 bookmark:@ user:Pierre-Yves David date:Sat Feb 25 18:34:01 2017 +0100 summary: color: initialize color for the localrepo ui https://www.mercurial-scm.org/repo/hg/rev/7f056fdbe37e changeset: 31112:7f056fdbe37e tag: tip user:Pierre-Yves David date:Sat Feb 25 15:00:44 2017 +0100 summary: color: add ui to effect rendering -- 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
Re: [PATCH 8 of 8 V2] hgweb: add a "followlines" link to hover-box in annotate
Gregory Szorc a écrit : On Sat, Feb 25, 2017 at 1:06 AM, Denis Laxalde wrote: # HG changeset patch # User Denis Laxalde # Date 1487773255 -3600 # Wed Feb 22 15:20:55 2017 +0100 # Node ID f1d1d7bcba3cd86787117cd44616ad1a5c619c5e # Parent 073bd73b65afcb2acd4783c14cb2983ef21fb5a6 # Available At https://hg.logilab.org/users/dlaxalde/hg # hg pull https://hg.logilab.org/users/dlaxalde/hg -r f1d1d7bcba3c # EXP-Topic linerange-log/hgweb-filelog hgweb: add a "followlines" link to hover-box in annotate The hover-box on line numbers in annotate view now holds a "follow lines :" link where ':' corresponds to the range of line numbers annotated by a given revision. This link points to the filelog view where the log is filtered to only include revisions changing the line range at stake (through `?linerange=:` query parameter). From this view, one can follow "diff" links which also points to filediff view with only selected line range visible. I'm going to gently push back and question the utility of this feature. First, obviously there are some killer features for looking at history of a range of lines. But I'm questioning whether this specific implementation adds enough value. I'm glad you do this since I wasn't myself much convinced of the added value of this feature. This is just the simplest way of exposing the "URL-based API" introduced in previous patches that I could think of at the moment and I did not want to invest more in something fancier before having discussions. (Basically "forgot" the trailing (RFC) in commit message's first line.) The annotate hover box as implemented in this patch links to a page showing a list of revisions touching those lines. That's useful. But I argue it is less useful than the following alternatives: * Show history for just this line * Show history for this function * Show history for a range of lines I specify The reason is (and this could just be my own experience biasing me) that the annotate block rarely maps to the unit being investigated when doing code archeology. When I'm looking at the annotate history of a file, I'm usually investigating a specific line, function, or range of lines. The annotate blocks don't map cleanly to those because in well-established files with lots of history, the annotate blocks are effectively random noise in terms of lines they cover. So with this implementation, there are many scenarios where the line range block is too small or too wide. I suppose looking at the line history of an annotate block is better than nothing and you have to start somewhere. But there are far more useful implementations IMO. I totally agree. I think one way to achieve a more interesting exposure of this feature would be to start from /file// view and have a way to select a range of lines. One simple thing would be to implement form with two elements in the header of the view. This my second choice for a "quickstart" implementation because I though having a form on top of the page would require too much scrolling and line-counting. One fancier idea would be take advantage of highlighting with pygments to let the user select the range of lines based on language tokens (not sure how big this task would be though). Also, the page it links to showing the revisions with links to a line range filtered diff is good but not great. I imagine developers will complain that it requires too many clicks to go to what they want (the actual line content). IMO it would be *really* useful if there were a single page showing multiple changesets and line range data for either/and a) raw line content b) annotate view c) diff view. That way, developers could scroll and see all versions of that line range. If you were looking at say the history of a function, this would be *extremely* useful compared to loading N pages. This improvement could be done as a follow-up and doesn't need to block this series. I can work on a ?patch=1 URL API (mimicking `hg log -p`) that would indeed be useful in this context. Again, this is great work and this is going to be a great feature. When this is complete, I anticipate the feature being stolen by Bitbucket, GitLab, GitHub, and others, as it is really a killer feature for code archeology. Thanks :) ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
[Bug 5492] New: Mercurial does not preserver unix ACL in '.hg.'
https://bz.mercurial-scm.org/show_bug.cgi?id=5492 Bug ID: 5492 Summary: Mercurial does not preserver unix ACL in '.hg.' Product: Mercurial Version: 4.1 Hardware: PC OS: Linux Status: UNCONFIRMED Severity: feature Priority: wish Component: Mercurial Assignee: bugzi...@mercurial-scm.org Reporter: pierre-yves.da...@ens-lyon.org CC: mercurial-devel@mercurial-scm.org Mercurial is successfully preserving the unix standard permission of file in '.hg/' (it us the same one as the one on '.hg/') but it does not perserve the unix ACL. Note that many unix tool also ignores ACL so Mercurial is not doing especially bad here. In addition ACL support is non-trivial since Python itself does not support interacting with ACL natively. But it is still worth tracking the issue, we might be able to do some progress. There is a Python module to handle ACL (https://pypi.python.org/pypi/PyACL). We could add support for ACL preservation if the module exists and maybe vendor it? -- You are receiving this mail because: You are on the CC list for the bug. ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel