From mads at kiilerich.com Fri Feb 1 03:38:21 2013 From: mads at kiilerich.com (Mads Kiilerich) Date: Fri, 01 Feb 2013 10:38:21 +0100 Subject: [PATCH STABLE] hgweb: remove baseline info from paper template In-Reply-To: <80f3dd3aa40280e97289.1359693810@yamac.lan> References: <1359563519.4200.7.camel@calx> <80f3dd3aa40280e97289.1359693810@yamac.lan> Message-ID: <510B8D0D.6020202@kiilerich.com> On 02/01/2013 05:43 AM, Pierre-Yves David wrote: > # HG changeset patch > # User Pierre-Yves David > # Date 1359693606 -3600 > # Branch stable > # Node ID 80f3dd3aa40280e97289153455b493c727ef0a52 > # Parent 2a1fac3650a5b4d650198604c82ab59969500374 > hgweb: remove baseline info from paper template > > The user interface is not considered ready for prime time yet. The internal code stay in > place custom template usage. The feature is ultimatly wished and will be > reenabled soon. The current issue is only related to the visual of the current > interface. A reference to the revision that introduced the feature, please. The template keyword 'currentbaseline' is also very strange - there is no 'baseline' concept anywhere in Mercurial. In 'changeset' it should be something like 'diffparent'. Diff between arbitrary revisions belongs elsewhere - and then it would be more descriptive to call the two nodes 'anode' and 'bnode'. So I suggest removing the keyword too so we can change it without breaking backward compatibility. Actually I suggest backing out the full feature until it is ready. /Mads > > diff --git a/mercurial/templates/paper/changeset.tmpl b/mercurial/templates/paper/changeset.tmpl > --- a/mercurial/templates/paper/changeset.tmpl > +++ b/mercurial/templates/paper/changeset.tmpl > @@ -72,18 +72,10 @@ files, or words in the commit message

> {diffstat}
> > > > - > - change baseline > - {parent%changesetbaseline} > - > - > - current baseline > - {currentbaseline|short} > - > > >

>
line diff
> > diff --git a/tests/test-hgweb-commands.t b/tests/test-hgweb-commands.t > --- a/tests/test-hgweb-commands.t > +++ b/tests/test-hgweb-commands.t > @@ -445,18 +445,10 @@ Logs and changes > > >
> > > - > - change baseline > - > - > - > - current baseline > - 000000000000 > - > > >
>
line diff
> > diff --git a/tests/test-hgweb-diffs.t b/tests/test-hgweb-diffs.t > --- a/tests/test-hgweb-diffs.t > +++ b/tests/test-hgweb-diffs.t > @@ -137,18 +137,10 @@ revision > > >
> > > - > - change baseline > - > - > - > - current baseline > - 000000000000 > - > > >
>
line diff
> > @@ -406,18 +398,10 @@ revision > > >
> > > - > - change baseline > - > - > - > - current baseline > - 000000000000 > - > > >
>
line diff
> > diff --git a/tests/test-hgweb-removed.t b/tests/test-hgweb-removed.t > --- a/tests/test-hgweb-removed.t > +++ b/tests/test-hgweb-removed.t > @@ -110,18 +110,10 @@ revision > > >
> > > - > - change baseline > - cb9a9f314b8b > - > - > - current baseline > - cb9a9f314b8b > - > > >
>
line diff
> > _______________________________________________ > Mercurial-devel mailing list > Mercurial-devel at selenic.com > http://selenic.com/mailman/listinfo/mercurial-devel From thomas at intevation.de Fri Feb 1 03:49:50 2013 From: thomas at intevation.de (Thomas Arendsen Hein) Date: Fri, 1 Feb 2013 10:49:50 +0100 Subject: [PATCH STABLE] hgweb: remove baseline info from paper template In-Reply-To: <510B8D0D.6020202@kiilerich.com> References: <1359563519.4200.7.camel@calx> <80f3dd3aa40280e97289.1359693810@yamac.lan> <510B8D0D.6020202@kiilerich.com> Message-ID: <20130201104540.827958150.thomas@intevation.de> * Mads Kiilerich [20130201 10:38]: > On 02/01/2013 05:43 AM, Pierre-Yves David wrote: > ># HG changeset patch > ># User Pierre-Yves David > ># Date 1359693606 -3600 > ># Branch stable > ># Node ID 80f3dd3aa40280e97289153455b493c727ef0a52 > ># Parent 2a1fac3650a5b4d650198604c82ab59969500374 > >hgweb: remove baseline info from paper template > > > >The user interface is not considered ready for prime time yet. The internal code stay in > >place custom template usage. The feature is ultimatly wished and will be > >reenabled soon. The current issue is only related to the visual of the current > >interface. > > A reference to the revision that introduced the feature, please. Yes, create an issue and include the number. > The template keyword 'currentbaseline' is also very strange - there > is no 'baseline' concept anywhere in Mercurial. In 'changeset' it > should be something like 'diffparent'. Diff between arbitrary > revisions belongs elsewhere - and then it would be more descriptive > to call the two nodes 'anode' and 'bnode'. > > So I suggest removing the keyword too so we can change it without > breaking backward compatibility. Actually I suggest backing out the > full feature until it is ready. I'd vote to keep the code as it generally works and anyone who is able to create templates based on this should be able to do a search/replace on the keywords later. Regards, Thomas -- thomas at intevation.de - http://intevation.de/~thomas/ - OpenPGP key: 0x5816791A Intevation GmbH, Neuer Graben 17, 49074 Osnabrueck - AG Osnabrueck, HR B 18998 Geschaeftsfuehrer: Frank Koormann, Bernhard Reiter, Dr. Jan-Oliver Wagner From pierre-yves.david at logilab.fr Fri Feb 1 04:11:49 2013 From: pierre-yves.david at logilab.fr (Pierre-Yves David) Date: Fri, 1 Feb 2013 11:11:49 +0100 Subject: [PATCH STABLE] hgweb: remove baseline info from paper template In-Reply-To: <510B8D0D.6020202@kiilerich.com> References: <1359563519.4200.7.camel@calx> <80f3dd3aa40280e97289.1359693810@yamac.lan> <510B8D0D.6020202@kiilerich.com> Message-ID: <20130201101149.GA26678@crater2.logilab.fr> On Fri, Feb 01, 2013 at 10:38:21AM +0100, Mads Kiilerich wrote: > On 02/01/2013 05:43 AM, Pierre-Yves David wrote: > ># HG changeset patch > ># User Pierre-Yves David > ># Date 1359693606 -3600 > ># Branch stable > ># Node ID 80f3dd3aa40280e97289153455b493c727ef0a52 > ># Parent 2a1fac3650a5b4d650198604c82ab59969500374 > >hgweb: remove baseline info from paper template > > > >The user interface is not considered ready for prime time yet. The internal code stay in > >place custom template usage. The feature is ultimatly wished and will be > >reenabled soon. The current issue is only related to the visual of the current > >interface. > > A reference to the revision that introduced the feature, please. good point, that's d605a82cf189 > The template keyword 'currentbaseline' is also very strange - there > is no 'baseline' concept anywhere in Mercurial. In 'changeset' it > should be something like 'diffparent'. Diff between arbitrary > revisions belongs elsewhere - and then it would be more descriptive > to call the two nodes 'anode' and 'bnode'. Yes baseline sound wrong and is not used anywhere in Mercurial. not even in d605a82cf189 description. > So I suggest removing the keyword too so we can change it without > breaking backward compatibility. Actually I suggest backing out the > full feature until it is ready. Bah, not sure about that. The code works so we can keep it arround but not advertise the keywork name for now -- Pierre-Yves David http://www.logilab.fr/ -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 198 bytes Desc: Digital signature URL: From mads at kiilerich.com Fri Feb 1 04:25:42 2013 From: mads at kiilerich.com (Mads Kiilerich) Date: Fri, 01 Feb 2013 11:25:42 +0100 Subject: [PATCH STABLE] icasefs: improve rename awareness of case-folding collision detection (issue3452) In-Reply-To: <3eca4bf6f77f64a83835.1359683069@juju> References: <3eca4bf6f77f64a83835.1359683069@juju> Message-ID: <510B9826.3060701@kiilerich.com> On 02/01/2013 02:44 AM, FUJIWARA Katsunori wrote: > # HG changeset patch > # User FUJIWARA Katsunori > # Date 1359682698 -32400 > # Branch stable > # Node ID 3eca4bf6f77f64a83835466f9b07022f5152a219 > # Parent 2a1fac3650a5b4d650198604c82ab59969500374 > icasefs: improve rename awareness of case-folding collision detection (issue3452) > > Before this patch, merging at (6) in the example below is aborted for > case-folding collision unexpectedly, because 'a' at (4) and 'A' at (5) > aren't recognized as source/destination of renaming. > > (0) -- (2) -- (4) ------- > \ \ \ > \ \ \ > (1) -- (3) -- (5) -- (6) > > 0: add file 'a' > 1: rename from 'a' to 'A' > 2: add file 'x' > 3: merge > 4: modify 'a' > 5: modify 'A' > 6: merge > > "copies.pathcopies()" used for case-folding collision detection scans > filelog entries only for the revisions which are grater than common > ancestor of merged revisions: in the example above, renaming from 'a' > to 'A' at (1) is not scanned in the merging at (6), because common > ancestor of merged revisions is (2) in this case. > > "copies.mergecopies()" can detect renaming in such case. > > But in the other hand, in the case merging branches without > modification of renamed file (= issue3370 case), like (3) in the > example above, "copies.mergecopies()" can't detect renaming. > > So, this patch uses both "copies.pathcopies()" and > "copies.mergecopies()". > > To prevent "copies.mergecopies()" from being called in > "manifestmerge()" again, "_checkcollision()" returns result of it, and > "manifestmerge()" reuses it, if it is invoked in "_checkcollision()". A tricky one ... It is also not exactly a one-liner patch. Considering the size of the patch, the frequency this case is hit, the impact when it is hit, and the timing: I don't think this is for stable now. Doing it right seems to require some refactorings - and it would be better to do it right. Some overall comments: It is a bit messy that it calls copies.mergecopies from different places far from each other. A first improvement to the patch would be to calculate it and pass it as a parameter to _checkcollision. It is also not obvious why we have the separation between calculateupdates and manifestmerge. You demonstrate that we sometimes need copies.mergecopies in calculateupdates, sometimes in manifestmerge. I think it would be better to start with a refactoring that merges calculateupdates into manifestmerge. It seems like that would simplify things. And ... > diff --git a/hgext/largefiles/overrides.py b/hgext/largefiles/overrides.py > --- a/hgext/largefiles/overrides.py > +++ b/hgext/largefiles/overrides.py > @@ -360,8 +360,9 @@ > # Finally, the merge.applyupdates function will then take care of > # writing the files into the working copy and lfcommands.updatelfiles > # will update the largefiles. > -def overridemanifestmerge(origfn, repo, p1, p2, pa, overwrite, partial): > - actions = origfn(repo, p1, p2, pa, overwrite, partial) > +def overridemanifestmerge(origfn, repo, p1, p2, pa, overwrite, partial, > + mergecopies=None): > + actions = origfn(repo, p1, p2, pa, overwrite, partial, mergecopies) > processed = [] > > for action in actions: > diff --git a/mercurial/merge.py b/mercurial/merge.py > --- a/mercurial/merge.py > +++ b/mercurial/merge.py > @@ -141,21 +141,33 @@ > if extractxs: > wctx, actx = extractxs > # class to delay looking up copy mapping > - class pathcopies(object): > + class copymap(object): > + def __init__(self): > + self._mergecopies = None > @util.propertycache > - def map(self): > + def pathcopies(self): > # {dst at mctx: src at wctx} copy mapping > return copies.pathcopies(wctx, mctx) > - pc = pathcopies() > + @util.propertycache > + def mergecopies(self): > + self._mergecopies = copies.mergecopies(wctx._repo, > + wctx, mctx, actx) > + return self._mergecopies[0] Calling the property mergecopies but only returning mergecopies[0] seems a bit confusing. > + def find(self, f1, f2): > + return (self.pathcopies.get(f1) == f2 or > + self.mergecopies.get(f1) == f2 or > + self.mergecopies.get(f2) == f1) > + cm = copymap() > > for fn in wctx: > fold = util.normcase(fn) > mfn = folded.get(fold, None) > - if (mfn and mfn != fn and pc.map.get(mfn) != fn and > + if (mfn and mfn != fn and not cm.find(mfn, fn) and > _remains(fn, wctx.manifest(), actx.manifest(), True) and > _remains(mfn, mctx.manifest(), actx.manifest())): > raise util.Abort(_("case-folding collision between %s and %s") > % (mfn, fn)) > + return cm._mergecopies Why make it private when you access it from the outside anyway? > > def _forgetremoved(wctx, mctx, branchmerge): > """ > @@ -185,7 +197,7 @@ > > return actions > > -def manifestmerge(repo, p1, p2, pa, overwrite, partial): > +def manifestmerge(repo, p1, p2, pa, overwrite, partial, mergecopies=None): > """ > Merge p1 and p2 with ancestor pa and generate merge action list > > @@ -204,7 +216,7 @@ > elif pa == p2: # backwards > pa = p1.p1() > elif pa and repo.ui.configbool("merge", "followcopies", True): > - ret = copies.mergecopies(repo, p1, p2, pa) > + ret = mergecopies or copies.mergecopies(repo, p1, p2, pa) > copy, movewithdir, diverge, renamedelete = ret > for of, fl in diverge.iteritems(): > act("divergent renames", "dr", of, fl) > @@ -440,13 +452,14 @@ > "Calculate the actions needed to merge mctx into tctx" > actions = [] > folding = not util.checkcase(repo.path) > + mergecopies = None > if folding: > # collision check is not needed for clean update > if (not branchmerge and > (force or not tctx.dirty(missing=True, branch=False))): > _checkcollision(mctx, None) > else: > - _checkcollision(mctx, (tctx, ancestor)) > + mergecopies = _checkcollision(mctx, (tctx, ancestor)) > if not force: > _checkunknown(repo, tctx, mctx) > if tctx.rev() is None: > @@ -454,7 +467,8 @@ > actions += manifestmerge(repo, tctx, mctx, > ancestor, > force and not branchmerge, > - partial) > + partial, > + mergecopies) > return actions > > def recordupdates(repo, actions, branchmerge): > diff --git a/tests/test-casecollision-merge.t b/tests/test-casecollision-merge.t > --- a/tests/test-casecollision-merge.t > +++ b/tests/test-casecollision-merge.t > @@ -22,33 +22,53 @@ > $ hg commit -m '#1' > $ hg update 0 > 1 files updated, 0 files merged, 1 files removed, 0 files unresolved > - $ echo 'modified at #2' > a > + $ echo x > x > + $ hg add x > $ hg commit -m '#2' > created new head > > - $ hg merge > - merging a and A to A > - 0 files updated, 1 files merged, 0 files removed, 0 files unresolved > - (branch merge, don't forget to commit) > + $ hg merge -q > + $ hg status -A > + M A > + R a > + C x > + > + $ hg update -q --clean 1 > + $ hg merge -q > + $ hg status -A > + M x > + C A > + > +additional test for issue3452: > + > + $ hg commit -m '#3' > + > + $ hg update -q --clean 2 > + $ echo 'a at 4' > a > + $ hg commit -m '#4' > + created new head > + > + $ hg update -q --clean 3 > + $ echo 'A at 5' > A > + $ hg commit -m '#5' > + > + $ hg merge -q --tool internal:other 4 > $ hg status -A > M A > a > - R a > + C x > $ cat A > - modified at #2 > + a at 4 > > - $ hg update --clean 1 > - 1 files updated, 0 files merged, 0 files removed, 0 files unresolved > - $ hg merge > - merging A and a to A > - 0 files updated, 1 files merged, 0 files removed, 0 files unresolved > - (branch merge, don't forget to commit) > - $ hg status -A > + $ hg update -q --clean 4 > + $ hg merge -q --tool internal:other 5 > + $ hg statu -A Reusing tests is fine, but refactoring tests while doing a fix makes it very hard to see whether the fix actually introduces a regression. Please separate them somehow - for example by an initial 'refactor test' or 'improve test coverage' patch. > M A > a > + R a > + C x > $ cat A > - modified at #2 > - > + A at 5 > $ cd .. > > (2) colliding file is not related to collided file /Mads From mads at kiilerich.com Fri Feb 1 04:40:43 2013 From: mads at kiilerich.com (Mads Kiilerich) Date: Fri, 01 Feb 2013 11:40:43 +0100 Subject: [PATCH STABLE] hgweb: remove baseline info from paper template In-Reply-To: <20130201101149.GA26678@crater2.logilab.fr> References: <1359563519.4200.7.camel@calx> <80f3dd3aa40280e97289.1359693810@yamac.lan> <510B8D0D.6020202@kiilerich.com> <20130201101149.GA26678@crater2.logilab.fr> Message-ID: <510B9BAB.1080001@kiilerich.com> On 02/01/2013 11:11 AM, Pierre-Yves David wrote: > On Fri, Feb 01, 2013 at 10:38:21AM +0100, Mads Kiilerich wrote: >> On 02/01/2013 05:43 AM, Pierre-Yves David wrote: >>> # HG changeset patch >>> # User Pierre-Yves David >>> # Date 1359693606 -3600 >>> # Branch stable >>> # Node ID 80f3dd3aa40280e97289153455b493c727ef0a52 >>> # Parent 2a1fac3650a5b4d650198604c82ab59969500374 >>> hgweb: remove baseline info from paper template >>> >>> The user interface is not considered ready for prime time yet. The internal code stay in >>> place custom template usage. The feature is ultimatly wished and will be >>> reenabled soon. The current issue is only related to the visual of the current >>> interface. >> A reference to the revision that introduced the feature, please. > good point, that's d605a82cf189 > >> The template keyword 'currentbaseline' is also very strange - there >> is no 'baseline' concept anywhere in Mercurial. In 'changeset' it >> should be something like 'diffparent'. Diff between arbitrary >> revisions belongs elsewhere - and then it would be more descriptive >> to call the two nodes 'anode' and 'bnode'. > Yes baseline sound wrong and is not used anywhere in Mercurial. not even > in d605a82cf189 description. > >> So I suggest removing the keyword too so we can change it without >> breaking backward compatibility. Actually I suggest backing out the >> full feature until it is ready. > Bah, not sure about that. The code works so we can keep it arround but > not advertise the keywork name for now Sure - it will be kept around in history after a backout and we can back it in again when it is ready. Leaving it (temporarily) as unused and untested code do not sound like a good idea to me. /Mads From hg at intevation.org Fri Feb 1 06:00:04 2013 From: hg at intevation.org (Mercurial Commits) Date: Fri, 01 Feb 2013 13:00:04 +0100 Subject: hg-i18n@18516: 2 outgoing changesets (2 stable) Message-ID: <1359720004.956023.21165.nullmailer@hg.intevation.org> 2 outgoing changesets (2 stable) in hg-i18n: http://bitbucket.org/mg/hg-i18n/changeset/7ef3d0d9d054 changeset: 18516:7ef3d0d9d054 branch: stable tag: tip user: FUJIWARA Katsunori date: Thu Jan 31 23:01:31 2013 +0900 summary: i18n-ja: synchronized with 2a1fac3650a5 http://bitbucket.org/mg/hg-i18n/changeset/f01df0ff3aa2 changeset: 18515:f01df0ff3aa2 branch: stable user: Wagner Bruna date: Thu Jan 31 09:58:36 2013 -0200 summary: i18n-pt_BR: synchronized with 68eecbaf1bd3 -- Repository URL: http://bitbucket.org/mg/hg-i18n From hg at intevation.org Fri Feb 1 06:00:05 2013 From: hg at intevation.org (Mercurial Commits) Date: Fri, 01 Feb 2013 13:00:05 +0100 Subject: mercurial/crew@18516: 2 outgoing changesets (2 stable) Message-ID: <1359720005.484457.21178.nullmailer@hg.intevation.org> 2 outgoing changesets (2 stable) in mercurial/crew: http://hg.intevation.org/mercurial/crew/rev/9fbeb61b8ad2 changeset: 18516:9fbeb61b8ad2 branch: stable bookmark: crew-stable tag: tip user: Kevin Bullock date: Thu Jan 31 20:01:26 2013 -0600 summary: rebase: mention phases in the help http://hg.intevation.org/mercurial/crew/rev/bf8bbbf4aa45 changeset: 18515:bf8bbbf4aa45 branch: stable user: Angel Ezquerra date: Thu Jan 31 22:36:22 2013 +0100 summary: hgwebdir: use web.prefix when creating url breadcrumbs (issue3790) -- Repository URL: http://hg.intevation.org/mercurial/crew From mads at kiilerich.com Fri Feb 1 08:52:36 2013 From: mads at kiilerich.com (Mads Kiilerich) Date: Fri, 01 Feb 2013 15:52:36 +0100 Subject: [PATCH 0 of 1] the bundle() revset predicate introduced in 2.5 Message-ID: Hi I'm posting this a bit too early or too late ... but for a reason. I just noticed that 03e552aaae67 "bundle: add revset expression to show bundle contents (issue3487)" will have its first release with 2.5. I suggest renaming the predicate or holding it back a bit. Some possible nice-to-haves for such a predicate - just to give some context - could be: - handling of more than 1 bundle and a way to filter on different bundles - predicate for revisions _only_ found in the bundle (which I assume would be _much_ more useful than the current behaviour and also simpler to implement and faster). After the release of 2.5 I would like to suggest this unionrepo for inclusion in Mercurial. It is very much like bundlerepo and do for now reuse the 'bundle()' predicate ... even though the name is very misleading. I could of course try to introduce another predicate ... but it would also be nice to reuse existing ones. It could thus have some advantages if this bundle() predicate was renamed before it was released and set in stone. It could perhaps be something like 'other()'. Or perhaps we could declare in 2.5 that it so far is 'unstable' and subject to change. This is not exactly an early warning, but still a warning ... /Mads From mads at kiilerich.com Fri Feb 1 08:52:37 2013 From: mads at kiilerich.com (Mads Kiilerich) Date: Fri, 01 Feb 2013 15:52:37 +0100 Subject: [PATCH 1 of 1] unionrepo: read-only operations on a union of two localrepos In-Reply-To: References: Message-ID: <4570a9ddd85c4f74454a.1359730357@mk-desktop> # HG changeset patch # User Mads Kiilerich # Date 1358520849 -3600 # Branch stable # Node ID 4570a9ddd85c4f74454a6e82291a86c0b352c47f # Parent 9fbeb61b8ad26eea6ed6983724ac49d7b874892d unionrepo: read-only operations on a union of two localrepos - just like bundlerepo without bundles. Primary use case is revlogs and diffs across local repos, as a kind of preview of pulls. diff --git a/mercurial/hg.py b/mercurial/hg.py --- a/mercurial/hg.py +++ b/mercurial/hg.py @@ -9,8 +9,8 @@ from i18n import _ from lock import release from node import hex, nullid -import localrepo, bundlerepo, httppeer, sshpeer, statichttprepo, bookmarks -import lock, util, extensions, error, node, scmutil, phases, url +import localrepo, bundlerepo, unionrepo, httppeer, sshpeer, statichttprepo +import bookmarks, lock, util, extensions, error, node, scmutil, phases, url import cmdutil, discovery import merge as mergemod import verify as verifymod @@ -64,6 +64,7 @@ schemes = { 'bundle': bundlerepo, + 'union': unionrepo, 'file': _local, 'http': httppeer, 'https': httppeer, diff --git a/mercurial/unionrepo.py b/mercurial/unionrepo.py new file mode 100644 --- /dev/null +++ b/mercurial/unionrepo.py @@ -0,0 +1,183 @@ +# unionrepo.py - repository class for viewing union of repositories +# +# Derived from bundlerepo.py +# Copyright 2006, 2007 Benoit Boissinot +# Copyright 2013 Unity Technologies, Mads Kiilerich +# +# This software may be used and distributed according to the terms of the +# GNU General Public License version 2 or any later version. + +"""Repository class for "in-memory pull" of one local repository to another, +allowing operations like log with revsets. +""" + +from node import nullid +import util, mdiff, scmutil +import localrepo, changelog, manifest, filelog, revlog + +class unionrevlog(revlog.revlog): + def __init__(self, opener, indexfile, revlog2, linkmapper): + # How it works: + # To retrieve a revision, we just need to know the node id so we can + # look it up in revlog2. + # + # basemap is indexed with revisions coming from the second revlog. + # + # To differentiate a rev in the second revlog from a rev in the revlog, + # we check revision against basemap. + opener = scmutil.readonlyvfs(opener) + revlog.revlog.__init__(self, opener, indexfile) + self.revlog2 = revlog2 + + self.basemap = {} # mapping rev that is in revlog2 to ... nothing + n = len(self) + self.bundlerevs = set() # used by 'bundle()' revset expression + for rev2 in self.revlog2: + rev = self.revlog2.index[rev2] + # rev numbers - in revlog2, very different from self.rev + _start, _csize, _rsize, _base, linkrev, p1rev, p2rev, node = rev + + if linkmapper is None: # link is to same revlog + assert linkrev == rev2 # we never link back + link = n + else: # rev must be mapped from repo2 cl to unified cl by linkmapper + link = linkmapper(linkrev) + + if node in self.nodemap: + # this happens for for the common revlog revisions + self.bundlerevs.add(self.nodemap[node]) + continue + + p1node = self.revlog2.node(p1rev) + p2node = self.revlog2.node(p2rev) + + e = (None, None, None, None, + link, self.rev(p1node), self.rev(p2node), node) + self.basemap[n] = None + self.index.insert(-1, e) + self.nodemap[node] = n + self.bundlerevs.add(n) + n += 1 + + def _chunk(self, rev): + if rev not in self.basemap: + return revlog.revlog._chunk(self, rev) + return self.revlog2._chunk(self.node(rev)) + + def revdiff(self, rev1, rev2): + """return or calculate a delta between two revisions""" + if rev1 in self.basemap and rev2 in self.basemap: + return self.revlog2.revdiff( + self.revlog2.rev(self.node(rev1)), + self.revlog2.rev(self.node(rev2))) + elif rev1 not in self.basemap and rev2 not in self.basemap: + return revlog.revlog.revdiff(self, rev1, rev2) + + return mdiff.textdiff(self.revision(self.node(rev1)), + self.revision(self.node(rev2))) + + def revision(self, nodeorrev): + """return an uncompressed revision of a given node or revision + number. + """ + if isinstance(nodeorrev, int): + rev = nodeorrev + node = self.node(rev) + else: + node = nodeorrev + rev = self.rev(node) + + if node == nullid: + return "" + + if rev in self.basemap: + text = self.revlog2.revision(node) + self._cache = (node, rev, text) + else: + text = revlog.revlog.revision(self, rev) + # already cached + return text + + def addrevision(self, text, transaction, link, p1=None, p2=None, d=None): + raise NotImplementedError + def addgroup(self, revs, linkmapper, transaction): + raise NotImplementedError + def strip(self, rev, minlink): + raise NotImplementedError + def checksize(self): + raise NotImplementedError + +class unionchangelog(unionrevlog, changelog.changelog): + def __init__(self, opener, opener2): + changelog.changelog.__init__(self, opener) + linkmapper = None + changelog2 = changelog.changelog(opener2) + unionrevlog.__init__(self, opener, self.indexfile, changelog2, + linkmapper) + +class unionmanifest(unionrevlog, manifest.manifest): + def __init__(self, opener, opener2, linkmapper): + manifest.manifest.__init__(self, opener) + manifest2 = manifest.manifest(opener2) + unionrevlog.__init__(self, opener, self.indexfile, manifest2, + linkmapper) + +class unionfilelog(unionrevlog, filelog.filelog): + def __init__(self, opener, path, opener2, linkmapper, repo): + filelog.filelog.__init__(self, opener, path) + filelog2 = filelog.filelog(opener2, path) + unionrevlog.__init__(self, opener, self.indexfile, filelog2, + linkmapper) + self._repo = repo + + def _file(self, f): + self._repo.file(f) + +class unionpeer(localrepo.localpeer): + def canpush(self): + return False + +class unionrepository(localrepo.localrepository): + def __init__(self, ui, path, path2): + localrepo.localrepository.__init__(self, ui, path) + self.ui.setconfig('phases', 'publish', False) + + self._url = 'union:%s+%s' % (util.expandpath(path), + util.expandpath(path2)) + self.repo2 = localrepo.localrepository(ui, path2) + + @localrepo.unfilteredpropertycache + def changelog(self): + return unionchangelog(self.sopener, self.repo2.sopener) + + def _clrev(self, rev2): + """map from repo2 changelog rev to temporary rev in self.changelog""" + node = self.repo2.changelog.node(rev2) + return self.changelog.rev(node) + + @localrepo.unfilteredpropertycache + def manifest(self): + return unionmanifest(self.sopener, self.repo2.sopener, + self._clrev) + + def url(self): + return self._url + + def file(self, f): + return unionfilelog(self.sopener, f, self.repo2.sopener, + self._clrev, self) + + def close(self): + self.repo2.close() + + def cancopy(self): + return False + + def peer(self): + return unionpeer(self) + +def instance(ui, path, create): + u = util.url(path) + assert u.scheme == 'union' + repopath, repopath2 = u.path.split("+", 1) + return unionrepository(ui, repopath, repopath2) diff --git a/tests/test-bundle-simple.t b/tests/test-bundle-simple.t new file mode 100644 --- /dev/null +++ b/tests/test-bundle-simple.t @@ -0,0 +1,127 @@ +# sed 's,bundle:repo1+repo2[.]hg,union:repo1+repo2,g' test-bundle-simple.t > test-union-simple.t + + $ hg init repo1 + $ cd repo1 + $ touch repo1-0 + $ echo repo1-0 > f + $ hg ci -Aqmrepo1-0 + $ touch repo1-1 + $ echo repo1-1 >> f + $ hg ci -Aqmrepo1-1 + $ touch repo1-2 + $ echo repo1-2 >> f + $ hg ci -Aqmrepo1-2 + $ hg log --template '{rev}:{node|short} {desc|firstline}\n' + 2:68c0685446a3 repo1-2 + 1:8a58db72e69d repo1-1 + 0:f093fec0529b repo1-0 + $ tip1=`hg id -q` + $ cd .. + + $ hg clone -q repo1 --rev 0 repo2 + $ cd repo2 + $ touch repo2-1 + $ sed '1irepo2-1 at top' f > f.tmp + $ mv f.tmp f + $ hg ci -Aqmrepo2-1 + $ touch repo2-2 + $ hg pull -q ../repo1 -r 1 + $ hg merge -q + $ hg ci -Aqmrepo2-2-merge + $ touch repo2-3 + $ echo repo2-3 >> f + $ hg ci -mrepo2-3 + $ hg log --template '{rev}:{node|short} {desc|firstline}\n' + 4:2f0d178c469c repo2-3 + 3:9e6fb3e0b9da repo2-2-merge + 2:8a58db72e69d repo1-1 + 1:c337dba826e7 repo2-1 + 0:f093fec0529b repo1-0 + $ cd .. + + $ hg -R repo2 bundle --all repo2.hg + 5 changesets found + + $ hg -R bundle:repo1+repo2.hg log --template '{rev}:{node|short} {desc|firstline}\n' --traceback + 5:2f0d178c469c repo2-3 + 4:9e6fb3e0b9da repo2-2-merge + 3:c337dba826e7 repo2-1 + 2:68c0685446a3 repo1-2 + 1:8a58db72e69d repo1-1 + 0:f093fec0529b repo1-0 + + $ hg -R bundle:repo1+repo2.hg mani -r $tip1 --traceback + f + repo1-0 + repo1-1 + repo1-2 + $ hg -R bundle:repo1+repo2.hg mani -r 4 --traceback + f + repo1-0 + repo1-1 + repo2-1 + repo2-2 + + $ hg -R repo1 cat repo1/f -r2 + repo1-0 + repo1-1 + repo1-2 + + $ hg -R bundle:repo1+repo2.hg cat -r$tip1 repo1/f --traceback + repo1-0 + repo1-1 + repo1-2 + + $ hg -R bundle:repo1+repo2.hg cat -r4 $TESTTMP/repo1/f + repo2-1 at top + repo1-0 + repo1-1 + + $ hg -R bundle:repo1+repo2.hg diff -r$tip1 -rtip + diff -r 68c0685446a3 -r 2f0d178c469c f + --- a/f Thu Jan 01 00:00:00 1970 +0000 + +++ b/f Thu Jan 01 00:00:00 1970 +0000 + @@ -1,3 +1,4 @@ + +repo2-1 at top + repo1-0 + repo1-1 + -repo1-2 + +repo2-3 + + $ hg -R bundle:repo1+repo2.hg heads --template '{rev}:{node|short} {desc|firstline}\n' + 5:2f0d178c469c repo2-3 + 2:68c0685446a3 repo1-2 + $ hg -R bundle:repo1+repo2.hg id -r "ancestor($tip1, 5)" + 8a58db72e69d + + $ hg -R bundle:repo1+repo2.hg annotate $TESTTMP/repo1/f -r tip --traceback + 3: repo2-1 at top + 0: repo1-0 + 1: repo1-1 + 5: repo2-3 + + $ hg clone -U bundle:repo1+repo2.hg repo3 --traceback + requesting all changes + adding changesets + adding manifests + adding file changes + added 6 changesets with 11 changes to 6 files (+1 heads) + + $ hg -R repo3 verify + checking changesets + checking manifests + crosschecking files in changesets and manifests + checking files + 6 files, 6 changesets, 11 total revisions + + $ hg -R repo3 heads --template '{rev}:{node|short} {desc|firstline}\n' + 5:2f0d178c469c repo2-3 + 2:68c0685446a3 repo1-2 + + $ hg -R repo3 log --template '{rev}:{node|short} {desc|firstline}\n' + 5:2f0d178c469c repo2-3 + 4:9e6fb3e0b9da repo2-2-merge + 3:c337dba826e7 repo2-1 + 2:68c0685446a3 repo1-2 + 1:8a58db72e69d repo1-1 + 0:f093fec0529b repo1-0 diff --git a/tests/test-union-simple.t b/tests/test-union-simple.t new file mode 100644 --- /dev/null +++ b/tests/test-union-simple.t @@ -0,0 +1,127 @@ +# sed 's,bundle:repo1+repo2[.]hg,union:repo1+repo2,g' test-bundle-simple.t > test-union-simple.t + + $ hg init repo1 + $ cd repo1 + $ touch repo1-0 + $ echo repo1-0 > f + $ hg ci -Aqmrepo1-0 + $ touch repo1-1 + $ echo repo1-1 >> f + $ hg ci -Aqmrepo1-1 + $ touch repo1-2 + $ echo repo1-2 >> f + $ hg ci -Aqmrepo1-2 + $ hg log --template '{rev}:{node|short} {desc|firstline}\n' + 2:68c0685446a3 repo1-2 + 1:8a58db72e69d repo1-1 + 0:f093fec0529b repo1-0 + $ tip1=`hg id -q` + $ cd .. + + $ hg clone -q repo1 --rev 0 repo2 + $ cd repo2 + $ touch repo2-1 + $ sed '1irepo2-1 at top' f > f.tmp + $ mv f.tmp f + $ hg ci -Aqmrepo2-1 + $ touch repo2-2 + $ hg pull -q ../repo1 -r 1 + $ hg merge -q + $ hg ci -Aqmrepo2-2-merge + $ touch repo2-3 + $ echo repo2-3 >> f + $ hg ci -mrepo2-3 + $ hg log --template '{rev}:{node|short} {desc|firstline}\n' + 4:2f0d178c469c repo2-3 + 3:9e6fb3e0b9da repo2-2-merge + 2:8a58db72e69d repo1-1 + 1:c337dba826e7 repo2-1 + 0:f093fec0529b repo1-0 + $ cd .. + + $ hg -R repo2 bundle --all repo2.hg + 5 changesets found + + $ hg -R union:repo1+repo2 log --template '{rev}:{node|short} {desc|firstline}\n' --traceback + 5:2f0d178c469c repo2-3 + 4:9e6fb3e0b9da repo2-2-merge + 3:c337dba826e7 repo2-1 + 2:68c0685446a3 repo1-2 + 1:8a58db72e69d repo1-1 + 0:f093fec0529b repo1-0 + + $ hg -R union:repo1+repo2 mani -r $tip1 --traceback + f + repo1-0 + repo1-1 + repo1-2 + $ hg -R union:repo1+repo2 mani -r 4 --traceback + f + repo1-0 + repo1-1 + repo2-1 + repo2-2 + + $ hg -R repo1 cat repo1/f -r2 + repo1-0 + repo1-1 + repo1-2 + + $ hg -R union:repo1+repo2 cat -r$tip1 repo1/f --traceback + repo1-0 + repo1-1 + repo1-2 + + $ hg -R union:repo1+repo2 cat -r4 $TESTTMP/repo1/f + repo2-1 at top + repo1-0 + repo1-1 + + $ hg -R union:repo1+repo2 diff -r$tip1 -rtip + diff -r 68c0685446a3 -r 2f0d178c469c f + --- a/f Thu Jan 01 00:00:00 1970 +0000 + +++ b/f Thu Jan 01 00:00:00 1970 +0000 + @@ -1,3 +1,4 @@ + +repo2-1 at top + repo1-0 + repo1-1 + -repo1-2 + +repo2-3 + + $ hg -R union:repo1+repo2 heads --template '{rev}:{node|short} {desc|firstline}\n' + 5:2f0d178c469c repo2-3 + 2:68c0685446a3 repo1-2 + $ hg -R union:repo1+repo2 id -r "ancestor($tip1, 5)" + 8a58db72e69d + + $ hg -R union:repo1+repo2 annotate $TESTTMP/repo1/f -r tip --traceback + 3: repo2-1 at top + 0: repo1-0 + 1: repo1-1 + 5: repo2-3 + + $ hg clone -U union:repo1+repo2 repo3 --traceback + requesting all changes + adding changesets + adding manifests + adding file changes + added 6 changesets with 11 changes to 6 files (+1 heads) + + $ hg -R repo3 verify + checking changesets + checking manifests + crosschecking files in changesets and manifests + checking files + 6 files, 6 changesets, 11 total revisions + + $ hg -R repo3 heads --template '{rev}:{node|short} {desc|firstline}\n' + 5:2f0d178c469c repo2-3 + 2:68c0685446a3 repo1-2 + + $ hg -R repo3 log --template '{rev}:{node|short} {desc|firstline}\n' + 5:2f0d178c469c repo2-3 + 4:9e6fb3e0b9da repo2-2-merge + 3:c337dba826e7 repo2-1 + 2:68c0685446a3 repo1-2 + 1:8a58db72e69d repo1-1 + 0:f093fec0529b repo1-0 From thomas at intevation.de Fri Feb 1 09:09:08 2013 From: thomas at intevation.de (Thomas Arendsen Hein) Date: Fri, 1 Feb 2013 16:09:08 +0100 Subject: Different (but valid) output in the testsuite In-Reply-To: <1331937936.9830.463.camel@calx> References: <20120310161758.GA3058@einstein.local> <1331580756.9830.279.camel@calx> <20120315233127.GC5119@einstein.local> <1331937936.9830.463.camel@calx> Message-ID: <20130201155504.804183277.thomas@intevation.de> * Matt Mackall [20120316 23:45]: > On Thu, 2012-03-15 at 23:31 +0000, Javi Merino wrote: > > > > --- /build/buildd-mercurial_2.1.1-2-hurd-i386-nljf5k/mercurial-2.1.1/tests/test-bad-pull.t > > > > +++ /build/buildd-mercurial_2.1.1-2-hurd-i386-nljf5k/mercurial-2.1.1/tests/test-bad-pull.t.err > > > > @@ -1,7 +1,7 @@ > > > > $ "$TESTDIR/hghave" serve || exit 80 > > > > > > > > $ hg clone http://localhost:$HGPORT/ copy > > > > - abort: error: Connection refused > > > > + abort: error: Address family not supported by protocol > > > > > > Not actually valid. ECONNREFUSED is very different from EAFNOSUPPORT. > > > > Right, but that doesn't mean that mercurial is broken, it's just that > > the kernel doesn't support IP. I may improve has_serve() in hghave to > > cover this and the possibility that the loopback interface is not > > configured so that these tests are skipped in those systems. > > How does this test work at all with no loopback or IPv4? Old thread, but as I just got informed about a user having this failed test on a linux PC. The reason was that IPv6 was disabled and /etc/hosts contained two entries for localhost, one being ::1 I don't think the test needs to be adjusted as this is a misconfiguration of the system. Regards, Thomas -- thomas at intevation.de - http://intevation.de/~thomas/ - OpenPGP key: 0x5816791A Intevation GmbH, Neuer Graben 17, 49074 Osnabrueck - AG Osnabrueck, HR B 18998 Geschaeftsfuehrer: Frank Koormann, Bernhard Reiter, Dr. Jan-Oliver Wagner From thomas at intevation.de Fri Feb 1 09:16:26 2013 From: thomas at intevation.de (Thomas Arendsen Hein) Date: Fri, 1 Feb 2013 16:16:26 +0100 Subject: [PATCH STABLE] hgweb: remove baseline info from paper template In-Reply-To: <510B9BAB.1080001@kiilerich.com> References: <1359563519.4200.7.camel@calx> <80f3dd3aa40280e97289.1359693810@yamac.lan> <510B8D0D.6020202@kiilerich.com> <20130201101149.GA26678@crater2.logilab.fr> <510B9BAB.1080001@kiilerich.com> Message-ID: <20130201161206.456013589.thomas@intevation.de> * Mads Kiilerich [20130201 11:40]: > On 02/01/2013 11:11 AM, Pierre-Yves David wrote: > >Bah, not sure about that. The code works so we can keep it arround but > >not advertise the keywork name for now > > Sure - it will be kept around in history after a backout and we can > back it in again when it is ready. > > Leaving it (temporarily) as unused and untested code do not sound > like a good idea to me. On the other hand, all tests during the freeze were with this code in place, none of the recent tests have been done with this code backed out. Keeping this code has a chance to keep a problem in unused code. Backing this code out has a chance to introduce a new change to the code, even it is a change that should not cause harm to anything else. Additionally this is another patch to look at in a time where even obviously correct patches can distract the people who look at them. Regards, Thomas -- thomas at intevation.de - http://intevation.de/~thomas/ - OpenPGP key: 0x5816791A Intevation GmbH, Neuer Graben 17, 49074 Osnabrueck - AG Osnabrueck, HR B 18998 Geschaeftsfuehrer: Frank Koormann, Bernhard Reiter, Dr. Jan-Oliver Wagner From mercurial-bugs at selenic.com Fri Feb 1 04:44:03 2013 From: mercurial-bugs at selenic.com (mercurial-bugs at selenic.com) Date: Fri, 01 Feb 2013 10:44:03 +0000 Subject: [Bug 3798] New: Unknown exception thrown if https proxy misconfigured Message-ID: http://bz.selenic.com/show_bug.cgi?id=3798 Priority: normal Bug ID: 3798 CC: mercurial-devel at selenic.com Assignee: bugzilla at selenic.com Summary: Unknown exception thrown if https proxy misconfigured Severity: bug Classification: Unclassified OS: Windows Reporter: cowwoc at bbs.darktech.org Hardware: PC Status: UNCONFIRMED Version: 2.4.2 Component: Mercurial Product: Mercurial When I run "hg clone
" against a misconfigured server (the HTTPd proxy in front of it is misconfigured, I'm still tracking it down). I get the following error: requesting all changes adding changesets adding manifests adding file changes transaction abort! rollback completed ** unknown exception encountered, please report by visiting ** http://mercurial.selenic.com/wiki/BugTracker ** Python 2.7.3 (default, Apr 10 2012, 23:24:47) [MSC v.1500 64 bit (AMD64)] ** Mercurial Distributed SCM (version 2.4.2) ** Extensions loaded: convert, mq, histedit Traceback (most recent call last): File "hg", line 42, in File "mercurial\dispatch.pyo", line 28, in run File "mercurial\dispatch.pyo", line 65, in dispatch File "mercurial\dispatch.pyo", line 88, in _runcatch File "mercurial\dispatch.pyo", line 741, in _dispatch File "mercurial\dispatch.pyo", line 514, in runcommand File "mercurial\dispatch.pyo", line 831, in _runcommand File "mercurial\dispatch.pyo", line 802, in checkargs File "mercurial\dispatch.pyo", line 738, in File "mercurial\util.pyo", line 472, in check File "mercurial\commands.pyo", line 1221, in clone File "mercurial\hg.pyo", line 381, in clone File "mercurial\localrepo.pyo", line 2582, in clone File "mercurial\localrepo.pyo", line 1771, in pull File "mercurial\localrepo.pyo", line 2375, in addchangegroup File "mercurial\revlog.pyo", line 1197, in addgroup File "mercurial\changegroup.pyo", line 192, in deltachunk File "mercurial\changegroup.pyo", line 17, in readexactly File "mercurial\util.pyo", line 908, in read File "mercurial\util.pyo", line 886, in splitbig File "mercurial\httppeer.pyo", line 20, in zgenerator zlib.error: Error -3 while decompressing: invalid distance code Ideally "hg" should provide a better error message than "transaction abort!". There is no indication of the cause unless you enable verbose mode. -- You are receiving this mail because: You are on the CC list for the bug. From kbullock+mercurial at ringworld.org Fri Feb 1 09:46:23 2013 From: kbullock+mercurial at ringworld.org (Kevin Bullock) Date: Fri, 1 Feb 2013 09:46:23 -0600 Subject: [PATCH STABLE] hgweb: remove baseline info from paper template In-Reply-To: <20130201104540.827958150.thomas@intevation.de> References: <1359563519.4200.7.camel@calx> <80f3dd3aa40280e97289.1359693810@yamac.lan> <510B8D0D.6020202@kiilerich.com> <20130201104540.827958150.thomas@intevation.de> Message-ID: On Feb 1, 2013, at 3:49 AM, Thomas Arendsen Hein wrote: > * Mads Kiilerich [20130201 10:38]: >> So I suggest removing the keyword too so we can change it without >> breaking backward compatibility. Actually I suggest backing out the >> full feature until it is ready. > > I'd vote to keep the code as it generally works and anyone who is > able to create templates based on this should be able to do a > search/replace on the keywords later. ...except that if it goes out in a release with that keyword, we'll have to support it forever. pacem in terris / ??? / ?????? / ????????? / ?? Kevin R. Bullock From ptc at fb.com Fri Feb 1 10:07:11 2013 From: ptc at fb.com (Paul Cavallaro) Date: Fri, 01 Feb 2013 08:07:11 -0800 Subject: [PATCH] revset: change ancestor to accept 0 or more arguments (issue3750) Message-ID: <014dd5ef89d8504ee662.1359734831@devrs153.prn1.facebook.com> # HG changeset patch # User Paul Cavallaro # Date 1359404361 28800 # Branch stable # Node ID 014dd5ef89d8504ee662ea508f32afaeba3f2f21 # Parent 692cbda1eb50fe30c70792cb1e9380b28769467c revset: change ancestor to accept 0 or more arguments (issue3750) Change ancestor to accept 0 or more arguments. The greatest common ancestor of a single changeset is that changeset. If passed no arguments, the empty list is returned. diff --git a/mercurial/revset.py b/mercurial/revset.py --- a/mercurial/revset.py +++ b/mercurial/revset.py @@ -278,20 +278,32 @@ return checkstatus(repo, subset, pat, 1) def ancestor(repo, subset, x): - """``ancestor(single, single)`` - Greatest common ancestor of the two changesets. + """``ancestor(*changeset)`` + Greatest common ancestor of the changesets. + + Accepts 0 or more changesets. + Will return empty list when passed no args. + Greatest common ancestor of a single changeset is that changeset. """ # i18n: "ancestor" is a keyword - l = getargs(x, 2, 2, _("ancestor requires two arguments")) - r = list(repo) - a = getset(repo, r, l[0]) - b = getset(repo, r, l[1]) - if len(a) != 1 or len(b) != 1: - # i18n: "ancestor" is a keyword - raise error.ParseError(_("ancestor arguments must be single revisions")) - an = [repo[a[0]].ancestor(repo[b[0]]).rev()] + l = getlist(x) + rl = list(repo) + anc = None - return [r for r in an if r in subset] + # (getset(repo, rl, i) for i in l) generates a list of lists + rev = repo.changelog.rev + ancestor = repo.changelog.ancestor + node = repo.changelog.node + for revs in (getset(repo, rl, i) for i in l): + for r in revs: + if anc is None: + anc = r + else: + anc = rev(ancestor(node(anc), node(r))) + + if anc is not None and anc in subset: + return [anc] + return [] def _ancestors(repo, subset, x, followfirst=False): args = getset(repo, list(repo), x) diff --git a/tests/test-revset.t b/tests/test-revset.t --- a/tests/test-revset.t +++ b/tests/test-revset.t @@ -218,17 +218,29 @@ $ log 'date(2005) and 1::' 4 +ancestor can accept 0 or more arguments + + $ log 'ancestor()' $ log 'ancestor(1)' - hg: parse error: ancestor requires two arguments - [255] + 1 $ log 'ancestor(4,5)' 1 $ log 'ancestor(4,5) and 4' + $ log 'ancestor(0,0,1,3)' + 0 + $ log 'ancestor(3,1,5,3,5,1)' + 1 + $ log 'ancestor(0,1,3,5)' + 0 + $ log 'ancestor(1,2,3,4,5)' + 1 $ log 'ancestors(5)' 0 1 3 5 + $ log 'ancestor(ancestors(5))' + 0 $ log 'author(bob)' 2 $ log 'author("re:bob|test")' From greg at gerg.ca Fri Feb 1 10:27:37 2013 From: greg at gerg.ca (Greg Ward) Date: Fri, 1 Feb 2013 11:27:37 -0500 Subject: [PATCH 2 of 2 STABLE] rebase: mention --rev in the help In-Reply-To: References: Message-ID: <20130201162737.GB8734@gerg.ca> On 31 January 2013, Pierre-Yves David said: > # HG changeset patch > # User Pierre-Yves David > # Date 1359671125 -3600 > # Branch stable > # Node ID fadbec65d390af7e2db69ecf8850787b937718ae > # Parent cb4cb6437ca0931d03b8b4f2caeec03983b2fc98 > rebase: mention --rev in the help > > The --rev option is included in the command usage but not explained anywhere. > This changeset add a small mention of it in the code to prevent confusion. This > small addition reference online help that are easier to update and improves at > release time Grammar plus a wrong word: This changeset adds a small mention of it in the help to prevent confusion. This small addition references online help that is easier to update and improve at release time. > Following Wagner Bruna advises, this is added in a plain new paragraph to not > invalidate current translation this close from the release. Grammar, punctuation, spelling: Following Wagner Bruna's advice, this is added in a plain new paragraph to not invalidate current translation this close to the release. > diff --git a/hgext/rebase.py b/hgext/rebase.py > --- a/hgext/rebase.py > +++ b/hgext/rebase.py > @@ -86,10 +86,14 @@ def rebase(ui, repo, **opts): > ``-b`` is less precise but more convenient than ``-s``: you can > specify any changeset in the source branch, and rebase will select > the whole branch. If you specify neither ``-s`` nor ``-b``, rebase > uses the parent of the working directory as the base. > > + For advanced usages, a third way is available through the ``--rev`` > + option. It allows to specify a strict set of changesets to rebase. > + See online documentation for details. Grammar, spacing, wording: For advanced usage, a third way is available through the ``--rev`` option. It allows you to specify the precise set of changesets to rebase. See online documentation for details. Also I would either drop the last sentence or include a direct hyperlink to the wiki page in question. Greg -- Greg Ward http://www.gerg.ca @gergdotca From ptc at fb.com Fri Feb 1 10:09:38 2013 From: ptc at fb.com (Paul Cavallaro) Date: Fri, 01 Feb 2013 08:09:38 -0800 Subject: [PATCH] dates: support 'today' and 'yesterday' in parsedate (issue3764) Message-ID: # HG changeset patch # User Paul Cavallaro # Date 1358963505 28800 # Node ID c5610452c19dab5b9ca1e905611ecd06b1ef50e8 # Parent 1f794204abbd7dd4bc329ae0c7c4fd7ce56b33af dates: support 'today' and 'yesterday' in parsedate (issue3764) Adding support to parsedate in util module to understand the more idiomatic dates 'today' and 'yesterday'. Added unified tests and docstring tests for added functionality. diff --git a/mercurial/help/dates.txt b/mercurial/help/dates.txt --- a/mercurial/help/dates.txt +++ b/mercurial/help/dates.txt @@ -18,6 +18,8 @@ - ``12-6`` - ``12/6`` - ``12/6/6`` (Dec 6 2006) +- ``today`` (midnight) +- ``yesterday`` (midnight) Lastly, there is Mercurial's internal format: diff --git a/mercurial/util.py b/mercurial/util.py --- a/mercurial/util.py +++ b/mercurial/util.py @@ -1027,6 +1027,14 @@ The date may be a "unixtime offset" string or in one of the specified formats. If the date already is a (unixtime, offset) tuple, it is returned. + + >>> parsedate(' today ') == parsedate(\ + datetime.date.today().strftime('%b %d')) + True + >>> parsedate( 'yesterday ') == parsedate((datetime.date.today() -\ + datetime.timedelta(days=1)\ + ).strftime('%b %d')) + True """ if not date: return 0, 0 @@ -1035,6 +1043,13 @@ if not formats: formats = defaultdateformats date = date.strip() + + if date == _('today'): + date = datetime.date.today().strftime('%b %d') + elif date == _('yesterday'): + date = (datetime.date.today() - + datetime.timedelta(days=1)).strftime('%b %d') + try: when, offset = map(int, date.split(' ')) except ValueError: diff --git a/tests/test-parse-date.t b/tests/test-parse-date.t --- a/tests/test-parse-date.t +++ b/tests/test-parse-date.t @@ -234,3 +234,20 @@ Sat Apr 15 13:30:00 2006 +0000 Wed Feb 01 13:00:30 2006 -0500 Wed Feb 01 13:00:30 2006 +0000 + +Test issue 3764 (interpreting 'today' and 'yesterday') + $ echo "hello" >> a + >>> import datetime + >>> today = datetime.date.today().strftime("%b %d") + >>> yesterday = (datetime.date.today() - datetime.timedelta(days=1)).strftime("%b %d") + >>> dates = open('dates', 'w') + >>> dates.write(today + '\n') + >>> dates.write(yesterday) + >>> dates.close() + $ hg ci -d "`sed -n '1p' dates`" -m "today is a good day to code" + $ hg log -d today --template '{desc}\n' + today is a good day to code + $ echo "goodbye" >> a + $ hg ci -d "`sed -n '2p' dates`" -m "the time traveler's code" + $ hg log -d yesterday --template '{desc}\n' + the time traveler's code From greg at gerg.ca Fri Feb 1 10:31:05 2013 From: greg at gerg.ca (Greg Ward) Date: Fri, 1 Feb 2013 11:31:05 -0500 Subject: [PATCH] dates: support 'today' and 'yesterday' in parsedate (issue3764) In-Reply-To: References: Message-ID: <20130201163105.GC8734@gerg.ca> On 01 February 2013, Paul Cavallaro said: > # HG changeset patch > # User Paul Cavallaro > # Date 1358963505 28800 > # Node ID c5610452c19dab5b9ca1e905611ecd06b1ef50e8 > # Parent 1f794204abbd7dd4bc329ae0c7c4fd7ce56b33af > dates: support 'today' and 'yesterday' in parsedate (issue3764) Mercurial is in feature freeze for the 2.5 release. Please resend in a few days, after 2.5 is out. Greg -- Greg Ward http://www.gerg.ca @gergdotca From bos at serpentine.com Fri Feb 1 11:22:34 2013 From: bos at serpentine.com (Bryan O'Sullivan) Date: Fri, 1 Feb 2013 09:22:34 -0800 Subject: [PATCH] dates: support 'today' and 'yesterday' in parsedate (issue3764) In-Reply-To: <20130201163105.GC8734@gerg.ca> References: <20130201163105.GC8734@gerg.ca> Message-ID: On Fri, Feb 1, 2013 at 8:31 AM, Greg Ward wrote: > Mercurial is in feature freeze for the 2.5 release. Please resend in a > few days, after 2.5 is out. > I'll just apply the patch in a few days. -------------- next part -------------- An HTML attachment was scrubbed... URL: From bos at serpentine.com Fri Feb 1 11:26:48 2013 From: bos at serpentine.com (Bryan O'Sullivan) Date: Fri, 1 Feb 2013 09:26:48 -0800 Subject: [PATCH] revset: change ancestor to accept 0 or more arguments (issue3750) In-Reply-To: <014dd5ef89d8504ee662.1359734831@devrs153.prn1.facebook.com> References: <014dd5ef89d8504ee662.1359734831@devrs153.prn1.facebook.com> Message-ID: On Fri, Feb 1, 2013 at 8:07 AM, Paul Cavallaro wrote: > revset: change ancestor to accept 0 or more arguments (issue3750) > Thanks. I'll apply this after the 2.5 freeze. -------------- next part -------------- An HTML attachment was scrubbed... URL: From kbullock+mercurial at ringworld.org Fri Feb 1 12:17:51 2013 From: kbullock+mercurial at ringworld.org (Kevin Bullock) Date: Fri, 01 Feb 2013 12:17:51 -0600 Subject: [PATCH 1 of 2] hgweb: rename 'changesetbaseline' template to 'diffbase' Message-ID: <58ddfba8e948636bb8bf.1359742671@opendoor.mincava.umn.edu> # HG changeset patch # User Kevin Bullock # Date 1359734305 21600 # Branch stable # Node ID 58ddfba8e948636bb8bf5911e35337e869fc51b5 # Parent 0c51532ec2335b89fa0283a84e57754495df2c08 hgweb: rename 'changesetbaseline' template to 'diffbase' More accurately reflects what it will be used for, and is also shorter. diff --git a/mercurial/templates/paper/map b/mercurial/templates/paper/map --- a/mercurial/templates/paper/map +++ b/mercurial/templates/paper/map @@ -101,7 +101,7 @@ changelogparent = ' changesetparent = '{node|short} ' -changesetbaseline = '{node|short} ' +diffbase = '{node|short} ' filerevparent = '{rename%filerename}{node|short} ' filerevchild = '{node|short} ' From kbullock+mercurial at ringworld.org Fri Feb 1 12:17:52 2013 From: kbullock+mercurial at ringworld.org (Kevin Bullock) Date: Fri, 01 Feb 2013 12:17:52 -0600 Subject: [PATCH 2 of 2] hgweb: rename 'currentbaseline' template keyword to 'baserev' In-Reply-To: <58ddfba8e948636bb8bf.1359742671@opendoor.mincava.umn.edu> References: <58ddfba8e948636bb8bf.1359742671@opendoor.mincava.umn.edu> Message-ID: <3eac82e1194f87a9a16b.1359742672@opendoor.mincava.umn.edu> # HG changeset patch # User Kevin Bullock # Date 1359735161 21600 # Branch stable # Node ID 3eac82e1194f87a9a16b982ddc61d920fda3fdf0 # Parent 58ddfba8e948636bb8bf5911e35337e869fc51b5 hgweb: rename 'currentbaseline' template keyword to 'baserev' Shorter and clearer. diff --git a/mercurial/hgweb/webcommands.py b/mercurial/hgweb/webcommands.py --- a/mercurial/hgweb/webcommands.py +++ b/mercurial/hgweb/webcommands.py @@ -293,7 +293,7 @@ def changeset(web, req, tmpl): node=ctx.hex(), parent=webutil.parents(ctx), child=webutil.children(ctx), - currentbaseline=basectx.hex(), + baserev=basectx.hex(), changesettag=showtags, changesetbookmark=showbookmarks, changesetbranch=showbranch, From kbullock+mercurial at ringworld.org Fri Feb 1 12:31:46 2013 From: kbullock+mercurial at ringworld.org (Kevin Bullock) Date: Fri, 1 Feb 2013 12:31:46 -0600 Subject: [PATCH STABLE] hgweb: remove baseline info from paper template In-Reply-To: <510B8D0D.6020202@kiilerich.com> References: <1359563519.4200.7.camel@calx> <80f3dd3aa40280e97289.1359693810@yamac.lan> <510B8D0D.6020202@kiilerich.com> Message-ID: <8865CB8F-B452-4316-8044-94A807ED8DF3@ringworld.org> On Feb 1, 2013, at 3:38 AM, Mads Kiilerich wrote: > On 02/01/2013 05:43 AM, Pierre-Yves David wrote: >> # HG changeset patch >> # User Pierre-Yves David >> # Date 1359693606 -3600 >> # Branch stable >> # Node ID 80f3dd3aa40280e97289153455b493c727ef0a52 >> # Parent 2a1fac3650a5b4d650198604c82ab59969500374 >> hgweb: remove baseline info from paper template >> >> The user interface is not considered ready for prime time yet. The internal code stay in >> place custom template usage. The feature is ultimatly wished and will be >> reenabled soon. The current issue is only related to the visual of the current >> interface. > > A reference to the revision that introduced the feature, please. Crewed after adding the reference and re-wrapping to 72 columns. > The template keyword 'currentbaseline' is also very strange - there is no 'baseline' concept anywhere in Mercurial. In 'changeset' it should be something like 'diffparent'. Diff between arbitrary revisions belongs elsewhere - and then it would be more descriptive to call the two nodes 'anode' and 'bnode'. > > So I suggest removing the keyword too so we can change it without breaking backward compatibility. Actually I suggest backing out the full feature until it is ready. Just patchbombed 2 patches that clean this up rather than backing out the code behind it. pacem in terris / ??? / ?????? / ????????? / ?? Kevin R. Bullock From kbullock+mercurial at ringworld.org Fri Feb 1 12:36:07 2013 From: kbullock+mercurial at ringworld.org (Kevin Bullock) Date: Fri, 1 Feb 2013 12:36:07 -0600 Subject: [PATCH 1 of 2] hgweb: rename 'changesetbaseline' template to 'diffbase' In-Reply-To: <58ddfba8e948636bb8bf.1359742671@opendoor.mincava.umn.edu> References: <58ddfba8e948636bb8bf.1359742671@opendoor.mincava.umn.edu> Message-ID: On Feb 1, 2013, at 12:17 PM, Kevin Bullock wrote: > # HG changeset patch > # User Kevin Bullock > # Date 1359734305 21600 > # Branch stable > # Node ID 58ddfba8e948636bb8bf5911e35337e869fc51b5 > # Parent 0c51532ec2335b89fa0283a84e57754495df2c08 > hgweb: rename 'changesetbaseline' template to 'diffbase' > > More accurately reflects what it will be used for, and is also shorter. > > diff --git a/mercurial/templates/paper/map b/mercurial/templates/paper/map > --- a/mercurial/templates/paper/map > +++ b/mercurial/templates/paper/map > @@ -101,7 +101,7 @@ changelogparent = ' > > changesetparent = '{node|short} ' > > -changesetbaseline = '{node|short} ' > +diffbase = '{node|short} ' Actually 'diffagainst' might be better here: the purpose of this template is to show a link that -changes- the rev we're diffing against, not to link to the rev itself. pacem in terris / ??? / ?????? / ????????? / ?? Kevin R. Bullock From hgbuildbot at kublai.com Fri Feb 1 12:51:26 2013 From: hgbuildbot at kublai.com (hgbuildbot at kublai.com) Date: Fri, 01 Feb 2013 10:51:26 -0800 Subject: buildbot success in Mercurial on hg tests (stable) Message-ID: <20130201185128.1D8D123344@hgbuildbot.cs.ubc.ca> The Buildbot has detected a restored build on builder hg tests (stable) while building hg. Full details are available at: http://hgbuildbot.kublai.com/builders/hg%20tests%20%28stable%29/builds/290 Buildbot URL: http://hgbuildbot.kublai.com/ Buildslave for this Build: p64.osuosl.test Build Reason: scheduler Build Source Stamp: [branch stable] 0c51532ec2335b89fa0283a84e57754495df2c08 Blamelist: Pierre-Yves David Build succeeded! sincerely, -The Buildbot From mpm at selenic.com Fri Feb 1 13:06:55 2013 From: mpm at selenic.com (Matt Mackall) Date: Fri, 01 Feb 2013 13:06:55 -0600 Subject: [PATCH STABLE] icasefs: improve rename awareness of case-folding collision detection (issue3452) In-Reply-To: <3eca4bf6f77f64a83835.1359683069@juju> References: <3eca4bf6f77f64a83835.1359683069@juju> Message-ID: <1359745615.4200.155.camel@calx> On Fri, 2013-02-01 at 10:44 +0900, FUJIWARA Katsunori wrote: > # HG changeset patch > # User FUJIWARA Katsunori > # Date 1359682698 -32400 > # Branch stable > # Node ID 3eca4bf6f77f64a83835466f9b07022f5152a219 > # Parent 2a1fac3650a5b4d650198604c82ab59969500374 > icasefs: improve rename awareness of case-folding collision detection (issue3452) Going to hold off on this one. Mergecopies() needs to die, it is broken in a number of ways. I think we need a deeper rethink of our collision-detection strategy. -- Mathematics is the supreme nostalgia of our time. From pierre-yves.david at ens-lyon.org Fri Feb 1 13:13:51 2013 From: pierre-yves.david at ens-lyon.org (Pierre-Yves David) Date: Fri, 1 Feb 2013 20:13:51 +0100 Subject: [PATCH 1 of 2] hgweb: rename 'changesetbaseline' template to 'diffbase' In-Reply-To: References: <58ddfba8e948636bb8bf.1359742671@opendoor.mincava.umn.edu> Message-ID: <20130201191351.GA17614@kraken.insecable.net> On Fri, Feb 01, 2013 at 12:36:07PM -0600, Kevin Bullock wrote: > On Feb 1, 2013, at 12:17 PM, Kevin Bullock wrote: > > > # HG changeset patch > > # User Kevin Bullock > > # Date 1359734305 21600 > > # Branch stable > > # Node ID 58ddfba8e948636bb8bf5911e35337e869fc51b5 > > # Parent 0c51532ec2335b89fa0283a84e57754495df2c08 > > hgweb: rename 'changesetbaseline' template to 'diffbase' > > > > More accurately reflects what it will be used for, and is also shorter. > > > > diff --git a/mercurial/templates/paper/map b/mercurial/templates/paper/map > > --- a/mercurial/templates/paper/map > > +++ b/mercurial/templates/paper/map > > @@ -101,7 +101,7 @@ changelogparent = ' > > > > changesetparent = '{node|short} ' > > > > -changesetbaseline = '{node|short} ' > > +diffbase = '{node|short} ' > > Actually 'diffagainst' might be better here: the purpose of this template is to show a link that -changes- the rev we're diffing against, not to link to the rev itself. So this is a "revision it would make sense to diff against" (and we are possibly already diffing against) So maybe "alternativediffbase" The current diffbase should probably be excluded from this list (That's a list isn't it?) -- Pierre-Yves David From thomas at intevation.de Fri Feb 1 13:25:02 2013 From: thomas at intevation.de (Thomas Arendsen Hein) Date: Fri, 1 Feb 2013 20:25:02 +0100 Subject: [PATCH 1 of 2] hgweb: rename 'changesetbaseline' template to 'diffbase' In-Reply-To: <20130201191351.GA17614@kraken.insecable.net> References: <58ddfba8e948636bb8bf.1359742671@opendoor.mincava.umn.edu> <20130201191351.GA17614@kraken.insecable.net> Message-ID: <20130201201504.105058183.thomas@intevation.de> * Pierre-Yves David [20130201 20:14]: > On Fri, Feb 01, 2013 at 12:36:07PM -0600, Kevin Bullock wrote: > > On Feb 1, 2013, at 12:17 PM, Kevin Bullock wrote: > > > > > # HG changeset patch > > > # User Kevin Bullock > > > # Date 1359734305 21600 > > > # Branch stable > > > # Node ID 58ddfba8e948636bb8bf5911e35337e869fc51b5 > > > # Parent 0c51532ec2335b89fa0283a84e57754495df2c08 > > > hgweb: rename 'changesetbaseline' template to 'diffbase' > > > > > > More accurately reflects what it will be used for, and is also shorter. > > > > > > diff --git a/mercurial/templates/paper/map b/mercurial/templates/paper/map > > > --- a/mercurial/templates/paper/map > > > +++ b/mercurial/templates/paper/map > > > @@ -101,7 +101,7 @@ changelogparent = ' > > > > > > changesetparent = '{node|short} ' > > > > > > -changesetbaseline = '{node|short} ' > > > +diffbase = '{node|short} ' > > > > Actually 'diffagainst' might be better here: the purpose of this template is to show a link that -changes- the rev we're diffing against, not to link to the rev itself. I still consider "diffbase" a good keyword here. > So this is a "revision it would make sense to diff against" (and we are possibly already diffing against) ... short: "diffrev" or "diffto" or "diffwith"? > So maybe "alternativediffbase" That is even longer than the imho too long "changesetbaseline", additionally it reads like "alternatived iffbase" But "altdiff" might be a good, too. > The current diffbase should probably be excluded from this list (That's a list isn't it?) Not today :) Regards, Thomas -- thomas at intevation.de - http://intevation.de/~thomas/ - OpenPGP key: 0x5816791A Intevation GmbH, Neuer Graben 17, 49074 Osnabrueck - AG Osnabrueck, HR B 18998 Geschaeftsfuehrer: Frank Koormann, Bernhard Reiter, Dr. Jan-Oliver Wagner From kbullock+mercurial at ringworld.org Fri Feb 1 13:33:41 2013 From: kbullock+mercurial at ringworld.org (Kevin Bullock) Date: Fri, 1 Feb 2013 13:33:41 -0600 Subject: [PATCH 2 of 2 STABLE] rebase: mention --rev in the help In-Reply-To: References: Message-ID: On Jan 31, 2013, at 4:30 PM, Pierre-Yves David wrote: > # HG changeset patch > # User Pierre-Yves David > # Date 1359671125 -3600 > # Branch stable > # Node ID fadbec65d390af7e2db69ecf8850787b937718ae > # Parent cb4cb6437ca0931d03b8b4f2caeec03983b2fc98 > rebase: mention --rev in the help Crewed an updated version after discussion on IRC: pacem in terris / ??? / ?????? / ????????? / ?? Kevin R. Bullock From kbullock+mercurial at ringworld.org Fri Feb 1 13:51:47 2013 From: kbullock+mercurial at ringworld.org (Kevin Bullock) Date: Fri, 01 Feb 2013 13:51:47 -0600 Subject: [PATCH 1 of 2 V2 STABLE] hgweb: rename 'changesetbaseline' template to 'difffrom' Message-ID: <41eabb5b87610bb4d241.1359748307@opendoor.mincava.umn.edu> # HG changeset patch # User Kevin Bullock # Date 1359734305 21600 # Branch stable # Node ID 41eabb5b87610bb4d2410b80c39cb7a3b91e3a5c # Parent 0324a1d88a53e2fdbc071d96c79eb5cf4e511372 hgweb: rename 'changesetbaseline' template to 'difffrom' More accurately reflects what it will be used for, and is also shorter. This template is used to change which rev the current rev is diff'd against. For example, if you're at '/rev/P1:REV', this would link to a path like '/rev/P2:REV'. Example usage in a template: {parent%difffrom} diff --git a/mercurial/templates/paper/map b/mercurial/templates/paper/map --- a/mercurial/templates/paper/map +++ b/mercurial/templates/paper/map @@ -101,7 +101,7 @@ changelogparent = ' changesetparent = '{node|short} ' -changesetbaseline = '{node|short} ' +difffrom = '{node|short} ' filerevparent = '{rename%filerename}{node|short} ' filerevchild = '{node|short} ' From kbullock+mercurial at ringworld.org Fri Feb 1 13:51:48 2013 From: kbullock+mercurial at ringworld.org (Kevin Bullock) Date: Fri, 01 Feb 2013 13:51:48 -0600 Subject: [PATCH 2 of 2 V2 STABLE] hgweb: rename 'currentbaseline' template keyword to 'basenode' In-Reply-To: <41eabb5b87610bb4d241.1359748307@opendoor.mincava.umn.edu> References: <41eabb5b87610bb4d241.1359748307@opendoor.mincava.umn.edu> Message-ID: <66ae2ded096887109998.1359748308@opendoor.mincava.umn.edu> # HG changeset patch # User Kevin Bullock # Date 1359735161 21600 # Branch stable # Node ID 66ae2ded096887109998a48a519637d02c6bfabd # Parent 41eabb5b87610bb4d2410b80c39cb7a3b91e3a5c hgweb: rename 'currentbaseline' template keyword to 'basenode' Shorter and clearer. This keyword represents the node we're currently diffing against. diff --git a/mercurial/hgweb/webcommands.py b/mercurial/hgweb/webcommands.py --- a/mercurial/hgweb/webcommands.py +++ b/mercurial/hgweb/webcommands.py @@ -293,7 +293,7 @@ def changeset(web, req, tmpl): node=ctx.hex(), parent=webutil.parents(ctx), child=webutil.children(ctx), - currentbaseline=basectx.hex(), + basenode=basectx.hex(), changesettag=showtags, changesetbookmark=showbookmarks, changesetbranch=showbranch, From thomas at intevation.de Fri Feb 1 13:44:37 2013 From: thomas at intevation.de (Thomas Arendsen Hein) Date: Fri, 01 Feb 2013 20:44:37 +0100 Subject: [PATCH stable] hgweb: urlescape all urls, HTML escape repo/tag/branch/... names Message-ID: <126768fae4c4df54ba6f.1359747877@panopeia.hq.intevation.de> # HG changeset patch # User Thomas Arendsen Hein # Date 1359747815 -3600 # Branch stable # Node ID 126768fae4c4df54ba6f60e9be733bad86c2db38 # Parent 0324a1d88a53e2fdbc071d96c79eb5cf4e511372 hgweb: urlescape all urls, HTML escape repo/tag/branch/... names Without this, repository paths or names containing e.g. & characters or html tags yielded strange results, possibly allowing cross-site scripting attacks. diff -r 0324a1d88a53 -r 126768fae4c4 mercurial/templates/atom/bookmarkentry.tmpl --- a/mercurial/templates/atom/bookmarkentry.tmpl Fri Feb 01 02:01:11 2013 +0100 +++ b/mercurial/templates/atom/bookmarkentry.tmpl Fri Feb 01 20:43:35 2013 +0100 @@ -1,7 +1,7 @@ {bookmark|escape} - - {urlbase}{url}#bookmark-{node} + + {urlbase}{url|urlescape}#bookmark-{node} {date|rfc3339date} {date|rfc3339date} {bookmark|strip|escape} diff -r 0324a1d88a53 -r 126768fae4c4 mercurial/templates/atom/bookmarks.tmpl --- a/mercurial/templates/atom/bookmarks.tmpl Fri Feb 01 02:01:11 2013 +0100 +++ b/mercurial/templates/atom/bookmarks.tmpl Fri Feb 01 20:43:35 2013 +0100 @@ -1,7 +1,7 @@ {header} - {urlbase}{url} - - + {urlbase}{url|urlescape} + + {repo|escape}: bookmarks {repo|escape} bookmark history Mercurial SCM diff -r 0324a1d88a53 -r 126768fae4c4 mercurial/templates/atom/branchentry.tmpl --- a/mercurial/templates/atom/branchentry.tmpl Fri Feb 01 02:01:11 2013 +0100 +++ b/mercurial/templates/atom/branchentry.tmpl Fri Feb 01 20:43:35 2013 +0100 @@ -1,7 +1,7 @@ {branch|escape} - - {urlbase}{url}#branch-{node} + + {urlbase}{url|urlescape}#branch-{node} {date|rfc3339date} {date|rfc3339date} diff -r 0324a1d88a53 -r 126768fae4c4 mercurial/templates/atom/branches.tmpl --- a/mercurial/templates/atom/branches.tmpl Fri Feb 01 02:01:11 2013 +0100 +++ b/mercurial/templates/atom/branches.tmpl Fri Feb 01 20:43:35 2013 +0100 @@ -1,7 +1,7 @@ {header} - {urlbase}{url} - - + {urlbase}{url|urlescape} + + {repo|escape}: branches {repo|escape} branch history Mercurial SCM diff -r 0324a1d88a53 -r 126768fae4c4 mercurial/templates/atom/changelog.tmpl --- a/mercurial/templates/atom/changelog.tmpl Fri Feb 01 02:01:11 2013 +0100 +++ b/mercurial/templates/atom/changelog.tmpl Fri Feb 01 20:43:35 2013 +0100 @@ -1,8 +1,8 @@ {header} - {urlbase}{url} - - + {urlbase}{url|urlescape} + + {repo|escape} Changelog {latestentry%feedupdated} diff -r 0324a1d88a53 -r 126768fae4c4 mercurial/templates/atom/changelogentry.tmpl --- a/mercurial/templates/atom/changelogentry.tmpl Fri Feb 01 02:01:11 2013 +0100 +++ b/mercurial/templates/atom/changelogentry.tmpl Fri Feb 01 20:43:35 2013 +0100 @@ -1,7 +1,7 @@ {desc|strip|firstline|strip|escape|nonempty} - {urlbase}{url}#changeset-{node} - + {urlbase}{url|urlescape}#changeset-{node} + {author|person|escape} {author|email|obfuscate} diff -r 0324a1d88a53 -r 126768fae4c4 mercurial/templates/atom/error.tmpl --- a/mercurial/templates/atom/error.tmpl Fri Feb 01 02:01:11 2013 +0100 +++ b/mercurial/templates/atom/error.tmpl Fri Feb 01 20:43:35 2013 +0100 @@ -1,8 +1,8 @@ {header} - {urlbase}{url} - - + {urlbase}{url|urlescape} + + Error 1970-01-01T00:00:00+00:00 diff -r 0324a1d88a53 -r 126768fae4c4 mercurial/templates/atom/filelog.tmpl --- a/mercurial/templates/atom/filelog.tmpl Fri Feb 01 02:01:11 2013 +0100 +++ b/mercurial/templates/atom/filelog.tmpl Fri Feb 01 20:43:35 2013 +0100 @@ -1,6 +1,6 @@ {header} - {urlbase}{url}atom-log/tip/{file|escape} - + {urlbase}{url|urlescape}atom-log/tip/{file|escape} + {repo|escape}: {file|escape} history {latestentry%feedupdated} diff -r 0324a1d88a53 -r 126768fae4c4 mercurial/templates/atom/tagentry.tmpl --- a/mercurial/templates/atom/tagentry.tmpl Fri Feb 01 02:01:11 2013 +0100 +++ b/mercurial/templates/atom/tagentry.tmpl Fri Feb 01 20:43:35 2013 +0100 @@ -1,7 +1,7 @@ {tag|escape} - - {urlbase}{url}#tag-{node} + + {urlbase}{url|urlescape}#tag-{node} {date|rfc3339date} {date|rfc3339date} {tag|strip|escape} diff -r 0324a1d88a53 -r 126768fae4c4 mercurial/templates/atom/tags.tmpl --- a/mercurial/templates/atom/tags.tmpl Fri Feb 01 02:01:11 2013 +0100 +++ b/mercurial/templates/atom/tags.tmpl Fri Feb 01 20:43:35 2013 +0100 @@ -1,7 +1,7 @@ {header} - {urlbase}{url} - - + {urlbase}{url|urlescape} + + {repo|escape}: tags {repo|escape} tag history Mercurial SCM diff -r 0324a1d88a53 -r 126768fae4c4 mercurial/templates/coal/header.tmpl --- a/mercurial/templates/coal/header.tmpl Fri Feb 01 02:01:11 2013 +0100 +++ b/mercurial/templates/coal/header.tmpl Fri Feb 01 20:43:35 2013 +0100 @@ -1,7 +1,7 @@ - + - - + + diff -r 0324a1d88a53 -r 126768fae4c4 mercurial/templates/coal/map --- a/mercurial/templates/coal/map Fri Feb 01 02:01:11 2013 +0100 +++ b/mercurial/templates/coal/map Fri Feb 01 20:43:35 2013 +0100 @@ -13,14 +13,14 @@ help = ../paper/help.tmpl helptopics = ../paper/helptopics.tmpl -helpentry = '{topic|escape}{summary|escape}' +helpentry = '{topic|escape}{summary|escape}' -naventry = '{label|escape} ' -navshortentry = '{label|escape} ' -navgraphentry = '{label|escape} ' -filenaventry = '{label|escape} ' -filedifflink = '{file|escape} ' -filenodelink = '{file|escape} ' +naventry = '{label|escape} ' +navshortentry = '{label|escape} ' +navgraphentry = '{label|escape} ' +filenaventry = '{label|escape} ' +filedifflink = '{file|escape} ' +filenodelink = '{file|escape} ' filenolink = '{file|escape} ' fileellipses = '...' diffstatlink = ../paper/diffstat.tmpl @@ -38,10 +38,10 @@ direntry = ' - - dir. {basename|escape}/ + + dir. {basename|escape}/ - + {emptydirs|escape} @@ -52,8 +52,8 @@ fileentry = ' - - file {basename|escape} + + file {basename|escape} {size} @@ -72,7 +72,7 @@ annotateline = ' - {author|user}@{rev} {linenumber} {line|escape} @@ -97,19 +97,19 @@ changelogparent = ' parent {rev}: - {node|short} + {node|short} ' -changesetparent = '{node|short} ' +changesetparent = '{node|short} ' -filerevparent = '{rename%filerename}{node|short} ' -filerevchild = '{node|short} ' +filerevparent = '{rename%filerename}{node|short} ' +filerevchild = '{node|short} ' filerename = '{file|escape}@' filelogrename = ' base - + {file|escape}@{node|short} ' @@ -117,17 +117,17 @@ parent: - + {rename%filerename}{node|short} ' -changesetchild = ' {node|short}' +changesetchild = ' {node|short}' changelogchild = ' child - + {node|short} @@ -136,7 +136,7 @@ child: - + {node|short} @@ -145,7 +145,7 @@ tagentry = ' - + {tag|escape} @@ -157,7 +157,7 @@ bookmarkentry = ' - + {bookmark|escape} @@ -169,7 +169,7 @@ branchentry = ' - + {branch|escape} @@ -186,41 +186,41 @@ filediffparent = ' parent {rev}: - {node|short} + {node|short} ' filelogparent = ' parent {rev}: - {node|short} + {node|short} ' filediffchild = ' child {rev}: - {node|short} + {node|short} ' filelogchild = ' child {rev}: - {node|short} + {node|short} ' indexentry = ' - {name|escape} + {name|escape} {description} {contact|obfuscate} {lastchange|rfc822date} {archives%indexarchiveentry} \n' -indexarchiveentry = ' ↓{type|escape}' +indexarchiveentry = ' ↓{type|escape}' index = ../paper/index.tmpl archiveentry = '
  • - {type|escape} + {type|escape}
  • ' notfound = ../paper/notfound.tmpl error = ../paper/error.tmpl urlparameter = '{separator}{name}={value|urlescape}' hiddenformentry = '' -breadcrumb = '> {name} ' +breadcrumb = '> {name|escape} ' diff -r 0324a1d88a53 -r 126768fae4c4 mercurial/templates/gitweb/bookmarks.tmpl --- a/mercurial/templates/gitweb/bookmarks.tmpl Fri Feb 01 02:01:11 2013 +0100 +++ b/mercurial/templates/gitweb/bookmarks.tmpl Fri Feb 01 20:43:35 2013 +0100 @@ -1,9 +1,9 @@ {header} {repo|escape}: Bookmarks + href="{url|urlescape}atom-bookmarks" title="Atom feed for {repo|escape}"/> + href="{url|urlescape}rss-bookmarks" title="RSS feed for {repo|escape}"/> @@ -13,15 +13,15 @@
    diff -r 0324a1d88a53 -r 126768fae4c4 mercurial/templates/gitweb/branches.tmpl --- a/mercurial/templates/gitweb/branches.tmpl Fri Feb 01 02:01:11 2013 +0100 +++ b/mercurial/templates/gitweb/branches.tmpl Fri Feb 01 20:43:35 2013 +0100 @@ -1,9 +1,9 @@ {header} {repo|escape}: Branches + href="{url|urlescape}atom-branches" title="Atom feed for {repo|escape}"/> + href="{url|urlescape}rss-branches" title="RSS feed for {repo|escape}"/> @@ -13,15 +13,15 @@ diff -r 0324a1d88a53 -r 126768fae4c4 mercurial/templates/gitweb/changelog.tmpl --- a/mercurial/templates/gitweb/changelog.tmpl Fri Feb 01 02:01:11 2013 +0100 +++ b/mercurial/templates/gitweb/changelog.tmpl Fri Feb 01 20:43:35 2013 +0100 @@ -1,9 +1,9 @@ {header} {repo|escape}: Changelog + href="{url|urlescape}atom-log" title="Atom feed for {repo|escape}"/> + href="{url|urlescape}rss-log" title="RSS feed for {repo|escape}"/> @@ -12,7 +12,7 @@ Mercurial {pathdef%breadcrumb} / changelog -
    + {sessionvars%hiddenformentry}
    -{desc|strip|escape|firstline|nonempty} {inbranch%inbranchtag}{branches%branchtag}{tags%tagtag}{bookmarks%bookmarktag} +{desc|strip|escape|firstline|nonempty} {inbranch%inbranchtag}{branches%branchtag}{tags%tagtag}{bookmarks%bookmarktag}
    diff -r 0324a1d88a53 -r 126768fae4c4 mercurial/templates/gitweb/error.tmpl --- a/mercurial/templates/gitweb/error.tmpl Fri Feb 01 02:01:11 2013 +0100 +++ b/mercurial/templates/gitweb/error.tmpl Fri Feb 01 20:43:35 2013 +0100 @@ -1,9 +1,9 @@ {header} {repo|escape}: Error + href="{url|urlescape}atom-log" title="Atom feed for {repo|escape}"/> + href="{url|urlescape}rss-log" title="RSS feed for {repo|escape}"/> @@ -13,14 +13,14 @@ diff -r 0324a1d88a53 -r 126768fae4c4 mercurial/templates/gitweb/fileannotate.tmpl --- a/mercurial/templates/gitweb/fileannotate.tmpl Fri Feb 01 02:01:11 2013 +0100 +++ b/mercurial/templates/gitweb/fileannotate.tmpl Fri Feb 01 20:43:35 2013 +0100 @@ -1,9 +1,9 @@ {header} {repo|escape}: {file|escape}@{node|short} (annotated) + href="{url|urlescape}atom-log" title="Atom feed for {repo|escape}"/> + href="{url|urlescape}rss-log" title="RSS feed for {repo|escape}"/> @@ -13,23 +13,23 @@ @@ -46,7 +46,7 @@ {branch%filerevbranch} - + {parent%fileannotateparent} {child%fileannotatechild} diff -r 0324a1d88a53 -r 126768fae4c4 mercurial/templates/gitweb/filecomparison.tmpl --- a/mercurial/templates/gitweb/filecomparison.tmpl Fri Feb 01 02:01:11 2013 +0100 +++ b/mercurial/templates/gitweb/filecomparison.tmpl Fri Feb 01 20:43:35 2013 +0100 @@ -1,9 +1,9 @@ {header} {repo|escape}: comparison {file|escape} + href="{url|urlescape}atom-log" title="Atom feed for {repo|escape}"/> + href="{url|urlescape}rss-log" title="RSS feed for {repo|escape}"/> @@ -13,23 +13,23 @@ @@ -39,7 +39,7 @@ {branch%filerevbranch} - + {parent%filecompparent} {child%filecompchild}
    changeset {rev}{node|short}
    {node|short}
    changeset {rev}{node|short}
    {node|short}
    diff -r 0324a1d88a53 -r 126768fae4c4 mercurial/templates/gitweb/filediff.tmpl --- a/mercurial/templates/gitweb/filediff.tmpl Fri Feb 01 02:01:11 2013 +0100 +++ b/mercurial/templates/gitweb/filediff.tmpl Fri Feb 01 20:43:35 2013 +0100 @@ -1,9 +1,9 @@ {header} {repo|escape}: diff {file|escape} + href="{url|urlescape}atom-log" title="Atom feed for {repo|escape}"/> + href="{url|urlescape}rss-log" title="RSS feed for {repo|escape}"/> @@ -13,23 +13,23 @@
    @@ -39,7 +39,7 @@ {branch%filerevbranch} changeset {rev} - {node|short} + {node|short} {parent%filediffparent} {child%filediffchild} diff -r 0324a1d88a53 -r 126768fae4c4 mercurial/templates/gitweb/filelog.tmpl --- a/mercurial/templates/gitweb/filelog.tmpl Fri Feb 01 02:01:11 2013 +0100 +++ b/mercurial/templates/gitweb/filelog.tmpl Fri Feb 01 20:43:35 2013 +0100 @@ -1,9 +1,9 @@ {header} {repo|escape}: File revisions + href="{url|urlescape}atom-log" title="Atom feed for {repo|escape}"/> + href="{url|urlescape}rss-log" title="RSS feed for {repo|escape}"/> @@ -13,20 +13,20 @@ diff -r 0324a1d88a53 -r 126768fae4c4 mercurial/templates/gitweb/filerevision.tmpl --- a/mercurial/templates/gitweb/filerevision.tmpl Fri Feb 01 02:01:11 2013 +0100 +++ b/mercurial/templates/gitweb/filerevision.tmpl Fri Feb 01 20:43:35 2013 +0100 @@ -1,9 +1,9 @@ {header} {repo|escape}: {file|escape}@{node|short} + href="{url|urlescape}atom-log" title="Atom feed for {repo|escape}"/> + href="{url|urlescape}rss-log" title="RSS feed for {repo|escape}"/> @@ -13,23 +13,23 @@ @@ -46,7 +46,7 @@ {branch%filerevbranch} changeset {rev} - {node|short} + {node|short} {parent%filerevparent} {child%filerevchild} diff -r 0324a1d88a53 -r 126768fae4c4 mercurial/templates/gitweb/footer.tmpl --- a/mercurial/templates/gitweb/footer.tmpl Fri Feb 01 02:01:11 2013 +0100 +++ b/mercurial/templates/gitweb/footer.tmpl Fri Feb 01 20:43:35 2013 +0100 @@ -2,8 +2,8 @@ -
    + {sessionvars%hiddenformentry}
    @@ -89,7 +89,7 @@ } var item = '
  • '; - item += '' + cur[3] + ''; + item += '' + cur[3] + ''; item += ' ' + tagspan + ''; item += '' + cur[5] + ', by ' + cur[4] + '
  • '; @@ -103,8 +103,8 @@ diff -r 0324a1d88a53 -r 126768fae4c4 mercurial/templates/gitweb/header.tmpl --- a/mercurial/templates/gitweb/header.tmpl Fri Feb 01 02:01:11 2013 +0100 +++ b/mercurial/templates/gitweb/header.tmpl Fri Feb 01 20:43:35 2013 +0100 @@ -2,7 +2,7 @@ - + - - + + diff -r 0324a1d88a53 -r 126768fae4c4 mercurial/templates/gitweb/help.tmpl --- a/mercurial/templates/gitweb/help.tmpl Fri Feb 01 02:01:11 2013 +0100 +++ b/mercurial/templates/gitweb/help.tmpl Fri Feb 01 20:43:35 2013 +0100 @@ -1,9 +1,9 @@ {header} {repo|escape}: Branches + href="{url|urlescape}atom-tags" title="Atom feed for {repo|escape}"/> + href="{url|urlescape}rss-tags" title="RSS feed for {repo|escape}"/> @@ -13,14 +13,14 @@ diff -r 0324a1d88a53 -r 126768fae4c4 mercurial/templates/gitweb/helptopics.tmpl --- a/mercurial/templates/gitweb/helptopics.tmpl Fri Feb 01 02:01:11 2013 +0100 +++ b/mercurial/templates/gitweb/helptopics.tmpl Fri Feb 01 20:43:35 2013 +0100 @@ -1,9 +1,9 @@ {header} {repo|escape}: Branches + href="{url|urlescape}atom-tags" title="Atom feed for {repo|escape}"/> + href="{url|urlescape}rss-tags" title="RSS feed for {repo|escape}"/> @@ -13,14 +13,14 @@ diff -r 0324a1d88a53 -r 126768fae4c4 mercurial/templates/gitweb/manifest.tmpl --- a/mercurial/templates/gitweb/manifest.tmpl Fri Feb 01 02:01:11 2013 +0100 +++ b/mercurial/templates/gitweb/manifest.tmpl Fri Feb 01 20:43:35 2013 +0100 @@ -1,9 +1,9 @@ {header} {repo|escape}: files + href="{url|urlescape}atom-log" title="Atom feed for {repo|escape}"/> + href="{url|urlescape}rss-log" title="RSS feed for {repo|escape}"/> @@ -13,16 +13,16 @@ @@ -32,7 +32,7 @@ drwxr-xr-x -[up] +[up]   {dentries%direntry} diff -r 0324a1d88a53 -r 126768fae4c4 mercurial/templates/gitweb/map --- a/mercurial/templates/gitweb/map Fri Feb 01 02:01:11 2013 +0100 +++ b/mercurial/templates/gitweb/map Fri Feb 01 20:43:35 2013 +0100 @@ -11,35 +11,35 @@ help = help.tmpl helptopics = helptopics.tmpl -helpentry = '{topic|escape}{summary|escape}' +helpentry = '{topic|escape}{summary|escape}' -naventry = '{label|escape} ' -navshortentry = '{label|escape} ' -navgraphentry = '{label|escape} ' -filenaventry = '{label|escape} ' -filedifflink = '{file|escape} ' +naventry = '{label|escape} ' +navshortentry = '{label|escape} ' +navgraphentry = '{label|escape} ' +filenaventry = '{label|escape} ' +filedifflink = '{file|escape} ' filenodelink = ' - {file|escape} + {file|escape} - file | - annotate | - diff | - comparison | - revisions + file | + annotate | + diff | + comparison | + revisions ' filenolink = ' - {file|escape} + {file|escape} file | annotate | - diff | - comparison | - revisions + diff | + comparison | + revisions ' @@ -59,11 +59,11 @@ - {basename|escape} - {emptydirs|escape} + {basename|escape} + {emptydirs|escape} - files + files ' fileentry = ' @@ -72,12 +72,12 @@ {date|isodate} {size} - {basename|escape} + {basename|escape} - file | - revisions | - annotate + file | + revisions | + annotate ' filerevision = filerevision.tmpl @@ -92,7 +92,7 @@ annotateline = ' - {author|user}@{rev}
    {linenumber}
    @@ -117,34 +117,34 @@ parent {rev}: - {node|short} + {node|short} ' -changesetbranch = 'branch{name}' +changesetbranch = 'branch{name|escape}' changesetparent = ' parent {rev} - {node|short} + {node|short} ' -filerevbranch = 'branch{name}' +filerevbranch = 'branch{name|escape}' filerevparent = ' parent {rev} - + {rename%filerename}{node|short} ' filerename = '{file|escape}@' -filelogrename = '| base' +filelogrename = '| base' fileannotateparent = ' parent {rev} - + {rename%filerename}{node|short} @@ -152,59 +152,59 @@ changelogchild = ' child {rev}: - {node|short} + {node|short} ' changesetchild = ' child {rev} - {node|short} + {node|short} ' filerevchild = ' child {rev} - {node|short} + {node|short} ' fileannotatechild = ' child {rev} - {node|short} + {node|short} ' tags = tags.tmpl tagentry = ' {date|rfc822date} - {tag|escape} + {tag|escape} - changeset | - changelog | - files + changeset | + changelog | + files ' bookmarks = bookmarks.tmpl bookmarkentry = ' {date|rfc822date} - {bookmark|escape} + {bookmark|escape} - changeset | - changelog | - files + changeset | + changelog | + files ' branches = branches.tmpl branchentry = ' {date|rfc822date} - {node|short} + {node|short} {branch|escape} - changeset | - changelog | - files + changeset | + changelog | + files ' diffblock = '
    {lines}
    ' @@ -212,7 +212,7 @@ parent {rev} - + {node|short} @@ -221,7 +221,7 @@ parent {rev} - + {node|short} @@ -229,64 +229,64 @@ filelogparent = ' parent {rev}:  - {node|short} + {node|short} ' filediffchild = ' child {rev} - {node|short} + {node|short} ' filecompchild = ' child {rev} - {node|short} + {node|short} ' filelogchild = ' child {rev}:  - {node|short} + {node|short} ' shortlog = shortlog.tmpl graph = graph.tmpl -tagtag = '{name} ' -branchtag = '{name} ' -inbranchtag = '{name} ' -bookmarktag = '{name} ' +tagtag = '{name|escape} ' +branchtag = '{name|escape} ' +inbranchtag = '{name|escape} ' +bookmarktag = '{name|escape} ' shortlogentry = ' {date|rfc822date} {author|person} - + {desc|strip|firstline|escape|nonempty} {inbranch%inbranchtag}{branches%branchtag}{tags%tagtag}{bookmarks%bookmarktag} - changeset | - files + changeset | + files ' filelogentry = ' {date|rfc822date} - + {desc|strip|firstline|escape|nonempty} - file | diff | annotate {rename%filelogrename} + file | diff | annotate {rename%filelogrename} ' -archiveentry = ' | {type|escape} ' +archiveentry = ' | {type|escape} ' indexentry = ' - + {name|escape} @@ -296,13 +296,13 @@ {archives%indexarchiveentry} {if(isdirectory, '', '' )} \n' -indexarchiveentry = ' {type|escape} ' +indexarchiveentry = ' {type|escape} ' index = index.tmpl urlparameter = '{separator}{name}={value|urlescape}' hiddenformentry = '' -breadcrumb = '> {name} ' +breadcrumb = '> {name|escape} ' diff -r 0324a1d88a53 -r 126768fae4c4 mercurial/templates/gitweb/notfound.tmpl --- a/mercurial/templates/gitweb/notfound.tmpl Fri Feb 01 02:01:11 2013 +0100 +++ b/mercurial/templates/gitweb/notfound.tmpl Fri Feb 01 20:43:35 2013 +0100 @@ -12,7 +12,7 @@ The specified repository "{repo|escape}" is unknown, sorry.

    -Please go back to the main repository list page. +Please go back to the main repository list page. {footer} diff -r 0324a1d88a53 -r 126768fae4c4 mercurial/templates/gitweb/search.tmpl --- a/mercurial/templates/gitweb/search.tmpl Fri Feb 01 02:01:11 2013 +0100 +++ b/mercurial/templates/gitweb/search.tmpl Fri Feb 01 20:43:35 2013 +0100 @@ -1,9 +1,9 @@ {header} {repo|escape}: Search + href="{url|urlescape}atom-log" title="Atom feed for {repo|escape}"/> + href="{url|urlescape}rss-log" title="RSS feed for {repo|escape}"/> @@ -11,7 +11,7 @@ Mercurial Mercurial {pathdef%breadcrumb} / search -
    + {sessionvars%hiddenformentry} diff -r 0324a1d88a53 -r 126768fae4c4 mercurial/templates/gitweb/shortlog.tmpl --- a/mercurial/templates/gitweb/shortlog.tmpl Fri Feb 01 02:01:11 2013 +0100 +++ b/mercurial/templates/gitweb/shortlog.tmpl Fri Feb 01 20:43:35 2013 +0100 @@ -1,9 +1,9 @@ {header} {repo|escape}: Shortlog + href="{url|urlescape}atom-log" title="Atom feed for {repo|escape}"/> + href="{url|urlescape}rss-log" title="RSS feed for {repo|escape}"/> @@ -12,22 +12,22 @@ Mercurial {pathdef%breadcrumb} / shortlog - + {sessionvars%hiddenformentry}
    diff -r 0324a1d88a53 -r 126768fae4c4 mercurial/templates/gitweb/summary.tmpl --- a/mercurial/templates/gitweb/summary.tmpl Fri Feb 01 02:01:11 2013 +0100 +++ b/mercurial/templates/gitweb/summary.tmpl Fri Feb 01 20:43:35 2013 +0100 @@ -1,16 +1,16 @@ {header} {repo|escape}: Summary + href="{url|urlescape}atom-log" title="Atom feed for {repo|escape}"/> + href="{url|urlescape}rss-log" title="RSS feed for {repo|escape}"/>
    -

    mercurial

    +

    mercurial

    diff -r 0324a1d88a53 -r 126768fae4c4 mercurial/templates/monoblue/manifest.tmpl --- a/mercurial/templates/monoblue/manifest.tmpl Fri Feb 01 02:01:11 2013 +0100 +++ b/mercurial/templates/monoblue/manifest.tmpl Fri Feb 01 20:43:35 2013 +0100 @@ -1,7 +1,7 @@ {header} {repo|escape}: files - - + + @@ -9,7 +9,7 @@ @@ -43,7 +43,7 @@ drwxr-xr-x - [up] + [up]   {dentries%direntry} diff -r 0324a1d88a53 -r 126768fae4c4 mercurial/templates/monoblue/map --- a/mercurial/templates/monoblue/map Fri Feb 01 02:01:11 2013 +0100 +++ b/mercurial/templates/monoblue/map Fri Feb 01 20:43:35 2013 +0100 @@ -11,35 +11,35 @@ help = help.tmpl helptopics = helptopics.tmpl -helpentry = '{topic|escape}{summary|escape}' +helpentry = '{topic|escape}{summary|escape}' -naventry = '{label|escape} ' -navshortentry = '{label|escape} ' -navgraphentry = '{label|escape} ' -filenaventry = '{label|escape}' -filedifflink = '{file|escape} ' +naventry = '{label|escape} ' +navshortentry = '{label|escape} ' +navgraphentry = '{label|escape} ' +filenaventry = '{label|escape}' +filedifflink = '{file|escape} ' filenodelink = ' - {file|escape} + {file|escape} - file | - annotate | - diff | - comparison | - revisions + file | + annotate | + diff | + comparison | + revisions ' filenolink = ' - {file|escape} + {file|escape} file | annotate | - diff | - comparison | - revisions + diff | + comparison | + revisions ' @@ -58,19 +58,19 @@ drwxr-xr-x - {basename|escape} - files + {basename|escape} + files ' fileentry = ' {permissions|permissions} {date|isodate} {size} - {basename|escape} + {basename|escape} - file | - revisions | - annotate + file | + revisions | + annotate ' filerevision = filerevision.tmpl @@ -85,7 +85,7 @@ annotateline = ' - {author|user}@{rev} @@ -112,136 +112,136 @@ parent {rev}: - {node|short} + {node|short} ' -changesetbranch = '
    branch
    {name}
    ' +changesetbranch = '
    branch
    {name|escape}
    ' changesetparent = '
    parent {rev}
    -
    {node|short}
    ' -filerevbranch = '
    branch
    {name}
    ' +
    {node|short}
    ' +filerevbranch = '
    branch
    {name|escape}
    ' filerevparent = '
    parent {rev}
    - + {rename%filerename}{node|short}
    ' filerename = '{file|escape}@' -filelogrename = '| base' +filelogrename = '| base' fileannotateparent = '
    parent {rev}
    - + {rename%filerename}{node|short}
    ' changelogchild = '
    child {rev}:
    -
    {node|short}
    ' +
    {node|short}
    ' changesetchild = '
    child {rev}
    -
    {node|short}
    ' +
    {node|short}
    ' filerevchild = '
    child {rev}
    - {node|short} + {node|short}
    ' fileannotatechild = '
    child {rev}
    - {node|short} + {node|short}
    ' tags = tags.tmpl tagentry = ' {date|rfc822date} - {tag|escape} + {tag|escape} - changeset | - changelog | - files + changeset | + changelog | + files ' bookmarks = bookmarks.tmpl bookmarkentry = ' {date|rfc822date} - {bookmark|escape} + {bookmark|escape} - changeset | - changelog | - files + changeset | + changelog | + files ' branches = branches.tmpl branchentry = ' {date|rfc822date} - {node|short} + {node|short} {branch|escape} - changeset | - changelog | - files + changeset | + changelog | + files ' diffblock = '
    {lines}
    ' filediffparent = '
    parent {rev}
    -
    {node|short}
    ' +
    {node|short}
    ' filecompparent = '
    parent {rev}
    -
    {node|short}
    ' +
    {node|short}
    ' filelogparent = ' parent {rev}:  - {node|short} + {node|short} ' filediffchild = '
    child {rev}
    -
    {node|short}
    ' +
    {node|short}
    ' filecompchild = '
    child {rev}
    -
    {node|short}
    ' +
    {node|short}
    ' filelogchild = ' child {rev}:  - {node|short} + {node|short} ' shortlog = shortlog.tmpl -tagtag = '{name} ' -branchtag = '{name} ' -inbranchtag = '{name} ' -bookmarktag = '{name} ' +tagtag = '{name|escape} ' +branchtag = '{name|escape} ' +inbranchtag = '{name|escape} ' +bookmarktag = '{name|escape} ' shortlogentry = ' {date|rfc822date} {author|person} - + {desc|strip|firstline|escape|nonempty} {inbranch%inbranchtag}{branches%branchtag}{tags%tagtag}{bookmarks%bookmarktag} - changeset | - files + changeset | + files ' filelogentry = ' {date|rfc822date} - {desc|strip|firstline|escape|nonempty} + {desc|strip|firstline|escape|nonempty} - file | diff | annotate + file | diff | annotate {rename%filelogrename} ' -archiveentry = '
  • {type|escape}
  • ' +archiveentry = '
  • {type|escape}
  • ' indexentry = ' - {name|escape} + {name|escape} {description} {contact|obfuscate} {lastchange|rfc822date} @@ -249,14 +249,14 @@ {if(isdirectory, '', '' )} \n' -indexarchiveentry = '{type|escape} ' +indexarchiveentry = '{type|escape} ' index = index.tmpl urlparameter = '{separator}{name}={value|urlescape}' hiddenformentry = '' graph = graph.tmpl -breadcrumb = '> {name} ' +breadcrumb = '> {name|escape} ' diff -r 0324a1d88a53 -r 126768fae4c4 mercurial/templates/monoblue/notfound.tmpl --- a/mercurial/templates/monoblue/notfound.tmpl Fri Feb 01 02:01:11 2013 +0100 +++ b/mercurial/templates/monoblue/notfound.tmpl Fri Feb 01 20:43:35 2013 +0100 @@ -1,7 +1,7 @@ {header} {repo|escape}: Mercurial repository not found - - + + @@ -9,7 +9,7 @@

    The specified repository "{repo|escape}" is unknown, sorry.

    -

    Please go back to the main repository list page.

    +

    Please go back to the main repository list page.

    {footer} diff -r 0324a1d88a53 -r 126768fae4c4 mercurial/templates/monoblue/search.tmpl --- a/mercurial/templates/monoblue/search.tmpl Fri Feb 01 02:01:11 2013 +0100 +++ b/mercurial/templates/monoblue/search.tmpl Fri Feb 01 20:43:35 2013 +0100 @@ -1,7 +1,7 @@ {header} {repo|escape}: Search - - + + @@ -9,7 +9,7 @@ diff -r 0324a1d88a53 -r 126768fae4c4 mercurial/templates/monoblue/shortlog.tmpl --- a/mercurial/templates/monoblue/shortlog.tmpl Fri Feb 01 02:01:11 2013 +0100 +++ b/mercurial/templates/monoblue/shortlog.tmpl Fri Feb 01 20:43:35 2013 +0100 @@ -1,7 +1,7 @@ {header} {repo|escape}: shortlog - - + + @@ -9,7 +9,7 @@ diff -r 0324a1d88a53 -r 126768fae4c4 mercurial/templates/monoblue/summary.tmpl --- a/mercurial/templates/monoblue/summary.tmpl Fri Feb 01 02:01:11 2013 +0100 +++ b/mercurial/templates/monoblue/summary.tmpl Fri Feb 01 20:43:35 2013 +0100 @@ -1,7 +1,7 @@ {header} {repo|escape}: Summary - - + + @@ -9,7 +9,7 @@ @@ -42,27 +42,27 @@
    {lastchange|rfc822date}
    -

    Changes

    +

    Changes

    {shortlog} - +
    ......
    -

    Tags

    +

    Tags

    {tags} - +
    ......
    -

    Bookmarks

    +

    Bookmarks

    {bookmarks%bookmarkentry} - +
    ......
    diff -r 0324a1d88a53 -r 126768fae4c4 mercurial/templates/monoblue/tags.tmpl --- a/mercurial/templates/monoblue/tags.tmpl Fri Feb 01 02:01:11 2013 +0100 +++ b/mercurial/templates/monoblue/tags.tmpl Fri Feb 01 20:43:35 2013 +0100 @@ -1,7 +1,7 @@ {header} {repo|escape}: Tags - - + + @@ -9,7 +9,7 @@ diff -r 0324a1d88a53 -r 126768fae4c4 mercurial/templates/paper/bookmarks.tmpl --- a/mercurial/templates/paper/bookmarks.tmpl Fri Feb 01 02:01:11 2013 +0100 +++ b/mercurial/templates/paper/bookmarks.tmpl Fri Feb 01 20:43:35 2013 +0100 @@ -1,9 +1,9 @@ {header} {repo|escape}: bookmarks + href="{url|urlescape}atom-bookmarks" title="Atom feed for {repo|escape}: bookmarks" /> + href="{url|urlescape}rss-bookmarks" title="RSS feed for {repo|escape}: bookmarks" /> @@ -11,22 +11,22 @@ @@ -35,7 +35,7 @@

    bookmarks

    - @@ -357,47 +423,28 @@ Dish up an empty repo; serve it cold. files, or words in the commit message
    - - -
    Specifying Single Revisions
    -

    - Mercurial supports several ways to specify individual revisions. -

    -

    - A plain integer is treated as a revision number. Negative integers are +

    Mercurial supports several ways to specify individual revisions.

    +

    A plain integer is treated as a revision number. Negative integers are treated as sequential offsets from the tip, with -1 denoting the tip, - -2 denoting the revision prior to the tip, and so forth. -

    -

    - A 40-digit hexadecimal string is treated as a unique revision - identifier. -

    -

    - A hexadecimal string less than 40 characters long is treated as a + -2 denoting the revision prior to the tip, and so forth.

    +

    A 40-digit hexadecimal string is treated as a unique revision + identifier.

    +

    A hexadecimal string less than 40 characters long is treated as a unique revision identifier and is referred to as a short-form identifier. A short-form identifier is only valid if it is the prefix - of exactly one full-length identifier. -

    -

    - Any other string is treated as a bookmark, tag, or branch name. A + of exactly one full-length identifier.

    +

    Any other string is treated as a bookmark, tag, or branch name. A bookmark is a movable pointer to a revision. A tag is a permanent name associated with a revision. A branch name denotes the tipmost revision - of that branch. Bookmark, tag, and branch names must not contain the ":" - character. -

    -

    - The reserved name "tip" always identifies the most recent revision. -

    -

    - The reserved name "null" indicates the null revision. This is the - revision of an empty repository, and the parent of revision 0. -

    -

    - The reserved name "." indicates the working directory parent. If no + of that branch. Bookmark, tag, and branch names must not contain the ":" + character.

    +

    The reserved name "tip" always identifies the most recent revision.

    +

    The reserved name "null" indicates the null revision. This is the + revision of an empty repository, and the parent of revision 0.

    +

    The reserved name "." indicates the working directory parent. If no working directory is checked out, it is equivalent to null. If an - uncommitted merge is in progress, "." is the revision of the first - parent. -

    + uncommitted merge is in progress, "." is the revision of the first + parent.

    From sid0 at fb.com Sat Feb 9 07:23:35 2013 From: sid0 at fb.com (Siddharth Agarwal) Date: Sat, 9 Feb 2013 13:23:35 +0000 Subject: [PATCH 4 of 5 V2] manifestmerge: handle abort on local unknown, remote created files In-Reply-To: <51163A55.30508@kiilerich.com> References: <51163A55.30508@kiilerich.com> Message-ID: <51164DD7.9060507@fb.com> On 02/09/2013 12:00 PM, Mads Kiilerich wrote: > Is this handling a new case and fixing a bug? Or is it duplicating > existing functionality as an optimization or cleanup? Duplicating existing functionality in a faster manner, and the next patch removes the original check. > (Should be explained here ... and perhaps tested if it makes any > visible changes.) No, it doesn't make any visible changes. The next changeset doesn't, either. > Do we have test coverage for all these cases? Yes, spread across a bunch of tests. From pierre-yves.david at ens-lyon.org Sat Feb 9 07:50:44 2013 From: pierre-yves.david at ens-lyon.org (Pierre-Yves David) Date: Sat, 9 Feb 2013 14:50:44 +0100 Subject: [PATCH 2 of 6] help: move the majority of the help command to the help module In-Reply-To: References: Message-ID: <20130209135044.GA2955@kraken.insecable.net> On Sat, Feb 09, 2013 at 01:00:36PM +0000, Dan Villiom Podlaski Christiansen wrote: > # HG changeset patch > # User Dan Villiom Podlaski Christiansen > # Date 1360414101 0 > # Node ID aa74feb1f11d43453e6ef3797e6c4c24f950a9dc > # Parent 9e480fad47e71fd9b954159cad337e8b91a5b9e5 > help: move the majority of the help command to the help module The change looks good, but the reason to do that is not very clear. It seems cleaner but there is more concrete motivation highlighted by stuff later in the series. You should make it clear. and please swear that this is code movement only and that did not changed a line. -- Pierre-Yves David From pierre-yves.david at ens-lyon.org Sat Feb 9 07:57:48 2013 From: pierre-yves.david at ens-lyon.org (Pierre-Yves David) Date: Sat, 9 Feb 2013 14:57:48 +0100 Subject: [PATCH 3 of 6] help: ReST tweaks In-Reply-To: <03c9cfc461cce54da65f.1360414837@s0-0.paconsult7.bbnplanet.net> References: <03c9cfc461cce54da65f.1360414837@s0-0.paconsult7.bbnplanet.net> Message-ID: <20130209135747.GB2955@kraken.insecable.net> On Sat, Feb 09, 2013 at 01:00:37PM +0000, Dan Villiom Podlaski Christiansen wrote: > # HG changeset patch > # User Dan Villiom Podlaski Christiansen > # Date 1360414103 0 > # Node ID 03c9cfc461cce54da65f0ad0529a734181022b83 > # Parent aa74feb1f11d43453e6ef3797e6c4c24f950a9dc > help: ReST tweaks > > Use a full header for topic titles; make the indent configurable by > the caller This patches is doing two stuff, you should probably split it. The changes to header is a bit obscure to me. looks like you are adding a '===' belong the header. But it must have been something there before. Why is that necessary ? > diff --git a/mercurial/help.py b/mercurial/help.py > --- a/mercurial/help.py > +++ b/mercurial/help.py > @@ -389,12 +389,17 @@ def help_(ui, name, unknowncmd=False, fu > else: > raise error.UnknownCommand(name) > > - rst = ["%s\n\n" % header] > + headerstyleline = '=' * encoding.colwidth(header) > + rst = ["%s\n%s\n%s\n\n" % (headerstyleline, header, headerstyleline)] > + > # description > if not doc: > - rst.append(" %s\n" % _("(no help text available)")) > + doc = _("(no help text available)") > if util.safehasattr(doc, '__call__'): > - rst += [" %s\n" % l for l in doc().splitlines()] > + doc = doc() > + > + indent = ' ' * int(opts.get('indent', 4)) > + rst += ["%s%s\n" % (indent, l) for l in doc.splitlines()] The new `indent` argument should be documented. (note: having the default value in the middle of the function is common but confusing) -- Pierre-Yves From pierre-yves.david at ens-lyon.org Sat Feb 9 07:59:50 2013 From: pierre-yves.david at ens-lyon.org (Pierre-Yves David) Date: Sat, 9 Feb 2013 14:59:50 +0100 Subject: [PATCH 4 of 6] hgweb: generate HTML documentation In-Reply-To: <675a399c2c9d5c94d479.1360414838@s0-0.paconsult7.bbnplanet.net> References: <675a399c2c9d5c94d479.1360414838@s0-0.paconsult7.bbnplanet.net> Message-ID: <20130209135950.GC2955@kraken.insecable.net> On Sat, Feb 09, 2013 at 01:00:38PM +0000, Dan Villiom Podlaski Christiansen wrote: > # HG changeset patch > # User Dan Villiom Podlaski Christiansen > # Date 1360414104 0 > # Node ID 675a399c2c9d5c94d4798bc8fd11f855eaff5672 > # Parent 03c9cfc461cce54da65f0ad0529a734181022b83 > hgweb: generate HTML documentation > > diff --git a/mercurial/help/templates.txt b/mercurial/help/templates.txt > --- a/mercurial/help/templates.txt > +++ b/mercurial/help/templates.txt > @@ -60,6 +60,8 @@ In addition to filters, there are some b > > - sub(pat, repl, expr) > > +- rstdoc(text, style) > + > Also, for any expression that returns a list, there is a list operator: > > - expr % "{template}" > diff --git a/mercurial/hgweb/webcommands.py b/mercurial/hgweb/webcommands.py > --- a/mercurial/hgweb/webcommands.py > +++ b/mercurial/hgweb/webcommands.py > @@ -995,8 +995,7 @@ def help(web, req, tmpl): > u.pushbuffer() extra pushbuffer call > u.verbose = True > try: > - commands.help_(u, topicname) > + doc = helpmod.help_(u, topicname, indent=0) > except error.UnknownCommand: > raise ErrorResponse(HTTP_NOT_FOUND) > - doc = u.popbuffer() while popbuffer have been removed (context manager anyone :-() > return tmpl('help', topic=topicname, doc=doc) > diff --git a/mercurial/templater.py b/mercurial/templater.py > --- a/mercurial/templater.py > +++ b/mercurial/templater.py > @@ -9,6 +9,7 @@ from i18n import _ > import sys, os, re > import util, config, templatefilters, parser, error > import types > +import minirst > > # template parsing > > @@ -287,6 +288,16 @@ def label(context, mapping, args): > t = stringify(args[1][0](context, mapping, args[1][1])) > yield runtemplate(context, mapping, compiletemplate(t, context)) > > +def rstdoc(context, mapping, args): > + if len(args) != 2: > + # i18n: "rstdoc" is a keyword > + raise error.ParseError(_("rstdoc expects two arguments")) > + > + text = stringify(args[0][0](context, mapping, args[0][1])) > + style = stringify(args[1][0](context, mapping, args[1][1])) > + > + return minirst.format(text, style=style) > + > methods = { > "string": lambda e, c: (runstring, e[1]), > "symbol": lambda e, c: (runsymbol, e[1]), > @@ -303,6 +314,7 @@ funcs = { > "ifeq": ifeq, > "join": join, > "label": label, > + "rstdoc": rstdoc, > "sub": sub, > } > > diff --git a/mercurial/templates/gitweb/help.tmpl b/mercurial/templates/gitweb/help.tmpl > --- a/mercurial/templates/gitweb/help.tmpl > +++ b/mercurial/templates/gitweb/help.tmpl > @@ -27,8 +27,8 @@ help > >
     
    > > -
    > -{doc|escape}
    > -
    > +
    > +{rstdoc(doc, "html")} > +
    > > {footer} > diff --git a/mercurial/templates/monoblue/help.tmpl b/mercurial/templates/monoblue/help.tmpl > --- a/mercurial/templates/monoblue/help.tmpl > +++ b/mercurial/templates/monoblue/help.tmpl > @@ -31,8 +31,8 @@ > > > > -
    > -    {doc|escape}
    > -    
    > +
    > + {rstdoc(doc, "html")} > +
    > > {footer} > diff --git a/mercurial/templates/paper/help.tmpl b/mercurial/templates/paper/help.tmpl > --- a/mercurial/templates/paper/help.tmpl > +++ b/mercurial/templates/paper/help.tmpl > @@ -31,9 +31,9 @@ >
    find changesets by author, revision, > files, or words in the commit message
    > > -
    > -{doc|escape}
    > -
    > +
    > +{rstdoc(doc, "html")} > +
    > > > > diff --git a/tests/test-hgweb-help.t b/tests/test-hgweb-help.t > --- a/tests/test-hgweb-help.t > +++ b/tests/test-hgweb-help.t > @@ -52,65 +52,105 @@ Dish up an empty repo; serve it cold. >
    find changesets by author, revision, > files, or words in the commit message
    > > -
    > +  
    > +

    > hg add [OPTION]... [FILE]... > +

    > +

    > + add the specified files on the next commit > +

    > +

    > + Schedule files to be version controlled and added to the > + repository. > +

    > +

    > + The files will be added to the repository at the next commit. To > + undo an add before that, see "hg forget". > +

    > +

    > + If no names are given, add all files to the repository. > +

    > +

    > + Returns 0 if all files are successfully added. > +

    > +

    > + options: > +

    > + > + > + > + > + > + > + > + > + > + > + > + > + > +
    -I--include PATTERN [+]include names matching the given patterns
    -X--exclude PATTERN [+]exclude names matching the given patterns
    -S--subreposrecurse into subrepositories
    -n--dry-rundo not perform actions, just print output
    > +

    > + [+] marked option can be specified multiple times > +

    > +

    > + global options: > +

    > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > +
    -R--repository REPOrepository root directory or name of overlay bundle file
    --cwd DIRchange working directory
    -y--noninteractivedo not prompt, automatically pick the first choice for all prompts
    -q--quietsuppress output
    -v--verboseenable additional output
    --config CONFIG [+]set/override config option (use 'section.name=value')
    --debugenable debugging output
    --debuggerstart debugger
    --encoding ENCODEset the charset encoding (default: ascii)
    --encodingmode MODEset the charset encoding mode (default: strict)
    --tracebackalways print a traceback on exception
    --timetime how long the command takes
    --profileprint command execution profile
    --versionoutput version information and exit
    -h--helpdisplay help and exit
    --hiddenconsider hidden changesets
    > +

    > + [+] marked option can be specified multiple times > +

    > > - add the specified files on the next commit > - > - Schedule files to be version controlled and added to the repository. > - > - The files will be added to the repository at the next commit. To undo an > - add before that, see "hg forget". > - > - If no names are given, add all files to the repository. > - > - An example showing how new (unknown) files are added automatically by "hg > - add": > - > - $ ls > - foo.c > - $ hg status > - ? foo.c > - $ hg add > - adding foo.c > - $ hg status > - A foo.c > - > - Returns 0 if all files are successfully added. > - > - options: > - > - -I --include PATTERN [+] include names matching the given patterns > - -X --exclude PATTERN [+] exclude names matching the given patterns > - -S --subrepos recurse into subrepositories > - -n --dry-run do not perform actions, just print output > - > - [+] marked option can be specified multiple times > - > - global options: > - > - -R --repository REPO repository root directory or name of overlay bundle > - file > - --cwd DIR change working directory > - -y --noninteractive do not prompt, automatically pick the first choice for > - all prompts > - -q --quiet suppress output > - -v --verbose enable additional output > - --config CONFIG [+] set/override config option (use 'section.name=value') > - --debug enable debugging output > - --debugger start debugger > - --encoding ENCODE set the charset encoding (default: ascii) > - --encodingmode MODE set the charset encoding mode (default: strict) > - --traceback always print a traceback on exception > - --time time how long the command takes > - --profile print command execution profile > - --version output version information and exit > - -h --help display help and exit > - --hidden consider hidden changesets > - > - [+] marked option can be specified multiple times > - > -
    > + > > > > @@ -164,74 +204,105 @@ Dish up an empty repo; serve it cold. >
    find changesets by author, revision, > files, or words in the commit message
    > > -
    > +  
    > +

    > hg remove [OPTION]... FILE... > +

    > +

    > + aliases: rm > +

    > +

    > + remove the specified files on the next commit > +

    > +

    > + Schedule the indicated files for removal from the current branch. > +

    > +

    > + This command schedules the files to be removed at the next commit. > + To undo a remove before that, see "hg revert". To undo added > + files, see "hg forget". > +

    > +

    > + Returns 0 on success, 1 if any warnings encountered. > +

    > +

    > + options: > +

    > + > + > + > + > + > + > + > + > + > + > + > + > + > +
    -A--afterrecord delete for missing files
    -f--forceremove (and delete) file even if added or modified
    -I--include PATTERN [+]include names matching the given patterns
    -X--exclude PATTERN [+]exclude names matching the given patterns
    > +

    > + [+] marked option can be specified multiple times > +

    > +

    > + global options: > +

    > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > +
    -R--repository REPOrepository root directory or name of overlay bundle file
    --cwd DIRchange working directory
    -y--noninteractivedo not prompt, automatically pick the first choice for all prompts
    -q--quietsuppress output
    -v--verboseenable additional output
    --config CONFIG [+]set/override config option (use 'section.name=value')
    --debugenable debugging output
    --debuggerstart debugger
    --encoding ENCODEset the charset encoding (default: ascii)
    --encodingmode MODEset the charset encoding mode (default: strict)
    --tracebackalways print a traceback on exception
    --timetime how long the command takes
    --profileprint command execution profile
    --versionoutput version information and exit
    -h--helpdisplay help and exit
    --hiddenconsider hidden changesets
    > +

    > + [+] marked option can be specified multiple times > +

    > > - aliases: rm > - > - remove the specified files on the next commit > - > - Schedule the indicated files for removal from the current branch. > - > - This command schedules the files to be removed at the next commit. To undo > - a remove before that, see "hg revert". To undo added files, see "hg > - forget". > - > - -A/--after can be used to remove only files that have already been > - deleted, -f/--force can be used to force deletion, and -Af can be used to > - remove files from the next revision without deleting them from the working > - directory. > - > - The following table details the behavior of remove for different file > - states (columns) and option combinations (rows). The file states are Added > - [A], Clean [C], Modified [M] and Missing [!] (as reported by "hg status"). > - The actions are Warn, Remove (from branch) and Delete (from disk): > - > - A C M ! > - -------------- > - none W RD W R > - -f R RD RD R > - -A W W W R > - -Af R R R R > - > - Note that remove never deletes files in Added [A] state from the working > - directory, not even if option --force is specified. > - > - Returns 0 on success, 1 if any warnings encountered. > - > - options: > - > - -A --after record delete for missing files > - -f --force remove (and delete) file even if added or modified > - -I --include PATTERN [+] include names matching the given patterns > - -X --exclude PATTERN [+] exclude names matching the given patterns > - > - [+] marked option can be specified multiple times > - > - global options: > - > - -R --repository REPO repository root directory or name of overlay bundle > - file > - --cwd DIR change working directory > - -y --noninteractive do not prompt, automatically pick the first choice for > - all prompts > - -q --quiet suppress output > - -v --verbose enable additional output > - --config CONFIG [+] set/override config option (use 'section.name=value') > - --debug enable debugging output > - --debugger start debugger > - --encoding ENCODE set the charset encoding (default: ascii) > - --encodingmode MODE set the charset encoding mode (default: strict) > - --traceback always print a traceback on exception > - --time time how long the command takes > - --profile print command execution profile > - --version output version information and exit > - -h --help display help and exit > - --hidden consider hidden changesets > - > - [+] marked option can be specified multiple times > - > -
    > + > > > > @@ -285,38 +356,50 @@ Dish up an empty repo; serve it cold. >
    find changesets by author, revision, > files, or words in the commit message
    > > -
    > -  Specifying Single Revisions
    > +  
    > + > + > +
    Specifying Single Revisions
    > +

    > + Mercurial supports several ways to specify individual revisions. > +

    > +

    > + A plain integer is treated as a revision number. Negative integers are > + treated as sequential offsets from the tip, with -1 denoting the tip, > + -2 denoting the revision prior to the tip, and so forth. > +

    > +

    > + A 40-digit hexadecimal string is treated as a unique revision > + identifier. > +

    > +

    > + A hexadecimal string less than 40 characters long is treated as a > + unique revision identifier and is referred to as a short-form > + identifier. A short-form identifier is only valid if it is the prefix > + of exactly one full-length identifier. > +

    > +

    > + Any other string is treated as a bookmark, tag, or branch name. A > + bookmark is a movable pointer to a revision. A tag is a permanent name > + associated with a revision. A branch name denotes the tipmost revision > + of that branch. Bookmark, tag, and branch names must not contain the ":" > + character. > +

    > +

    > + The reserved name "tip" always identifies the most recent revision. > +

    > +

    > + The reserved name "null" indicates the null revision. This is the > + revision of an empty repository, and the parent of revision 0. > +

    > +

    > + The reserved name "." indicates the working directory parent. If no > + working directory is checked out, it is equivalent to null. If an > + uncommitted merge is in progress, "." is the revision of the first > + parent. > +

    > > - Mercurial supports several ways to specify individual revisions. > - > - A plain integer is treated as a revision number. Negative integers are > - treated as sequential offsets from the tip, with -1 denoting the tip, -2 > - denoting the revision prior to the tip, and so forth. > - > - A 40-digit hexadecimal string is treated as a unique revision identifier. > - > - A hexadecimal string less than 40 characters long is treated as a unique > - revision identifier and is referred to as a short-form identifier. A > - short-form identifier is only valid if it is the prefix of exactly one > - full-length identifier. > - > - Any other string is treated as a bookmark, tag, or branch name. A bookmark > - is a movable pointer to a revision. A tag is a permanent name associated > - with a revision. A branch name denotes the tipmost revision of that > - branch. Bookmark, tag, and branch names must not contain the ":" > - character. > - > - The reserved name "tip" always identifies the most recent revision. > - > - The reserved name "null" indicates the null revision. This is the revision > - of an empty repository, and the parent of revision 0. > - > - The reserved name "." indicates the working directory parent. If no > - working directory is checked out, it is equivalent to null. If an > - uncommitted merge is in progress, "." is the revision of the first parent. > - > -
    > + > > > > _______________________________________________ > Mercurial-devel mailing list > Mercurial-devel at selenic.com > http://selenic.com/mailman/listinfo/mercurial-devel From pierre-yves.david at ens-lyon.org Sat Feb 9 08:02:19 2013 From: pierre-yves.david at ens-lyon.org (Pierre-Yves David) Date: Sat, 9 Feb 2013 15:02:19 +0100 Subject: [PATCH 5 of 6] minirst: HTML formatter tweaks In-Reply-To: <45b34ea40358b6f8fe14.1360414839@s0-0.paconsult7.bbnplanet.net> References: <45b34ea40358b6f8fe14.1360414839@s0-0.paconsult7.bbnplanet.net> Message-ID: <20130209140219.GD2955@kraken.insecable.net> On Sat, Feb 09, 2013 at 01:00:39PM +0000, Dan Villiom Podlaski Christiansen wrote: > # HG changeset patch > # User Dan Villiom Podlaski Christiansen > # Date 1360414106 0 > # Node ID 45b34ea40358b6f8fe14ef874ebbc5de5556f23c > # Parent 675a399c2c9d5c94d4798bc8fd11f855eaff5672 > minirst: HTML formatter tweaks > > - output table rows on distinct lines > - don't make the first row a table header You should make the reason for this change clear. Are you sure it does not break any other valid usage ? (note: two changes in a patches, but pretty related) > > diff --git a/mercurial/minirst.py b/mercurial/minirst.py > --- a/mercurial/minirst.py > +++ b/mercurial/minirst.py > @@ -546,11 +546,8 @@ def formathtml(blocks): > for row in table: > l = [] > for v in zip(row): > - if not t: > - l.append('%s' % v) > - else: > - l.append('%s' % v) > - t.append(' %s\n' % ''.join(l)) > + l.append('%s' % v) > + t.append(' %s\n' % '\n'.join(l)) > out.append('\n%s
    \n' % ''.join(t)) > elif btype == 'definition': > openlist('dl', level) > diff --git a/tests/test-minirst.py.out b/tests/test-minirst.py.out > --- a/tests/test-minirst.py.out > +++ b/tests/test-minirst.py.out > @@ -758,9 +758,15 @@ 30 column format: > html format: > ---------------------------------------------------------------------- > > - > - > - > + > + > + > + > + > + > + > + > + >
    abc
    123
    foobarbaz this list is very very very long man
    abc
    123
    foobarbaz this list is very very very long man
    > ---------------------------------------------------------------------- > > _______________________________________________ > Mercurial-devel mailing list > Mercurial-devel at selenic.com > http://selenic.com/mailman/listinfo/mercurial-devel From kbullock+mercurial at ringworld.org Sat Feb 9 08:04:06 2013 From: kbullock+mercurial at ringworld.org (Kevin Bullock) Date: Sat, 09 Feb 2013 14:04:06 +0000 Subject: [PATCH] tests: remove last two check-code warnings about killdaemons Message-ID: # HG changeset patch # User Kevin Bullock # Date 1360418293 0 # Node ID c99f13e430f9f52c702f125a8b7aa197bef71a7a # Parent 1cb04715fd4bb12bc5f3fd52a6b055201e704059 tests: remove last two check-code warnings about killdaemons Removes the last of the warnings in test-check-code-hg.t introduced in 667063b22a69. diff --git a/tests/test-check-code-hg.t b/tests/test-check-code-hg.t --- a/tests/test-check-code-hg.t +++ b/tests/test-check-code-hg.t @@ -11,10 +11,3 @@ New errors are not allowed. Warnings are $ hg manifest 2>/dev/null \ > | xargs "$check_code" --warnings --nolineno --per-file=0 \ > || false - tests/test-serve.t:0: - > > kill `cat hg.pid` - don't use kill, use killdaemons.py - tests/test-serve.t:0: - > > kill `cat hg.pid` 2>/dev/null - don't use kill, use killdaemons.py - [1] diff --git a/tests/test-serve.t b/tests/test-serve.t --- a/tests/test-serve.t +++ b/tests/test-serve.t @@ -9,12 +9,7 @@ > cat hg.pid >> "$DAEMON_PIDS" > echo % errors > cat errors.log - > if [ "$KILLQUIETLY" = "Y" ]; then - > kill `cat hg.pid` 2>/dev/null - > else - > kill `cat hg.pid` - > fi - > while kill -0 `cat hg.pid` 2>/dev/null; do sleep 0; done + > "$TESTDIR/killdaemons.py" hg.pid > } $ hg init test From bos at serpentine.com Sat Feb 9 08:06:41 2013 From: bos at serpentine.com (Bryan O'Sullivan) Date: Sat, 09 Feb 2013 14:06:41 +0000 Subject: [PATCH 01 of 11] merge: split out mostly-non-interactive working dir updates Message-ID: <8cf626e958d3dd67e45b.1360418801@australite.local> # HG changeset patch # User Bryan O'Sullivan # Date 1360418465 0 # Node ID 8cf626e958d3dd67e45bc4b1ef59ce328c37e123 # Parent 341868ef0cf6bb3fc9fc4f5b4f34047ba57b5a77 merge: split out mostly-non-interactive working dir updates In a later patch, we'll run these updates in parallel. diff --git a/mercurial/merge.py b/mercurial/merge.py --- a/mercurial/merge.py +++ b/mercurial/merge.py @@ -314,6 +314,34 @@ def manifestmerge(repo, p1, p2, pa, over def actionkey(a): return a[1] == "r" and -1 or 0, a +def getremove(repo, wctx, mctx, overwrite, args): + """apply usually-non-interactive updates to the working directory + + wctx is the working copy context + mctx is the context to be merged into the working copy + + yields tuples for progress updates + """ + audit = repo.wopener.audit + for i, arg in enumerate(args): + f = arg[0] + if arg[1] == 'r': + repo.ui.note(_("removing %s\n") % f) + if f == '.hgsubstate': # subrepo states need updating + subrepo.submerge(repo, wctx, mctx, wctx, overwrite) + audit(f) + try: + util.unlinkpath(repo.wjoin(f), ignoremissing=True) + except OSError, inst: + repo.ui.warn(_("update failed to remove %s: %s!\n") % + (f, inst.strerror)) + else: + repo.ui.note(_("getting %s\n") % f) + repo.wwrite(f, mctx.filectx(f).data(), arg[2][0]) + if f == '.hgsubstate': # subrepo states need updating + subrepo.submerge(repo, wctx, mctx, wctx, overwrite) + yield i, f + def applyupdates(repo, actions, wctx, mctx, actx, overwrite): """apply the merge action list to the working directory @@ -365,22 +393,22 @@ def applyupdates(repo, actions, wctx, mc util.unlinkpath(repo.wjoin(f)) numupdates = len(actions) + workeractions = [a for a in actions if a[1] in 'gr'] + updated = len([a for a in workeractions if a[1] == 'g']) + removed = len([a for a in workeractions if a[1] == 'r']) + actions = [a for a in actions if a[1] not in 'gr'] + + for i, item in getremove(repo, wctx, mctx, overwrite, workeractions): + repo.ui.progress(_('updating'), i + 1, item=item, total=numupdates, + unit=_('files')) + + z = len(workeractions) + for i, a in enumerate(actions): f, m, args, msg = a - repo.ui.progress(_('updating'), i + 1, item=f, total=numupdates, + repo.ui.progress(_('updating'), z + i + 1, item=f, total=numupdates, unit=_('files')) - if m == "r": # remove - repo.ui.note(_("removing %s\n") % f) - audit(f) - if f == '.hgsubstate': # subrepo states need updating - subrepo.submerge(repo, wctx, mctx, wctx, overwrite) - try: - util.unlinkpath(repo.wjoin(f), ignoremissing=True) - except OSError, inst: - repo.ui.warn(_("update failed to remove %s: %s!\n") % - (f, inst.strerror)) - removed += 1 - elif m == "m": # merge + if m == "m": # merge if fd == '.hgsubstate': # subrepo states need updating subrepo.submerge(repo, wctx, mctx, wctx.ancestor(mctx), overwrite) @@ -395,13 +423,6 @@ def applyupdates(repo, actions, wctx, mc updated += 1 else: merged += 1 - elif m == "g": # get - flags, = args - repo.ui.note(_("getting %s\n") % f) - repo.wwrite(f, mctx.filectx(f).data(), flags) - updated += 1 - if f == '.hgsubstate': # subrepo states need updating - subrepo.submerge(repo, wctx, mctx, wctx, overwrite) elif m == "d": # directory rename f2, fd, flags = args if f: From bos at serpentine.com Sat Feb 9 08:06:42 2013 From: bos at serpentine.com (Bryan O'Sullivan) Date: Sat, 09 Feb 2013 14:06:42 +0000 Subject: [PATCH 02 of 11] tests: update test output (will be folded into parent) In-Reply-To: <8cf626e958d3dd67e45b.1360418801@australite.local> References: <8cf626e958d3dd67e45b.1360418801@australite.local> Message-ID: # HG changeset patch # User Bryan O'Sullivan # Date 1360418465 0 # Node ID a56cf72522f2d60eacaeb47392e4c9127277cc4c # Parent 8cf626e958d3dd67e45bc4b1ef59ce328c37e123 tests: update test output (will be folded into parent) diff --git a/tests/test-graft.t b/tests/test-graft.t --- a/tests/test-graft.t +++ b/tests/test-graft.t @@ -150,8 +150,8 @@ Graft out of order, skipping a merge and overwrite: False, partial: False ancestor: 4c60f11aa304, local: 6b9e5368ca4e+, remote: 97f8bfe72746 e: remote is newer -> g + getting e updating: e 1/1 files (100.00%) - getting e e grafting revision 4 searching for copies back to rev 1 @@ -161,8 +161,8 @@ Graft out of order, skipping a merge and d: remote is newer -> g e: versions differ -> m preserving e for resolve of e + getting d updating: d 1/2 files (50.00%) - getting d updating: e 2/2 files (100.00%) picked tool 'internal:merge' for e (binary False symlink False) merging e diff --git a/tests/test-issue522.t b/tests/test-issue522.t --- a/tests/test-issue522.t +++ b/tests/test-issue522.t @@ -32,8 +32,8 @@ revision. overwrite: False, partial: False ancestor: bbd179dfa0a7, local: 71766447bdbb+, remote: 4d9e78aaceee foo: remote is newer -> g + getting foo updating: foo 1/1 files (100.00%) - getting foo 1 files updated, 0 files merged, 0 files removed, 0 files unresolved (branch merge, don't forget to commit) diff --git a/tests/test-issue672.t b/tests/test-issue672.t --- a/tests/test-issue672.t +++ b/tests/test-issue672.t @@ -36,10 +36,10 @@ http://mercurial.selenic.com/bts/issue67 ancestor: 81f4b099af3d, local: c64f439569a9+, remote: c12dcd37c90a 1: other deleted -> r 1a: remote created -> g + removing 1 updating: 1 1/2 files (50.00%) - removing 1 + getting 1a updating: 1a 2/2 files (100.00%) - getting 1a 1 files updated, 0 files merged, 1 files removed, 0 files unresolved (branch merge, don't forget to commit) diff --git a/tests/test-largefiles.t b/tests/test-largefiles.t --- a/tests/test-largefiles.t +++ b/tests/test-largefiles.t @@ -1679,8 +1679,8 @@ largefiles pulled on update - no server overwrite: False, partial: False ancestor: 000000000000, local: 000000000000+, remote: cf03e5bb9936 .hglf/f1: remote created -> g + getting .hglf/f1 updating: .hglf/f1 1/1 files (100.00%) - getting .hglf/f1 getting changed largefiles using http://localhost:$HGPORT2/ sending capabilities command diff --git a/tests/test-rename-dir-merge.t b/tests/test-rename-dir-merge.t --- a/tests/test-rename-dir-merge.t +++ b/tests/test-rename-dir-merge.t @@ -44,16 +44,16 @@ a/c: remote renamed directory to b/c -> d b/a: remote created -> g b/b: remote created -> g + removing a/a updating: a/a 1/5 files (20.00%) - removing a/a + removing a/b updating: a/b 2/5 files (40.00%) - removing a/b - updating: a/c 3/5 files (60.00%) + getting b/a + updating: b/a 3/5 files (60.00%) + getting b/b + updating: b/b 4/5 files (80.00%) + updating: a/c 5/5 files (100.00%) moving a/c to b/c - updating: b/a 4/5 files (80.00%) - getting b/a - updating: b/b 5/5 files (100.00%) - getting b/b 3 files updated, 0 files merged, 2 files removed, 0 files unresolved (branch merge, don't forget to commit) diff --git a/tests/test-rename-merge1.t b/tests/test-rename-merge1.t --- a/tests/test-rename-merge1.t +++ b/tests/test-rename-merge1.t @@ -41,17 +41,17 @@ a2: divergent renames -> dr b2: remote created -> g removing a - updating: a 1/3 files (33.33%) + getting b2 + updating: b2 1/3 files (33.33%) + updating: a 2/3 files (66.67%) picked tool 'internal:merge' for b (binary False symlink False) merging a and b to b my b at 044f8520aeeb+ other b at 85c198ef2f6c ancestor a at af1939970a1c premerge successful - updating: a2 2/3 files (66.67%) + updating: a2 3/3 files (100.00%) note: possible conflict - a2 was renamed multiple times to: c2 b2 - updating: b2 3/3 files (100.00%) - getting b2 1 files updated, 1 files merged, 0 files removed, 0 files unresolved (branch merge, don't forget to commit) @@ -183,11 +183,11 @@ Check for issue3074 ancestor: 19d7f95df299, local: 0084274f6b67+, remote: 5d32493049f0 file: rename and delete -> rd newfile: remote created -> g - updating: file 1/2 files (50.00%) + getting newfile + updating: newfile 1/2 files (50.00%) + updating: file 2/2 files (100.00%) note: possible conflict - file was deleted and renamed to: newfile - updating: newfile 2/2 files (100.00%) - getting newfile 1 files updated, 0 files merged, 0 files removed, 0 files unresolved (branch merge, don't forget to commit) $ hg status diff --git a/tests/test-rename-merge2.t b/tests/test-rename-merge2.t --- a/tests/test-rename-merge2.t +++ b/tests/test-rename-merge2.t @@ -126,8 +126,8 @@ args: preserving b for resolve of b rev: versions differ -> m preserving rev for resolve of rev + getting a updating: a 1/3 files (33.33%) - getting a updating: b 2/3 files (66.67%) picked tool 'python ../merge' for b (binary False symlink False) merging b and a to b @@ -231,8 +231,8 @@ args: b: remote created -> g rev: versions differ -> m preserving rev for resolve of rev + getting b updating: b 1/2 files (50.00%) - getting b updating: rev 2/2 files (100.00%) picked tool 'python ../merge' for rev (binary False symlink False) merging rev @@ -289,10 +289,10 @@ args: b: remote created -> g rev: versions differ -> m preserving rev for resolve of rev + removing a updating: a 1/3 files (33.33%) - removing a + getting b updating: b 2/3 files (66.67%) - getting b updating: rev 3/3 files (100.00%) picked tool 'python ../merge' for rev (binary False symlink False) merging rev @@ -380,12 +380,12 @@ m "um a c" "um x c" " " "10 do merg c: remote created -> g rev: versions differ -> m preserving rev for resolve of rev - updating: a 1/3 files (33.33%) + getting c + updating: c 1/3 files (33.33%) + updating: a 2/3 files (66.67%) note: possible conflict - a was renamed multiple times to: b c - updating: c 2/3 files (66.67%) - getting c updating: rev 3/3 files (100.00%) picked tool 'python ../merge' for rev (binary False symlink False) merging rev @@ -439,8 +439,8 @@ m "um a c" "um x c" " " "10 do merg preserving b for resolve of b rev: versions differ -> m preserving rev for resolve of rev + removing a updating: a 1/3 files (33.33%) - removing a updating: b 2/3 files (66.67%) picked tool 'python ../merge' for b (binary False symlink False) merging b @@ -469,8 +469,8 @@ m "um a c" "um x c" " " "10 do merg preserving b for resolve of b rev: versions differ -> m preserving rev for resolve of rev + getting a updating: a 1/3 files (33.33%) - getting a updating: b 2/3 files (66.67%) picked tool 'python ../merge' for b (binary False symlink False) merging b @@ -500,8 +500,8 @@ m "um a c" "um x c" " " "10 do merg preserving b for resolve of b rev: versions differ -> m preserving rev for resolve of rev + removing a updating: a 1/3 files (33.33%) - removing a updating: b 2/3 files (66.67%) picked tool 'python ../merge' for b (binary False symlink False) merging b @@ -530,8 +530,8 @@ m "um a c" "um x c" " " "10 do merg preserving b for resolve of b rev: versions differ -> m preserving rev for resolve of rev + getting a updating: a 1/3 files (33.33%) - getting a updating: b 2/3 files (66.67%) picked tool 'python ../merge' for b (binary False symlink False) merging b @@ -591,8 +591,8 @@ m "um a c" "um x c" " " "10 do merg preserving b for resolve of b rev: versions differ -> m preserving rev for resolve of rev + getting a updating: a 1/3 files (33.33%) - getting a updating: b 2/3 files (66.67%) picked tool 'python ../merge' for b (binary False symlink False) merging b @@ -731,13 +731,13 @@ m "nm a b" "um x a" " " "22 get a, c: remote created -> g rev: versions differ -> m preserving rev for resolve of rev - updating: b 1/3 files (33.33%) + getting c + updating: c 1/3 files (33.33%) + updating: b 2/3 files (66.67%) picked tool 'python ../merge' for b (binary False symlink False) merging b and a to b my b at 02963e448370+ other a at 2b958612230f ancestor a at 924404dff337 premerge successful - updating: c 2/3 files (66.67%) - getting c updating: rev 3/3 files (100.00%) picked tool 'python ../merge' for rev (binary False symlink False) merging rev diff --git a/tests/test-subrepo.t b/tests/test-subrepo.t --- a/tests/test-subrepo.t +++ b/tests/test-subrepo.t @@ -215,8 +215,8 @@ merge tests overwrite: False, partial: False ancestor: 60ca1237c194, local: 60ca1237c194+, remote: 6747d179aa9a t: remote is newer -> g + getting t updating: t 1/1 files (100.00%) - getting t 0 files updated, 0 files merged, 0 files removed, 0 files unresolved (branch merge, don't forget to commit) $ hg debugsub diff --git a/tests/test-up-local-change.t b/tests/test-up-local-change.t --- a/tests/test-up-local-change.t +++ b/tests/test-up-local-change.t @@ -49,12 +49,12 @@ a: versions differ -> m preserving a for resolve of a b: remote created -> g - updating: a 1/2 files (50.00%) + getting b + updating: b 1/2 files (50.00%) + updating: a 2/2 files (100.00%) picked tool 'true' for a (binary False symlink False) merging a my a at c19d34741b0a+ other a at 1e71731e6fbb ancestor a at c19d34741b0a - updating: b 2/2 files (100.00%) - getting b 1 files updated, 1 files merged, 0 files removed, 0 files unresolved $ hg parents changeset: 1:1e71731e6fbb @@ -70,8 +70,8 @@ b: other deleted -> r a: versions differ -> m preserving a for resolve of a + removing b updating: b 1/2 files (50.00%) - removing b updating: a 2/2 files (100.00%) picked tool 'true' for a (binary False symlink False) merging a @@ -103,12 +103,12 @@ a: versions differ -> m preserving a for resolve of a b: remote created -> g - updating: a 1/2 files (50.00%) + getting b + updating: b 1/2 files (50.00%) + updating: a 2/2 files (100.00%) picked tool 'true' for a (binary False symlink False) merging a my a at c19d34741b0a+ other a at 1e71731e6fbb ancestor a at c19d34741b0a - updating: b 2/2 files (100.00%) - getting b 1 files updated, 1 files merged, 0 files removed, 0 files unresolved $ hg parents changeset: 1:1e71731e6fbb diff --git a/tests/test-update-reverse.t b/tests/test-update-reverse.t --- a/tests/test-update-reverse.t +++ b/tests/test-update-reverse.t @@ -71,12 +71,12 @@ side1: other deleted -> r side2: other deleted -> r main: remote created -> g + removing side1 updating: side1 1/3 files (33.33%) - removing side1 + removing side2 updating: side2 2/3 files (66.67%) - removing side2 + getting main updating: main 3/3 files (100.00%) - getting main 1 files updated, 0 files merged, 2 files removed, 0 files unresolved $ ls From bos at serpentine.com Sat Feb 9 08:06:43 2013 From: bos at serpentine.com (Bryan O'Sullivan) Date: Sat, 09 Feb 2013 14:06:43 +0000 Subject: [PATCH 03 of 11] merge: handle subrepo merges and .hgsubstate specially In-Reply-To: <8cf626e958d3dd67e45b.1360418801@australite.local> References: <8cf626e958d3dd67e45b.1360418801@australite.local> Message-ID: # HG changeset patch # User Bryan O'Sullivan # Date 1360418465 0 # Node ID e4a245ec89c65f2ceaf1f2c3e22f5981efc2ca5f # Parent a56cf72522f2d60eacaeb47392e4c9127277cc4c merge: handle subrepo merges and .hgsubstate specially In an upcoming patch, we will update .hgsubstate in a non-interactive worker process. Merges of subrepo contents will still need to occur in the master process (since they may be interactive), so we move that code into a place where it will always run in what will become the master process. diff --git a/mercurial/merge.py b/mercurial/merge.py --- a/mercurial/merge.py +++ b/mercurial/merge.py @@ -314,10 +314,9 @@ def manifestmerge(repo, p1, p2, pa, over def actionkey(a): return a[1] == "r" and -1 or 0, a -def getremove(repo, wctx, mctx, overwrite, args): +def getremove(repo, mctx, overwrite, args): """apply usually-non-interactive updates to the working directory - wctx is the working copy context mctx is the context to be merged into the working copy yields tuples for progress updates @@ -327,8 +326,6 @@ def getremove(repo, wctx, mctx, overwrit f = arg[0] if arg[1] == 'r': repo.ui.note(_("removing %s\n") % f) - if f == '.hgsubstate': # subrepo states need updating - subrepo.submerge(repo, wctx, mctx, wctx, overwrite) audit(f) try: util.unlinkpath(repo.wjoin(f), ignoremissing=True) @@ -338,8 +335,6 @@ def getremove(repo, wctx, mctx, overwrit else: repo.ui.note(_("getting %s\n") % f) repo.wwrite(f, mctx.filectx(f).data(), arg[2][0]) - if f == '.hgsubstate': # subrepo states need updating - subrepo.submerge(repo, wctx, mctx, wctx, overwrite) yield i, f def applyupdates(repo, actions, wctx, mctx, actx, overwrite): @@ -398,10 +393,17 @@ def applyupdates(repo, actions, wctx, mc removed = len([a for a in workeractions if a[1] == 'r']) actions = [a for a in actions if a[1] not in 'gr'] - for i, item in getremove(repo, wctx, mctx, overwrite, workeractions): + hgsub = [a[1] for a in workeractions if a[0] == '.hgsubstate'] + if hgsub and hgsub[0] == 'r': + subrepo.submerge(repo, wctx, mctx, wctx, overwrite) + + for i, item in getremove(repo, mctx, overwrite, workeractions): repo.ui.progress(_('updating'), i + 1, item=item, total=numupdates, unit=_('files')) + if hgsub and hgsub[0] == 'g': + subrepo.submerge(repo, wctx, mctx, wctx, overwrite) + z = len(workeractions) for i, a in enumerate(actions): From bos at serpentine.com Sat Feb 9 08:06:44 2013 From: bos at serpentine.com (Bryan O'Sullivan) Date: Sat, 09 Feb 2013 14:06:44 +0000 Subject: [PATCH 04 of 11] merge: report non-interactive progress in chunks In-Reply-To: <8cf626e958d3dd67e45b.1360418801@australite.local> References: <8cf626e958d3dd67e45b.1360418801@australite.local> Message-ID: <0f7228360de75e966742.1360418804@australite.local> # HG changeset patch # User Bryan O'Sullivan # Date 1360418465 0 # Node ID 0f7228360de75e966742d29662ff6984077806ff # Parent e4a245ec89c65f2ceaf1f2c3e22f5981efc2ca5f merge: report non-interactive progress in chunks Instead of a monotonic count, getupdates yields the number of files it has updated since it last reported, and its caller sums the numbers when updating progress. We also report progress every 100 operations instead of for every operation. This will become important as soon as we start reporting progress over a pipe from multiple worker processes. diff --git a/mercurial/merge.py b/mercurial/merge.py --- a/mercurial/merge.py +++ b/mercurial/merge.py @@ -322,7 +322,8 @@ def getremove(repo, mctx, overwrite, arg yields tuples for progress updates """ audit = repo.wopener.audit - for i, arg in enumerate(args): + i = 0 + for arg in args: f = arg[0] if arg[1] == 'r': repo.ui.note(_("removing %s\n") % f) @@ -335,6 +336,11 @@ def getremove(repo, mctx, overwrite, arg else: repo.ui.note(_("getting %s\n") % f) repo.wwrite(f, mctx.filectx(f).data(), arg[2][0]) + if i == 100: + yield i, f + i = 0 + i += 1 + if i > 0: yield i, f def applyupdates(repo, actions, wctx, mctx, actx, overwrite): @@ -397,15 +403,15 @@ def applyupdates(repo, actions, wctx, mc if hgsub and hgsub[0] == 'r': subrepo.submerge(repo, wctx, mctx, wctx, overwrite) + z = 0 for i, item in getremove(repo, mctx, overwrite, workeractions): - repo.ui.progress(_('updating'), i + 1, item=item, total=numupdates, + z += i + repo.ui.progress(_('updating'), z, item=item, total=numupdates, unit=_('files')) if hgsub and hgsub[0] == 'g': subrepo.submerge(repo, wctx, mctx, wctx, overwrite) - z = len(workeractions) - for i, a in enumerate(actions): f, m, args, msg = a repo.ui.progress(_('updating'), z + i + 1, item=f, total=numupdates, From bos at serpentine.com Sat Feb 9 08:06:45 2013 From: bos at serpentine.com (Bryan O'Sullivan) Date: Sat, 09 Feb 2013 14:06:45 +0000 Subject: [PATCH 05 of 11] tests: getremove test output changes (fold into previous patch) In-Reply-To: <8cf626e958d3dd67e45b.1360418801@australite.local> References: <8cf626e958d3dd67e45b.1360418801@australite.local> Message-ID: <849757bef45281eefa0e.1360418805@australite.local> # HG changeset patch # User Bryan O'Sullivan # Date 1360418465 0 # Node ID 849757bef45281eefa0e7425865b00ddf4159f5d # Parent 0f7228360de75e966742d29662ff6984077806ff tests: getremove test output changes (fold into previous patch) diff --git a/tests/test-issue672.t b/tests/test-issue672.t --- a/tests/test-issue672.t +++ b/tests/test-issue672.t @@ -37,7 +37,6 @@ http://mercurial.selenic.com/bts/issue67 1: other deleted -> r 1a: remote created -> g removing 1 - updating: 1 1/2 files (50.00%) getting 1a updating: 1a 2/2 files (100.00%) 1 files updated, 0 files merged, 1 files removed, 0 files unresolved diff --git a/tests/test-rename-dir-merge.t b/tests/test-rename-dir-merge.t --- a/tests/test-rename-dir-merge.t +++ b/tests/test-rename-dir-merge.t @@ -45,11 +45,8 @@ b/a: remote created -> g b/b: remote created -> g removing a/a - updating: a/a 1/5 files (20.00%) removing a/b - updating: a/b 2/5 files (40.00%) getting b/a - updating: b/a 3/5 files (60.00%) getting b/b updating: b/b 4/5 files (80.00%) updating: a/c 5/5 files (100.00%) diff --git a/tests/test-rename-merge2.t b/tests/test-rename-merge2.t --- a/tests/test-rename-merge2.t +++ b/tests/test-rename-merge2.t @@ -290,7 +290,6 @@ args: rev: versions differ -> m preserving rev for resolve of rev removing a - updating: a 1/3 files (33.33%) getting b updating: b 2/3 files (66.67%) updating: rev 3/3 files (100.00%) diff --git a/tests/test-update-reverse.t b/tests/test-update-reverse.t --- a/tests/test-update-reverse.t +++ b/tests/test-update-reverse.t @@ -72,9 +72,7 @@ side2: other deleted -> r main: remote created -> g removing side1 - updating: side1 1/3 files (33.33%) removing side2 - updating: side2 2/3 files (66.67%) getting main updating: main 3/3 files (100.00%) 1 files updated, 0 files merged, 2 files removed, 0 files unresolved From bos at serpentine.com Sat Feb 9 08:06:46 2013 From: bos at serpentine.com (Bryan O'Sullivan) Date: Sat, 09 Feb 2013 14:06:46 +0000 Subject: [PATCH 06 of 11] worker: count the number of CPUs In-Reply-To: <8cf626e958d3dd67e45b.1360418801@australite.local> References: <8cf626e958d3dd67e45b.1360418801@australite.local> Message-ID: <06aa98485023be2c4275.1360418806@australite.local> # HG changeset patch # User Bryan O'Sullivan # Date 1360418465 0 # Node ID 06aa98485023be2c427552053398e8217db7b4d6 # Parent 849757bef45281eefa0e7425865b00ddf4159f5d worker: count the number of CPUs This works on the major platforms, and falls back to a safe guess of 1 elsewhere. diff --git a/mercurial/worker.py b/mercurial/worker.py new file mode 100644 --- /dev/null +++ b/mercurial/worker.py @@ -0,0 +1,29 @@ +# worker.py - master-slave parallelism support +# +# Copyright 2013 Facebook, Inc. +# +# This software may be used and distributed according to the terms of the +# GNU General Public License version 2 or any later version. + +import os + +def countcpus(): + '''try to count the number of CPUs on the system''' + + # posix + try: + n = int(os.sysconf('SC_NPROCESSORS_ONLN')) + if n > 0: + return n + except (AttributeError, ValueError): + pass + + # windows + try: + n = int(os.environ['NUMBER_OF_PROCESSORS']) + if n > 0: + return n + except (KeyError, ValueError): + pass + + return 1 From bos at serpentine.com Sat Feb 9 08:06:47 2013 From: bos at serpentine.com (Bryan O'Sullivan) Date: Sat, 09 Feb 2013 14:06:47 +0000 Subject: [PATCH 07 of 11] worker: estimate whether it's worth running a task in parallel In-Reply-To: <8cf626e958d3dd67e45b.1360418801@australite.local> References: <8cf626e958d3dd67e45b.1360418801@australite.local> Message-ID: # HG changeset patch # User Bryan O'Sullivan # Date 1360418465 0 # Node ID d167155227b6752f01da2c0693f27cc42a7a8dde # Parent 06aa98485023be2c427552053398e8217db7b4d6 worker: estimate whether it's worth running a task in parallel Not implemented for Windows yet. diff --git a/mercurial/worker.py b/mercurial/worker.py --- a/mercurial/worker.py +++ b/mercurial/worker.py @@ -27,3 +27,17 @@ def countcpus(): pass return 1 + +_numworkers = min(max(countcpus(), 4), 32) + +if os.name == 'nt': + _startupcost = 1e9 +else: + _startupcost = 0.01 + +def worthwhile(costperop, nops): + '''try to determine whether the benefit of multiple processes can + outweigh the cost of starting them''' + linear = costperop * nops + benefit = linear - (_startupcost * _numworkers + linear / _numworkers) + return benefit >= 0.15 From bos at serpentine.com Sat Feb 9 08:06:48 2013 From: bos at serpentine.com (Bryan O'Sullivan) Date: Sat, 09 Feb 2013 14:06:48 +0000 Subject: [PATCH 08 of 11] worker: partition a list (of tasks) into equal-sized chunks In-Reply-To: <8cf626e958d3dd67e45b.1360418801@australite.local> References: <8cf626e958d3dd67e45b.1360418801@australite.local> Message-ID: <023956ed1b098df7f93a.1360418808@australite.local> # HG changeset patch # User Bryan O'Sullivan # Date 1360418465 0 # Node ID 023956ed1b098df7f93a5c1857b2f5ec00f3e45d # Parent d167155227b6752f01da2c0693f27cc42a7a8dde worker: partition a list (of tasks) into equal-sized chunks diff --git a/mercurial/worker.py b/mercurial/worker.py --- a/mercurial/worker.py +++ b/mercurial/worker.py @@ -28,6 +28,19 @@ def countcpus(): return 1 +def partition(lst, nslices): + '''partition a list into N slices of equal size''' + n = len(lst) + chunk, slop = n / nslices, n % nslices + end = 0 + for i in xrange(nslices): + start = end + end = start + chunk + if slop: + end += 1 + slop -= 1 + yield lst[start:end] + _numworkers = min(max(countcpus(), 4), 32) if os.name == 'nt': From bos at serpentine.com Sat Feb 9 08:06:50 2013 From: bos at serpentine.com (Bryan O'Sullivan) Date: Sat, 09 Feb 2013 14:06:50 +0000 Subject: [PATCH 10 of 11] merge: apply non-interactive working dir updates in parallel In-Reply-To: <8cf626e958d3dd67e45b.1360418801@australite.local> References: <8cf626e958d3dd67e45b.1360418801@australite.local> Message-ID: # HG changeset patch # User Bryan O'Sullivan # Date 1360418465 0 # Node ID a278d66b8f8621ebafbb30a201000fca63983697 # Parent dfb4e4bfedfc6db5fddf08b95276de01f1b1366d merge: apply non-interactive working dir updates in parallel This has a big effect on the performance of working dir updates. Here are the results of update from null to the given rev in several repos, on a Linux 3.2 system with 32 cores running ext4, with the progress extension enabled. repo rev plain parallel speedup hg 7068089c95a2 0.9 0.3 3 mozilla-central fe1600b22c77 42.8 7.7 5.5 linux-2.6 9ef4b770e069 31.4 4.9 6.4 diff --git a/mercurial/merge.py b/mercurial/merge.py --- a/mercurial/merge.py +++ b/mercurial/merge.py @@ -7,7 +7,7 @@ from node import nullid, nullrev, hex, bin from i18n import _ -import error, util, filemerge, copies, subrepo +import error, util, filemerge, copies, subrepo, worker import errno, os, shutil class mergestate(object): @@ -404,7 +404,9 @@ def applyupdates(repo, actions, wctx, mc subrepo.submerge(repo, wctx, mctx, wctx, overwrite) z = 0 - for i, item in getremove(repo, mctx, overwrite, workeractions): + prog = worker.worker(0.001, getremove, (repo, mctx, overwrite), + workeractions) + for i, item in prog: z += i repo.ui.progress(_('updating'), z, item=item, total=numupdates, unit=_('files')) From bos at serpentine.com Sat Feb 9 08:06:51 2013 From: bos at serpentine.com (Bryan O'Sullivan) Date: Sat, 09 Feb 2013 14:06:51 +0000 Subject: [PATCH 11 of 11] merge: don't fiddle with name lookups or i18n in hot loops In-Reply-To: <8cf626e958d3dd67e45b.1360418801@australite.local> References: <8cf626e958d3dd67e45b.1360418801@australite.local> Message-ID: <994e4c0ed9a6d2ff25aa.1360418811@australite.local> # HG changeset patch # User Bryan O'Sullivan # Date 1360418465 0 # Node ID 994e4c0ed9a6d2ff25aacfcc9603ed9cef3909ac # Parent a278d66b8f8621ebafbb30a201000fca63983697 merge: don't fiddle with name lookups or i18n in hot loops We perform attribute dereferences and i18n lookups before looping. diff --git a/mercurial/merge.py b/mercurial/merge.py --- a/mercurial/merge.py +++ b/mercurial/merge.py @@ -321,21 +321,28 @@ def getremove(repo, mctx, overwrite, arg yields tuples for progress updates """ + verbose = repo.ui.verbose + unlink = util.unlinkpath + wjoin = repo.wjoin + fctx = mctx.filectx + wwrite = repo.wwrite audit = repo.wopener.audit i = 0 for arg in args: f = arg[0] if arg[1] == 'r': - repo.ui.note(_("removing %s\n") % f) + if verbose: + repo.ui.note(_("removing %s\n") % f) audit(f) try: - util.unlinkpath(repo.wjoin(f), ignoremissing=True) + unlink(wjoin(f), ignoremissing=True) except OSError, inst: repo.ui.warn(_("update failed to remove %s: %s!\n") % (f, inst.strerror)) else: - repo.ui.note(_("getting %s\n") % f) - repo.wwrite(f, mctx.filectx(f).data(), arg[2][0]) + if verbose: + repo.ui.note(_("getting %s\n") % f) + wwrite(f, fctx(f).data(), arg[2][0]) if i == 100: yield i, f i = 0 @@ -414,10 +421,13 @@ def applyupdates(repo, actions, wctx, mc if hgsub and hgsub[0] == 'g': subrepo.submerge(repo, wctx, mctx, wctx, overwrite) + _updating = _('updating') + _files = _('files') + progress = repo.ui.progress + for i, a in enumerate(actions): f, m, args, msg = a - repo.ui.progress(_('updating'), z + i + 1, item=f, total=numupdates, - unit=_('files')) + progress(_updating, z + i + 1, item=f, total=numupdates, unit=_files) if m == "m": # merge if fd == '.hgsubstate': # subrepo states need updating subrepo.submerge(repo, wctx, mctx, wctx.ancestor(mctx), @@ -462,7 +472,7 @@ def applyupdates(repo, actions, wctx, mc util.setflags(repo.wjoin(f), 'l' in flags, 'x' in flags) updated += 1 ms.commit() - repo.ui.progress(_('updating'), None, total=numupdates, unit=_('files')) + progress(_updating, None, total=numupdates, unit=_files) return updated, merged, removed, unresolved From bos at serpentine.com Sat Feb 9 08:06:49 2013 From: bos at serpentine.com (Bryan O'Sullivan) Date: Sat, 09 Feb 2013 14:06:49 +0000 Subject: [PATCH 09 of 11] worker: allow a function to be run in multiple worker processes In-Reply-To: <8cf626e958d3dd67e45b.1360418801@australite.local> References: <8cf626e958d3dd67e45b.1360418801@australite.local> Message-ID: # HG changeset patch # User Bryan O'Sullivan # Date 1360418465 0 # Node ID dfb4e4bfedfc6db5fddf08b95276de01f1b1366d # Parent 023956ed1b098df7f93a5c1857b2f5ec00f3e45d worker: allow a function to be run in multiple worker processes If we estimate that it will be worth the cost, we run the function in multiple processes. Otherwise, we run it in-process. Children report progress to the parent through a pipe. Not yet implemented on Windows. diff --git a/mercurial/worker.py b/mercurial/worker.py --- a/mercurial/worker.py +++ b/mercurial/worker.py @@ -5,7 +5,7 @@ # This software may be used and distributed according to the terms of the # GNU General Public License version 2 or any later version. -import os +import os, signal, sys def countcpus(): '''try to count the number of CPUs on the system''' @@ -54,3 +54,58 @@ def worthwhile(costperop, nops): linear = costperop * nops benefit = linear - (_startupcost * _numworkers + linear / _numworkers) return benefit >= 0.15 + +def worker(costperarg, func, staticargs, args): + '''run a function, possibly in parallel in multiple worker + processes. + + returns a progress iterator + + costperarg - cost of a single task + + func - function to run + + staticargs - arguments to pass to every invocation of the function + + args - arguments to split into chunks, to pass to individual + workers + ''' + if worthwhile(costperarg, len(args)): + return _platformworker(func, staticargs, args) + return func(*staticargs + (args,)) + +def _posixworker(func, staticargs, args): + rfd, wfd = os.pipe() + for pargs in partition(args, _numworkers): + pid = os.fork() + if pid == 0: + try: + os.close(rfd) + for i, item in func(*(staticargs + (pargs,))): + os.write(wfd, '%d %s\n' % (i, item)) + os._exit(0) + except KeyboardInterrupt: + os._exit(255) + os.close(wfd) + fp = os.fdopen(rfd, 'rb', 0) + oldhandler = signal.getsignal(signal.SIGINT) + signal.signal(signal.SIGINT, signal.SIG_IGN) + def cleanup(): + # python 2.4 is too dumb for try/yield/finally + signal.signal(signal.SIGINT, oldhandler) + problems = 0 + for i in xrange(_numworkers): + problems |= os.wait()[1] + if problems: + sys.exit(1) + try: + for line in fp: + l = line.split(' ', 1) + yield int(l[0]), l[1][:-1] + except: # re-raises + cleanup() + raise + cleanup() + +if os.name != 'nt': + _platformworker = _posixworker From hgbuildbot at kublai.com Sat Feb 9 08:18:39 2013 From: hgbuildbot at kublai.com (hgbuildbot at kublai.com) Date: Sat, 09 Feb 2013 06:18:39 -0800 Subject: buildbot failure in Mercurial on hg tests Message-ID: <20130209141841.045D535160@hgbuildbot.cs.ubc.ca> The Buildbot has detected a new failure on builder hg tests while building hg. Full details are available at: http://hgbuildbot.kublai.com/builders/hg%20tests/builds/485 Buildbot URL: http://hgbuildbot.kublai.com/ Buildslave for this Build: p64.osuosl.test Build Reason: scheduler Build Source Stamp: [branch default] d8cfe29c6b612fe6e250afdd7219eb4d461b9e3e Blamelist: Augie Fackler BUILD FAILED: failed run-tests.py (python2.4) run-tests.py (python2.5) run-tests.py (python2.6) pure http2 sincerely, -The Buildbot From kbullock+mercurial at ringworld.org Sat Feb 9 08:26:43 2013 From: kbullock+mercurial at ringworld.org (Kevin Bullock) Date: Sat, 9 Feb 2013 14:26:43 +0000 Subject: [PATCH] tests: remove last two check-code warnings about killdaemons In-Reply-To: References: Message-ID: On 9 Feb 2013, at 2:04 PM, Kevin Bullock wrote: > # HG changeset patch > # User Kevin Bullock > # Date 1360418293 0 > # Node ID c99f13e430f9f52c702f125a8b7aa197bef71a7a > # Parent 1cb04715fd4bb12bc5f3fd52a6b055201e704059 > tests: remove last two check-code warnings about killdaemons Crap, missed a patch. Should've been a series of 2. Re-send imminent. pacem in terris / ??? / ?????? / ????????? / ?? Kevin R. Bullock From kbullock+mercurial at ringworld.org Sat Feb 9 08:27:16 2013 From: kbullock+mercurial at ringworld.org (Kevin Bullock) Date: Sat, 09 Feb 2013 14:27:16 +0000 Subject: [PATCH 1 of 2] tests: guard against obsolete markers in the hg repo itself Message-ID: <1cb04715fd4bb12bc5f3.1360420036@s0-0.paconsult7.bbnplanet.net> # HG changeset patch # User Kevin Bullock # Date 1360416945 0 # Node ID 1cb04715fd4bb12bc5f3fd52a6b055201e704059 # Parent d8cfe29c6b612fe6e250afdd7219eb4d461b9e3e tests: guard against obsolete markers in the hg repo itself If obsolete markers appear in the hg repo (because of enabling evolve), then tests that run hg against the hg repo itself will see warnings like: obsolete feature not enabled but 4 markers found! As far as I can tell, this only occurs in test-check-code-hg.t -- in particular, it will -not- show up on tests that run against test-created repos, as most of the test suite does. diff --git a/tests/test-check-code-hg.t b/tests/test-check-code-hg.t --- a/tests/test-check-code-hg.t +++ b/tests/test-check-code-hg.t @@ -1,6 +1,6 @@ $ check_code="$TESTDIR"/../contrib/check-code.py $ cd "$TESTDIR"/.. - $ if hg identify -q > /dev/null; then : + $ if hg identify -q > /dev/null 2>&1; then : > else > echo "skipped: not a Mercurial working dir" >&2 > exit 80 @@ -8,8 +8,9 @@ New errors are not allowed. Warnings are strongly discouraged. - $ hg manifest | xargs "$check_code" --warnings --nolineno --per-file=0 \ - > || false + $ hg manifest 2>/dev/null \ + > | xargs "$check_code" --warnings --nolineno --per-file=0 \ + > || false tests/test-serve.t:0: > > kill `cat hg.pid` don't use kill, use killdaemons.py From kbullock+mercurial at ringworld.org Sat Feb 9 08:27:17 2013 From: kbullock+mercurial at ringworld.org (Kevin Bullock) Date: Sat, 09 Feb 2013 14:27:17 +0000 Subject: [PATCH 2 of 2] tests: remove last two check-code warnings about killdaemons In-Reply-To: <1cb04715fd4bb12bc5f3.1360420036@s0-0.paconsult7.bbnplanet.net> References: <1cb04715fd4bb12bc5f3.1360420036@s0-0.paconsult7.bbnplanet.net> Message-ID: # HG changeset patch # User Kevin Bullock # Date 1360418293 0 # Node ID c99f13e430f9f52c702f125a8b7aa197bef71a7a # Parent 1cb04715fd4bb12bc5f3fd52a6b055201e704059 tests: remove last two check-code warnings about killdaemons Removes the last of the warnings in test-check-code-hg.t introduced in 667063b22a69. diff --git a/tests/test-check-code-hg.t b/tests/test-check-code-hg.t --- a/tests/test-check-code-hg.t +++ b/tests/test-check-code-hg.t @@ -11,10 +11,3 @@ New errors are not allowed. Warnings are $ hg manifest 2>/dev/null \ > | xargs "$check_code" --warnings --nolineno --per-file=0 \ > || false - tests/test-serve.t:0: - > > kill `cat hg.pid` - don't use kill, use killdaemons.py - tests/test-serve.t:0: - > > kill `cat hg.pid` 2>/dev/null - don't use kill, use killdaemons.py - [1] diff --git a/tests/test-serve.t b/tests/test-serve.t --- a/tests/test-serve.t +++ b/tests/test-serve.t @@ -9,12 +9,7 @@ > cat hg.pid >> "$DAEMON_PIDS" > echo % errors > cat errors.log - > if [ "$KILLQUIETLY" = "Y" ]; then - > kill `cat hg.pid` 2>/dev/null - > else - > kill `cat hg.pid` - > fi - > while kill -0 `cat hg.pid` 2>/dev/null; do sleep 0; done + > "$TESTDIR/killdaemons.py" hg.pid > } $ hg init test From raf at durin42.com Sat Feb 9 08:28:51 2013 From: raf at durin42.com (Augie Fackler) Date: Sat, 9 Feb 2013 14:28:51 +0000 Subject: [PATCH 1 of 2] tests: guard against obsolete markers in the hg repo itself In-Reply-To: <1cb04715fd4bb12bc5f3.1360420036@s0-0.paconsult7.bbnplanet.net> References: <1cb04715fd4bb12bc5f3.1360420036@s0-0.paconsult7.bbnplanet.net> Message-ID: <075B565D-50CC-4CEB-94C3-A446E1F364BD@durin42.com> This one LG as well, push 'em. On Feb 9, 2013, at 2:27 PM, Kevin Bullock wrote: > # HG changeset patch > # User Kevin Bullock > # Date 1360416945 0 > # Node ID 1cb04715fd4bb12bc5f3fd52a6b055201e704059 > # Parent d8cfe29c6b612fe6e250afdd7219eb4d461b9e3e > tests: guard against obsolete markers in the hg repo itself > > If obsolete markers appear in the hg repo (because of enabling evolve), > then tests that run hg against the hg repo itself will see warnings like: > > obsolete feature not enabled but 4 markers found! > > As far as I can tell, this only occurs in test-check-code-hg.t -- in > particular, it will -not- show up on tests that run against test-created > repos, as most of the test suite does. > > diff --git a/tests/test-check-code-hg.t b/tests/test-check-code-hg.t > --- a/tests/test-check-code-hg.t > +++ b/tests/test-check-code-hg.t > @@ -1,6 +1,6 @@ > $ check_code="$TESTDIR"/../contrib/check-code.py > $ cd "$TESTDIR"/.. > - $ if hg identify -q > /dev/null; then : > + $ if hg identify -q > /dev/null 2>&1; then : >> else >> echo "skipped: not a Mercurial working dir" >&2 >> exit 80 > @@ -8,8 +8,9 @@ > > New errors are not allowed. Warnings are strongly discouraged. > > - $ hg manifest | xargs "$check_code" --warnings --nolineno --per-file=0 \ > - > || false > + $ hg manifest 2>/dev/null \ > + > | xargs "$check_code" --warnings --nolineno --per-file=0 \ > + > || false > tests/test-serve.t:0: >>> kill `cat hg.pid` > don't use kill, use killdaemons.py From raf at durin42.com Sat Feb 9 08:34:18 2013 From: raf at durin42.com (Augie Fackler) Date: Sat, 9 Feb 2013 14:34:18 +0000 Subject: buildbot failure in Mercurial on hg tests In-Reply-To: <20130209141841.045D535160@hgbuildbot.cs.ubc.ca> References: <20130209141841.045D535160@hgbuildbot.cs.ubc.ca> Message-ID: Fix for this already pushed On Feb 9, 2013, at 2:18 PM, hgbuildbot at kublai.com wrote: > The Buildbot has detected a new failure on builder hg tests while building hg. > Full details are available at: > http://hgbuildbot.kublai.com/builders/hg%20tests/builds/485 > > Buildbot URL: http://hgbuildbot.kublai.com/ > > Buildslave for this Build: p64.osuosl.test > > Build Reason: scheduler > Build Source Stamp: [branch default] d8cfe29c6b612fe6e250afdd7219eb4d461b9e3e > Blamelist: Augie Fackler > > BUILD FAILED: failed run-tests.py (python2.4) run-tests.py (python2.5) run-tests.py (python2.6) pure http2 > > sincerely, > -The Buildbot > > > > _______________________________________________ > Mercurial-devel mailing list > Mercurial-devel at selenic.com > http://selenic.com/mailman/listinfo/mercurial-devel From simohe at besonet.ch Sat Feb 9 08:43:41 2013 From: simohe at besonet.ch (Simon Heimberg) Date: Sat, 09 Feb 2013 14:43:41 -0000 Subject: [PATCH 0 of 2] histedit abort with clearer error message [~V3] In-Reply-To: <9DE30DAC-4D11-423F-B06E-63F94D61EA35@durin42.com> References: <9DE30DAC-4D11-423F-B06E-63F94D61EA35@durin42.com> Message-ID: Simplified the patch by removing the unreachable code. (We are two who are almost sure it is unreachable. I guess this is sure enough.) And use the clearer abort message suggested by Augie Fackler. In the 2nd patch also use it for the other message which reports the same failure. From simohe at besonet.ch Sat Feb 9 08:43:41 2013 From: simohe at besonet.ch (Simon Heimberg) Date: Sat, 09 Feb 2013 14:43:41 -0000 Subject: [PATCH 1 of 2] histedit: report when revisions to rebase are not ancestors of working dir In-Reply-To: References: Message-ID: <55d5658e8a2ccdb8f2cc.1375540897@lapsi.heimberg.home> # HG changeset patch # User Simon Heimberg # Date 1375540637 -7200 # Branch stable # Node ID 55d5658e8a2ccdb8f2cc3201959cd664fb3d9b9f # Parent b31e0be96c79156b8236b12315a6f699c1bf992a histedit: report when revisions to rebase are not ancestors of working dir Editing the history only is possible when the working dir is a descendant of the revisions to edit. When this happens explain it by writing abort: %s is not an ancestor of working directory diff -r b31e0be96c79 -r 55d5658e8a2c hgext/histedit.py --- a/hgext/histedit.py Mon Feb 04 23:41:11 2013 +0100 +++ b/hgext/histedit.py Sam Aug 03 16:37:17 2013 +0200 @@ -498,8 +498,8 @@ keep = opts.get('keep', False) revs = between(repo, parent, topmost, keep) if not revs: - ui.warn(_('nothing to edit\n')) - return 1 + raise util.Abort(_('%s is not an ancestor of working directory') % + node.short(parent)) ctxs = [repo[r] for r in revs] rules = opts.get('commands', '') diff -r b31e0be96c79 -r 55d5658e8a2c tests/test-histedit-revspec.t --- a/tests/test-histedit-revspec.t Mon Feb 04 23:41:11 2013 +0100 +++ b/tests/test-histedit-revspec.t Sam Aug 03 16:37:17 2013 +0200 @@ -65,5 +65,5 @@ $ hg up 2 1 files updated, 0 files merged, 0 files removed, 0 files unresolved $ hg histedit -r 4 - nothing to edit - [1] + abort: 08d98a8350f3 is not an ancestor of working directory + [255] From simohe at besonet.ch Sat Feb 9 08:43:42 2013 From: simohe at besonet.ch (Simon Heimberg) Date: Sat, 09 Feb 2013 14:43:42 -0000 Subject: [PATCH 2 of 2] histedit: always abort with same message when working dir is wrong In-Reply-To: References: Message-ID: # HG changeset patch # User Simon Heimberg # Date 1375540813 -7200 # Branch stable # Node ID b6556d3ef35f5b6b8e73e1ac9273b1ba3e929a43 # Parent 55d5658e8a2ccdb8f2cc3201959cd664fb3d9b9f histedit: always abort with same message when working dir is wrong. Using only one message makes live easier for translators. The clearer error message was supposed by Augie Fackler. diff -r 55d5658e8a2c -r b6556d3ef35f hgext/histedit.py --- a/hgext/histedit.py Sam Aug 03 16:37:17 2013 +0200 +++ b/hgext/histedit.py Sam Aug 03 16:40:13 2013 +0200 @@ -583,7 +583,7 @@ if not newchildren: # `parentctxnode` should match but no result. This means that # currentnode is not a descendant from parentctxnode. - msg = _('working directory parent is not a descendant of %s') + msg = _('%s is not an ancestor of working directory') hint = _('update to %s or descendant and run "hg histedit ' '--continue" again') % parentctx raise util.Abort(msg % parentctx, hint=hint) diff -r 55d5658e8a2c -r b6556d3ef35f tests/test-histedit-edit.t --- a/tests/test-histedit-edit.t Sam Aug 03 16:37:17 2013 +0200 +++ b/tests/test-histedit-edit.t Sam Aug 03 16:40:13 2013 +0200 @@ -73,7 +73,7 @@ $ hg up 0 0 files updated, 0 files merged, 3 files removed, 0 files unresolved $ HGEDITOR='echo foobaz > ' hg histedit --continue - abort: working directory parent is not a descendant of 055a42cdd887 + abort: 055a42cdd887 is not an ancestor of working directory (update to 055a42cdd887 or descendant and run "hg histedit --continue" again) [255] $ hg up 3 From natosha at unity3d.com Sat Feb 9 09:10:43 2013 From: natosha at unity3d.com (natosha at unity3d.com) Date: Sat, 09 Feb 2013 15:10:43 +0000 Subject: [PATCH] largefiles: make caching largefiles message more explicit Message-ID: <42691426804311ace536.1360422643@s0-0.paconsult7.bbnplanet.net> # HG changeset patch # User Na'Tosha Bard # Date 1360422501 0 # Node ID 42691426804311ace53611264cb3ed5f7da176d3 # Parent 97761496c65ae836d6b0983a3f48959dd3112364 largefiles: make caching largefiles message more explicit In some cases, caching largefiles may take a long time (if the user has pulled a lot of new heads). This patch makes it more clear what is happening, by showing the number of heads we are caching largefiles for. diff -r 97761496c65a -r 426914268043 hgext/largefiles/overrides.py --- a/hgext/largefiles/overrides.py Fri Feb 08 22:42:07 2013 +0000 +++ b/hgext/largefiles/overrides.py Sat Feb 09 15:08:21 2013 +0000 @@ -735,10 +735,11 @@ # will run into a problem later if we try to merge or rebase with one of # these heads, so cache the largefiles now directly into the system # cache. - ui.status(_("caching new largefiles\n")) numcached = 0 heads = lfutil.getcurrentheads(repo) newheads = set(heads).difference(set(oldheads)) + if len(newheads) > 0: + ui.status(_("caching largefiles for %s heads\n" % len(newheads))) for head in newheads: (cached, missing) = lfcommands.cachelfiles(ui, repo, head) numcached += len(cached) diff -r 97761496c65a -r 426914268043 tests/test-largefiles.t --- a/tests/test-largefiles.t Fri Feb 08 22:42:07 2013 +0000 +++ b/tests/test-largefiles.t Sat Feb 09 15:08:21 2013 +0000 @@ -883,7 +883,7 @@ adding file changes added 6 changesets with 16 changes to 8 files (run 'hg update' to get a working copy) - caching new largefiles + caching largefiles for 1 heads 3 largefiles cached 3 additional largefiles cached $ cd .. @@ -974,7 +974,7 @@ adding file changes added 1 changesets with 2 changes to 2 files (+1 heads) (run 'hg heads' to see heads, 'hg merge' to merge) - caching new largefiles + caching largefiles for 1 heads 0 largefiles cached $ hg rebase Invoking status precommit hook @@ -1273,7 +1273,7 @@ adding file changes added 2 changesets with 4 changes to 4 files (+1 heads) (run 'hg heads' to see heads, 'hg merge' to merge) - caching new largefiles + caching largefiles for 1 heads 2 largefiles cached $ hg merge merging sub/large4 From angel.ezquerra at gmail.com Sat Feb 9 09:19:42 2013 From: angel.ezquerra at gmail.com (Angel Ezquerra) Date: Sat, 09 Feb 2013 16:19:42 +0100 Subject: [PATCH 0 of 3 V2] [PATCH 0 of 3 ] interhg: bring (most of the) extension functionality into core and remove the interhg extension Message-ID: From angel.ezquerra at gmail.com Sat Feb 9 09:19:43 2013 From: angel.ezquerra at gmail.com (Angel Ezquerra) Date: Sat, 09 Feb 2013 16:19:43 +0100 Subject: [PATCH 1 of 3 V2] hgweb: add websub template filter In-Reply-To: References: Message-ID: <04299b2afc200171eeca.1360423183@Angel-PC.localdomain> # HG changeset patch # User Angel Ezquerra # Date 1360343132 -3600 # Node ID 04299b2afc200171eeca472c5d5644e84048a3b5 # Parent 766ad3e48bdff8ee2b2a3a9276eff398dcaafa02 hgweb: add websub template filter The purpose of this new filter is to make it possible to partially replace the functionality of the interhg extension. The idea is to be able to define regular expression based substitutions on a new "websub" config section. hgweb will then be able to apply these substitutions wherever the "websub" filter is used on a template. This first revision just adds the code necessary to load the websub expressions and adds the websub filter, but it does not add any calls to the websub filter itself on any of the templates. That will be done on the following revisions. diff --git a/mercurial/hgweb/hgweb_mod.py b/mercurial/hgweb/hgweb_mod.py --- a/mercurial/hgweb/hgweb_mod.py +++ b/mercurial/hgweb/hgweb_mod.py @@ -8,11 +8,14 @@ import os from mercurial import ui, hg, hook, error, encoding, templater, util, repoview +from mercurial.templatefilters import websub +from mercurial.i18n import _ from common import get_stat, ErrorResponse, permhooks, caching from common import HTTP_OK, HTTP_NOT_MODIFIED, HTTP_BAD_REQUEST from common import HTTP_NOT_FOUND, HTTP_SERVER_ERROR from request import wsgirequest -import webcommands, protocol, webutil +import webcommands, protocol, webutil, re + perms = { 'changegroup': 'pull', @@ -49,7 +52,6 @@ urlel = os.path.dirname(urlel) return reversed(breadcrumb) - class hgweb(object): def __init__(self, repo, name=None, baseui=None): if isinstance(repo, str): @@ -73,6 +75,7 @@ # a repo owner may set web.templates in .hg/hgrc to get any file # readable by the user running the CGI script self.templatepath = self.config('web', 'templates') + self.websubtable = self.loadwebsub() # The CGI scripts are often run by a user different from the repo owner. # Trust the settings from the .hg/hgrc files by default. @@ -258,6 +261,45 @@ return [''] return tmpl('error', error=inst.message) + def loadwebsub(self): + websubtable = [] + websubdefs = self.repo.ui.configitems('websub') + for key, pattern in websubdefs: + # grab the delimiter from the character after the "s" + unesc = pattern[1] + delim = re.escape(unesc) + + # identify portions of the pattern, taking care to avoid escaped + # delimiters. the replace format and flags are optional, but + # delimiters are required. + match = re.match( + r'^s%s(.+)(?:(?<=\\\\)|(? References: Message-ID: # HG changeset patch # User Angel Ezquerra # Date 1360363571 -3600 # Node ID ad4f7e5b4b23e34c81001d188bd82dcebc914dc8 # Parent 04299b2afc200171eeca472c5d5644e84048a3b5 hgweb, templates: apply the websub filter to revision descriptions In order to use this, add a [websub] section to your configuration and add websub expressions such as: italic = s/\b_(\S+)_\b/\1<\/i>/ bold = s/\*\b(\S+)\b\*/\1<\/b>/ bugzilla = s!((?:bug|b=|(?=#?\d{4,}))(?:\s*#?)(\d+))!\1!i diff --git a/mercurial/templates/gitweb/changelogentry.tmpl b/mercurial/templates/gitweb/changelogentry.tmpl --- a/mercurial/templates/gitweb/changelogentry.tmpl +++ b/mercurial/templates/gitweb/changelogentry.tmpl @@ -8,7 +8,7 @@ {author|obfuscate} [{date|rfc822date}] rev {rev}
    -{desc|strip|escape|addbreaks|nonempty} +{desc|strip|escape|websub|addbreaks|nonempty}

    diff --git a/mercurial/templates/gitweb/changeset.tmpl b/mercurial/templates/gitweb/changeset.tmpl --- a/mercurial/templates/gitweb/changeset.tmpl +++ b/mercurial/templates/gitweb/changeset.tmpl @@ -41,7 +41,7 @@
    -{desc|strip|escape|addbreaks|nonempty} +{desc|strip|escape|websub|addbreaks|nonempty}
    diff --git a/mercurial/templates/gitweb/fileannotate.tmpl b/mercurial/templates/gitweb/fileannotate.tmpl --- a/mercurial/templates/gitweb/fileannotate.tmpl +++ b/mercurial/templates/gitweb/fileannotate.tmpl @@ -56,7 +56,7 @@
    -{desc|strip|escape|addbreaks|nonempty} +{desc|strip|escape|websub|addbreaks|nonempty}
    diff --git a/mercurial/templates/gitweb/filerevision.tmpl b/mercurial/templates/gitweb/filerevision.tmpl --- a/mercurial/templates/gitweb/filerevision.tmpl +++ b/mercurial/templates/gitweb/filerevision.tmpl @@ -56,7 +56,7 @@
    -{desc|strip|escape|addbreaks|nonempty} +{desc|strip|escape|websub|addbreaks|nonempty}
    diff --git a/mercurial/templates/monoblue/changelogentry.tmpl b/mercurial/templates/monoblue/changelogentry.tmpl --- a/mercurial/templates/monoblue/changelogentry.tmpl +++ b/mercurial/templates/monoblue/changelogentry.tmpl @@ -2,5 +2,5 @@
    • {date|rfc822date}
    • by {author|obfuscate} [{date|rfc822date}] rev {rev}
    • -
    • {desc|strip|escape|addbreaks|nonempty}
    • +
    • {desc|strip|escape|websub|addbreaks|nonempty}
    diff --git a/mercurial/templates/monoblue/changeset.tmpl b/mercurial/templates/monoblue/changeset.tmpl --- a/mercurial/templates/monoblue/changeset.tmpl +++ b/mercurial/templates/monoblue/changeset.tmpl @@ -52,7 +52,7 @@ {child%changesetchild} -

    {desc|strip|escape|addbreaks|nonempty}

    +

    {desc|strip|escape|websub|addbreaks|nonempty}

    {files} diff --git a/mercurial/templates/monoblue/fileannotate.tmpl b/mercurial/templates/monoblue/fileannotate.tmpl --- a/mercurial/templates/monoblue/fileannotate.tmpl +++ b/mercurial/templates/monoblue/fileannotate.tmpl @@ -57,7 +57,7 @@
    {permissions|permissions}
    -

    {desc|strip|escape|addbreaks|nonempty}

    +

    {desc|strip|escape|websub|addbreaks|nonempty}

    {annotate%annotateline} diff --git a/mercurial/templates/monoblue/filerevision.tmpl b/mercurial/templates/monoblue/filerevision.tmpl --- a/mercurial/templates/monoblue/filerevision.tmpl +++ b/mercurial/templates/monoblue/filerevision.tmpl @@ -57,7 +57,7 @@
    {permissions|permissions}
    -

    {desc|strip|escape|addbreaks|nonempty}

    +

    {desc|strip|escape|websub|addbreaks|nonempty}

    {text%fileline} diff --git a/mercurial/templates/paper/changeset.tmpl b/mercurial/templates/paper/changeset.tmpl --- a/mercurial/templates/paper/changeset.tmpl +++ b/mercurial/templates/paper/changeset.tmpl @@ -40,7 +40,7 @@ files, or words in the commit message
    -
    {desc|strip|escape|nonempty}
    +
    {desc|strip|escape|websub|nonempty}
    diff --git a/mercurial/templates/paper/fileannotate.tmpl b/mercurial/templates/paper/fileannotate.tmpl --- a/mercurial/templates/paper/fileannotate.tmpl +++ b/mercurial/templates/paper/fileannotate.tmpl @@ -46,7 +46,7 @@ files, or words in the commit message -
    {desc|strip|escape|nonempty}
    +
    {desc|strip|escape|websub|nonempty}
    diff --git a/mercurial/templates/paper/filecomparison.tmpl b/mercurial/templates/paper/filecomparison.tmpl --- a/mercurial/templates/paper/filecomparison.tmpl +++ b/mercurial/templates/paper/filecomparison.tmpl @@ -45,7 +45,7 @@ files, or words in the commit message -
    {desc|strip|escape|nonempty}
    +
    {desc|strip|escape|websub|nonempty}
    diff --git a/mercurial/templates/paper/filediff.tmpl b/mercurial/templates/paper/filediff.tmpl --- a/mercurial/templates/paper/filediff.tmpl +++ b/mercurial/templates/paper/filediff.tmpl @@ -45,7 +45,7 @@ files, or words in the commit message -
    {desc|strip|escape|nonempty}
    +
    {desc|strip|escape|websub|nonempty}
    diff --git a/mercurial/templates/paper/filerevision.tmpl b/mercurial/templates/paper/filerevision.tmpl --- a/mercurial/templates/paper/filerevision.tmpl +++ b/mercurial/templates/paper/filerevision.tmpl @@ -44,7 +44,7 @@ files, or words in the commit message -
    {desc|strip|escape|nonempty}
    +
    {desc|strip|escape|websub|nonempty}
    diff --git a/mercurial/templates/spartan/changeset.tmpl b/mercurial/templates/spartan/changeset.tmpl --- a/mercurial/templates/spartan/changeset.tmpl +++ b/mercurial/templates/spartan/changeset.tmpl @@ -39,7 +39,7 @@ - +
    description:{desc|strip|escape|addbreaks|nonempty}{desc|strip|escape|websub|addbreaks|nonempty}
    diff --git a/mercurial/templates/spartan/fileannotate.tmpl b/mercurial/templates/spartan/fileannotate.tmpl --- a/mercurial/templates/spartan/fileannotate.tmpl +++ b/mercurial/templates/spartan/fileannotate.tmpl @@ -38,7 +38,7 @@ description: - {desc|strip|escape|addbreaks|nonempty} + {desc|strip|escape|websub|addbreaks|nonempty} diff --git a/mercurial/templates/spartan/filerevision.tmpl b/mercurial/templates/spartan/filerevision.tmpl --- a/mercurial/templates/spartan/filerevision.tmpl +++ b/mercurial/templates/spartan/filerevision.tmpl @@ -36,7 +36,7 @@ {permissions|permissions} description: - {desc|strip|escape|addbreaks|nonempty} + {desc|strip|escape|websub|addbreaks|nonempty} From angel.ezquerra at gmail.com Sat Feb 9 09:19:45 2013 From: angel.ezquerra at gmail.com (Angel Ezquerra) Date: Sat, 09 Feb 2013 16:19:45 +0100 Subject: [PATCH 3 of 3 V2] extensions: obsolete and remove interhg extension In-Reply-To: References: Message-ID: # HG changeset patch # User Angel Ezquerra # Date 1360404042 -3600 # Node ID d9346075486b227a691fce6f69138c1b599c0cfe # Parent ad4f7e5b4b23e34c81001d188bd82dcebc914dc8 extensions: obsolete and remove interhg extension With the addition of the websub filter extension this extension is no longer needed. We maintain a sort of backwards compatibility by reading the [interhg] section and using it as we would use the [websub] section. diff --git a/mercurial/extensions.py b/mercurial/extensions.py --- a/mercurial/extensions.py +++ b/mercurial/extensions.py @@ -11,7 +11,7 @@ _extensions = {} _order = [] -_ignore = ['hbisect', 'bookmarks', 'parentrevspec'] +_ignore = ['hbisect', 'bookmarks', 'parentrevspec', 'interhg'] def extensions(): for name in _order: diff --git a/mercurial/hgweb/hgweb_mod.py b/mercurial/hgweb/hgweb_mod.py --- a/mercurial/hgweb/hgweb_mod.py +++ b/mercurial/hgweb/hgweb_mod.py @@ -8,6 +8,7 @@ import os from mercurial import ui, hg, hook, error, encoding, templater, util, repoview +from mercurial import extensions from mercurial.templatefilters import websub from mercurial.i18n import _ from common import get_stat, ErrorResponse, permhooks, caching @@ -264,6 +265,8 @@ def loadwebsub(self): websubtable = [] websubdefs = self.repo.ui.configitems('websub') + # we must maintain interhg backwards compatibility + websubdefs += self.repo.ui.configitems('interhg') for key, pattern in websubdefs: # grab the delimiter from the character after the "s" unesc = pattern[1] diff --git a/tests/test-interhg.t b/tests/test-websub.t rename from tests/test-interhg.t rename to tests/test-websub.t --- a/tests/test-interhg.t +++ b/tests/test-websub.t @@ -5,11 +5,15 @@ $ cat > .hg/hgrc < [extensions] + > # this is only necessary to check that the mapping from + > # interhg to websub works > interhg = > - > [interhg] + > [websub] > issues = s|Issue(\d+)|Issue\1| > + > [interhg] + > # check that we maintain some interhg backwards compatibility... > # yes, 'x' is a weird delimiter... > markbugs = sxbugxbugx > EOF @@ -23,9 +27,8 @@ log - $ "$TESTDIR/get-with-headers.py" localhost:$HGPORT '' | grep bts - Issue123: fixed the bug!default tip - + $ "$TESTDIR/get-with-headers.py" localhost:$HGPORT "rev/tip" | grep bts +
    Issue123: fixed the bug!
    errors $ cat errors.log From natosha at unity3d.com Sat Feb 9 09:26:32 2013 From: natosha at unity3d.com (natosha at unity3d.com) Date: Sat, 09 Feb 2013 15:26:32 +0000 Subject: [PATCH] largefiles: document behavior of caching largefiles for new heads Message-ID: # HG changeset patch # User Na'Tosha Bard # Date 1360423546 0 # Node ID f8d2ba43dbdbc0afad50b66dd4c3c1da28ce6d65 # Parent 97761496c65ae836d6b0983a3f48959dd3112364 largefiles: document behavior of caching largefiles for new heads diff -r 97761496c65a -r f8d2ba43dbdb hgext/largefiles/__init__.py --- a/hgext/largefiles/__init__.py Fri Feb 08 22:42:07 2013 +0000 +++ b/hgext/largefiles/__init__.py Sat Feb 09 15:25:46 2013 +0000 @@ -41,11 +41,20 @@ enabled for this to work. When you pull a changeset that affects largefiles from a remote -repository, Mercurial behaves as normal. However, when you update to -such a revision, any largefiles needed by that revision are downloaded -and cached (if they have never been downloaded before). This means -that network access may be required to update to changesets you have -not previously updated to. +repository, the largefiles for the changeset usually won't be +pulled down until you update to the revision (there is one exception +to this case). However, when you update to such a revision, any +largefiles needed by that revision are downloaded and cached (if +they have never been downloaded before). This means that network +access may be required to update to changesets you have no +previously updated to. + +The one exception to the "largefiles won't be pulled until you update +to a revision that changes them" rule is when you pull new heads. +Because you could be pulling new heads (that you may later want to +merge with) from a non-default location (that Mercurial won't know +about later), when you pull new heads, largefiles revisions for those +heads are downloaded and cached locally. If you already have large files tracked by Mercurial without the largefiles extension, you will need to convert your repository in From bos at serpentine.com Sat Feb 9 09:32:17 2013 From: bos at serpentine.com (Bryan O'Sullivan) Date: Sat, 9 Feb 2013 07:32:17 -0800 Subject: [PATCH] largefiles: document behavior of caching largefiles for new heads In-Reply-To: References: Message-ID: On Sat, Feb 9, 2013 at 7:26 AM, wrote: > largefiles: document behavior of caching largefiles for new heads > Crewed, thanks. -------------- next part -------------- An HTML attachment was scrubbed... URL: From diptongo at gmail.com Sat Feb 9 09:32:44 2013 From: diptongo at gmail.com (Isaac Jurado) Date: Sat, 9 Feb 2013 16:32:44 +0100 Subject: [PATCH 09 of 11] worker: allow a function to be run in multiple worker processes In-Reply-To: References: <8cf626e958d3dd67e45b.1360418801@australite.local> Message-ID: <20130209153244.GA3665@findus> Replying Bryan O'Sullivan: > # HG changeset patch > # User Bryan O'Sullivan > # Date 1360418465 0 > # Node ID dfb4e4bfedfc6db5fddf08b95276de01f1b1366d > # Parent 023956ed1b098df7f93a5c1857b2f5ec00f3e45d > worker: allow a function to be run in multiple worker processes > > If we estimate that it will be worth the cost, we run the function in > multiple processes. Otherwise, we run it in-process. > > Children report progress to the parent through a pipe. > > Not yet implemented on Windows. > > diff --git a/mercurial/worker.py b/mercurial/worker.py > --- a/mercurial/worker.py > +++ b/mercurial/worker.py > @@ -5,7 +5,7 @@ > # This software may be used and distributed according to the terms of the > # GNU General Public License version 2 or any later version. > > -import os > +import os, signal, sys > > def countcpus(): > '''try to count the number of CPUs on the system''' > @@ -54,3 +54,58 @@ def worthwhile(costperop, nops): > linear = costperop * nops > benefit = linear - (_startupcost * _numworkers + linear / _numworkers) > return benefit >= 0.15 > + > +def worker(costperarg, func, staticargs, args): > + '''run a function, possibly in parallel in multiple worker > + processes. > + > + returns a progress iterator > + > + costperarg - cost of a single task > + > + func - function to run > + > + staticargs - arguments to pass to every invocation of the function > + > + args - arguments to split into chunks, to pass to individual > + workers > + ''' > + if worthwhile(costperarg, len(args)): > + return _platformworker(func, staticargs, args) > + return func(*staticargs + (args,)) > + > +def _posixworker(func, staticargs, args): > + rfd, wfd = os.pipe() > + for pargs in partition(args, _numworkers): > + pid = os.fork() > + if pid == 0: > + try: > + os.close(rfd) > + for i, item in func(*(staticargs + (pargs,))): > + os.write(wfd, '%d %s\n' % (i, item)) Cool trick! Taking advantage of atomic pipe writes :-) > + os._exit(0) > + except KeyboardInterrupt: > + os._exit(255) > + os.close(wfd) > + fp = os.fdopen(rfd, 'rb', 0) > + oldhandler = signal.getsignal(signal.SIGINT) > + signal.signal(signal.SIGINT, signal.SIG_IGN) > + def cleanup(): > + # python 2.4 is too dumb for try/yield/finally > + signal.signal(signal.SIGINT, oldhandler) > + problems = 0 > + for i in xrange(_numworkers): > + problems |= os.wait()[1] > + if problems: > + sys.exit(1) > + try: > + for line in fp: > + l = line.split(' ', 1) > + yield int(l[0]), l[1][:-1] > + except: # re-raises > + cleanup() > + raise > + cleanup() > + > +if os.name != 'nt': > + _platformworker = _posixworker > _______________________________________________ > Mercurial-devel mailing list > Mercurial-devel at selenic.com > http://selenic.com/mailman/listinfo/mercurial-devel -- Isaac Jurado "The noblest pleasure is the joy of understanding." Leonardo da Vinci From bos at serpentine.com Sat Feb 9 09:32:48 2013 From: bos at serpentine.com (Bryan O'Sullivan) Date: Sat, 9 Feb 2013 07:32:48 -0800 Subject: [PATCH] largefiles: make caching largefiles message more explicit In-Reply-To: <42691426804311ace536.1360422643@s0-0.paconsult7.bbnplanet.net> References: <42691426804311ace536.1360422643@s0-0.paconsult7.bbnplanet.net> Message-ID: On Sat, Feb 9, 2013 at 7:10 AM, wrote: > largefiles: make caching largefiles message more explicit > Crewed, thanks. -------------- next part -------------- An HTML attachment was scrubbed... URL: From idankk86 at gmail.com Sat Feb 9 09:35:26 2013 From: idankk86 at gmail.com (Idan Kamara) Date: Sat, 9 Feb 2013 17:35:26 +0200 Subject: [PATCH 09 of 11] worker: allow a function to be run in multiple worker processes In-Reply-To: References: <8cf626e958d3dd67e45b.1360418801@australite.local> Message-ID: On Sat, Feb 9, 2013 at 4:06 PM, Bryan O'Sullivan wrote: > > # HG changeset patch > # User Bryan O'Sullivan > # Date 1360418465 0 > # Node ID dfb4e4bfedfc6db5fddf08b95276de01f1b1366d > # Parent 023956ed1b098df7f93a5c1857b2f5ec00f3e45d > worker: allow a function to be run in multiple worker processes > > If we estimate that it will be worth the cost, we run the function in > multiple processes. Otherwise, we run it in-process. > > Children report progress to the parent through a pipe. > > Not yet implemented on Windows. > > diff --git a/mercurial/worker.py b/mercurial/worker.py > --- a/mercurial/worker.py > +++ b/mercurial/worker.py > @@ -5,7 +5,7 @@ > # This software may be used and distributed according to the terms of the > # GNU General Public License version 2 or any later version. > > -import os > +import os, signal, sys > > def countcpus(): > '''try to count the number of CPUs on the system''' > @@ -54,3 +54,58 @@ def worthwhile(costperop, nops): > linear = costperop * nops > benefit = linear - (_startupcost * _numworkers + linear / > _numworkers) > return benefit >= 0.15 > + > +def worker(costperarg, func, staticargs, args): > + '''run a function, possibly in parallel in multiple worker > + processes. > + > + returns a progress iterator > + > + costperarg - cost of a single task > + > + func - function to run > + > + staticargs - arguments to pass to every invocation of the function > + > + args - arguments to split into chunks, to pass to individual > + workers > + ''' > + if worthwhile(costperarg, len(args)): > + return _platformworker(func, staticargs, args) > + return func(*staticargs + (args,)) > + > +def _posixworker(func, staticargs, args): > + rfd, wfd = os.pipe() > + for pargs in partition(args, _numworkers): > + pid = os.fork() > + if pid == 0: > + try: > + os.close(rfd) > + for i, item in func(*(staticargs + (pargs,))): > + os.write(wfd, '%d %s\n' % (i, item)) > + os._exit(0) > + except KeyboardInterrupt: > + os._exit(255) Isn't it a problem you're not exiting here for other exceptions too, assuming this code isn't run by 'hg' (e.g. things that import mercurial, or the command server)? > + os.close(wfd) > + fp = os.fdopen(rfd, 'rb', 0) > + oldhandler = signal.getsignal(signal.SIGINT) > + signal.signal(signal.SIGINT, signal.SIG_IGN) > + def cleanup(): > + # python 2.4 is too dumb for try/yield/finally > + signal.signal(signal.SIGINT, oldhandler) > + problems = 0 > + for i in xrange(_numworkers): > + problems |= os.wait()[1] > + if problems: > + sys.exit(1) This exit is also going to be a problem for things that call into the internal API. And doesn't it also lose the cause of the error? -------------- next part -------------- An HTML attachment was scrubbed... URL: From pierre-yves.david at ens-lyon.org Sat Feb 9 09:37:49 2013 From: pierre-yves.david at ens-lyon.org (Pierre-Yves David) Date: Sat, 9 Feb 2013 16:37:49 +0100 Subject: [PATCH RFC] commit: add --reuse-message for keeping the old commit message during amend In-Reply-To: <51162333.30401@kiilerich.com> References: <379D27C9-B6EB-481B-8605-A11BE916470F@durin42.com> <51162333.30401@kiilerich.com> Message-ID: <20130209153749.GA4975@kraken.insecable.net> On Sat, Feb 09, 2013 at 11:21:39AM +0100, Mads Kiilerich wrote: > On 02/09/2013 12:05 AM, Augie Fackler wrote: > >On Feb 8, 2013, at 9:34 PM, Durham Goode wrote: > > > >># HG changeset patch > >># User Durham Goode > >># Date 1360352769 28800 > >># Node ID a761c31f54ca302d65b33199f6c9368890267eba > >># Parent e2b176cf28e374eb146c3e131871631ab9ace537 > >>commit: add --reuse-message for keeping the old commit message during amend > >> > >>When people do 'hg commit --amend', most of the time they don't want to change > >>the commit message. This adds a flag to do that without prompting the user. > >> > >>I imagine most people will use it in an alias such as: > >> > >> amend=commit --amend --reuse-message > >> > >>Questions: > >>- Anyone have a better name? 'reuse-message' matches git which is why it was > >>chosen, but it seems a little long. > >I don't have a better one. > > We usually don't use '-' in option names. > > (--reuse-message might be long, but it is still shorter than > --config ui.editor=true ... and more cross platform. The feature is > still nice to have, but not something completely new.) The name is not nice, but using the same option that git seems a good idea. -- Pierre-Yves From diptongo at gmail.com Sat Feb 9 09:39:18 2013 From: diptongo at gmail.com (Isaac Jurado) Date: Sat, 9 Feb 2013 16:39:18 +0100 Subject: [PATCH 09 of 11] worker: allow a function to be run in multiple worker processes In-Reply-To: References: <8cf626e958d3dd67e45b.1360418801@australite.local> Message-ID: <20130209153918.GB3665@findus> Replying Bryan O'Sullivan: > > + def cleanup(): > + # python 2.4 is too dumb for try/yield/finally > + signal.signal(signal.SIGINT, oldhandler) > + problems = 0 > + for i in xrange(_numworkers): > + problems |= os.wait()[1] > + if problems: > + sys.exit(1) A curiosity. Wouldn't this terminate the command server too? Maybe it's too soon to ask. Cheeres. -- Isaac Jurado "The noblest pleasure is the joy of understanding." Leonardo da Vinci From pierre-yves.david at ens-lyon.org Sat Feb 9 09:43:10 2013 From: pierre-yves.david at ens-lyon.org (Pierre-Yves David) Date: Sat, 9 Feb 2013 16:43:10 +0100 Subject: [PATCH RFC] commit: add --reuse-message for keeping the old commit message during amend In-Reply-To: <20130209153749.GA4975@kraken.insecable.net> References: <379D27C9-B6EB-481B-8605-A11BE916470F@durin42.com> <51162333.30401@kiilerich.com> <20130209153749.GA4975@kraken.insecable.net> Message-ID: <20130209154310.GB4975@kraken.insecable.net> On Sat, Feb 09, 2013 at 04:37:49PM +0100, Pierre-Yves David wrote: > On Sat, Feb 09, 2013 at 11:21:39AM +0100, Mads Kiilerich wrote: > > On 02/09/2013 12:05 AM, Augie Fackler wrote: > > >On Feb 8, 2013, at 9:34 PM, Durham Goode wrote: > > > > > >># HG changeset patch > > >># User Durham Goode > > >># Date 1360352769 28800 > > >># Node ID a761c31f54ca302d65b33199f6c9368890267eba > > >># Parent e2b176cf28e374eb146c3e131871631ab9ace537 > > >>commit: add --reuse-message for keeping the old commit message during amend > > >> > > >>When people do 'hg commit --amend', most of the time they don't want to change > > >>the commit message. This adds a flag to do that without prompting the user. > > >> > > >>I imagine most people will use it in an alias such as: > > >> > > >> amend=commit --amend --reuse-message > > >> > > >>Questions: > > >>- Anyone have a better name? 'reuse-message' matches git which is why it was > > >>chosen, but it seems a little long. > > >I don't have a better one. > > > > We usually don't use '-' in option names. > > > > (--reuse-message might be long, but it is still shorter than > > --config ui.editor=true ... and more cross platform. The feature is > > still nice to have, but not something completely new.) > > The name is not nice, but using the same option that git seems a good idea. Augies told me that git's "reuse-message" takes a commit at reuse the message of this commit. It has no default option and therefore behave different than we do here. We need another name. -- Pierre-Yves From raf at durin42.com Sat Feb 9 09:44:07 2013 From: raf at durin42.com (Augie Fackler) Date: Sat, 9 Feb 2013 15:44:07 +0000 Subject: [PATCH 0 of 2] histedit abort with clearer error message [~V3] In-Reply-To: References: <9DE30DAC-4D11-423F-B06E-63F94D61EA35@durin42.com> Message-ID: queued both, with a tweak to the log message in #1. Thanks! On Aug 3, 2013, at 3:41 PM, Simon Heimberg wrote: > Simplified the patch by removing the unreachable code. (We are two who are > almost sure it is unreachable. I guess this is sure enough.) > And use the clearer abort message suggested by Augie Fackler. In the 2nd > patch also use it for the other message which reports the same failure. From sid0 at fb.com Sat Feb 9 09:48:54 2013 From: sid0 at fb.com (Siddharth Agarwal) Date: Sat, 09 Feb 2013 15:48:54 +0000 Subject: [PATCH 2 of 4 V3] manifest: use a size 3 LRU cache to store parsed manifests In-Reply-To: References: Message-ID: <6cab05663f2d0ade0126.1360424934@sid0x220> # HG changeset patch # User Siddharth Agarwal # Date 1360424582 0 # Node ID 6cab05663f2d0ade01267e103cae12634fd49c28 # Parent c5e8d2d68a8e1a7bada44d98cbe528f8b25dae15 manifest: use a size 3 LRU cache to store parsed manifests Previously, the manifest cache would store the last manifest parsed. We could run into situations with operations like update where we would try parsing the manifest for a revision r1, then r2, then r1 again. This increases the cache size to 3 to avoid that bit of performance fragility. diff --git a/mercurial/manifest.py b/mercurial/manifest.py --- a/mercurial/manifest.py +++ b/mercurial/manifest.py @@ -28,7 +28,8 @@ class manifestdict(dict): class manifest(revlog.revlog): def __init__(self, opener): - self._mancache = None + # we expect to deal with not more than three revs at a time in merge + self._mancache = util.lrucachedict(3) revlog.revlog.__init__(self, opener, "00manifest.i") def parse(self, lines): @@ -51,12 +52,12 @@ class manifest(revlog.revlog): def read(self, node): if node == revlog.nullid: return manifestdict() # don't upset local cache - if self._mancache and self._mancache[0] == node: - return self._mancache[1] + if node in self._mancache: + return self._mancache[node][0] text = self.revision(node) arraytext = array.array('c', text) mapping = self.parse(text) - self._mancache = (node, mapping, arraytext) + self._mancache[node] = (mapping, arraytext) return mapping def _search(self, m, s, lo=0, hi=None): @@ -102,8 +103,9 @@ class manifest(revlog.revlog): def find(self, node, f): '''look up entry for a single file efficiently. return (node, flags) pair if found, (None, None) if not.''' - if self._mancache and self._mancache[0] == node: - return self._mancache[1].get(f), self._mancache[1].flags(f) + if node in self._mancache: + mapping = self._mancache[node][0] + return mapping.get(f), mapping.flags(f) text = self.revision(node) start, end = self._search(text, f) if start == end: @@ -143,7 +145,7 @@ class manifest(revlog.revlog): # if we're using the cache, make sure it is valid and # parented by the same node we're diffing against - if not (changed and self._mancache and p1 and self._mancache[0] == p1): + if not (changed and p1 and (p1 in self._mancache)): files = sorted(map) checkforbidden(files) @@ -156,7 +158,7 @@ class manifest(revlog.revlog): cachedelta = None else: added, removed = changed - addlist = self._mancache[2] + addlist = self._mancache[p1][1] checkforbidden(added) # combine the changed lists into one list for sorting @@ -208,6 +210,6 @@ class manifest(revlog.revlog): text = util.buffer(arraytext) n = self.addrevision(text, transaction, link, p1, p2, cachedelta) - self._mancache = (n, map, arraytext) + self._mancache[n] = (map, arraytext) return n From sid0 at fb.com Sat Feb 9 09:48:53 2013 From: sid0 at fb.com (Siddharth Agarwal) Date: Sat, 09 Feb 2013 15:48:53 +0000 Subject: [PATCH 1 of 4 V3] util: add an LRU cache dict Message-ID: # HG changeset patch # User Siddharth Agarwal # Date 1360424506 0 # Node ID c5e8d2d68a8e1a7bada44d98cbe528f8b25dae15 # Parent 08e00496e7b3bda8db3fbe7084a013d77e4932d2 util: add an LRU cache dict In certain cases we would like to have a cache of the last N results of a given computation, where N is small. This will be used in an upcoming patch to increase the size of the manifest cache from 1 to 3. diff --git a/mercurial/util.py b/mercurial/util.py --- a/mercurial/util.py +++ b/mercurial/util.py @@ -211,6 +211,31 @@ except AttributeError: del self[i] break +class lrucachedict(object): + '''cache most recent gets from or sets to this dictionary''' + def __init__(self, maxsize): + self._cache = {} + self._maxsize = maxsize + self._order = deque() + + def __getitem__(self, key): + value = self._cache[key] + self._order.remove(key) + self._order.append(key) + return value + + def __setitem__(self, key, value): + if key not in self._cache: + if len(self._cache) >= self._maxsize: + del self._cache[self._order.popleft()] + else: + self._order.remove(key) + self._cache[key] = value + self._order.append(key) + + def __contains__(self, key): + return key in self._cache + def lrucachefunc(func): '''cache most recent results of function calls''' cache = {} diff --git a/tests/test-lrucachedict.py b/tests/test-lrucachedict.py new file mode 100644 --- /dev/null +++ b/tests/test-lrucachedict.py @@ -0,0 +1,35 @@ +from mercurial import util + +def printifpresent(d, xs): + for x in xs: + present = x in d + print "'%s' in d: %s" % (x, present) + if present: + print "d['%s']: %s" % (x, d[x]) + +def test_lrucachedict(): + d = util.lrucachedict(4) + d['a'] = 'va' + d['b'] = 'vb' + d['c'] = 'vc' + d['d'] = 'vd' + + # all of these should be present + printifpresent(d, ['a', 'b', 'c', 'd']) + + # 'a' should be dropped because it was least recently used + d['e'] = 've' + printifpresent(d, ['a', 'b', 'c', 'd', 'e']) + + # touch entries in some order (get or set). + d['e'] + d['c'] = 'vc2' + d['d'] + d['b'] = 'vb2' + + # 'e' should be dropped now + d['f'] = 'vf' + printifpresent(d, ['b', 'c', 'd', 'e', 'f']) + +if __name__ == '__main__': + test_lrucachedict() diff --git a/tests/test-lrucachedict.py.out b/tests/test-lrucachedict.py.out new file mode 100644 --- /dev/null +++ b/tests/test-lrucachedict.py.out @@ -0,0 +1,26 @@ +'a' in d: True +d['a']: va +'b' in d: True +d['b']: vb +'c' in d: True +d['c']: vc +'d' in d: True +d['d']: vd +'a' in d: False +'b' in d: True +d['b']: vb +'c' in d: True +d['c']: vc +'d' in d: True +d['d']: vd +'e' in d: True +d['e']: ve +'b' in d: True +d['b']: vb2 +'c' in d: True +d['c']: vc2 +'d' in d: True +d['d']: vd +'e' in d: False +'f' in d: True +d['f']: vf From sid0 at fb.com Sat Feb 9 09:48:56 2013 From: sid0 at fb.com (Siddharth Agarwal) Date: Sat, 09 Feb 2013 15:48:56 +0000 Subject: [PATCH 4 of 4 V3] manifestmerge: handle abort on local unknown, remote created files In-Reply-To: References: Message-ID: # HG changeset patch # User Siddharth Agarwal # Date 1360424160 0 # Node ID a8047ff53c9e754629baf8347008ef456b713447 # Parent 0e6b206adfdd78e87dfb4f81c37a6b79f521ea18 manifestmerge: handle abort on local unknown, remote created files This replaces the _checkunknown call in calculateupdates with a more performant version. On a repository with over 150,000 files, this speeds up an update by 0.6-0.8 seconds, which is up to 25%. This does not introduce any UI changes. There is existing test coverage for every case, mostly in test-merge*.t. diff --git a/mercurial/merge.py b/mercurial/merge.py --- a/mercurial/merge.py +++ b/mercurial/merge.py @@ -224,7 +224,7 @@ def manifestmerge(repo, p1, p2, pa, bran m1['.hgsubstate'] += "+" break - prompts = [] + aborts, prompts = [], [] # Compare manifests for f, n in m1.iteritems(): if partial and not partial(f): @@ -285,15 +285,40 @@ def manifestmerge(repo, p1, p2, pa, bran actions.append((f2, "m", (f, f, True), "remote moved to " + f)) elif f not in ma: - if (not overwrite - and _checkunknownfile(repo, p1, p2, f)): - actions.append((f, "m", (f, f, False), - "remote differs from untracked local")) + # local unknown, remote created: the logic is described by the + # following table: + # + # force branchmerge different | action + # n * n | get + # n * y | abort + # y n * | get + # y y n | get + # y y y | merge + # + # Checking whether the files are different is expensive, so we + # don't do that when we can avoid it. + if force and not branchmerge: + actions.append((f, "g", (m2.flags(f),), "remote created")) else: - actions.append((f, "g", (m2.flags(f),), "remote created")) + different = _checkunknownfile(repo, p1, p2, f) + if force and branchmerge and different: + actions.append((f, "m", (f, f, False), + "remote differs from untracked local")) + elif not force and different: + aborts.append((f, "ud")) + else: + actions.append((f, "g", (m2.flags(f),), "remote created")) elif n != ma[f]: prompts.append((f, "dc")) # prompt deleted/changed + for f, m in sorted(aborts): + if m == "ud": + repo.ui.warn(_("%s: untracked file differs\n") % f) + else: assert False, m + if aborts: + raise util.Abort(_("untracked files in working directory differ " + "from files in requested revision")) + for f, m in sorted(prompts): if m == "cd": if repo.ui.promptchoice( @@ -447,8 +472,6 @@ def calculateupdates(repo, tctx, mctx, a _checkcollision(mctx, None) else: _checkcollision(mctx, (tctx, ancestor)) - if not force: - _checkunknown(repo, tctx, mctx) if tctx.rev() is None: actions += _forgetremoved(tctx, mctx, branchmerge) actions += manifestmerge(repo, tctx, mctx, From sid0 at fb.com Sat Feb 9 09:48:55 2013 From: sid0 at fb.com (Siddharth Agarwal) Date: Sat, 09 Feb 2013 15:48:55 +0000 Subject: [PATCH 3 of 4 V3] manifestmerge: pass in branchmerge and force separately In-Reply-To: References: Message-ID: <0e6b206adfdd78e87dfb.1360424935@sid0x220> # HG changeset patch # User Siddharth Agarwal # Date 1360337003 0 # Node ID 0e6b206adfdd78e87dfb4f81c37a6b79f521ea18 # Parent 6cab05663f2d0ade01267e103cae12634fd49c28 manifestmerge: pass in branchmerge and force separately This will be used in an upcoming patch. diff --git a/hgext/largefiles/overrides.py b/hgext/largefiles/overrides.py --- a/hgext/largefiles/overrides.py +++ b/hgext/largefiles/overrides.py @@ -360,8 +360,10 @@ def overridecheckunknownfile(origfn, rep # Finally, the merge.applyupdates function will then take care of # writing the files into the working copy and lfcommands.updatelfiles # will update the largefiles. -def overridemanifestmerge(origfn, repo, p1, p2, pa, overwrite, partial): - actions = origfn(repo, p1, p2, pa, overwrite, partial) +def overridemanifestmerge(origfn, repo, p1, p2, pa, branchmerge, force, + partial): + overwrite = force and not branchmerge + actions = origfn(repo, p1, p2, pa, branchmerge, force, partial) processed = [] for action in actions: diff --git a/mercurial/merge.py b/mercurial/merge.py --- a/mercurial/merge.py +++ b/mercurial/merge.py @@ -185,14 +185,15 @@ def _forgetremoved(wctx, mctx, branchmer return actions -def manifestmerge(repo, p1, p2, pa, overwrite, partial): +def manifestmerge(repo, p1, p2, pa, branchmerge, force, partial): """ Merge p1 and p2 with ancestor pa and generate merge action list - overwrite = whether we clobber working files + branchmerge and force are as passed in to update partial = function to filter file lists """ + overwrite = force and not branchmerge actions, copy, movewithdir = [], {}, {} if overwrite: @@ -208,8 +209,8 @@ def manifestmerge(repo, p1, p2, pa, over actions.append((of, "rd", (fl,), "rename and delete")) repo.ui.note(_("resolving manifests\n")) - repo.ui.debug(" overwrite: %s, partial: %s\n" - % (bool(overwrite), bool(partial))) + repo.ui.debug(" branchmerge: %s, force: %s, partial: %s\n" + % (bool(branchmerge), bool(force), bool(partial))) repo.ui.debug(" ancestor: %s, local: %s, remote: %s\n" % (pa, p1, p2)) m1, m2, ma = p1.manifest(), p2.manifest(), pa.manifest() @@ -452,7 +453,7 @@ def calculateupdates(repo, tctx, mctx, a actions += _forgetremoved(tctx, mctx, branchmerge) actions += manifestmerge(repo, tctx, mctx, ancestor, - force and not branchmerge, + branchmerge, force, partial) return actions diff --git a/tests/test-copy-move-merge.t b/tests/test-copy-move-merge.t --- a/tests/test-copy-move-merge.t +++ b/tests/test-copy-move-merge.t @@ -29,7 +29,7 @@ src: 'a' -> dst: 'c' * checking for directory renames resolving manifests - overwrite: False, partial: False + branchmerge: True, force: False, partial: False ancestor: b8bf91eeebbc, local: add3f11052fa+, remote: 17c05bb7fcb6 a: remote moved to b -> m preserving a for resolve of b diff --git a/tests/test-double-merge.t b/tests/test-double-merge.t --- a/tests/test-double-merge.t +++ b/tests/test-double-merge.t @@ -33,7 +33,7 @@ we get conflicts that shouldn't be there src: 'foo' -> dst: 'bar' * checking for directory renames resolving manifests - overwrite: False, partial: False + branchmerge: True, force: False, partial: False ancestor: e6dc8efe11cc, local: 6a0df1dad128+, remote: 484bf6903104 foo: remote copied to bar -> m preserving foo for resolve of bar diff --git a/tests/test-graft.t b/tests/test-graft.t --- a/tests/test-graft.t +++ b/tests/test-graft.t @@ -134,7 +134,7 @@ Graft out of order, skipping a merge and src: 'a' -> dst: 'b' * checking for directory renames resolving manifests - overwrite: False, partial: False + branchmerge: True, force: True, partial: False ancestor: 68795b066622, local: ef0ef43d49e7+, remote: 5d205f8b35b6 b: local copied/moved to a -> m preserving b for resolve of b @@ -147,7 +147,7 @@ Graft out of order, skipping a merge and grafting revision 5 searching for copies back to rev 1 resolving manifests - overwrite: False, partial: False + branchmerge: True, force: True, partial: False ancestor: 4c60f11aa304, local: 6b9e5368ca4e+, remote: 97f8bfe72746 e: remote is newer -> g updating: e 1/1 files (100.00%) @@ -156,7 +156,7 @@ Graft out of order, skipping a merge and grafting revision 4 searching for copies back to rev 1 resolving manifests - overwrite: False, partial: False + branchmerge: True, force: True, partial: False ancestor: 4c60f11aa304, local: 1905859650ec+, remote: 9c233e8e184d d: remote is newer -> g e: versions differ -> m diff --git a/tests/test-issue1802.t b/tests/test-issue1802.t --- a/tests/test-issue1802.t +++ b/tests/test-issue1802.t @@ -55,7 +55,7 @@ Simulate a Windows merge: unmatched files in local: b resolving manifests - overwrite: False, partial: False + branchmerge: True, force: False, partial: False ancestor: a03b0deabf2b, local: d6fa54f68ae1+, remote: 2d8bcf2dda39 a: update permissions -> e updating: a 1/1 files (100.00%) diff --git a/tests/test-issue522.t b/tests/test-issue522.t --- a/tests/test-issue522.t +++ b/tests/test-issue522.t @@ -29,7 +29,7 @@ revision. unmatched files in local: bar resolving manifests - overwrite: False, partial: False + branchmerge: True, force: False, partial: False ancestor: bbd179dfa0a7, local: 71766447bdbb+, remote: 4d9e78aaceee foo: remote is newer -> g updating: foo 1/1 files (100.00%) diff --git a/tests/test-issue672.t b/tests/test-issue672.t --- a/tests/test-issue672.t +++ b/tests/test-issue672.t @@ -32,7 +32,7 @@ http://mercurial.selenic.com/bts/issue67 src: '1' -> dst: '1a' checking for directory renames resolving manifests - overwrite: False, partial: False + branchmerge: True, force: False, partial: False ancestor: 81f4b099af3d, local: c64f439569a9+, remote: c12dcd37c90a 1: other deleted -> r 1a: remote created -> g @@ -63,7 +63,7 @@ http://mercurial.selenic.com/bts/issue67 src: '1' -> dst: '1a' * checking for directory renames resolving manifests - overwrite: False, partial: False + branchmerge: True, force: False, partial: False ancestor: c64f439569a9, local: e327dca35ac8+, remote: 746e9549ea96 1a: local copied/moved to 1 -> m preserving 1a for resolve of 1a @@ -86,7 +86,7 @@ http://mercurial.selenic.com/bts/issue67 src: '1' -> dst: '1a' * checking for directory renames resolving manifests - overwrite: False, partial: False + branchmerge: True, force: False, partial: False ancestor: c64f439569a9, local: 746e9549ea96+, remote: e327dca35ac8 1: remote moved to 1a -> m preserving 1 for resolve of 1a diff --git a/tests/test-largefiles.t b/tests/test-largefiles.t --- a/tests/test-largefiles.t +++ b/tests/test-largefiles.t @@ -1676,7 +1676,7 @@ largefiles pulled on update - no server $ mv 02a439e5c31c526465ab1a0ca1f431f76b827b90 empty/.hg/largefiles/ $ hg -R http-clone --debug up --config largefiles.usercache=http-clone-usercache resolving manifests - overwrite: False, partial: False + branchmerge: False, force: False, partial: False ancestor: 000000000000, local: 000000000000+, remote: cf03e5bb9936 .hglf/f1: remote created -> g updating: .hglf/f1 1/1 files (100.00%) diff --git a/tests/test-merge-commit.t b/tests/test-merge-commit.t --- a/tests/test-merge-commit.t +++ b/tests/test-merge-commit.t @@ -69,7 +69,7 @@ This should use bar at rev2 as the ancestor $ hg --debug merge 3 searching for copies back to rev 1 resolving manifests - overwrite: False, partial: False + branchmerge: True, force: False, partial: False ancestor: 0f2ff26688b9, local: 2263c1be0967+, remote: 0555950ead28 bar: versions differ -> m preserving bar for resolve of bar @@ -156,7 +156,7 @@ This should use bar at rev2 as the ancestor $ hg --debug merge 3 searching for copies back to rev 1 resolving manifests - overwrite: False, partial: False + branchmerge: True, force: False, partial: False ancestor: 0f2ff26688b9, local: 2263c1be0967+, remote: 3ffa6b9e35f0 bar: versions differ -> m preserving bar for resolve of bar diff --git a/tests/test-merge-types.t b/tests/test-merge-types.t --- a/tests/test-merge-types.t +++ b/tests/test-merge-types.t @@ -32,7 +32,7 @@ Symlink is local parent, executable is o $ hg merge --debug searching for copies back to rev 1 resolving manifests - overwrite: False, partial: False + branchmerge: True, force: False, partial: False ancestor: c334dc3be0da, local: 521a1e40188f+, remote: 3574f3e69b1c a: versions differ -> m preserving a for resolve of a @@ -65,7 +65,7 @@ Symlink is other parent, executable is l $ hg merge --debug searching for copies back to rev 1 resolving manifests - overwrite: False, partial: False + branchmerge: True, force: False, partial: False ancestor: c334dc3be0da, local: 3574f3e69b1c+, remote: 521a1e40188f a: versions differ -> m preserving a for resolve of a @@ -99,7 +99,7 @@ Update to link with local change should $ HGMERGE= hg up -y --debug searching for copies back to rev 2 resolving manifests - overwrite: False, partial: False + branchmerge: False, force: False, partial: False ancestor: c334dc3be0da, local: c334dc3be0da+, remote: 521a1e40188f a: versions differ -> m preserving a for resolve of a diff --git a/tests/test-merge7.t b/tests/test-merge7.t --- a/tests/test-merge7.t +++ b/tests/test-merge7.t @@ -81,7 +81,7 @@ pull and merge from test-a again $ hg merge --debug searching for copies back to rev 1 resolving manifests - overwrite: False, partial: False + branchmerge: True, force: False, partial: False ancestor: 96b70246a118, local: 50c3a7e29886+, remote: 40d11a4173a8 test.txt: versions differ -> m preserving test.txt for resolve of test.txt diff --git a/tests/test-rename-dir-merge.t b/tests/test-rename-dir-merge.t --- a/tests/test-rename-dir-merge.t +++ b/tests/test-rename-dir-merge.t @@ -37,7 +37,7 @@ discovered dir src: 'a/' -> dst: 'b/' pending file src: 'a/c' -> dst: 'b/c' resolving manifests - overwrite: False, partial: False + branchmerge: True, force: False, partial: False ancestor: f9b20c0d4c51, local: ce36d17b18fb+, remote: 397f8b00a740 a/a: other deleted -> r a/b: other deleted -> r @@ -88,7 +88,7 @@ discovered dir src: 'a/' -> dst: 'b/' pending file src: 'a/c' -> dst: 'b/c' resolving manifests - overwrite: False, partial: False + branchmerge: True, force: False, partial: False ancestor: f9b20c0d4c51, local: 397f8b00a740+, remote: ce36d17b18fb None: local renamed directory to b/c -> d updating:None 1/1 files (100.00%) diff --git a/tests/test-rename-merge1.t b/tests/test-rename-merge1.t --- a/tests/test-rename-merge1.t +++ b/tests/test-rename-merge1.t @@ -34,7 +34,7 @@ src: 'a2' -> dst: 'c2' ! checking for directory renames resolving manifests - overwrite: False, partial: False + branchmerge: True, force: False, partial: False ancestor: af1939970a1c, local: 044f8520aeeb+, remote: 85c198ef2f6c a: remote moved to b -> m preserving a for resolve of b @@ -179,7 +179,7 @@ Check for issue3074 src: 'file' -> dst: 'newfile' % checking for directory renames resolving manifests - overwrite: False, partial: False + branchmerge: True, force: False, partial: False ancestor: 19d7f95df299, local: 0084274f6b67+, remote: 5d32493049f0 file: rename and delete -> rd newfile: remote created -> g diff --git a/tests/test-rename-merge2.t b/tests/test-rename-merge2.t --- a/tests/test-rename-merge2.t +++ b/tests/test-rename-merge2.t @@ -84,7 +84,7 @@ args: src: 'a' -> dst: 'b' * checking for directory renames resolving manifests - overwrite: False, partial: False + branchmerge: True, force: False, partial: False ancestor: 924404dff337, local: e300d1c794ec+, remote: 4ce40f5aca24 a: remote copied to b -> m preserving a for resolve of b @@ -119,7 +119,7 @@ args: src: 'a' -> dst: 'b' * checking for directory renames resolving manifests - overwrite: False, partial: False + branchmerge: True, force: False, partial: False ancestor: 924404dff337, local: 86a2aa42fc76+, remote: f4db7e329e71 a: remote is newer -> g b: local copied/moved to a -> m @@ -157,7 +157,7 @@ args: src: 'a' -> dst: 'b' * checking for directory renames resolving manifests - overwrite: False, partial: False + branchmerge: True, force: False, partial: False ancestor: 924404dff337, local: e300d1c794ec+, remote: bdb19105162a a: remote moved to b -> m preserving a for resolve of b @@ -192,7 +192,7 @@ args: src: 'a' -> dst: 'b' * checking for directory renames resolving manifests - overwrite: False, partial: False + branchmerge: True, force: False, partial: False ancestor: 924404dff337, local: 02963e448370+, remote: f4db7e329e71 b: local copied/moved to a -> m preserving b for resolve of b @@ -226,7 +226,7 @@ args: src: 'a' -> dst: 'b' checking for directory renames resolving manifests - overwrite: False, partial: False + branchmerge: True, force: False, partial: False ancestor: 924404dff337, local: 94b33a1b7f2d+, remote: 4ce40f5aca24 b: remote created -> g rev: versions differ -> m @@ -256,7 +256,7 @@ args: src: 'a' -> dst: 'b' checking for directory renames resolving manifests - overwrite: False, partial: False + branchmerge: True, force: False, partial: False ancestor: 924404dff337, local: 86a2aa42fc76+, remote: 97c705ade336 rev: versions differ -> m preserving rev for resolve of rev @@ -283,7 +283,7 @@ args: src: 'a' -> dst: 'b' checking for directory renames resolving manifests - overwrite: False, partial: False + branchmerge: True, force: False, partial: False ancestor: 924404dff337, local: 94b33a1b7f2d+, remote: bdb19105162a a: other deleted -> r b: remote created -> g @@ -315,7 +315,7 @@ args: src: 'a' -> dst: 'b' checking for directory renames resolving manifests - overwrite: False, partial: False + branchmerge: True, force: False, partial: False ancestor: 924404dff337, local: 02963e448370+, remote: 97c705ade336 rev: versions differ -> m preserving rev for resolve of rev @@ -336,7 +336,7 @@ args: -------------- searching for copies back to rev 1 resolving manifests - overwrite: False, partial: False + branchmerge: True, force: False, partial: False ancestor: 924404dff337, local: 62e7bf090eba+, remote: 49b6d8032493 b: versions differ -> m preserving b for resolve of b @@ -374,7 +374,7 @@ m "um a c" "um x c" " " "10 do merg src: 'a' -> dst: 'c' ! checking for directory renames resolving manifests - overwrite: False, partial: False + branchmerge: True, force: False, partial: False ancestor: 924404dff337, local: 02963e448370+, remote: fe905ef2c33e a: divergent renames -> dr c: remote created -> g @@ -404,7 +404,7 @@ m "um a c" "um x c" " " "10 do merg -------------- searching for copies back to rev 1 resolving manifests - overwrite: False, partial: False + branchmerge: True, force: False, partial: False ancestor: 924404dff337, local: 86a2aa42fc76+, remote: af30c7647fc7 b: versions differ -> m preserving b for resolve of b @@ -432,7 +432,7 @@ m "um a c" "um x c" " " "10 do merg -------------- searching for copies back to rev 1 resolving manifests - overwrite: False, partial: False + branchmerge: True, force: False, partial: False ancestor: 924404dff337, local: 59318016310c+, remote: bdb19105162a a: other deleted -> r b: versions differ -> m @@ -462,7 +462,7 @@ m "um a c" "um x c" " " "10 do merg -------------- searching for copies back to rev 1 resolving manifests - overwrite: False, partial: False + branchmerge: True, force: False, partial: False ancestor: 924404dff337, local: 86a2aa42fc76+, remote: 8dbce441892a a: remote is newer -> g b: versions differ -> m @@ -493,7 +493,7 @@ m "um a c" "um x c" " " "10 do merg -------------- searching for copies back to rev 1 resolving manifests - overwrite: False, partial: False + branchmerge: True, force: False, partial: False ancestor: 924404dff337, local: 59318016310c+, remote: bdb19105162a a: other deleted -> r b: versions differ -> m @@ -523,7 +523,7 @@ m "um a c" "um x c" " " "10 do merg -------------- searching for copies back to rev 1 resolving manifests - overwrite: False, partial: False + branchmerge: True, force: False, partial: False ancestor: 924404dff337, local: 86a2aa42fc76+, remote: 8dbce441892a a: remote is newer -> g b: versions differ -> m @@ -554,7 +554,7 @@ m "um a c" "um x c" " " "10 do merg -------------- searching for copies back to rev 1 resolving manifests - overwrite: False, partial: False + branchmerge: True, force: False, partial: False ancestor: 924404dff337, local: 0b76e65c8289+, remote: 4ce40f5aca24 b: versions differ -> m preserving b for resolve of b @@ -582,7 +582,7 @@ m "um a c" "um x c" " " "10 do merg -------------- searching for copies back to rev 1 resolving manifests - overwrite: False, partial: False + branchmerge: True, force: False, partial: False ancestor: 924404dff337, local: 02963e448370+, remote: 8dbce441892a remote changed a which local deleted use (c)hanged version or leave (d)eleted? c @@ -615,7 +615,7 @@ m "um a c" "um x c" " " "10 do merg -------------- searching for copies back to rev 1 resolving manifests - overwrite: False, partial: False + branchmerge: True, force: False, partial: False ancestor: 924404dff337, local: 0b76e65c8289+, remote: bdb19105162a local changed a which remote deleted use (c)hanged version or (d)elete? c @@ -652,7 +652,7 @@ m "um a c" "um x c" " " "10 do merg src: 'a' -> dst: 'b' * checking for directory renames resolving manifests - overwrite: False, partial: False + branchmerge: True, force: False, partial: False ancestor: 924404dff337, local: e300d1c794ec+, remote: 49b6d8032493 a: remote moved to b -> m preserving a for resolve of b @@ -686,7 +686,7 @@ m "um a c" "um x c" " " "10 do merg src: 'a' -> dst: 'b' * checking for directory renames resolving manifests - overwrite: False, partial: False + branchmerge: True, force: False, partial: False ancestor: 924404dff337, local: 62e7bf090eba+, remote: f4db7e329e71 b: local copied/moved to a -> m preserving b for resolve of b @@ -724,7 +724,7 @@ m "nm a b" "um x a" " " "22 get a, src: 'a' -> dst: 'b' * checking for directory renames resolving manifests - overwrite: False, partial: False + branchmerge: True, force: False, partial: False ancestor: 924404dff337, local: 02963e448370+, remote: 2b958612230f b: local copied/moved to a -> m preserving b for resolve of b diff --git a/tests/test-subrepo.t b/tests/test-subrepo.t --- a/tests/test-subrepo.t +++ b/tests/test-subrepo.t @@ -203,7 +203,7 @@ merge tests $ hg merge 6 --debug # test change searching for copies back to rev 2 resolving manifests - overwrite: False, partial: False + branchmerge: True, force: False, partial: False ancestor: 1f14a2e2d3ec, local: f0d2028bf86d+, remote: 1831e14459c4 .hgsubstate: versions differ -> m updating: .hgsubstate 1/1 files (100.00%) @@ -212,7 +212,7 @@ merge tests getting subrepo t searching for copies back to rev 1 resolving manifests - overwrite: False, partial: False + branchmerge: False, force: False, partial: False ancestor: 60ca1237c194, local: 60ca1237c194+, remote: 6747d179aa9a t: remote is newer -> g updating: t 1/1 files (100.00%) @@ -232,7 +232,7 @@ merge tests $ HGMERGE=internal:merge hg merge --debug 7 # test conflict searching for copies back to rev 2 resolving manifests - overwrite: False, partial: False + branchmerge: True, force: False, partial: False ancestor: 1831e14459c4, local: e45c8b14af55+, remote: f94576341bcf .hgsubstate: versions differ -> m updating: .hgsubstate 1/1 files (100.00%) @@ -241,7 +241,7 @@ merge tests merging subrepo t searching for copies back to rev 2 resolving manifests - overwrite: False, partial: False + branchmerge: True, force: False, partial: False ancestor: 6747d179aa9a, local: 20a0db6fbf6c+, remote: 7af322bc1198 t: versions differ -> m preserving t for resolve of t diff --git a/tests/test-up-local-change.t b/tests/test-up-local-change.t --- a/tests/test-up-local-change.t +++ b/tests/test-up-local-change.t @@ -44,7 +44,7 @@ unmatched files in other: b resolving manifests - overwrite: False, partial: False + branchmerge: False, force: False, partial: False ancestor: c19d34741b0a, local: c19d34741b0a+, remote: 1e71731e6fbb a: versions differ -> m preserving a for resolve of a @@ -65,7 +65,7 @@ $ hg --debug up 0 resolving manifests - overwrite: False, partial: False + branchmerge: False, force: False, partial: False ancestor: 1e71731e6fbb, local: 1e71731e6fbb+, remote: c19d34741b0a b: other deleted -> r a: versions differ -> m @@ -98,7 +98,7 @@ unmatched files in other: b resolving manifests - overwrite: False, partial: False + branchmerge: False, force: False, partial: False ancestor: c19d34741b0a, local: c19d34741b0a+, remote: 1e71731e6fbb a: versions differ -> m preserving a for resolve of a @@ -176,7 +176,7 @@ create a second head $ hg --debug merge -f searching for copies back to rev 1 resolving manifests - overwrite: False, partial: False + branchmerge: True, force: True, partial: False ancestor: c19d34741b0a, local: 1e71731e6fbb+, remote: 83c51d0caff4 a: versions differ -> m preserving a for resolve of a diff --git a/tests/test-update-reverse.t b/tests/test-update-reverse.t --- a/tests/test-update-reverse.t +++ b/tests/test-update-reverse.t @@ -66,7 +66,7 @@ $ hg update --debug -C 1 resolving manifests - overwrite: True, partial: False + branchmerge: False, force: True, partial: False ancestor: 91ebc10ed028+, local: 91ebc10ed028+, remote: 71a760306caf side1: other deleted -> r side2: other deleted -> r From mercurial-bugs at selenic.com Sat Feb 9 04:50:57 2013 From: mercurial-bugs at selenic.com (mercurial-bugs at selenic.com) Date: Sat, 09 Feb 2013 10:50:57 +0000 Subject: [Bug 3813] New: rebase loses active bookmark Message-ID: http://bz.selenic.com/show_bug.cgi?id=3813 Priority: normal Bug ID: 3813 CC: mercurial-devel at selenic.com Assignee: bugzilla at selenic.com Summary: rebase loses active bookmark Severity: bug Classification: Unclassified OS: Mac OS Reporter: kbullock+mercurial at ringworld.org Hardware: PC Status: UNCONFIRMED Version: 2.5 Component: rebase Product: Mercurial I have a case where I'm on a bookmark behind the topological head, the head itself is another bookmark, and I've pulled some upstream changes that diverge from the topo-branch I'm on. Now I rebase my local changes (remember this includes -both- bookmarks, the further-back one is active). Rebase updates me to the tip and deletes .hg/bookmarks.current, leaving me with no active bookmark and sitting on a different change than I was on before. I have evolve enabled; not sure if this makes a difference or not. -- You are receiving this mail because: You are on the CC list for the bug. From angel.ezquerra at gmail.com Sat Feb 9 09:54:59 2013 From: angel.ezquerra at gmail.com (Angel Ezquerra) Date: Sat, 09 Feb 2013 16:54:59 +0100 Subject: [PATCH 0 of 3 V3 [NOW_WITH_DOCS!]] interhg: bring (most of the) extension functionality into core and remove the interhg extension Message-ID: I added some docs, which Kevin has kindly corrected for me. From angel.ezquerra at gmail.com Sat Feb 9 09:55:00 2013 From: angel.ezquerra at gmail.com (Angel Ezquerra) Date: Sat, 09 Feb 2013 16:55:00 +0100 Subject: [PATCH 1 of 3 V3 [NOW_WITH_DOCS!]] hgweb: add websub template filter In-Reply-To: References: Message-ID: <04299b2afc200171eeca.1360425300@Angel-PC.localdomain> # HG changeset patch # User Angel Ezquerra # Date 1360343132 -3600 # Node ID 04299b2afc200171eeca472c5d5644e84048a3b5 # Parent 766ad3e48bdff8ee2b2a3a9276eff398dcaafa02 hgweb: add websub template filter The purpose of this new filter is to make it possible to partially replace the functionality of the interhg extension. The idea is to be able to define regular expression based substitutions on a new "websub" config section. hgweb will then be able to apply these substitutions wherever the "websub" filter is used on a template. This first revision just adds the code necessary to load the websub expressions and adds the websub filter, but it does not add any calls to the websub filter itself on any of the templates. That will be done on the following revisions. diff --git a/mercurial/hgweb/hgweb_mod.py b/mercurial/hgweb/hgweb_mod.py --- a/mercurial/hgweb/hgweb_mod.py +++ b/mercurial/hgweb/hgweb_mod.py @@ -8,11 +8,14 @@ import os from mercurial import ui, hg, hook, error, encoding, templater, util, repoview +from mercurial.templatefilters import websub +from mercurial.i18n import _ from common import get_stat, ErrorResponse, permhooks, caching from common import HTTP_OK, HTTP_NOT_MODIFIED, HTTP_BAD_REQUEST from common import HTTP_NOT_FOUND, HTTP_SERVER_ERROR from request import wsgirequest -import webcommands, protocol, webutil +import webcommands, protocol, webutil, re + perms = { 'changegroup': 'pull', @@ -49,7 +52,6 @@ urlel = os.path.dirname(urlel) return reversed(breadcrumb) - class hgweb(object): def __init__(self, repo, name=None, baseui=None): if isinstance(repo, str): @@ -73,6 +75,7 @@ # a repo owner may set web.templates in .hg/hgrc to get any file # readable by the user running the CGI script self.templatepath = self.config('web', 'templates') + self.websubtable = self.loadwebsub() # The CGI scripts are often run by a user different from the repo owner. # Trust the settings from the .hg/hgrc files by default. @@ -258,6 +261,45 @@ return [''] return tmpl('error', error=inst.message) + def loadwebsub(self): + websubtable = [] + websubdefs = self.repo.ui.configitems('websub') + for key, pattern in websubdefs: + # grab the delimiter from the character after the "s" + unesc = pattern[1] + delim = re.escape(unesc) + + # identify portions of the pattern, taking care to avoid escaped + # delimiters. the replace format and flags are optional, but + # delimiters are required. + match = re.match( + r'^s%s(.+)(?:(?<=\\\\)|(? References: Message-ID: <3d1290c7131e8e1df991.1360425301@Angel-PC.localdomain> # HG changeset patch # User Angel Ezquerra # Date 1360424901 -3600 # Node ID 3d1290c7131e8e1df991f1753ab5e76d3e3cd21e # Parent 04299b2afc200171eeca472c5d5644e84048a3b5 hgweb: apply the websub filter to revision descriptions In order to use this, add a [websub] section to your configuration and add websub expressions such as: italic = s/\b_(\S+)_\b/\1<\/i>/ bold = s/\*\b(\S+)\b\*/\1<\/b>/ issues = s|issue(\d+)|issue\1|i bugzilla = s!((?:bug|b=|(?=#?\d{4,}))(?:\s*#?)(\d+))!\1!i This also adds documentation (proofed by Kevin!) to the config help section. diff --git a/mercurial/help/config.txt b/mercurial/help/config.txt --- a/mercurial/help/config.txt +++ b/mercurial/help/config.txt @@ -1463,3 +1463,36 @@ ``templates`` Where to find the HTML templates. Default is install path. + +``websub`` +------- + +Web substitution filter definition. You can use this section to +define a set of regular expression substitution patterns which +let you automatically modify the hgweb server output. + +The default hgweb templates only apply these substitution patterns +on the revision description fields. You can apply them anywhere +you want when you create your own templates by adding calls to the +"websub" filter (usually after calling the "escape" filter). + +This can be used, for example, to convert issue references to links +to your issue tracker, or to convert "markdown-like" syntax into +HTML (see the examples below). + +Each entry in this section names a substitution filter. +The value of each entry defines the substitution expression itself. +The websub expressions follow the old interhg extension syntax, +which in turn imitates the Unix sed replacement syntax:: + + pattername = s/SEARCH_REGEX/REPLACE_EXPRESSION/[i] + +You can use any separator other than "/". The final "i" is optional +and indicates that the search must be case insensitive. + +Examples:: + + [websub] + issues = s|issue(\d+)|issue\1|i + italic = s/\b_(\S+)_\b/\1<\/i>/ + bold = s/\*\b(\S+)\b\*/\1<\/b>/ diff --git a/mercurial/templates/gitweb/changelogentry.tmpl b/mercurial/templates/gitweb/changelogentry.tmpl --- a/mercurial/templates/gitweb/changelogentry.tmpl +++ b/mercurial/templates/gitweb/changelogentry.tmpl @@ -8,7 +8,7 @@ {author|obfuscate} [{date|rfc822date}] rev {rev}
    -{desc|strip|escape|addbreaks|nonempty} +{desc|strip|escape|websub|addbreaks|nonempty}

    diff --git a/mercurial/templates/gitweb/changeset.tmpl b/mercurial/templates/gitweb/changeset.tmpl --- a/mercurial/templates/gitweb/changeset.tmpl +++ b/mercurial/templates/gitweb/changeset.tmpl @@ -41,7 +41,7 @@
    -{desc|strip|escape|addbreaks|nonempty} +{desc|strip|escape|websub|addbreaks|nonempty}
    diff --git a/mercurial/templates/gitweb/fileannotate.tmpl b/mercurial/templates/gitweb/fileannotate.tmpl --- a/mercurial/templates/gitweb/fileannotate.tmpl +++ b/mercurial/templates/gitweb/fileannotate.tmpl @@ -56,7 +56,7 @@
    -{desc|strip|escape|addbreaks|nonempty} +{desc|strip|escape|websub|addbreaks|nonempty}
    diff --git a/mercurial/templates/gitweb/filerevision.tmpl b/mercurial/templates/gitweb/filerevision.tmpl --- a/mercurial/templates/gitweb/filerevision.tmpl +++ b/mercurial/templates/gitweb/filerevision.tmpl @@ -56,7 +56,7 @@
    -{desc|strip|escape|addbreaks|nonempty} +{desc|strip|escape|websub|addbreaks|nonempty}
    diff --git a/mercurial/templates/monoblue/changelogentry.tmpl b/mercurial/templates/monoblue/changelogentry.tmpl --- a/mercurial/templates/monoblue/changelogentry.tmpl +++ b/mercurial/templates/monoblue/changelogentry.tmpl @@ -2,5 +2,5 @@
    • {date|rfc822date}
    • by {author|obfuscate} [{date|rfc822date}] rev {rev}
    • -
    • {desc|strip|escape|addbreaks|nonempty}
    • +
    • {desc|strip|escape|websub|addbreaks|nonempty}
    diff --git a/mercurial/templates/monoblue/changeset.tmpl b/mercurial/templates/monoblue/changeset.tmpl --- a/mercurial/templates/monoblue/changeset.tmpl +++ b/mercurial/templates/monoblue/changeset.tmpl @@ -52,7 +52,7 @@ {child%changesetchild} -

    {desc|strip|escape|addbreaks|nonempty}

    +

    {desc|strip|escape|websub|addbreaks|nonempty}

    {files} diff --git a/mercurial/templates/monoblue/fileannotate.tmpl b/mercurial/templates/monoblue/fileannotate.tmpl --- a/mercurial/templates/monoblue/fileannotate.tmpl +++ b/mercurial/templates/monoblue/fileannotate.tmpl @@ -57,7 +57,7 @@
    {permissions|permissions}
    -

    {desc|strip|escape|addbreaks|nonempty}

    +

    {desc|strip|escape|websub|addbreaks|nonempty}

    {annotate%annotateline} diff --git a/mercurial/templates/monoblue/filerevision.tmpl b/mercurial/templates/monoblue/filerevision.tmpl --- a/mercurial/templates/monoblue/filerevision.tmpl +++ b/mercurial/templates/monoblue/filerevision.tmpl @@ -57,7 +57,7 @@
    {permissions|permissions}
    -

    {desc|strip|escape|addbreaks|nonempty}

    +

    {desc|strip|escape|websub|addbreaks|nonempty}

    {text%fileline} diff --git a/mercurial/templates/paper/changeset.tmpl b/mercurial/templates/paper/changeset.tmpl --- a/mercurial/templates/paper/changeset.tmpl +++ b/mercurial/templates/paper/changeset.tmpl @@ -40,7 +40,7 @@ files, or words in the commit message
    -
    {desc|strip|escape|nonempty}
    +
    {desc|strip|escape|websub|nonempty}
    diff --git a/mercurial/templates/paper/fileannotate.tmpl b/mercurial/templates/paper/fileannotate.tmpl --- a/mercurial/templates/paper/fileannotate.tmpl +++ b/mercurial/templates/paper/fileannotate.tmpl @@ -46,7 +46,7 @@ files, or words in the commit message -
    {desc|strip|escape|nonempty}
    +
    {desc|strip|escape|websub|nonempty}
    diff --git a/mercurial/templates/paper/filecomparison.tmpl b/mercurial/templates/paper/filecomparison.tmpl --- a/mercurial/templates/paper/filecomparison.tmpl +++ b/mercurial/templates/paper/filecomparison.tmpl @@ -45,7 +45,7 @@ files, or words in the commit message -
    {desc|strip|escape|nonempty}
    +
    {desc|strip|escape|websub|nonempty}
    diff --git a/mercurial/templates/paper/filediff.tmpl b/mercurial/templates/paper/filediff.tmpl --- a/mercurial/templates/paper/filediff.tmpl +++ b/mercurial/templates/paper/filediff.tmpl @@ -45,7 +45,7 @@ files, or words in the commit message -
    {desc|strip|escape|nonempty}
    +
    {desc|strip|escape|websub|nonempty}
    diff --git a/mercurial/templates/paper/filerevision.tmpl b/mercurial/templates/paper/filerevision.tmpl --- a/mercurial/templates/paper/filerevision.tmpl +++ b/mercurial/templates/paper/filerevision.tmpl @@ -44,7 +44,7 @@ files, or words in the commit message -
    {desc|strip|escape|nonempty}
    +
    {desc|strip|escape|websub|nonempty}
    diff --git a/mercurial/templates/spartan/changeset.tmpl b/mercurial/templates/spartan/changeset.tmpl --- a/mercurial/templates/spartan/changeset.tmpl +++ b/mercurial/templates/spartan/changeset.tmpl @@ -39,7 +39,7 @@ - +
    description:{desc|strip|escape|addbreaks|nonempty}{desc|strip|escape|websub|addbreaks|nonempty}
    diff --git a/mercurial/templates/spartan/fileannotate.tmpl b/mercurial/templates/spartan/fileannotate.tmpl --- a/mercurial/templates/spartan/fileannotate.tmpl +++ b/mercurial/templates/spartan/fileannotate.tmpl @@ -38,7 +38,7 @@ description: - {desc|strip|escape|addbreaks|nonempty} + {desc|strip|escape|websub|addbreaks|nonempty} diff --git a/mercurial/templates/spartan/filerevision.tmpl b/mercurial/templates/spartan/filerevision.tmpl --- a/mercurial/templates/spartan/filerevision.tmpl +++ b/mercurial/templates/spartan/filerevision.tmpl @@ -36,7 +36,7 @@ {permissions|permissions} description: - {desc|strip|escape|addbreaks|nonempty} + {desc|strip|escape|websub|addbreaks|nonempty} From angel.ezquerra at gmail.com Sat Feb 9 09:55:02 2013 From: angel.ezquerra at gmail.com (Angel Ezquerra) Date: Sat, 09 Feb 2013 16:55:02 +0100 Subject: [PATCH 3 of 3 V3 [NOW_WITH_DOCS!]] extensions: obsolete and remove interhg extension In-Reply-To: References: Message-ID: <6b18726f164093ab77ac.1360425302@Angel-PC.localdomain> # HG changeset patch # User Angel Ezquerra # Date 1360404042 -3600 # Node ID 6b18726f164093ab77ac754b088be2e90482b65c # Parent 3d1290c7131e8e1df991f1753ab5e76d3e3cd21e extensions: obsolete and remove interhg extension With the addition of the websub filter extension this extension is no longer needed. We maintain a sort of backwards compatibility by reading the [interhg] section and using it as we would use the [websub] section. diff --git a/mercurial/extensions.py b/mercurial/extensions.py --- a/mercurial/extensions.py +++ b/mercurial/extensions.py @@ -11,7 +11,7 @@ _extensions = {} _order = [] -_ignore = ['hbisect', 'bookmarks', 'parentrevspec'] +_ignore = ['hbisect', 'bookmarks', 'parentrevspec', 'interhg'] def extensions(): for name in _order: diff --git a/mercurial/hgweb/hgweb_mod.py b/mercurial/hgweb/hgweb_mod.py --- a/mercurial/hgweb/hgweb_mod.py +++ b/mercurial/hgweb/hgweb_mod.py @@ -8,6 +8,7 @@ import os from mercurial import ui, hg, hook, error, encoding, templater, util, repoview +from mercurial import extensions from mercurial.templatefilters import websub from mercurial.i18n import _ from common import get_stat, ErrorResponse, permhooks, caching @@ -264,6 +265,8 @@ def loadwebsub(self): websubtable = [] websubdefs = self.repo.ui.configitems('websub') + # we must maintain interhg backwards compatibility + websubdefs += self.repo.ui.configitems('interhg') for key, pattern in websubdefs: # grab the delimiter from the character after the "s" unesc = pattern[1] diff --git a/tests/test-interhg.t b/tests/test-websub.t rename from tests/test-interhg.t rename to tests/test-websub.t --- a/tests/test-interhg.t +++ b/tests/test-websub.t @@ -5,11 +5,15 @@ $ cat > .hg/hgrc < [extensions] + > # this is only necessary to check that the mapping from + > # interhg to websub works > interhg = > - > [interhg] + > [websub] > issues = s|Issue(\d+)|Issue\1| > + > [interhg] + > # check that we maintain some interhg backwards compatibility... > # yes, 'x' is a weird delimiter... > markbugs = sxbugxbugx > EOF @@ -23,9 +27,8 @@ log - $ "$TESTDIR/get-with-headers.py" localhost:$HGPORT '' | grep bts - Issue123: fixed the bug!default tip - + $ "$TESTDIR/get-with-headers.py" localhost:$HGPORT "rev/tip" | grep bts +
    Issue123: fixed the bug!
    errors $ cat errors.log From bos at serpentine.com Sat Feb 9 10:00:23 2013 From: bos at serpentine.com (Bryan O'Sullivan) Date: Sat, 9 Feb 2013 08:00:23 -0800 Subject: [PATCH 4 of 4 V3] manifestmerge: handle abort on local unknown, remote created files In-Reply-To: References: Message-ID: On Sat, Feb 9, 2013 at 7:48 AM, Siddharth Agarwal wrote: > manifestmerge: handle abort on local unknown, remote created files > Series crewed, thanks. -------------- next part -------------- An HTML attachment was scrubbed... URL: From natosha at unity3d.com Sat Feb 9 10:06:03 2013 From: natosha at unity3d.com (natosha at unity3d.com) Date: Sat, 09 Feb 2013 16:06:03 +0000 Subject: [PATCH] largefiles: fix test and check code Message-ID: # HG changeset patch # User Na'Tosha Bard # Date 1360425721 0 # Node ID ccdd9920f705df682210edc2b222e3fba236e539 # Parent 42691426804311ace53611264cb3ed5f7da176d3 largefiles: fix test and check code diff -r 426914268043 -r ccdd9920f705 hgext/largefiles/overrides.py --- a/hgext/largefiles/overrides.py Sat Feb 09 15:08:21 2013 +0000 +++ b/hgext/largefiles/overrides.py Sat Feb 09 16:02:01 2013 +0000 @@ -739,7 +739,7 @@ heads = lfutil.getcurrentheads(repo) newheads = set(heads).difference(set(oldheads)) if len(newheads) > 0: - ui.status(_("caching largefiles for %s heads\n" % len(newheads))) + ui.status(_("caching largefiles for %s heads\n") % len(newheads)) for head in newheads: (cached, missing) = lfcommands.cachelfiles(ui, repo, head) numcached += len(cached) diff -r 426914268043 -r ccdd9920f705 tests/test-largefiles-cache.t --- a/tests/test-largefiles-cache.t Sat Feb 09 15:08:21 2013 +0000 +++ b/tests/test-largefiles-cache.t Sat Feb 09 16:02:01 2013 +0000 @@ -37,7 +37,7 @@ adding file changes added 1 changesets with 1 changes to 1 files (run 'hg update' to get a working copy) - caching new largefiles + caching largefiles for 1 heads 0 largefiles cached Update working directory to "tip", which requires largefile("large"), From raf at durin42.com Sat Feb 9 10:06:46 2013 From: raf at durin42.com (Augie Fackler) Date: Sat, 9 Feb 2013 16:06:46 +0000 Subject: [PATCH] largefiles: fix test and check code In-Reply-To: References: Message-ID: <6BAD27FB-05AD-4C85-A67A-D924DA05E693@durin42.com> queued, thanks On Feb 9, 2013, at 4:06 PM, natosha at unity3d.com wrote: > # HG changeset patch > # User Na'Tosha Bard > # Date 1360425721 0 > # Node ID ccdd9920f705df682210edc2b222e3fba236e539 > # Parent 42691426804311ace53611264cb3ed5f7da176d3 > largefiles: fix test and check code > > diff -r 426914268043 -r ccdd9920f705 hgext/largefiles/overrides.py > --- a/hgext/largefiles/overrides.py Sat Feb 09 15:08:21 2013 +0000 > +++ b/hgext/largefiles/overrides.py Sat Feb 09 16:02:01 2013 +0000 > @@ -739,7 +739,7 @@ > heads = lfutil.getcurrentheads(repo) > newheads = set(heads).difference(set(oldheads)) > if len(newheads) > 0: > - ui.status(_("caching largefiles for %s heads\n" % len(newheads))) > + ui.status(_("caching largefiles for %s heads\n") % len(newheads)) > for head in newheads: > (cached, missing) = lfcommands.cachelfiles(ui, repo, head) > numcached += len(cached) > diff -r 426914268043 -r ccdd9920f705 tests/test-largefiles-cache.t > --- a/tests/test-largefiles-cache.t Sat Feb 09 15:08:21 2013 +0000 > +++ b/tests/test-largefiles-cache.t Sat Feb 09 16:02:01 2013 +0000 > @@ -37,7 +37,7 @@ > adding file changes > added 1 changesets with 1 changes to 1 files > (run 'hg update' to get a working copy) > - caching new largefiles > + caching largefiles for 1 heads > 0 largefiles cached > > Update working directory to "tip", which requires largefile("large"), From mercurial-bugs at selenic.com Sat Feb 9 05:17:16 2013 From: mercurial-bugs at selenic.com (mercurial-bugs at selenic.com) Date: Sat, 09 Feb 2013 11:17:16 +0000 Subject: [Bug 3814] New: hg outgoing fails when no changes and hidden changesets present Message-ID: http://bz.selenic.com/show_bug.cgi?id=3814 Priority: normal Bug ID: 3814 CC: mercurial-devel at selenic.com Assignee: pierre-yves.david at logilab.fr Summary: hg outgoing fails when no changes and hidden changesets present Severity: bug Classification: Unclassified OS: Linux Reporter: bboissin at gmail.com Hardware: PC Status: UNCONFIRMED Version: unspecified Component: evolution Product: Mercurial repro 52533 cd /tmp/ 52534 hg clone http://hg.intevation.org/mercurial/crew 52535 hg clone crew crew2 52536 cd crew2/ 52537 vi Makefile 52538 echo foo >> Makefile 52539 hg commit 52540 echo foo >> Makefile 52541 reset 52542 echo foo >> Makefile 52543 hg commit --amend 52544 hg push ../crew 52545 hg out fails with: bboissin at bboissin:/tmp/crew2$ hg out comparing with /tmp/crew searching for changes abort: unknown revision 'd7605dcb064705ce7daef508eeaed3764545c8b6'! -- You are receiving this mail because: You are on the CC list for the bug. From danchr at gmail.com Sat Feb 9 10:38:09 2013 From: danchr at gmail.com (Dan Villiom Podlaski Christiansen) Date: Sat, 09 Feb 2013 16:38:09 +0000 Subject: [PATCH 0 of 4] hgweb HTML help Message-ID: Hi, Slightly simplified queue; this one just gets us to the point where we generate HTML documentation. - Dan From danchr at gmail.com Sat Feb 9 10:38:10 2013 From: danchr at gmail.com (Dan Villiom Podlaski Christiansen) Date: Sat, 09 Feb 2013 16:38:10 +0000 Subject: [PATCH 1 of 4] hgweb help: add tests In-Reply-To: References: Message-ID: <981484b29c145cfd130a.1360427890@s0-0.paconsult7.bbnplanet.net> # HG changeset patch # User Dan Villiom Podlaski Christiansen # Date 1360427850 0 # Node ID 981484b29c145cfd130a5264d1c6391ef34882c7 # Parent 26627c30735a610f59979a36885b327b25d8dbff hgweb help: add tests diff --git a/tests/test-help.t b/tests/test-help.t --- a/tests/test-help.t +++ b/tests/test-help.t @@ -876,3 +876,396 @@ Test usage of section marks in help docu $ cd "$TESTDIR"/../doc $ python check-seclevel.py + +#if serve + +Test the help pages in hgweb. + +Dish up an empty repo; serve it cold. + + $ hg init "$TESTTMP/test" + $ hg serve -R "$TESTTMP/test" -n test -p $HGPORT -d --pid-file=hg.pid + $ cat hg.pid >> $DAEMON_PIDS + + $ "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT "help" + 200 Script output follows + + + + + + + + + + Help: Index + + + +
    + + +
    + + + + + + + + + + + +

    Topics

    configConfiguration Files
    datesDate Formats
    diffsDiff Formats
    environmentEnvironment Variables
    extensionsUsing Additional Features
    filesetsSpecifying File Sets
    glossaryGlossary
    hgignoreSyntax for Mercurial Ignore Files
    hgwebConfiguring hgweb
    merge-toolsMerge Tools
    multirevsSpecifying Multiple Revisions
    patternsFile Name Patterns
    phasesWorking with Phases
    revisionsSpecifying Single Revisions
    revsetsSpecifying Revision Sets
    subreposSubrepositories
    templatingTemplate Usage
    urlsURL Paths
    topic-containing-verboseThis is the topic to test omit indicating.

    Main Commands

    addadd the specified files on the next commit
    annotateshow changeset information by line for each file
    clonemake a copy of an existing repository
    commitcommit the specified files or all outstanding changes
    diffdiff repository (or selected files)
    exportdump the header and diffs for one or more changesets
    forgetforget the specified files on the next commit
    initcreate a new repository in the given directory
    logshow revision history of entire repository or files
    mergemerge working directory with another revision
    pullpull changes from the specified source
    pushpush changes to the specified destination
    removeremove the specified files on the next commit
    servestart stand-alone webserver
    statusshow changed files in the working directory
    summarysummarize working directory state
    updateupdate working directory (or switch revisions)

    Other Commands

    addremoveadd all new files, delete all missing files
    archivecreate an unversioned archive of a repository revision
    backoutreverse effect of earlier changeset
    bisectsubdivision search of changesets
    bookmarkstrack a line of development with movable markers
    branchset or show the current branch name
    brancheslist repository named branches
    bundlecreate a changegroup file
    catoutput the current or given revision of files
    copymark files as copied for the next commit
    graftcopy changes from other branches onto the current branch
    grepsearch for a pattern in specified files and revisions
    headsshow current repository heads or show branch heads
    helpshow help for a given topic or a help overview
    identifyidentify the working copy or specified revision
    importimport an ordered set of patches
    incomingshow new changesets found in source
    locatelocate files matching specific patterns
    manifestoutput the current or given revision of the project manifest
    nohelp(no help text available)
    outgoingshow changesets not found in the destination
    parentsshow the parents of the working directory or revision
    pathsshow aliases for remote repositories
    phaseset or show the current phase name
    recoverroll back an interrupted transaction
    renamerename files; equivalent of copy + remove
    resolveredo merges or set/view the merge status of files
    revertrestore files to their checkout state
    rollbackroll back the last transaction (dangerous)
    rootprint the root (top) of the current working directory
    showconfigshow combined config settings from all hgrc files
    tagadd one or more tags for the current or given revision
    tagslist repository tags
    tipshow the tip revision
    unbundleapply one or more changegroup files
    verifyverify the integrity of the repository
    versionoutput version and copyright information
    +
    +
    + + + + + + + + + $ "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT "help/add" + 200 Script output follows + + + + + + + + + + Help: add + + + +
    + + +
    + +

    Help: add

    + + +
    +  hg add [OPTION]... [FILE]...
    +  
    +  add the specified files on the next commit
    +  
    +      Schedule files to be version controlled and added to the repository.
    +  
    +      The files will be added to the repository at the next commit. To undo an
    +      add before that, see "hg forget".
    +  
    +      If no names are given, add all files to the repository.
    +  
    +      An example showing how new (unknown) files are added automatically by "hg
    +      add":
    +  
    +        $ ls
    +        foo.c
    +        $ hg status
    +        ? foo.c
    +        $ hg add
    +        adding foo.c
    +        $ hg status
    +        A foo.c
    +  
    +      Returns 0 if all files are successfully added.
    +  
    +  options:
    +  
    +   -I --include PATTERN [+] include names matching the given patterns
    +   -X --exclude PATTERN [+] exclude names matching the given patterns
    +   -S --subrepos            recurse into subrepositories
    +   -n --dry-run             do not perform actions, just print output
    +  
    +  [+] marked option can be specified multiple times
    +  
    +  global options:
    +  
    +   -R --repository REPO   repository root directory or name of overlay bundle
    +                          file
    +      --cwd DIR           change working directory
    +   -y --noninteractive    do not prompt, automatically pick the first choice for
    +                          all prompts
    +   -q --quiet             suppress output
    +   -v --verbose           enable additional output
    +      --config CONFIG [+] set/override config option (use 'section.name=value')
    +      --debug             enable debugging output
    +      --debugger          start debugger
    +      --encoding ENCODE   set the charset encoding (default: ascii)
    +      --encodingmode MODE set the charset encoding mode (default: strict)
    +      --traceback         always print a traceback on exception
    +      --time              time how long the command takes
    +      --profile           print command execution profile
    +      --version           output version information and exit
    +   -h --help              display help and exit
    +      --hidden            consider hidden changesets
    +  
    +  [+] marked option can be specified multiple times
    +  
    +  
    +
    +
    + + + + + + + + + $ "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT "help/remove" + 200 Script output follows + + + + + + + + + + Help: remove + + + +
    + + +
    + +

    Help: remove

    + + +
    +  hg remove [OPTION]... FILE...
    +  
    +  aliases: rm
    +  
    +  remove the specified files on the next commit
    +  
    +      Schedule the indicated files for removal from the current branch.
    +  
    +      This command schedules the files to be removed at the next commit. To undo
    +      a remove before that, see "hg revert". To undo added files, see "hg
    +      forget".
    +  
    +      -A/--after can be used to remove only files that have already been
    +      deleted, -f/--force can be used to force deletion, and -Af can be used to
    +      remove files from the next revision without deleting them from the working
    +      directory.
    +  
    +      The following table details the behavior of remove for different file
    +      states (columns) and option combinations (rows). The file states are Added
    +      [A], Clean [C], Modified [M] and Missing [!] (as reported by "hg status").
    +      The actions are Warn, Remove (from branch) and Delete (from disk):
    +  
    +           A C  M  !
    +      --------------
    +      none W RD W  R
    +      -f   R RD RD R
    +      -A   W W  W  R
    +      -Af  R R  R  R
    +  
    +      Note that remove never deletes files in Added [A] state from the working
    +      directory, not even if option --force is specified.
    +  
    +      Returns 0 on success, 1 if any warnings encountered.
    +  
    +  options:
    +  
    +   -A --after               record delete for missing files
    +   -f --force               remove (and delete) file even if added or modified
    +   -I --include PATTERN [+] include names matching the given patterns
    +   -X --exclude PATTERN [+] exclude names matching the given patterns
    +  
    +  [+] marked option can be specified multiple times
    +  
    +  global options:
    +  
    +   -R --repository REPO   repository root directory or name of overlay bundle
    +                          file
    +      --cwd DIR           change working directory
    +   -y --noninteractive    do not prompt, automatically pick the first choice for
    +                          all prompts
    +   -q --quiet             suppress output
    +   -v --verbose           enable additional output
    +      --config CONFIG [+] set/override config option (use 'section.name=value')
    +      --debug             enable debugging output
    +      --debugger          start debugger
    +      --encoding ENCODE   set the charset encoding (default: ascii)
    +      --encodingmode MODE set the charset encoding mode (default: strict)
    +      --traceback         always print a traceback on exception
    +      --time              time how long the command takes
    +      --profile           print command execution profile
    +      --version           output version information and exit
    +   -h --help              display help and exit
    +      --hidden            consider hidden changesets
    +  
    +  [+] marked option can be specified multiple times
    +  
    +  
    +
    +
    + + + + + + + + + $ "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT "help/revisions" + 200 Script output follows + + + + + + + + + + Help: revisions + + + +
    + + +
    + +

    Help: revisions

    + + +
    +  Specifying Single Revisions
    +  
    +      Mercurial supports several ways to specify individual revisions.
    +  
    +      A plain integer is treated as a revision number. Negative integers are
    +      treated as sequential offsets from the tip, with -1 denoting the tip, -2
    +      denoting the revision prior to the tip, and so forth.
    +  
    +      A 40-digit hexadecimal string is treated as a unique revision identifier.
    +  
    +      A hexadecimal string less than 40 characters long is treated as a unique
    +      revision identifier and is referred to as a short-form identifier. A
    +      short-form identifier is only valid if it is the prefix of exactly one
    +      full-length identifier.
    +  
    +      Any other string is treated as a bookmark, tag, or branch name. A bookmark
    +      is a movable pointer to a revision. A tag is a permanent name associated
    +      with a revision. A branch name denotes the tipmost revision of that
    +      branch. Bookmark, tag, and branch names must not contain the ":"
    +      character.
    +  
    +      The reserved name "tip" always identifies the most recent revision.
    +  
    +      The reserved name "null" indicates the null revision. This is the revision
    +      of an empty repository, and the parent of revision 0.
    +  
    +      The reserved name "." indicates the working directory parent. If no
    +      working directory is checked out, it is equivalent to null. If an
    +      uncommitted merge is in progress, "." is the revision of the first parent.
    +  
    +  
    +
    +
    + + + + + + + + + $ "$TESTDIR/killdaemons.py" $DAEMON_PIDS + +#endif From danchr at gmail.com Sat Feb 9 10:38:11 2013 From: danchr at gmail.com (Dan Villiom Podlaski Christiansen) Date: Sat, 09 Feb 2013 16:38:11 +0000 Subject: [PATCH 2 of 4] hgweb help: split up long lines (in generated output) In-Reply-To: References: Message-ID: <1ea8fc4fdd4969e1d500.1360427891@s0-0.paconsult7.bbnplanet.net> # HG changeset patch # User Dan Villiom Podlaski Christiansen # Date 1360427850 0 # Node ID 1ea8fc4fdd4969e1d500169bc6f79dca8c49313f # Parent 981484b29c145cfd130a5264d1c6391ef34882c7 hgweb help: split up long lines (in generated output) diff --git a/mercurial/templates/coal/map b/mercurial/templates/coal/map --- a/mercurial/templates/coal/map +++ b/mercurial/templates/coal/map @@ -13,7 +13,14 @@ graph = ../paper/graph.tmpl help = ../paper/help.tmpl helptopics = ../paper/helptopics.tmpl -helpentry = '{topic|escape}{summary|escape}' +helpentry = ' + + + {topic|escape} + + + {summary|escape} + ' naventry = '{label|escape} ' navshortentry = '{label|escape} ' diff --git a/mercurial/templates/gitweb/map b/mercurial/templates/gitweb/map --- a/mercurial/templates/gitweb/map +++ b/mercurial/templates/gitweb/map @@ -11,7 +11,14 @@ notfound = notfound.tmpl help = help.tmpl helptopics = helptopics.tmpl -helpentry = '{topic|escape}{summary|escape}' +helpentry = ' + + + {topic|escape} + + + {summary|escape} + ' naventry = '{label|escape} ' navshortentry = '{label|escape} ' diff --git a/mercurial/templates/monoblue/map b/mercurial/templates/monoblue/map --- a/mercurial/templates/monoblue/map +++ b/mercurial/templates/monoblue/map @@ -11,7 +11,14 @@ notfound = notfound.tmpl help = help.tmpl helptopics = helptopics.tmpl -helpentry = '{topic|escape}{summary|escape}' +helpentry = ' + + + {topic|escape} + + + {summary|escape} + ' naventry = '{label|escape} ' navshortentry = '{label|escape} ' diff --git a/mercurial/templates/paper/map b/mercurial/templates/paper/map --- a/mercurial/templates/paper/map +++ b/mercurial/templates/paper/map @@ -12,7 +12,14 @@ graph = graph.tmpl help = help.tmpl helptopics = helptopics.tmpl -helpentry = '{topic|escape}{summary|escape}' +helpentry = ' + + + {topic|escape} + + + {summary|escape} + ' naventry = '{label|escape} ' navshortentry = '{label|escape} ' diff --git a/tests/test-help.t b/tests/test-help.t --- a/tests/test-help.t +++ b/tests/test-help.t @@ -930,13 +930,524 @@ Dish up an empty repo; serve it cold. - + + + + + + + + + + + + + + + + + + + + - + + + + + + + + + + + + + + + + + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    Topics

    configConfiguration Files
    datesDate Formats
    diffsDiff Formats
    environmentEnvironment Variables
    extensionsUsing Additional Features
    filesetsSpecifying File Sets
    glossaryGlossary
    hgignoreSyntax for Mercurial Ignore Files
    hgwebConfiguring hgweb
    merge-toolsMerge Tools
    multirevsSpecifying Multiple Revisions
    patternsFile Name Patterns
    phasesWorking with Phases
    revisionsSpecifying Single Revisions
    revsetsSpecifying Revision Sets
    subreposSubrepositories
    templatingTemplate Usage
    urlsURL Paths
    topic-containing-verboseThis is the topic to test omit indicating.
    + + config + + + Configuration Files +
    + + dates + + + Date Formats +
    + + diffs + + + Diff Formats +
    + + environment + + + Environment Variables +
    + + extensions + + + Using Additional Features +
    + + filesets + + + Specifying File Sets +
    + + glossary + + + Glossary +
    + + hgignore + + + Syntax for Mercurial Ignore Files +
    + + hgweb + + + Configuring hgweb +
    + + merge-tools + + + Merge Tools +
    + + multirevs + + + Specifying Multiple Revisions +
    + + patterns + + + File Name Patterns +
    + + phases + + + Working with Phases +
    + + revisions + + + Specifying Single Revisions +
    + + revsets + + + Specifying Revision Sets +
    + + subrepos + + + Subrepositories +
    + + templating + + + Template Usage +
    + + urls + + + URL Paths +
    + + topic-containing-verbose + + + This is the topic to test omit indicating. +

    Main Commands

    addadd the specified files on the next commit
    annotateshow changeset information by line for each file
    clonemake a copy of an existing repository
    commitcommit the specified files or all outstanding changes
    diffdiff repository (or selected files)
    exportdump the header and diffs for one or more changesets
    forgetforget the specified files on the next commit
    initcreate a new repository in the given directory
    logshow revision history of entire repository or files
    mergemerge working directory with another revision
    pullpull changes from the specified source
    pushpush changes to the specified destination
    removeremove the specified files on the next commit
    servestart stand-alone webserver
    statusshow changed files in the working directory
    summarysummarize working directory state
    updateupdate working directory (or switch revisions)
    + + add + + + add the specified files on the next commit +
    + + annotate + + + show changeset information by line for each file +
    + + clone + + + make a copy of an existing repository +
    + + commit + + + commit the specified files or all outstanding changes +
    + + diff + + + diff repository (or selected files) +
    + + export + + + dump the header and diffs for one or more changesets +
    + + forget + + + forget the specified files on the next commit +
    + + init + + + create a new repository in the given directory +
    + + log + + + show revision history of entire repository or files +
    + + merge + + + merge working directory with another revision +
    + + pull + + + pull changes from the specified source +
    + + push + + + push changes to the specified destination +
    + + remove + + + remove the specified files on the next commit +
    + + serve + + + start stand-alone webserver +
    + + status + + + show changed files in the working directory +
    + + summary + + + summarize working directory state +
    + + update + + + update working directory (or switch revisions) +

    Other Commands

    addremoveadd all new files, delete all missing files
    archivecreate an unversioned archive of a repository revision
    backoutreverse effect of earlier changeset
    bisectsubdivision search of changesets
    bookmarkstrack a line of development with movable markers
    branchset or show the current branch name
    brancheslist repository named branches
    bundlecreate a changegroup file
    catoutput the current or given revision of files
    copymark files as copied for the next commit
    graftcopy changes from other branches onto the current branch
    grepsearch for a pattern in specified files and revisions
    headsshow current repository heads or show branch heads
    helpshow help for a given topic or a help overview
    identifyidentify the working copy or specified revision
    importimport an ordered set of patches
    incomingshow new changesets found in source
    locatelocate files matching specific patterns
    manifestoutput the current or given revision of the project manifest
    nohelp(no help text available)
    outgoingshow changesets not found in the destination
    parentsshow the parents of the working directory or revision
    pathsshow aliases for remote repositories
    phaseset or show the current phase name
    recoverroll back an interrupted transaction
    renamerename files; equivalent of copy + remove
    resolveredo merges or set/view the merge status of files
    revertrestore files to their checkout state
    rollbackroll back the last transaction (dangerous)
    rootprint the root (top) of the current working directory
    showconfigshow combined config settings from all hgrc files
    tagadd one or more tags for the current or given revision
    tagslist repository tags
    tipshow the tip revision
    unbundleapply one or more changegroup files
    verifyverify the integrity of the repository
    versionoutput version and copyright information
    + + addremove + + + add all new files, delete all missing files +
    + + archive + + + create an unversioned archive of a repository revision +
    + + backout + + + reverse effect of earlier changeset +
    + + bisect + + + subdivision search of changesets +
    + + bookmarks + + + track a line of development with movable markers +
    + + branch + + + set or show the current branch name +
    + + branches + + + list repository named branches +
    + + bundle + + + create a changegroup file +
    + + cat + + + output the current or given revision of files +
    + + copy + + + mark files as copied for the next commit +
    + + graft + + + copy changes from other branches onto the current branch +
    + + grep + + + search for a pattern in specified files and revisions +
    + + heads + + + show current repository heads or show branch heads +
    + + help + + + show help for a given topic or a help overview +
    + + identify + + + identify the working copy or specified revision +
    + + import + + + import an ordered set of patches +
    + + incoming + + + show new changesets found in source +
    + + locate + + + locate files matching specific patterns +
    + + manifest + + + output the current or given revision of the project manifest +
    + + nohelp + + + (no help text available) +
    + + outgoing + + + show changesets not found in the destination +
    + + parents + + + show the parents of the working directory or revision +
    + + paths + + + show aliases for remote repositories +
    + + phase + + + set or show the current phase name +
    + + recover + + + roll back an interrupted transaction +
    + + rename + + + rename files; equivalent of copy + remove +
    + + resolve + + + redo merges or set/view the merge status of files +
    + + revert + + + restore files to their checkout state +
    + + rollback + + + roll back the last transaction (dangerous) +
    + + root + + + print the root (top) of the current working directory +
    + + showconfig + + + show combined config settings from all hgrc files +
    + + tag + + + add one or more tags for the current or given revision +
    + + tags + + + list repository tags +
    + + tip + + + show the tip revision +
    + + unbundle + + + apply one or more changegroup files +
    + + verify + + + verify the integrity of the repository +
    + + version + + + output version and copyright information +
    From danchr at gmail.com Sat Feb 9 10:38:12 2013 From: danchr at gmail.com (Dan Villiom Podlaski Christiansen) Date: Sat, 09 Feb 2013 16:38:12 +0000 Subject: [PATCH 3 of 4] help: move the majority of the help command to the help module In-Reply-To: References: Message-ID: <469bcaf06fbc95a0384e.1360427892@s0-0.paconsult7.bbnplanet.net> # HG changeset patch # User Dan Villiom Podlaski Christiansen # Date 1360427850 0 # Node ID 469bcaf06fbc95a0384eea2d5e5a495e0e861745 # Parent 1ea8fc4fdd4969e1d500169bc6f79dca8c49313f help: move the majority of the help command to the help module We move the logic for generating the unformatted ReST source to the help module, in order to eventually avoid calling commands.help_() from hgweb. No functionality change. diff --git a/mercurial/commands.py b/mercurial/commands.py --- a/mercurial/commands.py +++ b/mercurial/commands.py @@ -7,9 +7,9 @@ from node import hex, bin, nullid, nullrev, short from lock import release -from i18n import _, gettext +from i18n import _ import os, re, difflib, time, tempfile, errno -import hg, scmutil, util, revlog, extensions, copies, error, bookmarks +import hg, scmutil, util, revlog, copies, error, bookmarks import patch, help, encoding, templatekw, discovery import archival, changegroup, cmdutil, hbisect import sshserver, hgweb, hgweb.server, commandserver @@ -3253,7 +3253,7 @@ def heads(ui, repo, *branchrevs, **opts) ('k', 'keyword', '', _('show topics matching keyword')), ], _('[-ec] [TOPIC]')) -def help_(ui, name=None, unknowncmd=False, full=True, **opts): +def help_(ui, name=None, **opts): """show help for a given topic or a help overview With no arguments, print a list of commands with short help messages. @@ -3266,291 +3266,9 @@ def help_(ui, name=None, unknowncmd=Fals textwidth = min(ui.termwidth(), 80) - 2 - def helpcmd(name): - try: - aliases, entry = cmdutil.findcmd(name, table, strict=unknowncmd) - except error.AmbiguousCommand, inst: - # py3k fix: except vars can't be used outside the scope of the - # except block, nor can be used inside a lambda. python issue4617 - prefix = inst.args[0] - select = lambda c: c.lstrip('^').startswith(prefix) - rst = helplist(select) - return rst - - rst = [] - - # check if it's an invalid alias and display its error if it is - if getattr(entry[0], 'badalias', False): - if not unknowncmd: - ui.pushbuffer() - entry[0](ui) - rst.append(ui.popbuffer()) - return rst - - # synopsis - if len(entry) > 2: - if entry[2].startswith('hg'): - rst.append("%s\n" % entry[2]) - else: - rst.append('hg %s %s\n' % (aliases[0], entry[2])) - else: - rst.append('hg %s\n' % aliases[0]) - # aliases - if full and not ui.quiet and len(aliases) > 1: - rst.append(_("\naliases: %s\n") % ', '.join(aliases[1:])) - rst.append('\n') - - # description - doc = gettext(entry[0].__doc__) - if not doc: - doc = _("(no help text available)") - if util.safehasattr(entry[0], 'definition'): # aliased command - if entry[0].definition.startswith('!'): # shell alias - doc = _('shell alias for::\n\n %s') % entry[0].definition[1:] - else: - doc = _('alias for: hg %s\n\n%s') % (entry[0].definition, doc) - doc = doc.splitlines(True) - if ui.quiet or not full: - rst.append(doc[0]) - else: - rst.extend(doc) - rst.append('\n') - - # check if this command shadows a non-trivial (multi-line) - # extension help text - try: - mod = extensions.find(name) - doc = gettext(mod.__doc__) or '' - if '\n' in doc.strip(): - msg = _('use "hg help -e %s" to show help for ' - 'the %s extension') % (name, name) - rst.append('\n%s\n' % msg) - except KeyError: - pass - - # options - if not ui.quiet and entry[1]: - rst.append('\n%s\n\n' % _("options:")) - rst.append(help.optrst(entry[1], ui.verbose)) - - if ui.verbose: - rst.append('\n%s\n\n' % _("global options:")) - rst.append(help.optrst(globalopts, ui.verbose)) - - if not ui.verbose: - if not full: - rst.append(_('\nuse "hg help %s" to show the full help text\n') - % name) - elif not ui.quiet: - omitted = _('use "hg -v help %s" to show more complete' - ' help and the global options') % name - notomitted = _('use "hg -v help %s" to show' - ' the global options') % name - help.indicateomitted(rst, omitted, notomitted) - - return rst - - - def helplist(select=None): - # list of commands - if name == "shortlist": - header = _('basic commands:\n\n') - else: - header = _('list of commands:\n\n') - - h = {} - cmds = {} - for c, e in table.iteritems(): - f = c.split("|", 1)[0] - if select and not select(f): - continue - if (not select and name != 'shortlist' and - e[0].__module__ != __name__): - continue - if name == "shortlist" and not f.startswith("^"): - continue - f = f.lstrip("^") - if not ui.debugflag and f.startswith("debug"): - continue - doc = e[0].__doc__ - if doc and 'DEPRECATED' in doc and not ui.verbose: - continue - doc = gettext(doc) - if not doc: - doc = _("(no help text available)") - h[f] = doc.splitlines()[0].rstrip() - cmds[f] = c.lstrip("^") - - rst = [] - if not h: - if not ui.quiet: - rst.append(_('no commands defined\n')) - return rst - - if not ui.quiet: - rst.append(header) - fns = sorted(h) - for f in fns: - if ui.verbose: - commands = cmds[f].replace("|",", ") - rst.append(" :%s: %s\n" % (commands, h[f])) - else: - rst.append(' :%s: %s\n' % (f, h[f])) - - if not name: - exts = help.listexts(_('enabled extensions:'), extensions.enabled()) - if exts: - rst.append('\n') - rst.extend(exts) - - rst.append(_("\nadditional help topics:\n\n")) - topics = [] - for names, header, doc in help.helptable: - topics.append((names[0], header)) - for t, desc in topics: - rst.append(" :%s: %s\n" % (t, desc)) - - optlist = [] - if not ui.quiet: - if ui.verbose: - optlist.append((_("global options:"), globalopts)) - if name == 'shortlist': - optlist.append((_('use "hg help" for the full list ' - 'of commands'), ())) - else: - if name == 'shortlist': - msg = _('use "hg help" for the full list of commands ' - 'or "hg -v" for details') - elif name and not full: - msg = _('use "hg help %s" to show the full help ' - 'text') % name - else: - msg = _('use "hg -v help%s" to show builtin aliases and ' - 'global options') % (name and " " + name or "") - optlist.append((msg, ())) - - if optlist: - for title, options in optlist: - rst.append('\n%s\n' % title) - if options: - rst.append('\n%s\n' % help.optrst(options, ui.verbose)) - return rst - - def helptopic(name): - for names, header, doc in help.helptable: - if name in names: - break - else: - raise error.UnknownCommand(name) - - rst = ["%s\n\n" % header] - # description - if not doc: - rst.append(" %s\n" % _("(no help text available)")) - if util.safehasattr(doc, '__call__'): - rst += [" %s\n" % l for l in doc().splitlines()] - - if not ui.verbose: - omitted = (_('use "hg help -v %s" to show more complete help') % - name) - help.indicateomitted(rst, omitted) - - try: - cmdutil.findcmd(name, table) - rst.append(_('\nuse "hg help -c %s" to see help for ' - 'the %s command\n') % (name, name)) - except error.UnknownCommand: - pass - return rst - - def helpext(name): - try: - mod = extensions.find(name) - doc = gettext(mod.__doc__) or _('no help text available') - except KeyError: - mod = None - doc = extensions.disabledext(name) - if not doc: - raise error.UnknownCommand(name) - - if '\n' not in doc: - head, tail = doc, "" - else: - head, tail = doc.split('\n', 1) - rst = [_('%s extension - %s\n\n') % (name.split('.')[-1], head)] - if tail: - rst.extend(tail.splitlines(True)) - rst.append('\n') - - if not ui.verbose: - omitted = (_('use "hg help -v %s" to show more complete help') % - name) - help.indicateomitted(rst, omitted) - - if mod: - try: - ct = mod.cmdtable - except AttributeError: - ct = {} - modcmds = set([c.split('|', 1)[0] for c in ct]) - rst.extend(helplist(modcmds.__contains__)) - else: - rst.append(_('use "hg help extensions" for information on enabling ' - 'extensions\n')) - return rst - - def helpextcmd(name): - cmd, ext, mod = extensions.disabledcmd(ui, name, - ui.configbool('ui', 'strict')) - doc = gettext(mod.__doc__).splitlines()[0] - - rst = help.listexts(_("'%s' is provided by the following " - "extension:") % cmd, {ext: doc}, indent=4) - rst.append('\n') - rst.append(_('use "hg help extensions" for information on enabling ' - 'extensions\n')) - return rst - - - rst = [] - kw = opts.get('keyword') - if kw: - matches = help.topicmatch(kw) - for t, title in (('topics', _('Topics')), - ('commands', _('Commands')), - ('extensions', _('Extensions')), - ('extensioncommands', _('Extension Commands'))): - if matches[t]: - rst.append('%s:\n\n' % title) - rst.extend(minirst.maketable(sorted(matches[t]), 1)) - rst.append('\n') - elif name and name != 'shortlist': - i = None - if unknowncmd: - queries = (helpextcmd,) - elif opts.get('extension'): - queries = (helpext,) - elif opts.get('command'): - queries = (helpcmd,) - else: - queries = (helptopic, helpcmd, helpext, helpextcmd) - for f in queries: - try: - rst = f(name) - i = None - break - except error.UnknownCommand, inst: - i = inst - if i: - raise i - else: - # program name - if not ui.quiet: - rst = [_("Mercurial Distributed SCM\n"), '\n'] - rst.extend(helplist()) - keep = ui.verbose and ['verbose'] or [] - text = ''.join(rst) + text = help.help_(ui, name, **opts) + formatted, pruned = minirst.format(text, textwidth, keep=keep) if 'verbose' in pruned: keep.append('omitted') diff --git a/mercurial/help.py b/mercurial/help.py --- a/mercurial/help.py +++ b/mercurial/help.py @@ -6,9 +6,10 @@ # GNU General Public License version 2 or any later version. from i18n import gettext, _ -import itertools, sys, os +import itertools, sys, os, error import extensions, revset, fileset, templatekw, templatefilters, filemerge import encoding, util, minirst +import cmdutil def listexts(header, exts, indent=1): '''return a text listing of the given extensions''' @@ -206,3 +207,297 @@ addtopicsymbols('merge-tools', '.. inter addtopicsymbols('revsets', '.. predicatesmarker', revset.symbols) addtopicsymbols('templates', '.. keywordsmarker', templatekw.dockeywords) addtopicsymbols('templates', '.. filtersmarker', templatefilters.filters) + +def help_(ui, name, unknowncmd=False, full=True, **opts): + ''' + Generate the help for 'name' as unformatted restructured text. If + 'name' is None, describe the commands available. + ''' + + import commands # avoid cycle + + def helpcmd(name): + try: + aliases, entry = cmdutil.findcmd(name, commands.table, + strict=unknowncmd) + except error.AmbiguousCommand, inst: + # py3k fix: except vars can't be used outside the scope of the + # except block, nor can be used inside a lambda. python issue4617 + prefix = inst.args[0] + select = lambda c: c.lstrip('^').startswith(prefix) + rst = helplist(select) + return rst + + rst = [] + + # check if it's an invalid alias and display its error if it is + if getattr(entry[0], 'badalias', False): + if not unknowncmd: + ui.pushbuffer() + entry[0](ui) + rst.append(ui.popbuffer()) + return rst + + # synopsis + if len(entry) > 2: + if entry[2].startswith('hg'): + rst.append("%s\n" % entry[2]) + else: + rst.append('hg %s %s\n' % (aliases[0], entry[2])) + else: + rst.append('hg %s\n' % aliases[0]) + # aliases + if full and not ui.quiet and len(aliases) > 1: + rst.append(_("\naliases: %s\n") % ', '.join(aliases[1:])) + rst.append('\n') + + # description + doc = gettext(entry[0].__doc__) + if not doc: + doc = _("(no help text available)") + if util.safehasattr(entry[0], 'definition'): # aliased command + if entry[0].definition.startswith('!'): # shell alias + doc = _('shell alias for::\n\n %s') % entry[0].definition[1:] + else: + doc = _('alias for: hg %s\n\n%s') % (entry[0].definition, doc) + doc = doc.splitlines(True) + if ui.quiet or not full: + rst.append(doc[0]) + else: + rst.extend(doc) + rst.append('\n') + + # check if this command shadows a non-trivial (multi-line) + # extension help text + try: + mod = extensions.find(name) + doc = gettext(mod.__doc__) or '' + if '\n' in doc.strip(): + msg = _('use "hg help -e %s" to show help for ' + 'the %s extension') % (name, name) + rst.append('\n%s\n' % msg) + except KeyError: + pass + + # options + if not ui.quiet and entry[1]: + rst.append('\n%s\n\n' % _("options:")) + rst.append(optrst(entry[1], ui.verbose)) + + if ui.verbose: + rst.append('\n%s\n\n' % _("global options:")) + rst.append(optrst(commands.globalopts, ui.verbose)) + + if not ui.verbose: + if not full: + rst.append(_('\nuse "hg help %s" to show the full help text\n') + % name) + elif not ui.quiet: + omitted = _('use "hg -v help %s" to show more complete' + ' help and the global options') % name + notomitted = _('use "hg -v help %s" to show' + ' the global options') % name + indicateomitted(rst, omitted, notomitted) + + return rst + + + def helplist(select=None): + # list of commands + if name == "shortlist": + header = _('basic commands:\n\n') + else: + header = _('list of commands:\n\n') + + h = {} + cmds = {} + for c, e in commands.table.iteritems(): + f = c.split("|", 1)[0] + if select and not select(f): + continue + if (not select and name != 'shortlist' and + e[0].__module__ != commands.__name__): + continue + if name == "shortlist" and not f.startswith("^"): + continue + f = f.lstrip("^") + if not ui.debugflag and f.startswith("debug"): + continue + doc = e[0].__doc__ + if doc and 'DEPRECATED' in doc and not ui.verbose: + continue + doc = gettext(doc) + if not doc: + doc = _("(no help text available)") + h[f] = doc.splitlines()[0].rstrip() + cmds[f] = c.lstrip("^") + + rst = [] + if not h: + if not ui.quiet: + rst.append(_('no commands defined\n')) + return rst + + if not ui.quiet: + rst.append(header) + fns = sorted(h) + for f in fns: + if ui.verbose: + commacmds = cmds[f].replace("|",", ") + rst.append(" :%s: %s\n" % (commacmds, h[f])) + else: + rst.append(' :%s: %s\n' % (f, h[f])) + + if not name: + exts = listexts(_('enabled extensions:'), extensions.enabled()) + if exts: + rst.append('\n') + rst.extend(exts) + + rst.append(_("\nadditional help topics:\n\n")) + topics = [] + for names, header, doc in helptable: + topics.append((names[0], header)) + for t, desc in topics: + rst.append(" :%s: %s\n" % (t, desc)) + + optlist = [] + if not ui.quiet: + if ui.verbose: + optlist.append((_("global options:"), commands.globalopts)) + if name == 'shortlist': + optlist.append((_('use "hg help" for the full list ' + 'of commands'), ())) + else: + if name == 'shortlist': + msg = _('use "hg help" for the full list of commands ' + 'or "hg -v" for details') + elif name and not full: + msg = _('use "hg help %s" to show the full help ' + 'text') % name + else: + msg = _('use "hg -v help%s" to show builtin aliases and ' + 'global options') % (name and " " + name or "") + optlist.append((msg, ())) + + if optlist: + for title, options in optlist: + rst.append('\n%s\n' % title) + if options: + rst.append('\n%s\n' % optrst(options, ui.verbose)) + return rst + + def helptopic(name): + for names, header, doc in helptable: + if name in names: + break + else: + raise error.UnknownCommand(name) + + rst = ["%s\n\n" % header] + # description + if not doc: + rst.append(" %s\n" % _("(no help text available)")) + if util.safehasattr(doc, '__call__'): + rst += [" %s\n" % l for l in doc().splitlines()] + + if not ui.verbose: + omitted = (_('use "hg help -v %s" to show more complete help') % + name) + indicateomitted(rst, omitted) + + try: + cmdutil.findcmd(name, commands.table) + rst.append(_('\nuse "hg help -c %s" to see help for ' + 'the %s command\n') % (name, name)) + except error.UnknownCommand: + pass + return rst + + def helpext(name): + try: + mod = extensions.find(name) + doc = gettext(mod.__doc__) or _('no help text available') + except KeyError: + mod = None + doc = extensions.disabledext(name) + if not doc: + raise error.UnknownCommand(name) + + if '\n' not in doc: + head, tail = doc, "" + else: + head, tail = doc.split('\n', 1) + rst = [_('%s extension - %s\n\n') % (name.split('.')[-1], head)] + if tail: + rst.extend(tail.splitlines(True)) + rst.append('\n') + + if not ui.verbose: + omitted = (_('use "hg help -v %s" to show more complete help') % + name) + indicateomitted(rst, omitted) + + if mod: + try: + ct = mod.cmdtable + except AttributeError: + ct = {} + modcmds = set([c.split('|', 1)[0] for c in ct]) + rst.extend(helplist(modcmds.__contains__)) + else: + rst.append(_('use "hg help extensions" for information on enabling ' + 'extensions\n')) + return rst + + def helpextcmd(name): + cmd, ext, mod = extensions.disabledcmd(ui, name, + ui.configbool('ui', 'strict')) + doc = gettext(mod.__doc__).splitlines()[0] + + rst = listexts(_("'%s' is provided by the following " + "extension:") % cmd, {ext: doc}, indent=4) + rst.append('\n') + rst.append(_('use "hg help extensions" for information on enabling ' + 'extensions\n')) + return rst + + + rst = [] + kw = opts.get('keyword') + if kw: + matches = topicmatch(kw) + for t, title in (('topics', _('Topics')), + ('commands', _('Commands')), + ('extensions', _('Extensions')), + ('extensioncommands', _('Extension Commands'))): + if matches[t]: + rst.append('%s:\n\n' % title) + rst.extend(minirst.maketable(sorted(matches[t]), 1)) + rst.append('\n') + elif name and name != 'shortlist': + i = None + if unknowncmd: + queries = (helpextcmd,) + elif opts.get('extension'): + queries = (helpext,) + elif opts.get('command'): + queries = (helpcmd,) + else: + queries = (helptopic, helpcmd, helpext, helpextcmd) + for f in queries: + try: + rst = f(name) + i = None + break + except error.UnknownCommand, inst: + i = inst + if i: + raise i + else: + # program name + if not ui.quiet: + rst = [_("Mercurial Distributed SCM\n"), '\n'] + rst.extend(helplist()) + + return ''.join(rst) From danchr at gmail.com Sat Feb 9 10:38:13 2013 From: danchr at gmail.com (Dan Villiom Podlaski Christiansen) Date: Sat, 09 Feb 2013 16:38:13 +0000 Subject: [PATCH 4 of 4] hgweb: generate HTML documentation In-Reply-To: References: Message-ID: # HG changeset patch # User Dan Villiom Podlaski Christiansen # Date 1360427850 0 # Node ID d825c3feaf4f0e8f17f9c20c2f75bd319f602208 # Parent 469bcaf06fbc95a0384eea2d5e5a495e0e861745 hgweb: generate HTML documentation It's generated from the raw ReST source, as returned from help.help_(). diff --git a/mercurial/help/templates.txt b/mercurial/help/templates.txt --- a/mercurial/help/templates.txt +++ b/mercurial/help/templates.txt @@ -60,6 +60,8 @@ In addition to filters, there are some b - sub(pat, repl, expr) +- rstdoc(text, style) + Also, for any expression that returns a list, there is a list operator: - expr % "{template}" diff --git a/mercurial/hgweb/webcommands.py b/mercurial/hgweb/webcommands.py --- a/mercurial/hgweb/webcommands.py +++ b/mercurial/hgweb/webcommands.py @@ -992,11 +992,9 @@ def help(web, req, tmpl): othercommands=othercommands, title='Index') u = webutil.wsgiui() - u.pushbuffer() u.verbose = True try: - commands.help_(u, topicname) + doc = helpmod.help_(u, topicname) except error.UnknownCommand: raise ErrorResponse(HTTP_NOT_FOUND) - doc = u.popbuffer() return tmpl('help', topic=topicname, doc=doc) diff --git a/mercurial/templater.py b/mercurial/templater.py --- a/mercurial/templater.py +++ b/mercurial/templater.py @@ -9,6 +9,7 @@ from i18n import _ import sys, os, re import util, config, templatefilters, parser, error import types +import minirst # template parsing @@ -287,6 +288,16 @@ def label(context, mapping, args): t = stringify(args[1][0](context, mapping, args[1][1])) yield runtemplate(context, mapping, compiletemplate(t, context)) +def rstdoc(context, mapping, args): + if len(args) != 2: + # i18n: "rstdoc" is a keyword + raise error.ParseError(_("rstdoc expects two arguments")) + + text = stringify(args[0][0](context, mapping, args[0][1])) + style = stringify(args[1][0](context, mapping, args[1][1])) + + return minirst.format(text, style=style) + methods = { "string": lambda e, c: (runstring, e[1]), "symbol": lambda e, c: (runsymbol, e[1]), @@ -303,6 +314,7 @@ funcs = { "ifeq": ifeq, "join": join, "label": label, + "rstdoc": rstdoc, "sub": sub, } diff --git a/mercurial/templates/gitweb/help.tmpl b/mercurial/templates/gitweb/help.tmpl --- a/mercurial/templates/gitweb/help.tmpl +++ b/mercurial/templates/gitweb/help.tmpl @@ -27,8 +27,8 @@ help
     
    -
    -{doc|escape}
    -
    +
    +{rstdoc(doc, "html")} +
    {footer} diff --git a/mercurial/templates/monoblue/help.tmpl b/mercurial/templates/monoblue/help.tmpl --- a/mercurial/templates/monoblue/help.tmpl +++ b/mercurial/templates/monoblue/help.tmpl @@ -31,8 +31,8 @@ -
    -    {doc|escape}
    -    
    +
    + {rstdoc(doc, "html")} +
    {footer} diff --git a/mercurial/templates/paper/help.tmpl b/mercurial/templates/paper/help.tmpl --- a/mercurial/templates/paper/help.tmpl +++ b/mercurial/templates/paper/help.tmpl @@ -31,9 +31,9 @@
    find changesets by author, revision, files, or words in the commit message
    -
    -{doc|escape}
    -
    +
    +{rstdoc(doc, "html")} +
    diff --git a/tests/test-help.t b/tests/test-help.t --- a/tests/test-help.t +++ b/tests/test-help.t @@ -1502,65 +1502,65 @@ Dish up an empty repo; serve it cold.
    find changesets by author, revision, files, or words in the commit message
    -
    +  
    +

    hg add [OPTION]... [FILE]... +

    +

    + add the specified files on the next commit +

    +

    + Schedule files to be version controlled and added to the + repository. +

    +

    + The files will be added to the repository at the next commit. To + undo an add before that, see "hg forget". +

    +

    + If no names are given, add all files to the repository. +

    +

    + Returns 0 if all files are successfully added. +

    +

    + options: +

    + + + + + +
    -I--include PATTERN [+]include names matching the given patterns
    -X--exclude PATTERN [+]exclude names matching the given patterns
    -S--subreposrecurse into subrepositories
    -n--dry-rundo not perform actions, just print output
    +

    + [+] marked option can be specified multiple times +

    +

    + global options: +

    + + + + + + + + + + + + + + + + + +
    -R--repository REPOrepository root directory or name of overlay bundle file
    --cwd DIRchange working directory
    -y--noninteractivedo not prompt, automatically pick the first choice for all prompts
    -q--quietsuppress output
    -v--verboseenable additional output
    --config CONFIG [+]set/override config option (use 'section.name=value')
    --debugenable debugging output
    --debuggerstart debugger
    --encoding ENCODEset the charset encoding (default: ascii)
    --encodingmode MODEset the charset encoding mode (default: strict)
    --tracebackalways print a traceback on exception
    --timetime how long the command takes
    --profileprint command execution profile
    --versionoutput version information and exit
    -h--helpdisplay help and exit
    --hiddenconsider hidden changesets
    +

    + [+] marked option can be specified multiple times +

    - add the specified files on the next commit - - Schedule files to be version controlled and added to the repository. - - The files will be added to the repository at the next commit. To undo an - add before that, see "hg forget". - - If no names are given, add all files to the repository. - - An example showing how new (unknown) files are added automatically by "hg - add": - - $ ls - foo.c - $ hg status - ? foo.c - $ hg add - adding foo.c - $ hg status - A foo.c - - Returns 0 if all files are successfully added. - - options: - - -I --include PATTERN [+] include names matching the given patterns - -X --exclude PATTERN [+] exclude names matching the given patterns - -S --subrepos recurse into subrepositories - -n --dry-run do not perform actions, just print output - - [+] marked option can be specified multiple times - - global options: - - -R --repository REPO repository root directory or name of overlay bundle - file - --cwd DIR change working directory - -y --noninteractive do not prompt, automatically pick the first choice for - all prompts - -q --quiet suppress output - -v --verbose enable additional output - --config CONFIG [+] set/override config option (use 'section.name=value') - --debug enable debugging output - --debugger start debugger - --encoding ENCODE set the charset encoding (default: ascii) - --encodingmode MODE set the charset encoding mode (default: strict) - --traceback always print a traceback on exception - --time time how long the command takes - --profile print command execution profile - --version output version information and exit - -h --help display help and exit - --hidden consider hidden changesets - - [+] marked option can be specified multiple times - -
    + @@ -1614,74 +1614,65 @@ Dish up an empty repo; serve it cold.
    find changesets by author, revision, files, or words in the commit message
    -
    +  
    +

    hg remove [OPTION]... FILE... +

    +

    + aliases: rm +

    +

    + remove the specified files on the next commit +

    +

    + Schedule the indicated files for removal from the current branch. +

    +

    + This command schedules the files to be removed at the next commit. + To undo a remove before that, see "hg revert". To undo added + files, see "hg forget". +

    +

    + Returns 0 on success, 1 if any warnings encountered. +

    +

    + options: +

    + + + + + +
    -A--afterrecord delete for missing files
    -f--forceremove (and delete) file even if added or modified
    -I--include PATTERN [+]include names matching the given patterns
    -X--exclude PATTERN [+]exclude names matching the given patterns
    +

    + [+] marked option can be specified multiple times +

    +

    + global options: +

    + + + + + + + + + + + + + + + + + +
    -R--repository REPOrepository root directory or name of overlay bundle file
    --cwd DIRchange working directory
    -y--noninteractivedo not prompt, automatically pick the first choice for all prompts
    -q--quietsuppress output
    -v--verboseenable additional output
    --config CONFIG [+]set/override config option (use 'section.name=value')
    --debugenable debugging output
    --debuggerstart debugger
    --encoding ENCODEset the charset encoding (default: ascii)
    --encodingmode MODEset the charset encoding mode (default: strict)
    --tracebackalways print a traceback on exception
    --timetime how long the command takes
    --profileprint command execution profile
    --versionoutput version information and exit
    -h--helpdisplay help and exit
    --hiddenconsider hidden changesets
    +

    + [+] marked option can be specified multiple times +

    - aliases: rm - - remove the specified files on the next commit - - Schedule the indicated files for removal from the current branch. - - This command schedules the files to be removed at the next commit. To undo - a remove before that, see "hg revert". To undo added files, see "hg - forget". - - -A/--after can be used to remove only files that have already been - deleted, -f/--force can be used to force deletion, and -Af can be used to - remove files from the next revision without deleting them from the working - directory. - - The following table details the behavior of remove for different file - states (columns) and option combinations (rows). The file states are Added - [A], Clean [C], Modified [M] and Missing [!] (as reported by "hg status"). - The actions are Warn, Remove (from branch) and Delete (from disk): - - A C M ! - -------------- - none W RD W R - -f R RD RD R - -A W W W R - -Af R R R R - - Note that remove never deletes files in Added [A] state from the working - directory, not even if option --force is specified. - - Returns 0 on success, 1 if any warnings encountered. - - options: - - -A --after record delete for missing files - -f --force remove (and delete) file even if added or modified - -I --include PATTERN [+] include names matching the given patterns - -X --exclude PATTERN [+] exclude names matching the given patterns - - [+] marked option can be specified multiple times - - global options: - - -R --repository REPO repository root directory or name of overlay bundle - file - --cwd DIR change working directory - -y --noninteractive do not prompt, automatically pick the first choice for - all prompts - -q --quiet suppress output - -v --verbose enable additional output - --config CONFIG [+] set/override config option (use 'section.name=value') - --debug enable debugging output - --debugger start debugger - --encoding ENCODE set the charset encoding (default: ascii) - --encodingmode MODE set the charset encoding mode (default: strict) - --traceback always print a traceback on exception - --time time how long the command takes - --profile print command execution profile - --version output version information and exit - -h --help display help and exit - --hidden consider hidden changesets - - [+] marked option can be specified multiple times - -
    + @@ -1735,38 +1726,50 @@ Dish up an empty repo; serve it cold.
    find changesets by author, revision, files, or words in the commit message
    -
    +  
    +

    Specifying Single Revisions +

    +

    + Mercurial supports several ways to specify individual revisions. +

    +

    + A plain integer is treated as a revision number. Negative integers are + treated as sequential offsets from the tip, with -1 denoting the tip, + -2 denoting the revision prior to the tip, and so forth. +

    +

    + A 40-digit hexadecimal string is treated as a unique revision + identifier. +

    +

    + A hexadecimal string less than 40 characters long is treated as a + unique revision identifier and is referred to as a short-form + identifier. A short-form identifier is only valid if it is the prefix + of exactly one full-length identifier. +

    +

    + Any other string is treated as a bookmark, tag, or branch name. A + bookmark is a movable pointer to a revision. A tag is a permanent name + associated with a revision. A branch name denotes the tipmost revision + of that branch. Bookmark, tag, and branch names must not contain the ":" + character. +

    +

    + The reserved name "tip" always identifies the most recent revision. +

    +

    + The reserved name "null" indicates the null revision. This is the + revision of an empty repository, and the parent of revision 0. +

    +

    + The reserved name "." indicates the working directory parent. If no + working directory is checked out, it is equivalent to null. If an + uncommitted merge is in progress, "." is the revision of the first + parent. +

    - Mercurial supports several ways to specify individual revisions. - - A plain integer is treated as a revision number. Negative integers are - treated as sequential offsets from the tip, with -1 denoting the tip, -2 - denoting the revision prior to the tip, and so forth. - - A 40-digit hexadecimal string is treated as a unique revision identifier. - - A hexadecimal string less than 40 characters long is treated as a unique - revision identifier and is referred to as a short-form identifier. A - short-form identifier is only valid if it is the prefix of exactly one - full-length identifier. - - Any other string is treated as a bookmark, tag, or branch name. A bookmark - is a movable pointer to a revision. A tag is a permanent name associated - with a revision. A branch name denotes the tipmost revision of that - branch. Bookmark, tag, and branch names must not contain the ":" - character. - - The reserved name "tip" always identifies the most recent revision. - - The reserved name "null" indicates the null revision. This is the revision - of an empty repository, and the parent of revision 0. - - The reserved name "." indicates the working directory parent. If no - working directory is checked out, it is equivalent to null. If an - uncommitted merge is in progress, "." is the revision of the first parent. - -
    + From natosha at unity3d.com Sat Feb 9 10:39:28 2013 From: natosha at unity3d.com (natosha at unity3d.com) Date: Sat, 09 Feb 2013 16:39:28 +0000 Subject: [PATCH] largefiles: add --no-largefiles-caching option to pull Message-ID: <8c4097213e8ce9e07eeb.1360427968@s0-0.paconsult7.bbnplanet.net> # HG changeset patch # User Na'Tosha Bard # Date 1360425447 0 # Node ID 8c4097213e8ce9e07eebdc2f4ceca9687f463048 # Parent 7f26c8bcbd74c0248acea8247f7b12b4aafe5a53 largefiles: add --no-largefiles-caching option to pull The caching of largefiles for new heads that are pulled makes sense in a lot of cases and is a reasonable default (if you pull a new head, you may have pulled it from a non-default location that Mercurial won't know about later and you may want to merge with that head later). However, if you tend not to pull from different repositories and have a lot of branches being added on a regular basis in your default repository, the default caching behavior can be an unecessary overhead (if you know you are pulling from the default remote location, you can easily get the largefiles later when you need them to merge, and you may not want to cache largefiles for a dozen new heads right now). This changeset implements a --no-largefiles-caching flag to pull, which will override and disable the default caching behavior. diff -r 7f26c8bcbd74 -r 8c4097213e8c hgext/largefiles/overrides.py --- a/hgext/largefiles/overrides.py Sat Feb 09 15:25:46 2013 +0000 +++ b/hgext/largefiles/overrides.py Sat Feb 09 15:57:27 2013 +0000 @@ -731,19 +731,21 @@ repo.lfpullsource = source oldheads = lfutil.getcurrentheads(repo) result = orig(ui, repo, source, **opts) - # If we do not have the new largefiles for any new heads we pulled, we - # will run into a problem later if we try to merge or rebase with one of - # these heads, so cache the largefiles now directly into the system - # cache. - numcached = 0 - heads = lfutil.getcurrentheads(repo) - newheads = set(heads).difference(set(oldheads)) - if len(newheads) > 0: - ui.status(_("caching largefiles for %s heads\n") % len(newheads)) - for head in newheads: - (cached, missing) = lfcommands.cachelfiles(ui, repo, head) - numcached += len(cached) - ui.status(_("%d largefiles cached\n") % numcached) + if not opts.get('no_largefiles_caching'): + # If we do not have the new largefiles for any new heads we + # pulled, we will run into a problem later if we try to merge + # or rebase with one of these heads, so cache the largefiles + # now directly into the system cache. + numcached = 0 + heads = lfutil.getcurrentheads(repo) + newheads = set(heads).difference(set(oldheads)) + if len(newheads) > 0: + ui.status(_("caching largefiles for %s heads\n") % + len(newheads)) + for head in newheads: + (cached, missing) = lfcommands.cachelfiles(ui, repo, head) + numcached += len(cached) + ui.status(_("%d largefiles cached\n") % numcached) if opts.get('all_largefiles'): revspostpull = len(repo) revs = [] diff -r 7f26c8bcbd74 -r 8c4097213e8c hgext/largefiles/uisetup.py --- a/hgext/largefiles/uisetup.py Sat Feb 09 15:25:46 2013 +0000 +++ b/hgext/largefiles/uisetup.py Sat Feb 09 15:57:27 2013 +0000 @@ -79,7 +79,9 @@ entry = extensions.wrapcommand(commands.table, 'pull', overrides.overridepull) pullopt = [('', 'all-largefiles', None, - _('download all pulled versions of largefiles'))] + _('download all pulled versions of largefiles')), + ('', 'no-largefiles-caching', None, + _('do not cache largefiles for new heads'))] entry[1].extend(pullopt) entry = extensions.wrapcommand(commands.table, 'clone', overrides.overrideclone) diff -r 7f26c8bcbd74 -r 8c4097213e8c tests/test-largefiles.t --- a/tests/test-largefiles.t Sat Feb 09 15:25:46 2013 +0000 +++ b/tests/test-largefiles.t Sat Feb 09 15:57:27 2013 +0000 @@ -859,6 +859,30 @@ abort: --all-largefiles is incompatible with non-local destination ssh://localhost/a [255] +Test pulling with the --no-largefiles-caching flag + + $ rm -Rf a-backup + $ hg clone -r 1 a a-backup + adding changesets + adding manifests + adding file changes + added 2 changesets with 8 changes to 4 files + updating to branch default + getting changed largefiles + 2 largefiles updated, 0 removed + 4 files updated, 0 files merged, 0 files removed, 0 files unresolved + $ rm "${USERCACHE}"/* + $ cd a-backup + $ hg pull --no-largefiles-caching + pulling from $TESTTMP/a + searching for changes + adding changesets + adding manifests + adding file changes + added 6 changesets with 16 changes to 8 files + (run 'hg update' to get a working copy) + $ cd .. + Test pulling with --all-largefiles flag. Also test that the largefiles are downloaded from 'default' instead of 'default-push' when no source is specified (issue3584) From idankk86 at gmail.com Sat Feb 9 11:17:01 2013 From: idankk86 at gmail.com (Idan Kamara) Date: Sat, 09 Feb 2013 19:17:01 +0200 Subject: [PATCH 2 of 2] tests: add a test runner utility that prints nothing when all tests pass In-Reply-To: <4a4b4c13211532f5bdf4.1360430220@idan> References: <4a4b4c13211532f5bdf4.1360430220@idan> Message-ID: <15828f7e5de2c59201fb.1360430221@idan> # HG changeset patch # User Idan Kamara # Date 1360430019 -7200 # Node ID 15828f7e5de2c59201fbe8a996a7d71a6bb07926 # Parent 26627c30735a610f59979a36885b327b25d8dbff tests: add a test runner utility that prints nothing when all tests pass This will be used to run tests through run-tests, which will expect no output for a unit test that passes successfully. The motivation for using unit tests instead of the current Python tests is that they don't require an output file for comparison and that they're easier to write because of the available tools from unittest (setup, asserts). diff --git a/tests/silenttestrunner.py b/tests/silenttestrunner.py new file mode 100644 --- /dev/null +++ b/tests/silenttestrunner.py @@ -0,0 +1,18 @@ +import unittest, sys + +def main(modulename): + '''run the tests found in module, printing nothing when all tests pass''' + module = sys.modules[modulename] + suite = unittest.defaultTestLoader.loadTestsFromModule(module) + results = unittest.TestResult() + suite.run(results) + if results.errors or results.failures: + for tc, exc in results.errors: + print 'ERROR:', tc + print + sys.stdout.write(exc) + for tc, exc in results.failures: + print 'FAIL:', tc + print + sys.stdout.write(exc) + sys.exit(1) From idankk86 at gmail.com Sat Feb 9 11:17:00 2013 From: idankk86 at gmail.com (Idan Kamara) Date: Sat, 09 Feb 2013 19:17:00 +0200 Subject: [PATCH 1 of 2] test-atomictempfile: convert to unit test Message-ID: <4a4b4c13211532f5bdf4.1360430220@idan> # HG changeset patch # User Idan Kamara # Date 1360429365 -7200 # Node ID 4a4b4c13211532f5bdf48c6f09a50023fbef176b # Parent 15828f7e5de2c59201fbe8a996a7d71a6bb07926 test-atomictempfile: convert to unit test diff --git a/tests/test-atomictempfile.py b/tests/test-atomictempfile.py --- a/tests/test-atomictempfile.py +++ b/tests/test-atomictempfile.py @@ -1,48 +1,42 @@ import os import glob +import unittest +import silenttestrunner + from mercurial.util import atomictempfile -# basic usage -def test1_simple(): - if os.path.exists('foo'): - os.remove('foo') - file = atomictempfile('foo') - (dir, basename) = os.path.split(file._tempname) - assert not os.path.isfile('foo') - assert basename in glob.glob('.foo-*') +class testatomictempfile(unittest.TestCase): + def test1_simple(self): + if os.path.exists('foo'): + os.remove('foo') + file = atomictempfile('foo') + (dir, basename) = os.path.split(file._tempname) + self.assertFalse(os.path.isfile('foo')) + self.assertTrue(basename in glob.glob('.foo-*')) - file.write('argh\n') - file.close() + file.write('argh\n') + file.close() - assert os.path.isfile('foo') - assert basename not in glob.glob('.foo-*') - print 'OK' + self.assertTrue(os.path.isfile('foo')) + self.assertTrue(basename not in glob.glob('.foo-*')) -# discard() removes the temp file without making the write permanent -def test2_discard(): - if os.path.exists('foo'): - os.remove('foo') - file = atomictempfile('foo') - (dir, basename) = os.path.split(file._tempname) + # discard() removes the temp file without making the write permanent + def test2_discard(self): + if os.path.exists('foo'): + os.remove('foo') + file = atomictempfile('foo') + (dir, basename) = os.path.split(file._tempname) - file.write('yo\n') - file.discard() + file.write('yo\n') + file.discard() - assert not os.path.isfile('foo') - assert basename not in os.listdir('.') - print 'OK' + self.assertFalse(os.path.isfile('foo')) + self.assertTrue(basename not in os.listdir('.')) -# if a programmer screws up and passes bad args to atomictempfile, they -# get a plain ordinary TypeError, not infinite recursion -def test3_oops(): - try: - file = atomictempfile() - except TypeError: - print "OK" - else: - print "expected TypeError" + # if a programmer screws up and passes bad args to atomictempfile, they + # get a plain ordinary TypeError, not infinite recursion + def test3_oops(self): + self.assertRaises(TypeError, atomictempfile) if __name__ == '__main__': - test1_simple() - test2_discard() - test3_oops() + silenttestrunner.main(__name__) diff --git a/tests/test-atomictempfile.py.out b/tests/test-atomictempfile.py.out deleted file mode 100644 --- a/tests/test-atomictempfile.py.out +++ /dev/null @@ -1,3 +0,0 @@ -OK -OK -OK From idankk86 at gmail.com Sat Feb 9 11:18:34 2013 From: idankk86 at gmail.com (Idan Kamara) Date: Sat, 9 Feb 2013 19:18:34 +0200 Subject: [PATCH 1 of 2] test-atomictempfile: convert to unit test In-Reply-To: <4a4b4c13211532f5bdf4.1360430220@idan> References: <4a4b4c13211532f5bdf4.1360430220@idan> Message-ID: On Sat, Feb 9, 2013 at 7:17 PM, Idan Kamara wrote: > > # HG changeset patch > # User Idan Kamara > # Date 1360429365 -7200 > # Node ID 4a4b4c13211532f5bdf48c6f09a50023fbef176b > # Parent 15828f7e5de2c59201fbe8a996a7d71a6bb07926 > test-atomictempfile: convert to unit test Oops, this should have been patch #2. -------------- next part -------------- An HTML attachment was scrubbed... URL: From bos at serpentine.com Sat Feb 9 11:20:36 2013 From: bos at serpentine.com (Bryan O'Sullivan) Date: Sat, 9 Feb 2013 09:20:36 -0800 Subject: [PATCH 1 of 4] hgweb help: add tests In-Reply-To: <981484b29c145cfd130a.1360427890@s0-0.paconsult7.bbnplanet.net> References: <981484b29c145cfd130a.1360427890@s0-0.paconsult7.bbnplanet.net> Message-ID: On Sat, Feb 9, 2013 at 8:38 AM, Dan Villiom Podlaski Christiansen < danchr at gmail.com> wrote: > hgweb help: add tests > This doesn't apply for me. -------------- next part -------------- An HTML attachment was scrubbed... URL: From bos at serpentine.com Sat Feb 9 11:23:25 2013 From: bos at serpentine.com (Bryan O'Sullivan) Date: Sat, 9 Feb 2013 09:23:25 -0800 Subject: [PATCH 09 of 11] worker: allow a function to be run in multiple worker processes In-Reply-To: References: <8cf626e958d3dd67e45b.1360418801@australite.local> Message-ID: On Sat, Feb 9, 2013 at 7:35 AM, Idan Kamara wrote: > This exit is also going to be a problem for things that > call into the internal API. > The master process will only exit if one of the workers exits abnormally. That should only occur if the worker crashes, in which case we would have crashed before anyway. -------------- next part -------------- An HTML attachment was scrubbed... URL: From bos at serpentine.com Sat Feb 9 11:32:35 2013 From: bos at serpentine.com (Bryan O'Sullivan) Date: Sat, 9 Feb 2013 09:32:35 -0800 Subject: [PATCH 2 of 3] dirstate: walk returns None for files under symlink directory In-Reply-To: References: Message-ID: On Tue, Feb 5, 2013 at 3:38 PM, Durham Goode wrote: > dirstate: walk returns None for files under symlink directory > > Previously dirstate.walk would return a stat object for files in the dmap > that were under a symlink directory. Now it will return None (when the > unknown > parameter is True) to indicate that they are no longer considered part of > the > repository. > This patch looks good, but "symlink directory" is awkward and confusing. I'd use something like "symlink that replaces a directory" instead - it's not great wording, but it doesn't make me go "what does that mean?". -------------- next part -------------- An HTML attachment was scrubbed... URL: From idankk86 at gmail.com Sat Feb 9 11:33:42 2013 From: idankk86 at gmail.com (Idan Kamara) Date: Sat, 9 Feb 2013 19:33:42 +0200 Subject: [PATCH 09 of 11] worker: allow a function to be run in multiple worker processes In-Reply-To: References: <8cf626e958d3dd67e45b.1360418801@australite.local> Message-ID: On Sat, Feb 9, 2013 at 7:23 PM, Bryan O'Sullivan wrote: > > On Sat, Feb 9, 2013 at 7:35 AM, Idan Kamara wrote: >> >> This exit is also going to be a problem for things that >> call into the internal API. > > > The master process will only exit if one of the workers exits abnormally. > That should only occur if the worker crashes, in which case we would have > crashed before anyway. An exception would be raised and caught at dispatch, converted to an error exit code and returned by dispatch.dispatch(). $ grep -r 'sys\.exit' mercurial/ mercurial/sshserver.py:99: sys.exit(0) mercurial/keepalive.py:741: sys.exit() mercurial/dispatch.py:28: sys.exit((dispatch(request(sys.argv[1:])) or 0) & 255) mercurial/dispatch.py:202: # Commands shouldn't sys.exit directly, but give a return code. mercurial/lsprof.py:105: sys.exit(2) The one at dispatch.py:28 isn't invoked by callers to the internal API. From bos at serpentine.com Sat Feb 9 11:34:19 2013 From: bos at serpentine.com (Bryan O'Sullivan) Date: Sat, 9 Feb 2013 09:34:19 -0800 Subject: [PATCH 3 of 3] addremove: don't audit the path for paths already in the dirstate In-Reply-To: References: Message-ID: On Tue, Feb 5, 2013 at 3:38 PM, Durham Goode wrote: > addremove: don't audit the path for paths already in the dirstate > This looks good, thanks. -------------- next part -------------- An HTML attachment was scrubbed... URL: From natosha at unity3d.com Sat Feb 9 11:47:03 2013 From: natosha at unity3d.com (Na'Tosha Bard) Date: Sat, 9 Feb 2013 17:47:03 +0000 Subject: [PATCH] largefiles: add --no-largefiles-caching option to pull In-Reply-To: <8c4097213e8ce9e07eeb.1360427968@s0-0.paconsult7.bbnplanet.net> References: <8c4097213e8ce9e07eeb.1360427968@s0-0.paconsult7.bbnplanet.net> Message-ID: 2013/2/9 > # HG changeset patch > # User Na'Tosha Bard > # Date 1360425447 0 > # Node ID 8c4097213e8ce9e07eebdc2f4ceca9687f463048 > # Parent 7f26c8bcbd74c0248acea8247f7b12b4aafe5a53 > largefiles: add --no-largefiles-caching option to pull Please don't queue this; we've decided to change the behavior in a different way. I'll send a new changeset later. -- *Na'Tosha Bard* Software Developer | Unity Technologies - Copenhagen *E-Mail:* natosha at unity3d.com *Skype:* natosha.bard -------------- next part -------------- An HTML attachment was scrubbed... URL: From kbullock+mercurial at ringworld.org Sat Feb 9 11:54:32 2013 From: kbullock+mercurial at ringworld.org (Kevin Bullock) Date: Sat, 09 Feb 2013 17:54:32 +0000 Subject: [PATCH 1 of 3] summary: test that current bookmark isn't shown Message-ID: <501b0d5829a15fbf4d79.1360432472@s0-0.paconsult7.bbnplanet.net> # HG changeset patch # User Kevin Bullock # Date 1360359163 0 # Node ID 501b0d5829a15fbf4d79c665c280ae4f7898ecfe # Parent 46edbc49a9f213dd9c78e4dbaa8809661058bb07 summary: test that current bookmark isn't shown This exposes the current behavior in a test. A later change will make summary show when the active bookmark has moved out from under us. diff --git a/tests/test-bookmarks.t b/tests/test-bookmarks.t --- a/tests/test-bookmarks.t +++ b/tests/test-bookmarks.t @@ -467,6 +467,13 @@ create bundle with two heads update to current bookmark if it's not the parent + $ hg summary + parent: 2:db815d6d32e6 + 2 + branch: default + bookmarks: Y x y + commit: 1 added, 1 unknown (new branch head) + update: 2 new changesets (update) $ hg update updating to active bookmark Z 1 files updated, 0 files merged, 0 files removed, 0 files unresolved From kbullock+mercurial at ringworld.org Sat Feb 9 11:54:33 2013 From: kbullock+mercurial at ringworld.org (Kevin Bullock) Date: Sat, 09 Feb 2013 17:54:33 +0000 Subject: [PATCH 2 of 3] summary: simplify handling of active bookmark In-Reply-To: <501b0d5829a15fbf4d79.1360432472@s0-0.paconsult7.bbnplanet.net> References: <501b0d5829a15fbf4d79.1360432472@s0-0.paconsult7.bbnplanet.net> Message-ID: <04f1a301c90a00480839.1360432473@s0-0.paconsult7.bbnplanet.net> # HG changeset patch # User Kevin Bullock # Date 1359309226 21600 # Node ID 04f1a301c90a00480839f8ee86c7e550a7e98f87 # Parent 501b0d5829a15fbf4d79c665c280ae4f7898ecfe summary: simplify handling of active bookmark diff --git a/mercurial/commands.py b/mercurial/commands.py --- a/mercurial/commands.py +++ b/mercurial/commands.py @@ -5574,13 +5574,9 @@ def summary(ui, repo, **opts): current = repo._bookmarkcurrent # i18n: column positioning for "hg summary" ui.write(_('bookmarks:'), label='log.bookmark') - if current is not None: - try: - marks.remove(current) - ui.write(' *' + current, label='bookmarks.current') - except ValueError: - # current bookmark not in parent ctx marks - pass + if current is not None and current in marks: + ui.write(' *' + current, label='bookmarks.current') + marks.remove(current) for m in marks: ui.write(' ' + m, label='log.bookmark') ui.write('\n', label='log.bookmark') From kbullock+mercurial at ringworld.org Sat Feb 9 11:54:34 2013 From: kbullock+mercurial at ringworld.org (Kevin Bullock) Date: Sat, 09 Feb 2013 17:54:34 +0000 Subject: [PATCH 3 of 3] summary: show active bookmark even if not at current changeset In-Reply-To: <501b0d5829a15fbf4d79.1360432472@s0-0.paconsult7.bbnplanet.net> References: <501b0d5829a15fbf4d79.1360432472@s0-0.paconsult7.bbnplanet.net> Message-ID: <9d727e125244520c4fe6.1360432474@s0-0.paconsult7.bbnplanet.net> # HG changeset patch # User Kevin Bullock # Date 1360360042 0 # Node ID 9d727e125244520c4fe60a4b8d60e29269d24af3 # Parent 04f1a301c90a00480839f8ee86c7e550a7e98f87 summary: show active bookmark even if not at current changeset Before this change, 'hg summary' would not show the active bookmark unless it pointed to the working directory parent. After this change, it will show it in parentheses, like so: parent: 18581:f0ff45fe6700 tip summary: simplify handling of active bookmark branch: default bookmarks: [crew] commit: (clean) update: (current) diff --git a/mercurial/commands.py b/mercurial/commands.py --- a/mercurial/commands.py +++ b/mercurial/commands.py @@ -5574,9 +5574,12 @@ def summary(ui, repo, **opts): current = repo._bookmarkcurrent # i18n: column positioning for "hg summary" ui.write(_('bookmarks:'), label='log.bookmark') - if current is not None and current in marks: - ui.write(' *' + current, label='bookmarks.current') - marks.remove(current) + if current is not None: + if current in marks: + ui.write(' *' + current, label='bookmarks.current') + marks.remove(current) + else: + ui.write('[%s]' % current, label='bookmarks.current') for m in marks: ui.write(' ' + m, label='log.bookmark') ui.write('\n', label='log.bookmark') diff --git a/tests/test-bookmarks.t b/tests/test-bookmarks.t --- a/tests/test-bookmarks.t +++ b/tests/test-bookmarks.t @@ -471,7 +471,7 @@ update to current bookmark if it's not t parent: 2:db815d6d32e6 2 branch: default - bookmarks: Y x y + bookmarks:[Z] Y x y commit: 1 added, 1 unknown (new branch head) update: 2 new changesets (update) $ hg update From brodie at sf.io Sat Feb 9 11:55:15 2013 From: brodie at sf.io (Brodie Rao) Date: Sat, 09 Feb 2013 17:55:15 +0000 Subject: [PATCH v2] amend: support amending merge changesets (issue3778) In-Reply-To: References: Message-ID: # HG changeset patch # User Brodie Rao # Date 1360357714 0 # Node ID a7a029fb74d698deccb925807672c7d7328ac1be # Parent 2fefd1170bf269e26bb304553009f38e0117c342 amend: support amending merge changesets (issue3778) diff --git a/mercurial/cmdutil.py b/mercurial/cmdutil.py --- a/mercurial/cmdutil.py +++ b/mercurial/cmdutil.py @@ -1644,7 +1644,13 @@ def amend(ui, repo, commitfunc, old, ext # Also update it from the intermediate commit or from the wctx extra.update(ctx.extra()) - files = set(old.files()) + if len(old.parents()) > 1: + # ctx.files() isn't reliable for merges, so fall back to the + # slower repo.status() method + files = set([fn for st in repo.status(base, old)[:3] + for fn in st]) + else: + files = set(old.files()) # Second, we use either the commit we just did, or if there were no # changes the parent of the working directory as the version of the @@ -1709,7 +1715,7 @@ def amend(ui, repo, commitfunc, old, ext extra['amend_source'] = old.hex() new = context.memctx(repo, - parents=[base.node(), nullid], + parents=[base.node(), old.p2().node()], text=message, files=files, filectxfn=filectxfn, diff --git a/mercurial/commands.py b/mercurial/commands.py --- a/mercurial/commands.py +++ b/mercurial/commands.py @@ -1301,8 +1301,6 @@ def commit(ui, repo, *pats, **opts): old = repo['.'] if old.phase() == phases.public: raise util.Abort(_('cannot amend public changesets')) - if len(old.parents()) > 1: - raise util.Abort(_('cannot amend merge changesets')) if len(repo[None].parents()) > 1: raise util.Abort(_('cannot amend while merging')) if (not obsolete._enabled) and old.children(): diff --git a/tests/test-commit-amend.t b/tests/test-commit-amend.t --- a/tests/test-commit-amend.t +++ b/tests/test-commit-amend.t @@ -304,7 +304,7 @@ Same thing, different code path: $ hg branches default 2:ce12b0b57d46 -Refuse to amend merges: +Refuse to amend during a merge: $ hg up -q default $ hg merge foo @@ -314,9 +314,6 @@ Refuse to amend merges: abort: cannot amend while merging [255] $ hg ci -m 'merge' - $ hg ci --amend - abort: cannot amend merge changesets - [255] Follow copies/renames: @@ -518,3 +515,231 @@ Test that rewriting leaving instability date: Thu Jan 01 00:00:00 1970 +0000 summary: babar + +Amend a merge changeset (with renames and conflicts from the second parent): + + $ hg up -q default + $ hg branch -q bar + $ hg cp a aa + $ hg mv z zz + $ echo cc > cc + $ hg add cc + $ hg ci -m aazzcc + $ hg up -q default + $ echo a >> a + $ echo dd > cc + $ hg add cc + $ hg ci -m aa + $ hg merge -q bar + warning: conflicts during merge. + merging cc incomplete! (edit conflicts, then use 'hg resolve --mark') + [1] + $ hg resolve -m cc + $ hg ci -m 'merge bar' + $ hg log --config diff.git=1 -pr . + changeset: 23:d51446492733 + tag: tip + parent: 22:30d96aeaf27b + parent: 21:1aa437659d19 + user: test + date: Thu Jan 01 00:00:00 1970 +0000 + summary: merge bar + + diff --git a/a b/aa + copy from a + copy to aa + diff --git a/cc b/cc + --- a/cc + +++ b/cc + @@ -1,1 +1,5 @@ + +<<<<<<< local + dd + +======= + +cc + +>>>>>>> other + diff --git a/z b/zz + rename from z + rename to zz + + $ hg debugrename aa + aa renamed from a:a80d06849b333b8a3d5c445f8ba3142010dcdc9e + $ hg debugrename zz + zz renamed from z:69a1b67522704ec122181c0890bd16e9d3e7516a + $ hg debugrename cc + cc not renamed + $ hg ci --amend -m 'merge bar (amend message)' + $ hg log --config diff.git=1 -pr . + changeset: 24:59de3dce7a79 + tag: tip + parent: 22:30d96aeaf27b + parent: 21:1aa437659d19 + user: test + date: Thu Jan 01 00:00:00 1970 +0000 + summary: merge bar (amend message) + + diff --git a/a b/aa + copy from a + copy to aa + diff --git a/cc b/cc + --- a/cc + +++ b/cc + @@ -1,1 +1,5 @@ + +<<<<<<< local + dd + +======= + +cc + +>>>>>>> other + diff --git a/z b/zz + rename from z + rename to zz + + $ hg debugrename aa + aa renamed from a:a80d06849b333b8a3d5c445f8ba3142010dcdc9e + $ hg debugrename zz + zz renamed from z:69a1b67522704ec122181c0890bd16e9d3e7516a + $ hg debugrename cc + cc not renamed + $ hg mv zz z + $ hg ci --amend -m 'merge bar (undo rename)' + $ hg log --config diff.git=1 -pr . + changeset: 26:7fb89c461f81 + tag: tip + parent: 22:30d96aeaf27b + parent: 21:1aa437659d19 + user: test + date: Thu Jan 01 00:00:00 1970 +0000 + summary: merge bar (undo rename) + + diff --git a/a b/aa + copy from a + copy to aa + diff --git a/cc b/cc + --- a/cc + +++ b/cc + @@ -1,1 +1,5 @@ + +<<<<<<< local + dd + +======= + +cc + +>>>>>>> other + + $ hg debugrename z + z not renamed + +Amend a merge changeset (with renames during the merge): + + $ hg up -q bar + $ echo x > x + $ hg add x + $ hg ci -m x + $ hg up -q default + $ hg merge -q bar + $ hg mv aa aaa + $ echo aa >> aaa + $ hg ci -m 'merge bar again' + $ hg log --config diff.git=1 -pr . + changeset: 28:982d7a34ffee + tag: tip + parent: 26:7fb89c461f81 + parent: 27:4c94d5bc65f5 + user: test + date: Thu Jan 01 00:00:00 1970 +0000 + summary: merge bar again + + diff --git a/aa b/aa + deleted file mode 100644 + --- a/aa + +++ /dev/null + @@ -1,2 +0,0 @@ + -a + -a + diff --git a/aaa b/aaa + new file mode 100644 + --- /dev/null + +++ b/aaa + @@ -0,0 +1,3 @@ + +a + +a + +aa + diff --git a/x b/x + new file mode 100644 + --- /dev/null + +++ b/x + @@ -0,0 +1,1 @@ + +x + + $ hg debugrename aaa + aaa renamed from aa:37d9b5d994eab34eda9c16b195ace52c7b129980 + $ hg mv aaa aa + $ hg ci --amend -m 'merge bar again (undo rename)' + $ hg log --config diff.git=1 -pr . + changeset: 30:522688c0e71b + tag: tip + parent: 26:7fb89c461f81 + parent: 27:4c94d5bc65f5 + user: test + date: Thu Jan 01 00:00:00 1970 +0000 + summary: merge bar again (undo rename) + + diff --git a/aa b/aa + --- a/aa + +++ b/aa + @@ -1,2 +1,3 @@ + a + a + +aa + diff --git a/x b/x + new file mode 100644 + --- /dev/null + +++ b/x + @@ -0,0 +1,1 @@ + +x + + $ hg debugrename aa + aa not renamed + $ hg debugrename -r .^ aa + aa renamed from a:a80d06849b333b8a3d5c445f8ba3142010dcdc9e + +Amend a merge changeset (with manifest-level conflicts): + + $ hg up -q bar + $ hg rm aa + $ hg ci -m 'rm aa' + $ hg up -q default + $ echo aa >> aa + $ hg ci -m aa + $ hg merge -q bar + local changed aa which remote deleted + use (c)hanged version or (d)elete? c + $ hg ci -m 'merge bar (with conflicts)' + $ hg log --config diff.git=1 -pr . + changeset: 33:5f9904c491b8 + tag: tip + parent: 32:01780b896f58 + parent: 31:67db8847a540 + user: test + date: Thu Jan 01 00:00:00 1970 +0000 + summary: merge bar (with conflicts) + + + $ hg rm aa + $ hg ci --amend -m 'merge bar (with conflicts, amended)' + $ hg log --config diff.git=1 -pr . + changeset: 35:6ce0c89781a3 + tag: tip + parent: 32:01780b896f58 + parent: 31:67db8847a540 + user: test + date: Thu Jan 01 00:00:00 1970 +0000 + summary: merge bar (with conflicts, amended) + + diff --git a/aa b/aa + deleted file mode 100644 + --- a/aa + +++ /dev/null + @@ -1,4 +0,0 @@ + -a + -a + -aa + -aa + From hgbuildbot at kublai.com Sat Feb 9 12:41:53 2013 From: hgbuildbot at kublai.com (hgbuildbot at kublai.com) Date: Sat, 09 Feb 2013 10:41:53 -0800 Subject: buildbot success in Mercurial on hg tests Message-ID: <20130209184157.37F9636F45@hgbuildbot.cs.ubc.ca> The Buildbot has detected a restored build on builder hg tests while building hg. Full details are available at: http://hgbuildbot.kublai.com/builders/hg%20tests/builds/488 Buildbot URL: http://hgbuildbot.kublai.com/ Buildslave for this Build: p64.osuosl.test Build Reason: scheduler Build Source Stamp: [branch default] 46edbc49a9f213dd9c78e4dbaa8809661058bb07 Blamelist: Na'Tosha Bard ,Simon Heimberg Build succeeded! sincerely, -The Buildbot From angel.ezquerra at gmail.com Sat Feb 9 14:42:31 2013 From: angel.ezquerra at gmail.com (Angel Ezquerra) Date: Sat, 09 Feb 2013 21:42:31 +0100 Subject: [PATCH V3] hgweb: teach archive how to handle file patterns Message-ID: # HG changeset patch # User Angel Ezquerra # Date 1360141605 -3600 # Node ID c0509330eb416104bed8cc7d0a4038f818dd5e5d # Parent b6c8e79948a05d01920392cd12ac5c8279d5c62b hgweb: teach archive how to handle file patterns The archive web command now takes into account the "file" request entry, if one is provided. The provided "file" is processed as a "path" pattern by default, which makes it easy to only archive a certain file or directory. However, it is possible to specify a different type of pattern, such as relglob by specifying it explicitly on the query URL. Note that only "safe" patterns are allowed. Safe patterns are 'path', 'relpath', 'glog' and 'relglob'. Other pattern types are not allowed because they could be expensive to calculate. With this change hgweb can to process requests such as: 1. http://mercurial.selenic.com/hg/tip.zip/mercurial/templates This will download all files on the mercurial/templates directory as a zip file 2. http://mercurial.selenic.com/hg/tip.tar.gz/relglob:*.py This will download all *.py files in the repository into a tar.gz file. An so forth. Note that this is a first step to add support for downloading directories from the web interface. Currently the only way to use this feature is by manually constructing the URL that you want to download. We will have to modify the archiveentry map entry on the different templates so that it adds the current folder path to the archive links. This revision also adds a test for this feature to test-archive.t. diff --git a/mercurial/hgweb/webcommands.py b/mercurial/hgweb/webcommands.py --- a/mercurial/hgweb/webcommands.py +++ b/mercurial/hgweb/webcommands.py @@ -795,7 +795,7 @@ if not ((type_ in allowed or web.configbool("web", "allow" + type_, False))): msg = 'Archive type not allowed: %s' % type_ - raise ErrorResponse(HTTP_FORBIDDEN, msg) + #raise ErrorResponse(HTTP_FORBIDDEN, msg) reponame = re.sub(r"\W+", "-", os.path.basename(web.reponame)) cnode = web.repo.lookup(key) @@ -803,6 +803,17 @@ if cnode == key or key == 'tip': arch_version = short(cnode) name = "%s-%s" % (reponame, arch_version) + + ctx = webutil.changectx(web.repo, req) + pats = [] + file = req.form.get('file', None) + defaultpat = 'path' + if file: + pats = [req.form['file'][0]] + if not scmutil.patsaresafe(pats, defaultpat): + msg = 'Archive pattern not allowed: %s' % pats[0] + raise ErrorResponse(HTTP_FORBIDDEN, msg) + mimetype, artype, extension, encoding = web.archive_specs[type_] headers = [ ('Content-Disposition', 'attachment; filename=%s%s' % (name, extension)) @@ -811,10 +822,9 @@ headers.append(('Content-Encoding', encoding)) req.headers.extend(headers) req.respond(HTTP_OK, mimetype) - - ctx = webutil.changectx(web.repo, req) + matchfn = scmutil.match(ctx, pats, default=defaultpat) archival.archive(web.repo, req, cnode, artype, prefix=name, - matchfn=scmutil.match(ctx, []), + matchfn=matchfn, subrepos=web.configbool("web", "archivesubrepos")) return [] diff --git a/mercurial/scmutil.py b/mercurial/scmutil.py --- a/mercurial/scmutil.py +++ b/mercurial/scmutil.py @@ -682,6 +682,15 @@ return l +def patsaresafe(pats, defaultpattype): + for pat in pats: + pattype = defaultpattype + if ':' in pat: + pattype = pat.split(':')[0] + if pattype.lower() not in ('path', 'relpath', 'glog', 'relglob'): + return False + return True + def expandpats(pats): if not util.expandglobs: return list(pats) diff --git a/tests/test-archive.t b/tests/test-archive.t --- a/tests/test-archive.t +++ b/tests/test-archive.t @@ -69,9 +69,14 @@ > msvcrt.setmode(sys.stdout.fileno(), os.O_BINARY) > except ImportError: > pass - > node, archive = sys.argv[1:] - > f = urllib2.urlopen('http://127.0.0.1:%s/?cmd=archive;node=%s;type=%s' - > % (os.environ['HGPORT'], node, archive)) + > if len(sys.argv) <= 3: + > node, archive = sys.argv[1:] + > requeststr = 'cmd=archive;node=%s;type=%s' % (node, archive) + > else: + > node, archive, file = sys.argv[1:] + > requeststr = 'cmd=archive;node=%s;type=%s;file=%s' % (node, archive, file) + > f = urllib2.urlopen('http://127.0.0.1:%s/?%s' + > % (os.environ['HGPORT'], requeststr)) > sys.stdout.write(f.read()) > EOF $ python getarchive.py "$TIP" gz | gunzip | tar tf - 2>/dev/null @@ -92,6 +97,8 @@ testing: test-archive-2c0277f05ed4/baz/bletch OK testing: test-archive-2c0277f05ed4/foo OK No errors detected in compressed data of archive.zip. + $ python getarchive.py "$TIP" gz baz | gunzip | tar tf - 2>/dev/null + test-archive-2c0277f05ed4/baz/bletch $ "$TESTDIR/killdaemons.py" $DAEMON_PIDS From angel.ezquerra at gmail.com Sat Feb 9 14:58:29 2013 From: angel.ezquerra at gmail.com (Angel Ezquerra) Date: Sat, 9 Feb 2013 20:58:29 +0000 Subject: [PATCH 2 of 3] hgweb, templates: apply the websub filter to revision descriptions In-Reply-To: <511632E0.7070604@kiilerich.com> References: <0ca84e16d89af5c0125d.1360404123@Angel-PC.localdomain> <511632E0.7070604@kiilerich.com> Message-ID: On Sat, Feb 9, 2013 at 11:28 AM, Mads Kiilerich wrote: > On 02/09/2013 11:02 AM, Angel Ezquerra wrote: >> >> # HG changeset patch >> # User Angel Ezquerra >> # Date 1360363571 -3600 >> # Node ID 0ca84e16d89af5c0125d19e741605caca09da49f >> # Parent d2fe4130209f6877d841926df79ba02842c83e20 >> hgweb, templates: apply the websub filter to revision descriptions >> >> In order to use this, add a [websub] section to your configuration and add >> websub expressions such as: >> >> italic = s/\b_(\S+)_\b/\1<\/i>/ >> bold = s/\*\b(\S+)\b\*/\1<\/b>/ >> bugzilla = s!((?:bug|b=|(?=#?\d{4,}))(?:\s*#?)(\d+))!> href="http://bz.selenic.com/\2">\1!i > > > This should be documented in mercurial/help/config.txt . > > I assume these template changes also has some intentional and accidental > changes to the test results? > > /Mads > I resent a new version that adds the documentation. I also ran the hgweb tests and everything seems fine: $ ./run-tests.py test-hgweb*.t ............. # Ran 13 tests, 0 skipped, 0 failed. Angel From natosha at unity3d.com Sat Feb 9 15:09:22 2013 From: natosha at unity3d.com (natosha at unity3d.com) Date: Sat, 09 Feb 2013 21:09:22 +0000 Subject: [PATCH] largefiles: don't cache largefiles for pulled heads by default Message-ID: # HG changeset patch # User Na'Tosha Bard # Date 1360444062 0 # Node ID ec59cb6ffec44f330b52f4a0a41b117de38a0987 # Parent 7f26c8bcbd74c0248acea8247f7b12b4aafe5a53 largefiles: don't cache largefiles for pulled heads by default After discussion, we've agreed that largefiles for newly pulled heads should not be cached by default. The use case for this is using largefiles repos with multiple remote servers (and therefore multiple remote largefiles caches), where users will be pulling from non-default locations on a regular basis. We think this use case will be significantly less common than the use case where all largefiles are stored on the same central server, so the default should be no caching. The old behavior can be obtained by passing the --cache-largefiles flag to pull. diff -r 7f26c8bcbd74 -r ec59cb6ffec4 hgext/largefiles/__init__.py --- a/hgext/largefiles/__init__.py Sat Feb 09 15:25:46 2013 +0000 +++ b/hgext/largefiles/__init__.py Sat Feb 09 21:07:42 2013 +0000 @@ -41,13 +41,17 @@ enabled for this to work. When you pull a changeset that affects largefiles from a remote -repository, the largefiles for the changeset usually won't be -pulled down until you update to the revision (there is one exception -to this case). However, when you update to such a revision, any -largefiles needed by that revision are downloaded and cached (if -they have never been downloaded before). This means that network -access may be required to update to changesets you have no -previously updated to. +repository, the largefiles for the changeset won't be pulled down. +Instead, when you later update to such a revision, any largefiles +needed by that revision are downloaded and cached (if they have +never been downloaded before). This means that network access may +be required to update to changesets you have previously updated to. + +If you know you are pulling from a non-default location and want to +ensure that you will have the largefiles needed to merge or rebase +with new heads that you are pulling, then you can pull with the +--cache-largefiles flag to pre-emptively download any largefiles +that are new in the heads you are pulling. The one exception to the "largefiles won't be pulled until you update to a revision that changes them" rule is when you pull new heads. diff -r 7f26c8bcbd74 -r ec59cb6ffec4 hgext/largefiles/overrides.py --- a/hgext/largefiles/overrides.py Sat Feb 09 15:25:46 2013 +0000 +++ b/hgext/largefiles/overrides.py Sat Feb 09 21:07:42 2013 +0000 @@ -731,19 +731,21 @@ repo.lfpullsource = source oldheads = lfutil.getcurrentheads(repo) result = orig(ui, repo, source, **opts) - # If we do not have the new largefiles for any new heads we pulled, we - # will run into a problem later if we try to merge or rebase with one of - # these heads, so cache the largefiles now directly into the system - # cache. - numcached = 0 - heads = lfutil.getcurrentheads(repo) - newheads = set(heads).difference(set(oldheads)) - if len(newheads) > 0: - ui.status(_("caching largefiles for %s heads\n") % len(newheads)) - for head in newheads: - (cached, missing) = lfcommands.cachelfiles(ui, repo, head) - numcached += len(cached) - ui.status(_("%d largefiles cached\n") % numcached) + if opts.get('cache_largefiles'): + # If you are pulling from a remote location that is not your + # default location, you may want to cache largefiles for new heads + # that have been pulled, so you can easily merge or rebase with + # them later + numcached = 0 + heads = lfutil.getcurrentheads(repo) + newheads = set(heads).difference(set(oldheads)) + if len(newheads) > 0: + ui.status(_("caching largefiles for %s heads\n") % + len(newheads)) + for head in newheads: + (cached, missing) = lfcommands.cachelfiles(ui, repo, head) + numcached += len(cached) + ui.status(_("%d largefiles cached\n") % numcached) if opts.get('all_largefiles'): revspostpull = len(repo) revs = [] diff -r 7f26c8bcbd74 -r ec59cb6ffec4 hgext/largefiles/uisetup.py --- a/hgext/largefiles/uisetup.py Sat Feb 09 15:25:46 2013 +0000 +++ b/hgext/largefiles/uisetup.py Sat Feb 09 21:07:42 2013 +0000 @@ -79,7 +79,9 @@ entry = extensions.wrapcommand(commands.table, 'pull', overrides.overridepull) pullopt = [('', 'all-largefiles', None, - _('download all pulled versions of largefiles'))] + _('download all pulled versions of largefiles')), + ('', 'cache-largefiles', None, + _('caches new largefiles in all pulled heads'))] entry[1].extend(pullopt) entry = extensions.wrapcommand(commands.table, 'clone', overrides.overrideclone) diff -r 7f26c8bcbd74 -r ec59cb6ffec4 tests/test-largefiles-cache.t --- a/tests/test-largefiles-cache.t Sat Feb 09 15:25:46 2013 +0000 +++ b/tests/test-largefiles-cache.t Sat Feb 09 21:07:42 2013 +0000 @@ -37,8 +37,6 @@ adding file changes added 1 changesets with 1 changes to 1 files (run 'hg update' to get a working copy) - caching largefiles for 1 heads - 0 largefiles cached Update working directory to "tip", which requires largefile("large"), but there is no cache file for it. So, hg must treat it as diff -r 7f26c8bcbd74 -r ec59cb6ffec4 tests/test-largefiles.t --- a/tests/test-largefiles.t Sat Feb 09 15:25:46 2013 +0000 +++ b/tests/test-largefiles.t Sat Feb 09 21:07:42 2013 +0000 @@ -883,9 +883,7 @@ adding file changes added 6 changesets with 16 changes to 8 files (run 'hg update' to get a working copy) - caching largefiles for 1 heads - 3 largefiles cached - 3 additional largefiles cached + 6 additional largefiles cached $ cd .. Rebasing between two repositories does not revert largefiles to old @@ -974,8 +972,6 @@ adding file changes added 1 changesets with 2 changes to 2 files (+1 heads) (run 'hg heads' to see heads, 'hg merge' to merge) - caching largefiles for 1 heads - 0 largefiles cached $ hg rebase Invoking status precommit hook M sub/normal4 @@ -1265,7 +1261,8 @@ $ hg commit -m "Modify large4 to test merge" Invoking status precommit hook M sub/large4 - $ hg pull ../e +# Test --cache-largefiles flag + $ hg pull --cache-largefiles ../e pulling from ../e searching for changes adding changesets From bos at serpentine.com Sat Feb 9 15:23:05 2013 From: bos at serpentine.com (Bryan O'Sullivan) Date: Sat, 09 Feb 2013 21:23:05 +0000 Subject: [PATCH 1 of 2] merge: rename p1 to wctx in manifestmerge Message-ID: <68226cb20b4ad583c3bd.1360444985@australite.local> # HG changeset patch # User Bryan O'Sullivan # Date 1360444976 0 # Node ID 68226cb20b4ad583c3bdf54044c59ea979ec6e7f # Parent 712d538d7512cbfd079c54f460243611a0593612 merge: rename p1 to wctx in manifestmerge This is always a workingctx, and this name is more in line with other functions in this module. diff --git a/mercurial/merge.py b/mercurial/merge.py --- a/mercurial/merge.py +++ b/mercurial/merge.py @@ -185,7 +185,7 @@ def _forgetremoved(wctx, mctx, branchmer return actions -def manifestmerge(repo, p1, p2, pa, branchmerge, force, partial): +def manifestmerge(repo, wctx, p2, pa, branchmerge, force, partial): """ Merge p1 and p2 with ancestor pa and generate merge action list @@ -197,11 +197,11 @@ def manifestmerge(repo, p1, p2, pa, bran actions, copy, movewithdir = [], {}, {} if overwrite: - pa = p1 + pa = wctx elif pa == p2: # backwards - pa = p1.p1() + pa = wctx.p1() elif pa and repo.ui.configbool("merge", "followcopies", True): - ret = copies.mergecopies(repo, p1, p2, pa) + ret = copies.mergecopies(repo, wctx, p2, pa) copy, movewithdir, diverge, renamedelete = ret for of, fl in diverge.iteritems(): actions.append((of, "dr", (fl,), "divergent renames")) @@ -211,16 +211,16 @@ def manifestmerge(repo, p1, p2, pa, bran repo.ui.note(_("resolving manifests\n")) repo.ui.debug(" branchmerge: %s, force: %s, partial: %s\n" % (bool(branchmerge), bool(force), bool(partial))) - repo.ui.debug(" ancestor: %s, local: %s, remote: %s\n" % (pa, p1, p2)) + repo.ui.debug(" ancestor: %s, local: %s, remote: %s\n" % (pa, wctx, p2)) - m1, m2, ma = p1.manifest(), p2.manifest(), pa.manifest() + m1, m2, ma = wctx.manifest(), p2.manifest(), pa.manifest() copied = set(copy.values()) copied.update(movewithdir.values()) if '.hgsubstate' in m1: # check whether sub state is modified - for s in sorted(p1.substate): - if p1.sub(s).dirty(): + for s in sorted(wctx.substate): + if wctx.sub(s).dirty(): m1['.hgsubstate'] += "+" break @@ -300,7 +300,7 @@ def manifestmerge(repo, p1, p2, pa, bran if force and not branchmerge: actions.append((f, "g", (m2.flags(f),), "remote created")) else: - different = _checkunknownfile(repo, p1, p2, f) + different = _checkunknownfile(repo, wctx, p2, f) if force and branchmerge and different: actions.append((f, "m", (f, f, False), "remote differs from untracked local")) From bos at serpentine.com Sat Feb 9 15:23:06 2013 From: bos at serpentine.com (Bryan O'Sullivan) Date: Sat, 09 Feb 2013 21:23:06 +0000 Subject: [PATCH 2 of 2] merge: don't call copies.mergecopies unless we need to In-Reply-To: <68226cb20b4ad583c3bd.1360444985@australite.local> References: <68226cb20b4ad583c3bd.1360444985@australite.local> Message-ID: <53956d5e085898c0b6fe.1360444986@australite.local> # HG changeset patch # User Bryan O'Sullivan # Date 1360444976 0 # Node ID 53956d5e085898c0b6fe4ec1159f4706dfbc1baa # Parent 68226cb20b4ad583c3bdf54044c59ea979ec6e7f merge: don't call copies.mergecopies unless we need to This reduces the amount of time we spend calculating when doing a clean non-merge update. In a large repo, the time dropped from 10.1 seconds to 3.4. diff --git a/mercurial/merge.py b/mercurial/merge.py --- a/mercurial/merge.py +++ b/mercurial/merge.py @@ -200,6 +200,8 @@ def manifestmerge(repo, wctx, p2, pa, br pa = wctx elif pa == p2: # backwards pa = wctx.p1() + elif not branchmerge and not wctx.dirty(missing=True): + pass elif pa and repo.ui.configbool("merge", "followcopies", True): ret = copies.mergecopies(repo, wctx, p2, pa) copy, movewithdir, diverge, renamedelete = ret diff --git a/tests/test-subrepo.t b/tests/test-subrepo.t --- a/tests/test-subrepo.t +++ b/tests/test-subrepo.t @@ -210,7 +210,6 @@ merge tests subrepo merge f0d2028bf86d+ 1831e14459c4 1f14a2e2d3ec subrepo t: other changed, get t:6747d179aa9a688023c4b0cad32e4c92bb7f34ad:hg getting subrepo t - searching for copies back to rev 1 resolving manifests branchmerge: False, force: False, partial: False ancestor: 60ca1237c194, local: 60ca1237c194+, remote: 6747d179aa9a From pierre-yves.david at ens-lyon.org Sat Feb 9 14:47:57 2013 From: pierre-yves.david at ens-lyon.org (pierre-yves.david at ens-lyon.org) Date: Sat, 09 Feb 2013 20:47:57 +0000 Subject: [PATCH STABLE] outgoing: fix possible filtering crash in outgoing (issue3814) Message-ID: # HG changeset patch # User Pierre-Yves David # Date 1360432441 0 # Branch stable # Node ID c76622632f68a66539f7468363f195a6564dd0bb # Parent 9a06aab5981b510a22900d2686a597afe7a5dfbe outgoing: fix possible filtering crash in outgoing (issue3814) If there is no outgoiing changesets but we have filtered revision in outgoing.excluded We run into a filtering related crash. The excluded revision should not be there in the first place but discovery need cleanup in default, not stable. diff --git a/mercurial/scmutil.py b/mercurial/scmutil.py --- a/mercurial/scmutil.py +++ b/mercurial/scmutil.py @@ -16,10 +16,14 @@ def nochangesfound(ui, repo, excluded=No nodes excluded from the push/pull. ''' secretlist = [] if excluded: for n in excluded: + if n not in repo: + # discovery should not have included the filtered revision, + # we have to explicitly exclude it until discovery is cleanup. + continue ctx = repo[n] if ctx.phase() >= phases.secret and not ctx.extinct(): secretlist.append(n) if secretlist: diff --git a/tests/test-obsolete.t b/tests/test-obsolete.t --- a/tests/test-obsolete.t +++ b/tests/test-obsolete.t @@ -863,5 +863,27 @@ This test issue 3805 [1] $ "$TESTDIR/killdaemons.py" $DAEMON_PIDS #endif + +This test issue 3814 + +(nothing to push but locally hidden changeset) + + $ cd .. + $ hg init repo-issue3814 + $ cd repo-issue3805 + $ hg push -r 3816541e5485 ../repo-issue3814 + pushing to ../repo-issue3814 + searching for changes + adding changesets + adding manifests + adding file changes + added 1 changesets with 1 changes to 1 files + $ hg out ../repo-issue3814 + comparing with ../repo-issue3814 + searching for changes + no changes found + [1] + + From mads at kiilerich.com Sat Feb 9 15:28:11 2013 From: mads at kiilerich.com (Mads Kiilerich) Date: Sat, 09 Feb 2013 22:28:11 +0100 Subject: [PATCH 1 of 2] merge: rename p1 to wctx in manifestmerge In-Reply-To: <68226cb20b4ad583c3bd.1360444985@australite.local> References: <68226cb20b4ad583c3bd.1360444985@australite.local> Message-ID: <5116BF6B.8080401@kiilerich.com> On 02/09/2013 10:23 PM, Bryan O'Sullivan wrote: > # HG changeset patch > # User Bryan O'Sullivan > # Date 1360444976 0 > # Node ID 68226cb20b4ad583c3bdf54044c59ea979ec6e7f > # Parent 712d538d7512cbfd079c54f460243611a0593612 > merge: rename p1 to wctx in manifestmerge > > This is always a workingctx, and this name is more in line with other > functions in this module. I would like to go in the opposite direction and make manifestmerge more symmetric and independent of wctx and strategy for applying changes to a working directory. That would bring it closer to being usable for in memory merge. /Mads > diff --git a/mercurial/merge.py b/mercurial/merge.py > --- a/mercurial/merge.py > +++ b/mercurial/merge.py > @@ -185,7 +185,7 @@ def _forgetremoved(wctx, mctx, branchmer > > return actions > > -def manifestmerge(repo, p1, p2, pa, branchmerge, force, partial): > +def manifestmerge(repo, wctx, p2, pa, branchmerge, force, partial): > """ > Merge p1 and p2 with ancestor pa and generate merge action list > > @@ -197,11 +197,11 @@ def manifestmerge(repo, p1, p2, pa, bran > actions, copy, movewithdir = [], {}, {} > > if overwrite: > - pa = p1 > + pa = wctx > elif pa == p2: # backwards > - pa = p1.p1() > + pa = wctx.p1() > elif pa and repo.ui.configbool("merge", "followcopies", True): > - ret = copies.mergecopies(repo, p1, p2, pa) > + ret = copies.mergecopies(repo, wctx, p2, pa) > copy, movewithdir, diverge, renamedelete = ret > for of, fl in diverge.iteritems(): > actions.append((of, "dr", (fl,), "divergent renames")) > @@ -211,16 +211,16 @@ def manifestmerge(repo, p1, p2, pa, bran > repo.ui.note(_("resolving manifests\n")) > repo.ui.debug(" branchmerge: %s, force: %s, partial: %s\n" > % (bool(branchmerge), bool(force), bool(partial))) > - repo.ui.debug(" ancestor: %s, local: %s, remote: %s\n" % (pa, p1, p2)) > + repo.ui.debug(" ancestor: %s, local: %s, remote: %s\n" % (pa, wctx, p2)) > > - m1, m2, ma = p1.manifest(), p2.manifest(), pa.manifest() > + m1, m2, ma = wctx.manifest(), p2.manifest(), pa.manifest() > copied = set(copy.values()) > copied.update(movewithdir.values()) > > if '.hgsubstate' in m1: > # check whether sub state is modified > - for s in sorted(p1.substate): > - if p1.sub(s).dirty(): > + for s in sorted(wctx.substate): > + if wctx.sub(s).dirty(): > m1['.hgsubstate'] += "+" > break > > @@ -300,7 +300,7 @@ def manifestmerge(repo, p1, p2, pa, bran > if force and not branchmerge: > actions.append((f, "g", (m2.flags(f),), "remote created")) > else: > - different = _checkunknownfile(repo, p1, p2, f) > + different = _checkunknownfile(repo, wctx, p2, f) > if force and branchmerge and different: > actions.append((f, "m", (f, f, False), > "remote differs from untracked local")) > _______________________________________________ > Mercurial-devel mailing list > Mercurial-devel at selenic.com > http://selenic.com/mailman/listinfo/mercurial-devel From bos at serpentine.com Sat Feb 9 15:30:39 2013 From: bos at serpentine.com (Bryan O'Sullivan) Date: Sat, 9 Feb 2013 13:30:39 -0800 Subject: [PATCH 1 of 2] merge: rename p1 to wctx in manifestmerge In-Reply-To: <5116BF6B.8080401@kiilerich.com> References: <68226cb20b4ad583c3bd.1360444985@australite.local> <5116BF6B.8080401@kiilerich.com> Message-ID: On Sat, Feb 9, 2013 at 1:28 PM, Mads Kiilerich wrote: > I would like to go in the opposite direction and make manifestmerge more > symmetric and independent of wctx and strategy for applying changes to a > working directory. That would bring it closer to being usable for in memory > merge. > That makes sense. I still applied the patch for now - when you have time to work on improving its symmetry, please feel free to change the name back. -------------- next part -------------- An HTML attachment was scrubbed... URL: From raf at durin42.com Sat Feb 9 15:42:36 2013 From: raf at durin42.com (Augie Fackler) Date: Sat, 09 Feb 2013 15:42:36 -0600 Subject: [PATCH] export: clobber files with -o (bc) (issue3652) Message-ID: <1a2f4c633410f6bc49b9.1360446156@augie-macbookair> # HG changeset patch # User Augie Fackler # Date 1360445937 21600 # Node ID 1a2f4c633410f6bc49b94c65d74939165bbc2dd7 # Parent 0b6e6eacc939c303136cb38af108e307d640c26e export: clobber files with -o (bc) (issue3652) This violated user expectation. Updated the code to clobber files, but preserve the behavior of appending multiple patches requested in a single export. Includes tests. diff --git a/mercurial/cmdutil.py b/mercurial/cmdutil.py --- a/mercurial/cmdutil.py +++ b/mercurial/cmdutil.py @@ -170,7 +170,8 @@ inst.args[0]) def makefileobj(repo, pat, node=None, desc=None, total=None, - seqno=None, revwidth=None, mode='wb', pathname=None): + seqno=None, revwidth=None, mode='wb', modemap={}, + pathname=None): writable = mode not in ('r', 'rb') @@ -196,9 +197,11 @@ return pat if util.safehasattr(pat, 'read') and 'r' in mode: return pat - return open(makefilename(repo, pat, node, desc, total, seqno, revwidth, - pathname), - mode) + fn = makefilename(repo, pat, node, desc, total, seqno, revwidth, pathname) + mode = modemap.get(fn, mode) + if mode == 'wb': + modemap[fn] = 'ab' + return open(fn, mode) def openrevlog(repo, cmd, file_, opts): """opens the changelog, manifest, a filelog or a given revlog""" @@ -539,6 +542,7 @@ total = len(revs) revwidth = max([len(str(rev)) for rev in revs]) + filemode = {} def single(rev, seqno, fp): ctx = repo[rev] @@ -554,7 +558,8 @@ desc_lines = ctx.description().rstrip().split('\n') desc = desc_lines[0] #Commit always has a first line. fp = makefileobj(repo, template, node, desc=desc, total=total, - seqno=seqno, revwidth=revwidth, mode='ab') + seqno=seqno, revwidth=revwidth, mode='wb', + modemap=filemode) if fp != template: shouldclose = True if fp and fp != sys.stdout and util.safehasattr(fp, 'name'): diff --git a/tests/test-export.t b/tests/test-export.t --- a/tests/test-export.t +++ b/tests/test-export.t @@ -91,13 +91,28 @@ foo-foo_10.patch foo-foo_11.patch +Doing it again clobbers the files rather than appending: + $ hg export -v -o "foo-%m.patch" 2:3 + exporting patches: + foo-foo_2.patch + foo-foo_3.patch + $ grep HG foo-foo_2.patch | wc -l + \s*1 (re) + $ grep HG foo-foo_3.patch | wc -l + \s*1 (re) + Exporting 4 changesets to a file: $ hg export -o export_internal 1 2 3 4 $ grep HG export_internal | wc -l \s*4 (re) -Exporting 4 changesets to a file: +Doing it again clobbers the file rather than appending: + $ hg export -o export_internal 1 2 3 4 + $ grep HG export_internal | wc -l + \s*4 (re) + +Exporting 4 changesets to stdout: $ hg export 1 2 3 4 | grep HG | wc -l \s*4 (re) From kbullock+mercurial at ringworld.org Sat Feb 9 15:46:58 2013 From: kbullock+mercurial at ringworld.org (Kevin Bullock) Date: Sat, 09 Feb 2013 21:46:58 +0000 Subject: [PATCH] revset: add update() revset to return target rev for 'hg update' Message-ID: <57ba45c914886c80342d.1360446418@s0-0.paconsult7.bbnplanet.net> # HG changeset patch # User Kevin Bullock # Date 1360405949 0 # Node ID 57ba45c914886c80342df5d0f130fbc72780f2e7 # Parent 9d727e125244520c4fe60a4b8d60e29269d24af3 revset: add update() revset to return target rev for 'hg update' diff --git a/mercurial/revset.py b/mercurial/revset.py --- a/mercurial/revset.py +++ b/mercurial/revset.py @@ -13,6 +13,7 @@ from i18n import _ import encoding import obsolete as obsmod import repoview +import bookmarks, scmutil def _revancestors(repo, revs, followfirst): """Like revlog.ancestors(), but supports followfirst.""" @@ -1514,6 +1515,15 @@ def unstable(repo, subset, x): unstables = obsmod.getrevs(repo, 'unstable') return [r for r in subset if r in unstables] +def update(repo, subset, x): + """``update()`` + The target revisions that a bare 'hg update' will update to. + """ + if repo._bookmarkcurrent and not bookmarks.iscurrent(repo): + target = repo._bookmarks[repo._bookmarkcurrent].rev() + target = scmutil.revsingle(repo, None, 'tip').rev() + repo.ui.debug(repr(target) + '\n') + return [r for r in subset if r == target] def user(repo, subset, x): """``user(string)`` @@ -1600,6 +1610,7 @@ symbols = { "tagged": tagged, "user": user, "unstable": unstable, + "update": update, "_list": _list, } diff --git a/tests/test-revset.t b/tests/test-revset.t --- a/tests/test-revset.t +++ b/tests/test-revset.t @@ -446,6 +446,11 @@ we can use patterns when searching for t $ log 'branch(unknown)' abort: unknown revision 'unknown'! [255] + $ log 'update()' + 9 + $ hg up 8 + $ log 'update()' + 9 $ log 'user(bob)' 2 From hg at intevation.org Sat Feb 9 15:50:10 2013 From: hg at intevation.org (Mercurial Commits) Date: Sat, 09 Feb 2013 22:50:10 +0100 Subject: mercurial@18612: 32 new changesets Message-ID: <1360446610.664727.18751.nullmailer@hg.intevation.org> 32 new changesets in mercurial: http://selenic.com/repo/hg//rev/3490c91a1fcb changeset: 18581:3490c91a1fcb parent: 18576:97761496c65a user: Benoit Boissinot date: Fri Feb 08 21:55:46 2013 +0100 summary: templates: export extra as a dict to templates http://selenic.com/repo/hg//rev/ef78450c8df6 changeset: 18582:ef78450c8df6 user: Benoit Boissinot date: Fri Feb 08 23:49:14 2013 +0100 summary: templater: add get() function to access dict element (e.g. extra) http://selenic.com/repo/hg//rev/b27b17a5362a changeset: 18583:b27b17a5362a parent: 18576:97761496c65a parent: 18580:9a06aab5981b user: Kevin Bullock date: Sat Feb 09 10:36:31 2013 +0000 summary: merge with mpm stable http://selenic.com/repo/hg//rev/3af017bd8ef9 changeset: 18584:3af017bd8ef9 parent: 18582:ef78450c8df6 parent: 18583:b27b17a5362a user: Kevin Bullock date: Sat Feb 09 10:40:26 2013 +0000 summary: merge crew heads http://selenic.com/repo/hg//rev/b280f3bfc8a0 changeset: 18585:b280f3bfc8a0 user: Benoit Boissinot date: Sat Feb 09 12:08:02 2013 +0100 summary: revlog: document v0 format http://selenic.com/repo/hg//rev/40f9472f5737 changeset: 18586:40f9472f5737 user: Augie Fackler date: Fri Feb 08 17:14:12 2013 -0600 summary: byterange: remove old two-arg raise trick http://selenic.com/repo/hg//rev/cbf5f3eb9d13 changeset: 18587:cbf5f3eb9d13 user: Augie Fackler date: Sat Feb 09 06:07:32 2013 -0600 summary: changelog: hexlify node when throwing a LookupError on a filtered node http://selenic.com/repo/hg//rev/3241fc65e3cd changeset: 18588:3241fc65e3cd user: Augie Fackler date: Sat Feb 09 05:26:16 2013 -0600 summary: test-https.t: stop using kill `cat $pidfile` http://selenic.com/repo/hg//rev/91aac2797c40 changeset: 18589:91aac2797c40 user: Augie Fackler date: Sat Feb 09 05:29:10 2013 -0600 summary: test-hgweb-raw.t: use killdaemons instead of kill `cat pidfile` http://selenic.com/repo/hg//rev/104e120416ec changeset: 18590:104e120416ec user: Augie Fackler date: Sat Feb 09 05:30:40 2013 -0600 summary: test-inotify-debuginotify.t: migrate to killdaemons from kill `cat pidfile` http://selenic.com/repo/hg//rev/f58175f409b0 changeset: 18591:f58175f409b0 user: Augie Fackler date: Sat Feb 09 05:32:00 2013 -0600 summary: test-inotify-issue1371.t: switch to killdaemons from kill `cat pidfile` http://selenic.com/repo/hg//rev/f7c4eb60b0c3 changeset: 18592:f7c4eb60b0c3 user: Augie Fackler date: Sat Feb 09 05:33:39 2013 -0600 summary: test-inotify-issue1542.t: migrate to killdaemons from kill `cat pidfile` http://selenic.com/repo/hg//rev/895d65364570 changeset: 18593:895d65364570 user: Augie Fackler date: Sat Feb 09 05:34:22 2013 -0600 summary: test-inotify-issue1556.t: migrate to killdaemons from kill `cat pidfile` http://selenic.com/repo/hg//rev/a9e830ecd9fb changeset: 18594:a9e830ecd9fb user: Augie Fackler date: Sat Feb 09 05:35:20 2013 -0600 summary: test-inotify-lookup.t: migrate to killdaemons from kill `cat pidfile` http://selenic.com/repo/hg//rev/37479af47bd0 changeset: 18595:37479af47bd0 user: Augie Fackler date: Sat Feb 09 05:36:19 2013 -0600 summary: test-inotify.t: migrate to killdaemons from kill `cat pidfile` http://selenic.com/repo/hg//rev/d8cfe29c6b61 changeset: 18596:d8cfe29c6b61 user: Augie Fackler date: Sat Feb 09 05:37:36 2013 -0600 summary: test-obsolete.t: migrate to killdaemons from kill `cat pidfile` http://selenic.com/repo/hg//rev/542110817450 changeset: 18597:542110817450 user: Augie Fackler date: Sat Feb 09 07:44:22 2013 -0600 summary: byterange: remove now-unused sys import http://selenic.com/repo/hg//rev/4723ccb62282 changeset: 18598:4723ccb62282 user: Benoit Boissinot date: Sat Feb 09 15:57:04 2013 +0100 summary: check-code: add Makefile target to run check-code http://selenic.com/repo/hg//rev/5cd1dbf4c5d2 changeset: 18599:5cd1dbf4c5d2 user: Na'Tosha Bard date: Sat Feb 09 15:25:46 2013 +0000 summary: largefiles: document behavior of caching largefiles for new heads http://selenic.com/repo/hg//rev/8ba520003ae0 changeset: 18600:8ba520003ae0 user: Na'Tosha Bard date: Sat Feb 09 15:08:21 2013 +0000 summary: largefiles: make caching largefiles message more explicit http://selenic.com/repo/hg//rev/ce844e8e8af2 changeset: 18601:ce844e8e8af2 user: Kevin Bullock date: Sat Feb 09 13:35:45 2013 +0000 summary: tests: guard against obsolete markers in the hg repo itself http://selenic.com/repo/hg//rev/339a3fa19695 changeset: 18602:339a3fa19695 user: Kevin Bullock date: Sat Feb 09 13:58:13 2013 +0000 summary: tests: remove last two check-code warnings about killdaemons http://selenic.com/repo/hg//rev/2251b3184e6e changeset: 18603:2251b3184e6e parent: 18600:8ba520003ae0 user: Siddharth Agarwal date: Sat Feb 09 15:41:46 2013 +0000 summary: util: add an LRU cache dict http://selenic.com/repo/hg//rev/a1141f04e368 changeset: 18604:a1141f04e368 user: Siddharth Agarwal date: Sat Feb 09 15:43:02 2013 +0000 summary: manifest: use a size 3 LRU cache to store parsed manifests http://selenic.com/repo/hg//rev/bcf29565d89f changeset: 18605:bcf29565d89f user: Siddharth Agarwal date: Fri Feb 08 15:23:23 2013 +0000 summary: manifestmerge: pass in branchmerge and force separately http://selenic.com/repo/hg//rev/95773237df7f changeset: 18606:95773237df7f user: Siddharth Agarwal date: Sat Feb 09 15:36:00 2013 +0000 summary: manifestmerge: handle abort on local unknown, remote created files http://selenic.com/repo/hg//rev/26627c30735a changeset: 18607:26627c30735a parent: 18606:95773237df7f parent: 18602:339a3fa19695 user: Bryan O'Sullivan date: Sat Feb 09 15:59:44 2013 +0000 summary: Merge http://selenic.com/repo/hg//rev/3adbd57e1794 changeset: 18608:3adbd57e1794 user: Simon Heimberg date: Sat Aug 03 16:37:17 2013 +0200 summary: histedit: report when revisions to edit are not ancestors of working dir http://selenic.com/repo/hg//rev/909cb9ddba4a changeset: 18609:909cb9ddba4a user: Simon Heimberg date: Sat Aug 03 16:40:13 2013 +0200 summary: histedit: always abort with same message when working dir is wrong. http://selenic.com/repo/hg//rev/46edbc49a9f2 changeset: 18610:46edbc49a9f2 user: Na'Tosha Bard date: Sat Feb 09 16:02:01 2013 +0000 summary: largefiles: fix test and check code http://selenic.com/repo/hg//rev/18c2184c27dc changeset: 18611:18c2184c27dc user: Bryan O'Sullivan date: Sat Feb 09 21:24:24 2013 +0000 summary: merge: rename p1 to wctx in manifestmerge http://selenic.com/repo/hg//rev/0b6e6eacc939 changeset: 18612:0b6e6eacc939 tag: tip user: Bryan O'Sullivan date: Sat Feb 09 21:24:36 2013 +0000 summary: merge: don't call copies.mergecopies unless we need to -- Repository URL: http://selenic.com/repo/hg/ From mpm at selenic.com Sat Feb 9 15:55:50 2013 From: mpm at selenic.com (Matt Mackall) Date: Sat, 09 Feb 2013 21:55:50 +0000 Subject: [PATCH] revset: add update() revset to return target rev for 'hg update' In-Reply-To: <57ba45c914886c80342d.1360446418@s0-0.paconsult7.bbnplanet.net> References: <57ba45c914886c80342d.1360446418@s0-0.paconsult7.bbnplanet.net> Message-ID: <1360446950.3873.44.camel@calx> On Sat, 2013-02-09 at 21:46 +0000, Kevin Bullock wrote: > # HG changeset patch > # User Kevin Bullock > # Date 1360405949 0 > # Node ID 57ba45c914886c80342df5d0f130fbc72780f2e7 > # Parent 9d727e125244520c4fe60a4b8d60e29269d24af3 > revset: add update() revset to return target rev for 'hg update' > > diff --git a/mercurial/revset.py b/mercurial/revset.py > --- a/mercurial/revset.py > +++ b/mercurial/revset.py > @@ -13,6 +13,7 @@ from i18n import _ > import encoding > import obsolete as obsmod > import repoview > +import bookmarks, scmutil Hrm, circular import. > def _revancestors(repo, revs, followfirst): > """Like revlog.ancestors(), but supports followfirst.""" > @@ -1514,6 +1515,15 @@ def unstable(repo, subset, x): > unstables = obsmod.getrevs(repo, 'unstable') > return [r for r in subset if r in unstables] > > +def update(repo, subset, x): > + """``update()`` > + The target revisions that a bare 'hg update' will update to. > + """ > + if repo._bookmarkcurrent and not bookmarks.iscurrent(repo): > + target = repo._bookmarks[repo._bookmarkcurrent].rev() > + target = scmutil.revsingle(repo, None, 'tip').rev() Hmm. don't see how this deals with the current branch. > + repo.ui.debug(repr(target) + '\n') Left-over? > + return [r for r in subset if r == target] > > def user(repo, subset, x): > """``user(string)`` > @@ -1600,6 +1610,7 @@ symbols = { > "tagged": tagged, > "user": user, > "unstable": unstable, > + "update": update, > "_list": _list, > } > > diff --git a/tests/test-revset.t b/tests/test-revset.t > --- a/tests/test-revset.t > +++ b/tests/test-revset.t > @@ -446,6 +446,11 @@ we can use patterns when searching for t > $ log 'branch(unknown)' > abort: unknown revision 'unknown'! > [255] > + $ log 'update()' > + 9 > + $ hg up 8 > + $ log 'update()' > + 9 > $ log 'user(bob)' > 2 > > _______________________________________________ > Mercurial-devel mailing list > Mercurial-devel at selenic.com > http://selenic.com/mailman/listinfo/mercurial-devel -- Mathematics is the supreme nostalgia of our time. From raf at durin42.com Sat Feb 9 15:57:26 2013 From: raf at durin42.com (Augie Fackler) Date: Sat, 09 Feb 2013 15:57:26 -0600 Subject: [PATCH] parsedate: understand "now" as a shortcut for the current time Message-ID: # HG changeset patch # User Augie Fackler # Date 1360445962 21600 # Node ID a2906f188cb708ee3983ac75551256c730b0cef9 # Parent 0b6e6eacc939c303136cb38af108e307d640c26e parsedate: understand "now" as a shortcut for the current time diff --git a/mercurial/help/dates.txt b/mercurial/help/dates.txt --- a/mercurial/help/dates.txt +++ b/mercurial/help/dates.txt @@ -20,6 +20,7 @@ - ``12/6/6`` (Dec 6 2006) - ``today`` (midnight) - ``yesterday`` (midnight) +- ``now`` - right now Lastly, there is Mercurial's internal format: diff --git a/mercurial/util.py b/mercurial/util.py --- a/mercurial/util.py +++ b/mercurial/util.py @@ -1060,6 +1060,12 @@ datetime.timedelta(days=1)\ ).strftime('%b %d')) True + >>> now, tz = makedate() + >>> strnow, strtz = parsedate('now') + >>> (strnow - now) < 1 + True + >>> tz == strtz + True """ if not date: return 0, 0 @@ -1069,6 +1075,8 @@ formats = defaultdateformats date = date.strip() + if date == _('now'): + return makedate() if date == _('today'): date = datetime.date.today().strftime('%b %d') elif date == _('yesterday'): diff --git a/tests/test-parse-date.t b/tests/test-parse-date.t --- a/tests/test-parse-date.t +++ b/tests/test-parse-date.t @@ -251,3 +251,8 @@ $ hg ci -d "`sed -n '2p' dates`" -m "the time traveler's code" $ hg log -d yesterday --template '{desc}\n' the time traveler's code + $ echo "foo" >> a + $ hg commit -d now -m 'Explicitly committed now.' + $ hg log -d today --template '{desc}\n' + Explicitly committed now. + today is a good day to code From bos at serpentine.com Sat Feb 9 15:57:49 2013 From: bos at serpentine.com (Bryan O'Sullivan) Date: Sat, 9 Feb 2013 13:57:49 -0800 Subject: [PATCH 09 of 11] worker: allow a function to be run in multiple worker processes In-Reply-To: References: <8cf626e958d3dd67e45b.1360418801@australite.local> Message-ID: On Sat, Feb 9, 2013 at 9:33 AM, Idan Kamara wrote: > An exception would be raised and caught at dispatch, converted to an error > exit code and returned by dispatch.dispatch(). > Only it doesn't have any cases for "I want to exit silently" except for when code calls sys.exit ... which is what I already do. Remember, in this case, the worker process that has crashed has already printed its abort or crash message. There's no advantage to the master printing more stuff. -------------- next part -------------- An HTML attachment was scrubbed... URL: From bos at serpentine.com Sat Feb 9 15:58:47 2013 From: bos at serpentine.com (Bryan O'Sullivan) Date: Sat, 9 Feb 2013 13:58:47 -0800 Subject: [PATCH] parsedate: understand "now" as a shortcut for the current time In-Reply-To: References: Message-ID: On Sat, Feb 9, 2013 at 1:57 PM, Augie Fackler wrote: > parsedate: understand "now" as a shortcut for the current time > LGTM. -------------- next part -------------- An HTML attachment was scrubbed... URL: From pierre-yves.david at ens-lyon.org Sat Feb 9 16:09:09 2013 From: pierre-yves.david at ens-lyon.org (pierre-yves.david at ens-lyon.org) Date: Sat, 09 Feb 2013 22:09:09 +0000 Subject: [PATCH RESEND] test: display used python hash seed Message-ID: <27f60febcba4f36ec23d.1360447749@serpens.logilab.fr> # HG changeset patch # User Pierre-Yves David # Date 1359505444 -3600 # Node ID 27f60febcba4f36ec23d8e6cc67be54f176eea33 # Parent 0b6e6eacc939c303136cb38af108e307d640c26e test: display used python hash seed We keep using a random seed for each run, but we "compute" it ourself to be able to reproduce a failed test run. diff --git a/tests/run-tests.py b/tests/run-tests.py --- a/tests/run-tests.py +++ b/tests/run-tests.py @@ -50,10 +50,11 @@ import shutil import subprocess import signal import sys import tempfile import time +import random import re import threading import killdaemons as killmod import cPickle as pickle import Queue as queue @@ -1251,11 +1252,15 @@ def main(): os.environ['GREP_OPTIONS'] = '' os.environ['http_proxy'] = '' os.environ['no_proxy'] = '' os.environ['NO_PROXY'] = '' os.environ['TERM'] = 'xterm' - os.environ['PYTHONHASHSEED'] = os.environ.get('PYTHONHASHSEED', 'random') + if 'PYTHONHASHSEED' not in os.environ: + # use a random python hash seed all the time + # we do the randomness ourself to know what seed is used + os.environ['PYTHONHASHSEED'] = str(random.getrandbits(32)) + print 'python hash seed:', os.environ['PYTHONHASHSEED'] # unset env related to hooks for k in os.environ.keys(): if k.startswith('HG_'): # can't remove on solaris From raf at durin42.com Sat Feb 9 16:10:53 2013 From: raf at durin42.com (Augie Fackler) Date: Sat, 9 Feb 2013 22:10:53 +0000 Subject: [PATCH STABLE] outgoing: fix possible filtering crash in outgoing (issue3814) In-Reply-To: References: Message-ID: <1A5CD981-4509-4B05-8EB9-C9A4171F6353@durin42.com> crewed On Feb 9, 2013, at 8:47 PM, pierre-yves.david at ens-lyon.org wrote: > # HG changeset patch > # User Pierre-Yves David > # Date 1360432441 0 > # Branch stable > # Node ID c76622632f68a66539f7468363f195a6564dd0bb > # Parent 9a06aab5981b510a22900d2686a597afe7a5dfbe > outgoing: fix possible filtering crash in outgoing (issue3814) > > If there is no outgoiing changesets but we have filtered revision in outgoing.excluded > We run into a filtering related crash. The excluded revision should not be there > in the first place but discovery need cleanup in default, not stable. > > diff --git a/mercurial/scmutil.py b/mercurial/scmutil.py > --- a/mercurial/scmutil.py > +++ b/mercurial/scmutil.py > @@ -16,10 +16,14 @@ def nochangesfound(ui, repo, excluded=No > nodes excluded from the push/pull. > ''' > secretlist = [] > if excluded: > for n in excluded: > + if n not in repo: > + # discovery should not have included the filtered revision, > + # we have to explicitly exclude it until discovery is cleanup. > + continue > ctx = repo[n] > if ctx.phase() >= phases.secret and not ctx.extinct(): > secretlist.append(n) > > if secretlist: > diff --git a/tests/test-obsolete.t b/tests/test-obsolete.t > --- a/tests/test-obsolete.t > +++ b/tests/test-obsolete.t > @@ -863,5 +863,27 @@ This test issue 3805 > [1] > > $ "$TESTDIR/killdaemons.py" $DAEMON_PIDS > > #endif > + > +This test issue 3814 > + > +(nothing to push but locally hidden changeset) > + > + $ cd .. > + $ hg init repo-issue3814 > + $ cd repo-issue3805 > + $ hg push -r 3816541e5485 ../repo-issue3814 > + pushing to ../repo-issue3814 > + searching for changes > + adding changesets > + adding manifests > + adding file changes > + added 1 changesets with 1 changes to 1 files > + $ hg out ../repo-issue3814 > + comparing with ../repo-issue3814 > + searching for changes > + no changes found > + [1] > + > + > _______________________________________________ > Mercurial-devel mailing list > Mercurial-devel at selenic.com > http://selenic.com/mailman/listinfo/mercurial-devel From raf at durin42.com Sat Feb 9 16:16:17 2013 From: raf at durin42.com (Augie Fackler) Date: Sat, 9 Feb 2013 22:16:17 +0000 Subject: [PATCH] export: clobber files with -o (bc) (issue3652) In-Reply-To: <1a2f4c633410f6bc49b9.1360446156@augie-macbookair> References: <1a2f4c633410f6bc49b9.1360446156@augie-macbookair> Message-ID: Kevin and Bryan generously looked this over in meatspace. Pushed. On Feb 9, 2013, at 9:42 PM, Augie Fackler wrote: > # HG changeset patch > # User Augie Fackler > # Date 1360445937 21600 > # Node ID 1a2f4c633410f6bc49b94c65d74939165bbc2dd7 > # Parent 0b6e6eacc939c303136cb38af108e307d640c26e > export: clobber files with -o (bc) (issue3652) > > This violated user expectation. Updated the code to clobber files, but > preserve the behavior of appending multiple patches requested in a > single export. Includes tests. > > diff --git a/mercurial/cmdutil.py b/mercurial/cmdutil.py > --- a/mercurial/cmdutil.py > +++ b/mercurial/cmdutil.py > @@ -170,7 +170,8 @@ > inst.args[0]) > > def makefileobj(repo, pat, node=None, desc=None, total=None, > - seqno=None, revwidth=None, mode='wb', pathname=None): > + seqno=None, revwidth=None, mode='wb', modemap={}, > + pathname=None): > > writable = mode not in ('r', 'rb') > > @@ -196,9 +197,11 @@ > return pat > if util.safehasattr(pat, 'read') and 'r' in mode: > return pat > - return open(makefilename(repo, pat, node, desc, total, seqno, revwidth, > - pathname), > - mode) > + fn = makefilename(repo, pat, node, desc, total, seqno, revwidth, pathname) > + mode = modemap.get(fn, mode) > + if mode == 'wb': > + modemap[fn] = 'ab' > + return open(fn, mode) > > def openrevlog(repo, cmd, file_, opts): > """opens the changelog, manifest, a filelog or a given revlog""" > @@ -539,6 +542,7 @@ > > total = len(revs) > revwidth = max([len(str(rev)) for rev in revs]) > + filemode = {} > > def single(rev, seqno, fp): > ctx = repo[rev] > @@ -554,7 +558,8 @@ > desc_lines = ctx.description().rstrip().split('\n') > desc = desc_lines[0] #Commit always has a first line. > fp = makefileobj(repo, template, node, desc=desc, total=total, > - seqno=seqno, revwidth=revwidth, mode='ab') > + seqno=seqno, revwidth=revwidth, mode='wb', > + modemap=filemode) > if fp != template: > shouldclose = True > if fp and fp != sys.stdout and util.safehasattr(fp, 'name'): > diff --git a/tests/test-export.t b/tests/test-export.t > --- a/tests/test-export.t > +++ b/tests/test-export.t > @@ -91,13 +91,28 @@ > foo-foo_10.patch > foo-foo_11.patch > > +Doing it again clobbers the files rather than appending: > + $ hg export -v -o "foo-%m.patch" 2:3 > + exporting patches: > + foo-foo_2.patch > + foo-foo_3.patch > + $ grep HG foo-foo_2.patch | wc -l > + \s*1 (re) > + $ grep HG foo-foo_3.patch | wc -l > + \s*1 (re) > + > Exporting 4 changesets to a file: > > $ hg export -o export_internal 1 2 3 4 > $ grep HG export_internal | wc -l > \s*4 (re) > > -Exporting 4 changesets to a file: > +Doing it again clobbers the file rather than appending: > + $ hg export -o export_internal 1 2 3 4 > + $ grep HG export_internal | wc -l > + \s*4 (re) > + > +Exporting 4 changesets to stdout: > > $ hg export 1 2 3 4 | grep HG | wc -l > \s*4 (re) > _______________________________________________ > Mercurial-devel mailing list > Mercurial-devel at selenic.com > http://selenic.com/mailman/listinfo/mercurial-devel From hgbuildbot at kublai.com Sat Feb 9 16:22:58 2013 From: hgbuildbot at kublai.com (hgbuildbot at kublai.com) Date: Sat, 09 Feb 2013 14:22:58 -0800 Subject: buildbot failure in Mercurial on hg tests Message-ID: <20130209222258.CD7E536EB3@hgbuildbot.cs.ubc.ca> The Buildbot has detected a new failure on builder hg tests while building hg. Full details are available at: http://hgbuildbot.kublai.com/builders/hg%20tests/builds/489 Buildbot URL: http://hgbuildbot.kublai.com/ Buildslave for this Build: p64.osuosl.test Build Reason: scheduler Build Source Stamp: [branch default] 0b6e6eacc939c303136cb38af108e307d640c26e Blamelist: Bryan O'Sullivan BUILD FAILED: failed run-tests.py (python2.5) sincerely, -The Buildbot From mpm at selenic.com Sat Feb 9 16:19:39 2013 From: mpm at selenic.com (Matt Mackall) Date: Sat, 09 Feb 2013 22:19:39 +0000 Subject: [PATCH 3 of 3] summary: show active bookmark even if not at current changeset In-Reply-To: <9d727e125244520c4fe6.1360432474@s0-0.paconsult7.bbnplanet.net> References: <501b0d5829a15fbf4d79.1360432472@s0-0.paconsult7.bbnplanet.net> <9d727e125244520c4fe6.1360432474@s0-0.paconsult7.bbnplanet.net> Message-ID: <1360448379.3873.46.camel@calx> On Sat, 2013-02-09 at 17:54 +0000, Kevin Bullock wrote: > # HG changeset patch > # User Kevin Bullock > # Date 1360360042 0 > # Node ID 9d727e125244520c4fe60a4b8d60e29269d24af3 > # Parent 04f1a301c90a00480839f8ee86c7e550a7e98f87 > summary: show active bookmark even if not at current changeset > > Before this change, 'hg summary' would not show the active bookmark > unless it pointed to the working directory parent. After this change, it > will show it in parentheses, like so: > > parent: 18581:f0ff45fe6700 tip > summary: simplify handling of active bookmark > branch: default > bookmarks: [crew] > commit: (clean) > update: (current) Looks good to me. > diff --git a/mercurial/commands.py b/mercurial/commands.py > --- a/mercurial/commands.py > +++ b/mercurial/commands.py > @@ -5574,9 +5574,12 @@ def summary(ui, repo, **opts): > current = repo._bookmarkcurrent > # i18n: column positioning for "hg summary" > ui.write(_('bookmarks:'), label='log.bookmark') > - if current is not None and current in marks: > - ui.write(' *' + current, label='bookmarks.current') > - marks.remove(current) > + if current is not None: > + if current in marks: > + ui.write(' *' + current, label='bookmarks.current') > + marks.remove(current) > + else: > + ui.write('[%s]' % current, label='bookmarks.current') > for m in marks: > ui.write(' ' + m, label='log.bookmark') > ui.write('\n', label='log.bookmark') > diff --git a/tests/test-bookmarks.t b/tests/test-bookmarks.t > --- a/tests/test-bookmarks.t > +++ b/tests/test-bookmarks.t > @@ -471,7 +471,7 @@ update to current bookmark if it's not t > parent: 2:db815d6d32e6 > 2 > branch: default > - bookmarks: Y x y > + bookmarks:[Z] Y x y > commit: 1 added, 1 unknown (new branch head) > update: 2 new changesets (update) > $ hg update > _______________________________________________ > Mercurial-devel mailing list > Mercurial-devel at selenic.com > http://selenic.com/mailman/listinfo/mercurial-devel -- Mathematics is the supreme nostalgia of our time. From bos at serpentine.com Sat Feb 9 16:21:52 2013 From: bos at serpentine.com (Bryan O'Sullivan) Date: Sat, 9 Feb 2013 14:21:52 -0800 Subject: [PATCH RESEND] test: display used python hash seed In-Reply-To: <27f60febcba4f36ec23d.1360447749@serpens.logilab.fr> References: <27f60febcba4f36ec23d.1360447749@serpens.logilab.fr> Message-ID: On Sat, Feb 9, 2013 at 2:09 PM, wrote: > test: display used python hash seed > Pushed to crew, thanks. -------------- next part -------------- An HTML attachment was scrubbed... URL: From natosha at unity3d.com Sat Feb 9 16:28:34 2013 From: natosha at unity3d.com (Na'Tosha Bard) Date: Sat, 9 Feb 2013 22:28:34 +0000 Subject: [PATCH 11 of 11] merge: don't fiddle with name lookups or i18n in hot loops In-Reply-To: <994e4c0ed9a6d2ff25aa.1360418811@australite.local> References: <8cf626e958d3dd67e45b.1360418801@australite.local> <994e4c0ed9a6d2ff25aa.1360418811@australite.local> Message-ID: 2013/2/9 Bryan O'Sullivan > # HG changeset patch > # User Bryan O'Sullivan > # Date 1360418465 0 > # Node ID 994e4c0ed9a6d2ff25aacfcc9603ed9cef3909ac > # Parent a278d66b8f8621ebafbb30a201000fca63983697 > merge: don't fiddle with name lookups or i18n in hot loops I tested this entire patch series on the Unity repo *Before the patch series, updating from null to tip (~57.000 files) on OS X: real 1m17.607s user 0m32.664s sys 0m24.141s After the patch series: real 0m36.322s user 0m38.497s sys 0m30.022s* -- *Na'Tosha Bard* Software Developer | Unity Technologies - Copenhagen *E-Mail:* natosha at unity3d.com *Skype:* natosha.bard -------------- next part -------------- An HTML attachment was scrubbed... URL: From hg at intevation.org Sat Feb 9 16:45:10 2013 From: hg at intevation.org (Mercurial Commits) Date: Sat, 09 Feb 2013 23:45:10 +0100 Subject: mercurial@18616: 4 new changesets Message-ID: <1360449910.905149.20476.nullmailer@hg.intevation.org> 4 new changesets in mercurial: http://selenic.com/repo/hg//rev/1a2f4c633410 changeset: 18613:1a2f4c633410 user: Augie Fackler date: Sat Feb 09 15:38:57 2013 -0600 summary: export: clobber files with -o (bc) (issue3652) http://selenic.com/repo/hg//rev/b2586e2cc67a changeset: 18614:b2586e2cc67a user: Augie Fackler date: Sat Feb 09 15:39:22 2013 -0600 summary: parsedate: understand "now" as a shortcut for the current time http://selenic.com/repo/hg//rev/e7b89b5127c2 changeset: 18615:e7b89b5127c2 user: Pierre-Yves David date: Sat Feb 09 17:54:01 2013 +0000 summary: outgoing: fix possible filtering crash in outgoing (issue3814) http://selenic.com/repo/hg//rev/35b4affe6fdd changeset: 18616:35b4affe6fdd tag: tip user: Pierre-Yves David date: Wed Jan 30 01:24:04 2013 +0100 summary: test: display used python hash seed -- Repository URL: http://selenic.com/repo/hg/ From martin at geisler.net Sat Feb 9 16:58:40 2013 From: martin at geisler.net (Martin Geisler) Date: Sat, 09 Feb 2013 23:58:40 +0100 Subject: [PATCH 2 of 3 V3 [NOW_WITH_DOCS!]] hgweb: apply the websub filter to revision descriptions In-Reply-To: <3d1290c7131e8e1df991.1360425301@Angel-PC.localdomain> (sfid-20130209_172015_360749_F2D92680) (Angel Ezquerra's message of "Sat, 09 Feb 2013 16:55:01 +0100") References: <3d1290c7131e8e1df991.1360425301@Angel-PC.localdomain> Message-ID: <878v6x14db.fsf@go.home> Angel Ezquerra writes: > # HG changeset patch > # User Angel Ezquerra > # Date 1360424901 -3600 > # Node ID 3d1290c7131e8e1df991f1753ab5e76d3e3cd21e > # Parent 04299b2afc200171eeca472c5d5644e84048a3b5 > hgweb: apply the websub filter to revision descriptions > > In order to use this, add a [websub] section to your configuration and add > websub expressions such as: > > italic = s/\b_(\S+)_\b/\1<\/i>/ > bold = s/\*\b(\S+)\b\*/\1<\/b>/ > issues = s|issue(\d+)|issue\1|i > bugzilla = s!((?:bug|b=|(?=#?\d{4,}))(?:\s*#?)(\d+))!\1!i > > This also adds documentation (proofed by Kevin!) to the config help section. > > diff --git a/mercurial/help/config.txt b/mercurial/help/config.txt > --- a/mercurial/help/config.txt > +++ b/mercurial/help/config.txt > @@ -1463,3 +1463,36 @@ > > ``templates`` > Where to find the HTML templates. Default is install path. > + > +``websub`` > +------- The underline should be three '-'s longer to match the text. -- Martin Geisler From bos at serpentine.com Sat Feb 9 16:59:49 2013 From: bos at serpentine.com (Bryan O'Sullivan) Date: Sat, 9 Feb 2013 14:59:49 -0800 Subject: [PATCH V3] hgweb: teach archive how to handle file patterns In-Reply-To: References: Message-ID: On Sat, Feb 9, 2013 at 12:42 PM, Angel Ezquerra wrote: > +++ b/mercurial/hgweb/webcommands.py > @@ -795,7 +795,7 @@ > if not ((type_ in allowed or > web.configbool("web", "allow" + type_, False))): > msg = 'Archive type not allowed: %s' % type_ > - raise ErrorResponse(HTTP_FORBIDDEN, msg) > + #raise ErrorResponse(HTTP_FORBIDDEN, msg) > Oops? -------------- next part -------------- An HTML attachment was scrubbed... URL: From martin at geisler.net Sat Feb 9 17:03:30 2013 From: martin at geisler.net (Martin Geisler) Date: Sun, 10 Feb 2013 00:03:30 +0100 Subject: [PATCH 3 of 3 V3 [NOW_WITH_DOCS!]] extensions: obsolete and remove interhg extension In-Reply-To: <6b18726f164093ab77ac.1360425302@Angel-PC.localdomain> (sfid-20130209_172015_979861_EF0686CE) (Angel Ezquerra's message of "Sat, 09 Feb 2013 16:55:02 +0100") References: <6b18726f164093ab77ac.1360425302@Angel-PC.localdomain> Message-ID: <8738x51459.fsf@go.home> Angel Ezquerra writes: > # HG changeset patch > # User Angel Ezquerra > # Date 1360404042 -3600 > # Node ID 6b18726f164093ab77ac754b088be2e90482b65c > # Parent 3d1290c7131e8e1df991f1753ab5e76d3e3cd21e > extensions: obsolete and remove interhg extension > > With the addition of the websub filter extension this extension is no longer > needed. We maintain a sort of backwards compatibility by reading the [interhg] > section and using it as we would use the [websub] section. > > diff --git a/mercurial/extensions.py b/mercurial/extensions.py > --- a/mercurial/extensions.py > +++ b/mercurial/extensions.py > @@ -11,7 +11,7 @@ > > _extensions = {} > _order = [] > -_ignore = ['hbisect', 'bookmarks', 'parentrevspec'] > +_ignore = ['hbisect', 'bookmarks', 'parentrevspec', 'interhg'] > > def extensions(): > for name in _order: > diff --git a/mercurial/hgweb/hgweb_mod.py b/mercurial/hgweb/hgweb_mod.py > --- a/mercurial/hgweb/hgweb_mod.py > +++ b/mercurial/hgweb/hgweb_mod.py > @@ -8,6 +8,7 @@ > > import os > from mercurial import ui, hg, hook, error, encoding, templater, util, repoview > +from mercurial import extensions > from mercurial.templatefilters import websub > from mercurial.i18n import _ > from common import get_stat, ErrorResponse, permhooks, caching > @@ -264,6 +265,8 @@ > def loadwebsub(self): > websubtable = [] > websubdefs = self.repo.ui.configitems('websub') > + # we must maintain interhg backwards compatibility > + websubdefs += self.repo.ui.configitems('interhg') Would it not be better if the interhg extension became a tiny extension that just did this? That way the core wont need to care about the old functionality and new users wont have to care about patterns in an [interhg] extension. -- Martin Geisler From bos at serpentine.com Sat Feb 9 17:04:28 2013 From: bos at serpentine.com (Bryan O'Sullivan) Date: Sat, 9 Feb 2013 15:04:28 -0800 Subject: [PATCH] export: show 'Date' header in a format that also is readable for humans In-Reply-To: <055060daf58dbe46c667.1360402284@localhost.localdomain> References: <055060daf58dbe46c667.1360402284@localhost.localdomain> Message-ID: On Sat, Feb 9, 2013 at 1:31 AM, Mads Kiilerich wrote: > export: show 'Date' header in a format that also is readable for humans > Looks good to me. -------------- next part -------------- An HTML attachment was scrubbed... URL: From mpm at selenic.com Sat Feb 9 17:06:59 2013 From: mpm at selenic.com (Matt Mackall) Date: Sat, 09 Feb 2013 23:06:59 +0000 Subject: [PATCH 3 of 3 V3 [NOW_WITH_DOCS!]] extensions: obsolete and remove interhg extension In-Reply-To: <8738x51459.fsf@go.home> References: <6b18726f164093ab77ac.1360425302@Angel-PC.localdomain> <8738x51459.fsf@go.home> Message-ID: <1360451219.3873.47.camel@calx> On Sun, 2013-02-10 at 00:03 +0100, Martin Geisler wrote: > Angel Ezquerra writes: > > > # HG changeset patch > > # User Angel Ezquerra > > # Date 1360404042 -3600 > > # Node ID 6b18726f164093ab77ac754b088be2e90482b65c > > # Parent 3d1290c7131e8e1df991f1753ab5e76d3e3cd21e > > extensions: obsolete and remove interhg extension > > > > With the addition of the websub filter extension this extension is no longer > > needed. We maintain a sort of backwards compatibility by reading the [interhg] > > section and using it as we would use the [websub] section. > > > > diff --git a/mercurial/extensions.py b/mercurial/extensions.py > > --- a/mercurial/extensions.py > > +++ b/mercurial/extensions.py > > @@ -11,7 +11,7 @@ > > > > _extensions = {} > > _order = [] > > -_ignore = ['hbisect', 'bookmarks', 'parentrevspec'] > > +_ignore = ['hbisect', 'bookmarks', 'parentrevspec', 'interhg'] > > > > def extensions(): > > for name in _order: > > diff --git a/mercurial/hgweb/hgweb_mod.py b/mercurial/hgweb/hgweb_mod.py > > --- a/mercurial/hgweb/hgweb_mod.py > > +++ b/mercurial/hgweb/hgweb_mod.py > > @@ -8,6 +8,7 @@ > > > > import os > > from mercurial import ui, hg, hook, error, encoding, templater, util, repoview > > +from mercurial import extensions > > from mercurial.templatefilters import websub > > from mercurial.i18n import _ > > from common import get_stat, ErrorResponse, permhooks, caching > > @@ -264,6 +265,8 @@ > > def loadwebsub(self): > > websubtable = [] > > websubdefs = self.repo.ui.configitems('websub') > > + # we must maintain interhg backwards compatibility > > + websubdefs += self.repo.ui.configitems('interhg') > > Would it not be better if the interhg extension became a tiny extension > that just did this? > > That way the core wont need to care about the old functionality and new > users wont have to care about patterns in an [interhg] extension. We considered this. I'd prefer to have the extension go away. -- Mathematics is the supreme nostalgia of our time. From martin at geisler.net Sat Feb 9 17:07:45 2013 From: martin at geisler.net (Martin Geisler) Date: Sun, 10 Feb 2013 00:07:45 +0100 Subject: [PATCH 3 of 6] help: ReST tweaks In-Reply-To: <03c9cfc461cce54da65f.1360414837@s0-0.paconsult7.bbnplanet.net> (sfid-20130209_142009_595890_D2672C7D) (Dan Villiom Podlaski Christiansen's message of "Sat, 09 Feb 2013 13:00:37 +0000") References: <03c9cfc461cce54da65f.1360414837@s0-0.paconsult7.bbnplanet.net> Message-ID: <87y5exytku.fsf@go.home> Dan Villiom Podlaski Christiansen writes: > # HG changeset patch > # User Dan Villiom Podlaski Christiansen > # Date 1360414103 0 > # Node ID 03c9cfc461cce54da65f0ad0529a734181022b83 > # Parent aa74feb1f11d43453e6ef3797e6c4c24f950a9dc > help: ReST tweaks > > Use a full header for topic titles; make the indent configurable by > the caller > > diff --git a/mercurial/help.py b/mercurial/help.py > --- a/mercurial/help.py > +++ b/mercurial/help.py > @@ -389,12 +389,17 @@ def help_(ui, name, unknowncmd=False, fu > else: > raise error.UnknownCommand(name) > > - rst = ["%s\n\n" % header] > + headerstyleline = '=' * encoding.colwidth(header) > + rst = ["%s\n%s\n%s\n\n" % (headerstyleline, header, headerstyleline)] When we discussed this I had a strong feeling that we already had this code available somewhere: it's in doc/gendoc.py :) Maybe you could move this into minirst and then let gendoc import it back -- that way we get consistent headings. -- Martin Geisler From martin at geisler.net Sat Feb 9 17:10:16 2013 From: martin at geisler.net (Martin Geisler) Date: Sun, 10 Feb 2013 00:10:16 +0100 Subject: [PATCH 3 of 6] help: ReST tweaks In-Reply-To: <03c9cfc461cce54da65f.1360414837@s0-0.paconsult7.bbnplanet.net> (sfid-20130209_142009_595890_D2672C7D) (Dan Villiom Podlaski Christiansen's message of "Sat, 09 Feb 2013 13:00:37 +0000") References: <03c9cfc461cce54da65f.1360414837@s0-0.paconsult7.bbnplanet.net> Message-ID: <87txplytgn.fsf@go.home> Dan Villiom Podlaski Christiansen writes: > # HG changeset patch > # User Dan Villiom Podlaski Christiansen > # Date 1360414103 0 > # Node ID 03c9cfc461cce54da65f0ad0529a734181022b83 > # Parent aa74feb1f11d43453e6ef3797e6c4c24f950a9dc > help: ReST tweaks > > Use a full header for topic titles; make the indent configurable by > the caller > > diff --git a/mercurial/help.py b/mercurial/help.py > --- a/mercurial/help.py > +++ b/mercurial/help.py > @@ -389,12 +389,17 @@ def help_(ui, name, unknowncmd=False, fu > else: > raise error.UnknownCommand(name) > > - rst = ["%s\n\n" % header] > + headerstyleline = '=' * encoding.colwidth(header) > + rst = ["%s\n%s\n%s\n\n" % (headerstyleline, header, headerstyleline)] > + > # description > if not doc: > - rst.append(" %s\n" % _("(no help text available)")) > + doc = _("(no help text available)") > if util.safehasattr(doc, '__call__'): > - rst += [" %s\n" % l for l in doc().splitlines()] > + doc = doc() > + > + indent = ' ' * int(opts.get('indent', 4)) > + rst += ["%s%s\n" % (indent, l) for l in doc.splitlines()] The minirst.format function has an indent argument -- can that not be used instead? -- Martin Geisler From hgbuildbot at kublai.com Sat Feb 9 17:16:36 2013 From: hgbuildbot at kublai.com (hgbuildbot at kublai.com) Date: Sat, 09 Feb 2013 15:16:36 -0800 Subject: buildbot success in Mercurial on OS X 10.7 hg tests Message-ID: <20130209231637.B33DA36DFE@hgbuildbot.cs.ubc.ca> The Buildbot has detected a restored build on builder OS X 10.7 hg tests while building hg. Full details are available at: http://hgbuildbot.kublai.com/builders/OS%20X%2010.7%20hg%20tests/builds/404 Buildbot URL: http://hgbuildbot.kublai.com/ Buildslave for this Build: lion Build Reason: scheduler Build Source Stamp: [branch default] 54211081745094b4ff3ec3e824dcacf24c89d1ff Blamelist: Augie Fackler ,Benoit Boissinot ,Kevin Bullock Build succeeded! sincerely, -The Buildbot From hg at intevation.org Sat Feb 9 17:15:23 2013 From: hg at intevation.org (Mercurial Commits) Date: Sun, 10 Feb 2013 00:15:23 +0100 Subject: mercurial@18623: 7 new changesets (1 stable) Message-ID: <1360451723.214629.21495.nullmailer@hg.intevation.org> 7 new changesets (1 stable) in mercurial: http://selenic.com/repo/hg//rev/227479f61db9 changeset: 18617:227479f61db9 branch: stable parent: 18580:9a06aab5981b user: Pierre-Yves David date: Sat Feb 09 17:54:01 2013 +0000 summary: outgoing: fix possible filtering crash in outgoing (issue3814) http://selenic.com/repo/hg//rev/43ffd0279876 changeset: 18618:43ffd0279876 parent: 18615:e7b89b5127c2 parent: 18617:227479f61db9 user: Kevin Bullock date: Sat Feb 09 22:25:58 2013 +0000 summary: merge with stable http://selenic.com/repo/hg//rev/c768e3da3cc2 changeset: 18619:c768e3da3cc2 parent: 18618:43ffd0279876 parent: 18616:35b4affe6fdd user: Kevin Bullock date: Sat Feb 09 22:27:13 2013 +0000 summary: merge crew heads http://selenic.com/repo/hg//rev/7da487b0256a changeset: 18620:7da487b0256a user: Kevin Bullock date: Fri Feb 08 21:32:43 2013 +0000 summary: summary: test that current bookmark isn't shown http://selenic.com/repo/hg//rev/b1e949f6c17d changeset: 18621:b1e949f6c17d user: Kevin Bullock date: Sun Jan 27 11:53:46 2013 -0600 summary: summary: simplify handling of active bookmark http://selenic.com/repo/hg//rev/f9eebf5629fa changeset: 18622:f9eebf5629fa user: Kevin Bullock date: Fri Feb 08 21:47:22 2013 +0000 summary: summary: show active bookmark even if not at current changeset http://selenic.com/repo/hg//rev/0027a5cec9d0 changeset: 18623:0027a5cec9d0 tag: tip user: Matt Mackall date: Sat Feb 09 22:54:34 2013 +0000 summary: summary: add missing space for updated active bookmark display -- Repository URL: http://selenic.com/repo/hg/ From brodie at sf.io Sat Feb 9 17:15:58 2013 From: brodie at sf.io (Brodie Rao) Date: Sat, 9 Feb 2013 23:15:58 +0000 Subject: [PATCH V3] hgweb: teach archive how to handle file patterns In-Reply-To: References: Message-ID: On Sat, Feb 9, 2013 at 8:42 PM, Angel Ezquerra wrote: > # HG changeset patch > # User Angel Ezquerra > # Date 1360141605 -3600 > # Node ID c0509330eb416104bed8cc7d0a4038f818dd5e5d > # Parent b6c8e79948a05d01920392cd12ac5c8279d5c62b > hgweb: teach archive how to handle file patterns > > The archive web command now takes into account the "file" request entry, if one > is provided. > > The provided "file" is processed as a "path" pattern by default, which makes it > easy to only archive a certain file or directory. However, it is possible to > specify a different type of pattern, such as relglob by specifying it > explicitly on the query URL. Note that only "safe" patterns are allowed. Safe > patterns are 'path', 'relpath', 'glog' and 'relglob'. Other pattern types are > not allowed because they could be expensive to calculate. > > With this change hgweb can to process requests such as: > > 1. http://mercurial.selenic.com/hg/tip.zip/mercurial/templates > > This will download all files on the mercurial/templates directory as a zip > file The format for this URL seems a little strange. What happens if you do 'curl -O http://mercurial.selenic.com/hg/tip.zip/mercurial/templates'? Does it figure out that the filename should be tip.zip? And what happens if you want to download an archive for a branch/bookmark/tag that has forward slashes in it? I wonder if making this a GET parameter might be cleaner. > 2. http://mercurial.selenic.com/hg/tip.tar.gz/relglob:*.py > > This will download all *.py files in the repository into a tar.gz file. > > An so forth. > > Note that this is a first step to add support for downloading directories from > the web interface. Currently the only way to use this feature is by manually > constructing the URL that you want to download. We will have to modify the > archiveentry map entry on the different templates so that it adds the current > folder path to the archive links. > > This revision also adds a test for this feature to test-archive.t. > > diff --git a/mercurial/hgweb/webcommands.py b/mercurial/hgweb/webcommands.py > --- a/mercurial/hgweb/webcommands.py > +++ b/mercurial/hgweb/webcommands.py > @@ -795,7 +795,7 @@ > if not ((type_ in allowed or > web.configbool("web", "allow" + type_, False))): > msg = 'Archive type not allowed: %s' % type_ > - raise ErrorResponse(HTTP_FORBIDDEN, msg) > + #raise ErrorResponse(HTTP_FORBIDDEN, msg) > > reponame = re.sub(r"\W+", "-", os.path.basename(web.reponame)) > cnode = web.repo.lookup(key) > @@ -803,6 +803,17 @@ > if cnode == key or key == 'tip': > arch_version = short(cnode) > name = "%s-%s" % (reponame, arch_version) > + > + ctx = webutil.changectx(web.repo, req) > + pats = [] > + file = req.form.get('file', None) > + defaultpat = 'path' > + if file: > + pats = [req.form['file'][0]] > + if not scmutil.patsaresafe(pats, defaultpat): > + msg = 'Archive pattern not allowed: %s' % pats[0] > + raise ErrorResponse(HTTP_FORBIDDEN, msg) > + > mimetype, artype, extension, encoding = web.archive_specs[type_] > headers = [ > ('Content-Disposition', 'attachment; filename=%s%s' % (name, extension)) > @@ -811,10 +822,9 @@ > headers.append(('Content-Encoding', encoding)) > req.headers.extend(headers) > req.respond(HTTP_OK, mimetype) > - > - ctx = webutil.changectx(web.repo, req) > + matchfn = scmutil.match(ctx, pats, default=defaultpat) > archival.archive(web.repo, req, cnode, artype, prefix=name, > - matchfn=scmutil.match(ctx, []), > + matchfn=matchfn, > subrepos=web.configbool("web", "archivesubrepos")) > return [] > > diff --git a/mercurial/scmutil.py b/mercurial/scmutil.py > --- a/mercurial/scmutil.py > +++ b/mercurial/scmutil.py > @@ -682,6 +682,15 @@ > > return l > > +def patsaresafe(pats, defaultpattype): > + for pat in pats: > + pattype = defaultpattype > + if ':' in pat: > + pattype = pat.split(':')[0] > + if pattype.lower() not in ('path', 'relpath', 'glog', 'relglob'): > + return False > + return True > + > def expandpats(pats): > if not util.expandglobs: > return list(pats) > diff --git a/tests/test-archive.t b/tests/test-archive.t > --- a/tests/test-archive.t > +++ b/tests/test-archive.t > @@ -69,9 +69,14 @@ > > msvcrt.setmode(sys.stdout.fileno(), os.O_BINARY) > > except ImportError: > > pass > - > node, archive = sys.argv[1:] > - > f = urllib2.urlopen('http://127.0.0.1:%s/?cmd=archive;node=%s;type=%s' > - > % (os.environ['HGPORT'], node, archive)) > + > if len(sys.argv) <= 3: > + > node, archive = sys.argv[1:] > + > requeststr = 'cmd=archive;node=%s;type=%s' % (node, archive) > + > else: > + > node, archive, file = sys.argv[1:] > + > requeststr = 'cmd=archive;node=%s;type=%s;file=%s' % (node, archive, file) > + > f = urllib2.urlopen('http://127.0.0.1:%s/?%s' > + > % (os.environ['HGPORT'], requeststr)) > > sys.stdout.write(f.read()) > > EOF > $ python getarchive.py "$TIP" gz | gunzip | tar tf - 2>/dev/null > @@ -92,6 +97,8 @@ > testing: test-archive-2c0277f05ed4/baz/bletch OK > testing: test-archive-2c0277f05ed4/foo OK > No errors detected in compressed data of archive.zip. > + $ python getarchive.py "$TIP" gz baz | gunzip | tar tf - 2>/dev/null > + test-archive-2c0277f05ed4/baz/bletch > > $ "$TESTDIR/killdaemons.py" $DAEMON_PIDS > > _______________________________________________ > Mercurial-devel mailing list > Mercurial-devel at selenic.com > http://selenic.com/mailman/listinfo/mercurial-devel From mads at kiilerich.com Sat Feb 9 17:22:36 2013 From: mads at kiilerich.com (Mads Kiilerich) Date: Sun, 10 Feb 2013 00:22:36 +0100 Subject: [PATCH] serve: introduce --get and --post for easy testing of hgweb Message-ID: <86f6b4786d8d292843a9.1360452156@localhost.localdomain> # HG changeset patch # User Mads Kiilerich # Date 1359297965 -3600 # Node ID 86f6b4786d8d292843a9509b0c99f8e855ef4e9d # Parent 19f90544863eadb00baf80ef21811d41b2beb54b serve: introduce --get and --post for easy testing of hgweb These options can be useful both in the test suite and for other kinds of hgweb testing. diff --git a/mercurial/commands.py b/mercurial/commands.py --- a/mercurial/commands.py +++ b/mercurial/commands.py @@ -8,7 +8,7 @@ from node import hex, bin, nullid, nullrev, short from lock import release from i18n import _, gettext -import os, re, difflib, time, tempfile, errno +import os, re, difflib, time, tempfile, errno, sys import hg, scmutil, util, revlog, extensions, copies, error, bookmarks import patch, help, encoding, templatekw, discovery import archival, changegroup, cmdutil, hbisect @@ -5251,7 +5251,9 @@ ('t', 'templates', '', _('web templates to use'), _('TEMPLATE')), ('', 'style', '', _('template style to use'), _('STYLE')), ('6', 'ipv6', None, _('use IPv6 in addition to IPv4')), - ('', 'certificate', '', _('SSL certificate file'), _('FILE'))], + ('', 'certificate', '', _('SSL certificate file'), _('FILE')), + ('', 'get', '', _('just GET url'), _('URL')), + ('', 'post', '', _('just POST url'), _('URL'))], _('[OPTION]...')) def serve(ui, repo, **opts): """start stand-alone webserver @@ -5275,6 +5277,9 @@ a port number of 0; in this case, the server will print the port number it uses. + --get and --post will process a single hgweb request and show the output + without starting a server. Headers will be shown in verbose mode. + Returns 0 on success. """ @@ -5320,6 +5325,45 @@ app = hgweb.hgweb(o, baseui=ui) + get = opts.get('get') + post = opts.get('post') + if get or post: + url = util.url(get or post) + + environ = dict(os.environ.iteritems()) + environ['REQUEST_METHOD'] = get and 'GET' or 'POST' + environ['wsgi.url_scheme'] = url.scheme or 'http' + environ['SERVER_NAME'] = url.host or 'localhost' + environ['SERVER_PORT'] = url.port or (url.scheme == 'https' and '443' or '80') + environ['SCRIPT_NAME'] = '' + environ['PATH_INFO'] = '/' + url.path + environ['QUERY_STRING'] = url.query or '' + + environ['wsgi.input'] = sys.stdin + environ['wsgi.errors'] = sys.stderr + environ['wsgi.version'] = (1, 0) + environ['wsgi.multithread'] = False + environ['wsgi.multiprocess'] = True + environ['wsgi.run_once'] = True + + def start_response(status, response_headers, exc_info=None): + if exc_info: + raise exc_info[0](exc_info[1], exc_info[2]) + # this is for stdout - don't use \r\n as HTTP mandates + ui.note(status + '\n') + for header in response_headers: + if header[0] == 'ETag' and not ui.debugflag: + continue + ui.note('%s: %s\n' % header) + ui.note('\n') + return ui.write + + content = app(environ, start_response) + for chunk in content: + ui.write(chunk) + getattr(content, 'close', lambda : None)() + return + class service(object): def init(self): util.setsignalhandler() diff --git a/tests/test-hgweb-commands.t b/tests/test-hgweb-commands.t --- a/tests/test-hgweb-commands.t +++ b/tests/test-hgweb-commands.t @@ -1366,73 +1366,46 @@ $ hg phase -fs 4 $ hg bookmark -r4 secret - $ cat > hgweb.cgi < from mercurial import demandimport; demandimport.enable() - > from mercurial.hgweb import hgweb - > from mercurial.hgweb import wsgicgi - > app = hgweb('.', 'test') - > wsgicgi.launch(app) - > HGWEB - $ . "$TESTDIR/cgienv" - $ PATH_INFO=/bookmarks; export PATH_INFO - $ QUERY_STRING='style=raw' - $ python hgweb.cgi | grep -v ETag: - Status: 200 Script output follows\r (esc) - Content-Type: text/plain; charset=ascii\r (esc) - \r (esc) + $ hg serve --get 'http://server/bookmarks?style=raw' -v + 200 Script output follows + Content-Type: text/plain; charset=ascii + listbookmarks hides secret bookmarks - $ PATH_INFO=/; export PATH_INFO - $ QUERY_STRING='cmd=listkeys&namespace=bookmarks' - $ python hgweb.cgi - Status: 200 Script output follows\r (esc) - Content-Type: application/mercurial-0.1\r (esc) - Content-Length: 0\r (esc) - \r (esc) + $ hg serve --get 'http://server/?cmd=listkeys&namespace=bookmarks' -v + 200 Script output follows + Content-Type: application/mercurial-0.1 + Content-Length: 0 + search works with filtering - $ PATH_INFO=/log; export PATH_INFO - $ QUERY_STRING='rev=babar' - $ python hgweb.cgi > search - $ grep Status search - Status: 200 Script output follows\r (esc) + $ hg serve --get 'http://server/log/?rev=babar/' -v | head -n1 + 200 Script output follows summary works with filtering (issue3810) - $ PATH_INFO=/summary; export PATH_INFO - $ QUERY_STRING='style=monoblue'; export QUERY_STRING - $ python hgweb.cgi > summary.out - $ grep "^Status" summary.out - Status: 200 Script output follows\r (esc) + $ hg serve --get 'http://server/summary?style=monoblue' -v | head -n1 + 200 Script output follows proper status for filtered revision - (missing rev) - $ PATH_INFO=/rev/5; export PATH_INFO - $ QUERY_STRING='style=raw' - $ python hgweb.cgi #> search - Status: 404 Not Found\r (esc) - ETag: *\r (glob) (esc) - Content-Type: text/plain; charset=ascii\r (esc) - \r (esc) + $ hg serve --get 'http://server/rev/5?style=raw' -v + 404 Not Found + Content-Type: text/plain; charset=ascii + error: unknown revision '5' - - (filtered rev) - $ PATH_INFO=/rev/4; export PATH_INFO - $ QUERY_STRING='style=raw' - $ python hgweb.cgi #> search - Status: 404 Not Found\r (esc) - ETag: *\r (glob) (esc) - Content-Type: text/plain; charset=ascii\r (esc) - \r (esc) + $ hg serve --get 'http://server/rev/4?style=raw' -v + 404 Not Found + Content-Type: text/plain; charset=ascii + error: unknown revision '4' From martin at geisler.net Sat Feb 9 17:26:11 2013 From: martin at geisler.net (Martin Geisler) Date: Sun, 10 Feb 2013 00:26:11 +0100 Subject: [PATCH 6 of 6] highlight: use docutils for generating help if possible In-Reply-To: <40da011562a84f69cd3c.1360414840@s0-0.paconsult7.bbnplanet.net> (sfid-20130209_142011_473676_969DFDB2) (Dan Villiom Podlaski Christiansen's message of "Sat, 09 Feb 2013 13:00:40 +0000") References: <40da011562a84f69cd3c.1360414840@s0-0.paconsult7.bbnplanet.net> Message-ID: <87obftysq4.fsf@go.home> Dan Villiom Podlaski Christiansen writes: > # HG changeset patch > # User Dan Villiom Podlaski Christiansen > # Date 1360414108 0 > # Node ID 40da011562a84f69cd3c198e9c44cd4545bdeedb > # Parent 45b34ea40358b6f8fe14ef874ebbc5de5556f23c > highlight: use docutils for generating help if possible I really like the idea of trying to use Docutils for HTML generation if it's available -- redoing their work feels suboptimal to me. I'm not a fan of putting this into the highlight extension, which in my mind is an extension for enabling pygments in hgweb. A smaller and more targeted extension feels better to me -- hgwebrst maybe? > diff --git a/hgext/highlight/__init__.py b/hgext/highlight/__init__.py > --- a/hgext/highlight/__init__.py > +++ b/hgext/highlight/__init__.py > @@ -21,9 +21,13 @@ There is a single configuration option:: > The default is 'colorful'. > """ > > -import highlight > +import highlight, rst > + > from mercurial.hgweb import webcommands, webutil, common > -from mercurial import extensions, encoding > +from mercurial import extensions, encoding, minirst > + > +import cgi, traceback > + > testedwith = 'internal' > > def filerevision_highlight(orig, web, tmpl, fctx): > @@ -48,6 +52,24 @@ def annotate_highlight(orig, web, req, t > highlight.pygmentize('annotateline', fctx, style, tmpl) > return orig(web, req, tmpl) > > +def format_docutils(orig, *args, **opts): > + if opts.get('style') == 'html': > + try: > + return rst.publish(args[0]) > + except Exception: That's too general: you ought to detect if docutils is there by catching an ImportError (above). That is something like try: from docutils import core except ImportError: core = None and then later if core is None: # fallback else: # use core.publish_parts > --- /dev/null > +++ b/hgext/highlight/rst.py > @@ -0,0 +1,32 @@ > +# rst.py - generate HTML from docutils source > +# > +# Copyright 2010-2013 Matt Mackall and others > +# > +# This software may be used and distributed according to the terms of the > +# GNU General Public License version 2 or any later version. > +# > +# The original module was split in an interface and an implementation > +# file to defer pygments loading and speedup extension setup. I think you've copied that header from another highlight file and copied too much here. > +from docutils.parsers.rst import roles > +from docutils import core, nodes, utils > + > +def role_hg(name, rawtext, text, lineno, inliner, > + options={}, content=[]): > + text = "hg " + utils.unescape(text) > + linktext = nodes.literal(rawtext, text) > + parts = text.split() > + cmd, args = parts[1], parts[2:] > + if cmd == 'help' and args: > + cmd = args[0] # link to 'dates' for 'hg help dates' > + node = nodes.reference(rawtext, '', linktext, > + refuri="%s" % cmd) > + return [node], [] > + > +roles.register_local_role("hg", role_hg) > + > +def publish(text, **opts): > + parts = core.publish_parts(text, writer_name='html', > + enable_exit_status=True, **opts) Doesn't enable_exit_status=True mean that docutils will exit the program if it encounters an error? (... moments later...) Yeah, I found this in docutils.core: if (enable_exit_status and self.document and (self.document.reporter.max_level >= self.settings.exit_status_level)): sys.exit(self.document.reporter.max_level + 10) -- Martin Geisler From angel.ezquerra at gmail.com Sat Feb 9 17:31:36 2013 From: angel.ezquerra at gmail.com (Angel Ezquerra) Date: Sat, 9 Feb 2013 23:31:36 +0000 Subject: [PATCH V3] hgweb: teach archive how to handle file patterns In-Reply-To: References: Message-ID: On Sat, Feb 9, 2013 at 11:15 PM, Brodie Rao wrote: > On Sat, Feb 9, 2013 at 8:42 PM, Angel Ezquerra wrote: >> # HG changeset patch >> # User Angel Ezquerra >> # Date 1360141605 -3600 >> # Node ID c0509330eb416104bed8cc7d0a4038f818dd5e5d >> # Parent b6c8e79948a05d01920392cd12ac5c8279d5c62b >> hgweb: teach archive how to handle file patterns >> >> The archive web command now takes into account the "file" request entry, if one >> is provided. >> >> The provided "file" is processed as a "path" pattern by default, which makes it >> easy to only archive a certain file or directory. However, it is possible to >> specify a different type of pattern, such as relglob by specifying it >> explicitly on the query URL. Note that only "safe" patterns are allowed. Safe >> patterns are 'path', 'relpath', 'glog' and 'relglob'. Other pattern types are >> not allowed because they could be expensive to calculate. >> >> With this change hgweb can to process requests such as: >> >> 1. http://mercurial.selenic.com/hg/tip.zip/mercurial/templates >> >> This will download all files on the mercurial/templates directory as a zip >> file > > The format for this URL seems a little strange. What happens if you do > 'curl -O http://mercurial.selenic.com/hg/tip.zip/mercurial/templates'? > Does it figure out that the filename should be tip.zip? And what > happens if you want to download an archive for a branch/bookmark/tag > that has forward slashes in it? > > I wonder if making this a GET parameter might be cleaner. Actually the commit message is wrong. The actual address would be: http://mercurial.selenic.com/hg/archive/tip.tar.gz/relglob:*.py Which makes it unique, since we could already do: http://mercurial.selenic.com/hg/archive/tip.tar.gz I'll fix the commit message (using evolve! :-) when I resend the series. Cheers, Angel From kbullock+mercurial at ringworld.org Sat Feb 9 18:23:42 2013 From: kbullock+mercurial at ringworld.org (Kevin Bullock) Date: Sun, 10 Feb 2013 00:23:42 +0000 Subject: [PATCH] merge: take wlock only when we actually need to start updating Message-ID: <1a54947f6b32cf6aa0ab.1360455822@s0-0.paconsult7.bbnplanet.net> # HG changeset patch # User Kevin Bullock # Date 1360455052 0 # Node ID 1a54947f6b32cf6aa0ab4703b7c75d042257d8f1 # Parent 0027a5cec9d00873ca14129b4589975083e5e71d merge: take wlock only when we actually need to start updating Right now we have a big huge blob of code that's just deciding where to update to and whether we should actually do it based on the options the user specified (--check, --clean, --force, and friends). None of this modifies the working directory. diff --git a/mercurial/merge.py b/mercurial/merge.py --- a/mercurial/merge.py +++ b/mercurial/merge.py @@ -587,65 +587,65 @@ def update(repo, node, branchmerge, forc """ onode = node + wc = repo[None] + if node is None: + # tip of current branch + try: + node = repo.branchtip(wc.branch()) + except error.RepoLookupError: + if wc.branch() == "default": # no default branch! + node = repo.lookup("tip") # update to tip + else: + raise util.Abort(_("branch %s not found") % wc.branch()) + overwrite = force and not branchmerge + pl = wc.parents() + p1, p2 = pl[0], repo[node] + if ancestor: + pa = repo[ancestor] + else: + pa = p1.ancestor(p2) + + fp1, fp2, xp1, xp2 = p1.node(), p2.node(), str(p1), str(p2) + + ### check phase + if not overwrite and len(pl) > 1: + raise util.Abort(_("outstanding uncommitted merges")) + if branchmerge: + if pa == p2: + raise util.Abort(_("merging with a working directory ancestor" + " has no effect")) + elif pa == p1: + if not mergeancestor and p1.branch() == p2.branch(): + raise util.Abort(_("nothing to merge"), + hint=_("use 'hg update' " + "or check 'hg heads'")) + if not force and (wc.files() or wc.deleted()): + raise util.Abort(_("outstanding uncommitted changes"), + hint=_("use 'hg status' to list changes")) + for s in sorted(wc.substate): + if wc.sub(s).dirty(): + raise util.Abort(_("outstanding uncommitted changes in " + "subrepository '%s'") % s) + + elif not overwrite: + if pa == p1 or pa == p2: # linear + pass # all good + elif wc.dirty(missing=True): + raise util.Abort(_("crosses branches (merge branches or use" + " --clean to discard changes)")) + elif onode is None: + raise util.Abort(_("crosses branches (merge branches or update" + " --check to force update)")) + else: + # Allow jumping branches if clean and specific rev given + pa = p1 + + ### calculate phase + actions = calculateupdates(repo, wc, p2, pa, + branchmerge, force, partial) + wlock = repo.wlock() try: - wc = repo[None] - if node is None: - # tip of current branch - try: - node = repo.branchtip(wc.branch()) - except error.RepoLookupError: - if wc.branch() == "default": # no default branch! - node = repo.lookup("tip") # update to tip - else: - raise util.Abort(_("branch %s not found") % wc.branch()) - overwrite = force and not branchmerge - pl = wc.parents() - p1, p2 = pl[0], repo[node] - if ancestor: - pa = repo[ancestor] - else: - pa = p1.ancestor(p2) - - fp1, fp2, xp1, xp2 = p1.node(), p2.node(), str(p1), str(p2) - - ### check phase - if not overwrite and len(pl) > 1: - raise util.Abort(_("outstanding uncommitted merges")) - if branchmerge: - if pa == p2: - raise util.Abort(_("merging with a working directory ancestor" - " has no effect")) - elif pa == p1: - if not mergeancestor and p1.branch() == p2.branch(): - raise util.Abort(_("nothing to merge"), - hint=_("use 'hg update' " - "or check 'hg heads'")) - if not force and (wc.files() or wc.deleted()): - raise util.Abort(_("outstanding uncommitted changes"), - hint=_("use 'hg status' to list changes")) - for s in sorted(wc.substate): - if wc.sub(s).dirty(): - raise util.Abort(_("outstanding uncommitted changes in " - "subrepository '%s'") % s) - - elif not overwrite: - if pa == p1 or pa == p2: # linear - pass # all good - elif wc.dirty(missing=True): - raise util.Abort(_("crosses branches (merge branches or use" - " --clean to discard changes)")) - elif onode is None: - raise util.Abort(_("crosses branches (merge branches or update" - " --check to force update)")) - else: - # Allow jumping branches if clean and specific rev given - pa = p1 - - ### calculate phase - actions = calculateupdates(repo, wc, p2, pa, - branchmerge, force, partial) - ### apply phase if not branchmerge: # just jump to the new rev fp1, fp2, xp1, xp2 = fp2, nullid, xp2, '' From kbullock+mercurial at ringworld.org Sat Feb 9 18:28:32 2013 From: kbullock+mercurial at ringworld.org (Kevin Bullock) Date: Sun, 10 Feb 2013 00:28:32 +0000 Subject: [PATCH V3] hgweb: teach archive how to handle file patterns In-Reply-To: References: Message-ID: On 9 Feb 2013, at 11:15 PM, Brodie Rao wrote: > On Sat, Feb 9, 2013 at 8:42 PM, Angel Ezquerra wrote: >> # HG changeset patch >> # User Angel Ezquerra >> # Date 1360141605 -3600 >> # Node ID c0509330eb416104bed8cc7d0a4038f818dd5e5d >> # Parent b6c8e79948a05d01920392cd12ac5c8279d5c62b >> hgweb: teach archive how to handle file patterns >> >> The archive web command now takes into account the "file" request entry, if one >> is provided. >> >> The provided "file" is processed as a "path" pattern by default, which makes it >> easy to only archive a certain file or directory. However, it is possible to >> specify a different type of pattern, such as relglob by specifying it >> explicitly on the query URL. Note that only "safe" patterns are allowed. Safe >> patterns are 'path', 'relpath', 'glog' and 'relglob'. Other pattern types are >> not allowed because they could be expensive to calculate. >> >> With this change hgweb can to process requests such as: >> >> 1. http://mercurial.selenic.com/hg/tip.zip/mercurial/templates >> >> This will download all files on the mercurial/templates directory as a zip >> file > > The format for this URL seems a little strange. What happens if you do > 'curl -O http://mercurial.selenic.com/hg/tip.zip/mercurial/templates'? > Does it figure out that the filename should be tip.zip? And what > happens if you want to download an archive for a branch/bookmark/tag > that has forward slashes in it? > > I wonder if making this a GET parameter might be cleaner. The Content-Disposition: header should take care of this. But making the path/pattern a query string might be a slightly better fit, yeah. pacem in terris / ??? / ?????? / ????????? / ?? Kevin R. Bullock From bos at serpentine.com Sat Feb 9 18:28:54 2013 From: bos at serpentine.com (Bryan O'Sullivan) Date: Sat, 9 Feb 2013 16:28:54 -0800 Subject: [PATCH 11 of 11] merge: don't fiddle with name lookups or i18n in hot loops In-Reply-To: References: <8cf626e958d3dd67e45b.1360418801@australite.local> <994e4c0ed9a6d2ff25aa.1360418811@australite.local> Message-ID: On Sat, Feb 9, 2013 at 2:28 PM, Na'Tosha Bard wrote: > *Before the patch series, updating from null to tip (~57.000 files) on OS > X: > real 1m17.607s > > After the patch series: > **real 0m36.322s* Not bad. That matches my measurements on OS X, too - I think HFS+ is the bottleneck (surprise!). Patches are in crew now. -------------- next part -------------- An HTML attachment was scrubbed... URL: From hgbuildbot at kublai.com Sat Feb 9 18:33:56 2013 From: hgbuildbot at kublai.com (hgbuildbot at kublai.com) Date: Sat, 09 Feb 2013 16:33:56 -0800 Subject: buildbot success in Mercurial on OS X 10.6 hg tests Message-ID: <20130210003358.BC61B36E93@hgbuildbot.cs.ubc.ca> The Buildbot has detected a restored build on builder OS X 10.6 hg tests while building hg. Full details are available at: http://hgbuildbot.kublai.com/builders/OS%20X%2010.6%20hg%20tests/builds/445 Buildbot URL: http://hgbuildbot.kublai.com/ Buildslave for this Build: sl Build Reason: scheduler Build Source Stamp: [branch default] 46edbc49a9f213dd9c78e4dbaa8809661058bb07 Blamelist: Na'Tosha Bard ,Simon Heimberg Build succeeded! sincerely, -The Buildbot From kbullock+mercurial at ringworld.org Sat Feb 9 18:40:44 2013 From: kbullock+mercurial at ringworld.org (Kevin Bullock) Date: Sun, 10 Feb 2013 00:40:44 +0000 Subject: [PATCH] merge: take wlock only when we actually need to start updating In-Reply-To: <1a54947f6b32cf6aa0ab.1360455822@s0-0.paconsult7.bbnplanet.net> References: <1a54947f6b32cf6aa0ab.1360455822@s0-0.paconsult7.bbnplanet.net> Message-ID: <7AB6FA37-5FBC-47F3-8481-06C3ADB7C0CF@ringworld.org> On 10 Feb 2013, at 12:23 AM, Kevin Bullock wrote: > # HG changeset patch > # User Kevin Bullock > # Date 1360455052 0 > # Node ID 1a54947f6b32cf6aa0ab4703b7c75d042257d8f1 > # Parent 0027a5cec9d00873ca14129b4589975083e5e71d > merge: take wlock only when we actually need to start updating Dropping this after consulting Matt. pacem in terris / ??? / ?????? / ????????? / ?? Kevin R. Bullock From hgbuildbot at kublai.com Sat Feb 9 21:57:50 2013 From: hgbuildbot at kublai.com (hgbuildbot at kublai.com) Date: Sat, 09 Feb 2013 19:57:50 -0800 Subject: buildbot failure in Mercurial on OS X 10.6 hg tests Message-ID: <20130210035750.52C5937AA9@hgbuildbot.cs.ubc.ca> The Buildbot has detected a new failure on builder OS X 10.6 hg tests while building hg. Full details are available at: http://hgbuildbot.kublai.com/builders/OS%20X%2010.6%20hg%20tests/builds/446 Buildbot URL: http://hgbuildbot.kublai.com/ Buildslave for this Build: sl Build Reason: scheduler Build Source Stamp: [branch default] a8648f32b8edd6eff6bc600b93d7e83c2e05e650 Blamelist: Augie Fackler ,Bryan O'Sullivan ,Kevin Bullock ,Matt Mackall ,Pierre-Yves David BUILD FAILED: failed pure sincerely, -The Buildbot From idankk86 at gmail.com Sun Feb 10 02:09:20 2013 From: idankk86 at gmail.com (Idan Kamara) Date: Sun, 10 Feb 2013 10:09:20 +0200 Subject: [PATCH 11 of 11] merge: don't fiddle with name lookups or i18n in hot loops In-Reply-To: References: <8cf626e958d3dd67e45b.1360418801@australite.local> <994e4c0ed9a6d2ff25aa.1360418811@australite.local> Message-ID: On Sun, Feb 10, 2013 at 2:28 AM, Bryan O'Sullivan wrote: > Patches are in crew now. Someone takes the time to look over your work (on a Saturday..), raises some unsettled concerns, but you decide to push it anyway? Not cool. -------------- next part -------------- An HTML attachment was scrubbed... URL: From hgbuildbot at kublai.com Sun Feb 10 02:17:19 2013 From: hgbuildbot at kublai.com (hgbuildbot at kublai.com) Date: Sun, 10 Feb 2013 00:17:19 -0800 Subject: buildbot failure in Mercurial on OS X 10.7 hg tests Message-ID: <20130210081719.B7B0C37AA9@hgbuildbot.cs.ubc.ca> The Buildbot has detected a new failure on builder OS X 10.7 hg tests while building hg. Full details are available at: http://hgbuildbot.kublai.com/builders/OS%20X%2010.7%20hg%20tests/builds/405 Buildbot URL: http://hgbuildbot.kublai.com/ Buildslave for this Build: lion Build Reason: scheduler Build Source Stamp: [branch default] f9eebf5629fa6282e069989d5d29af3d762657c8 Blamelist: Augie Fackler ,Benoit Boissinot ,Bryan O'Sullivan ,Kevin Bullock ,Na'Tosha Bard ,Pierre-Yves David ,Siddharth Agarwal ,Simon Heimberg BUILD FAILED: failed run-tests.py (python2.6) pure sincerely, -The Buildbot From hgbuildbot at kublai.com Sun Feb 10 04:43:45 2013 From: hgbuildbot at kublai.com (hgbuildbot at kublai.com) Date: Sun, 10 Feb 2013 02:43:45 -0800 Subject: buildbot success in Mercurial on hg tests Message-ID: <20130210104347.417FF37874@hgbuildbot.cs.ubc.ca> The Buildbot has detected a restored build on builder hg tests while building hg. Full details are available at: http://hgbuildbot.kublai.com/builders/hg%20tests/builds/491 Buildbot URL: http://hgbuildbot.kublai.com/ Buildslave for this Build: p64.osuosl.test Build Reason: scheduler Build Source Stamp: [branch default] 6204e4d4dd6d10834540357dbf1deac6636077c8 Blamelist: Augie Fackler Build succeeded! sincerely, -The Buildbot From angel.ezquerra at gmail.com Sun Feb 10 04:56:44 2013 From: angel.ezquerra at gmail.com (Angel Ezquerra) Date: Sun, 10 Feb 2013 11:56:44 +0100 Subject: [PATCH 0 of 2 V4] hgweb: teach archive how to handle file patterns Message-ID: Compared to the previous version this adds a test for the rejection of "unsafe" patterns. To do so I had to modify a helper function in test-archive.t, which I did on a separate patch. From angel.ezquerra at gmail.com Sun Feb 10 04:56:45 2013 From: angel.ezquerra at gmail.com (Angel Ezquerra) Date: Sun, 10 Feb 2013 11:56:45 +0100 Subject: [PATCH 1 of 2 V4] test-archive: gracefully handle HTTPErrors on get-with-headers In-Reply-To: References: Message-ID: # HG changeset patch # User Angel Ezquerra # Date 1360141605 -3600 # Node ID be3e96a41d0f4b7a1f1dd443f5261d6eeb66626a # Parent b6c8e79948a05d01920392cd12ac5c8279d5c62b test-archive: gracefully handle HTTPErrors on get-with-headers This avoids pritting out a traceback when a get-with-headers call causes hgweb to respond with an HTTPError code. diff --git a/tests/test-archive.t b/tests/test-archive.t --- a/tests/test-archive.t +++ b/tests/test-archive.t @@ -69,10 +69,18 @@ > msvcrt.setmode(sys.stdout.fileno(), os.O_BINARY) > except ImportError: > pass - > node, archive = sys.argv[1:] - > f = urllib2.urlopen('http://127.0.0.1:%s/?cmd=archive;node=%s;type=%s' - > % (os.environ['HGPORT'], node, archive)) - > sys.stdout.write(f.read()) + > if len(sys.argv) <= 3: + > node, archive = sys.argv[1:] + > requeststr = 'cmd=archive;node=%s;type=%s' % (node, archive) + > else: + > node, archive, file = sys.argv[1:] + > requeststr = 'cmd=archive;node=%s;type=%s;file=%s' % (node, archive, file) + > try: + > f = urllib2.urlopen('http://127.0.0.1:%s/?%s' + > % (os.environ['HGPORT'], requeststr)) + > sys.stdout.write(f.read()) + > except urllib2.HTTPError, e: + > sys.stderr.write(str(e) + '\n') > EOF $ python getarchive.py "$TIP" gz | gunzip | tar tf - 2>/dev/null test-archive-2c0277f05ed4/.hg_archival.txt From angel.ezquerra at gmail.com Sun Feb 10 04:56:46 2013 From: angel.ezquerra at gmail.com (Angel Ezquerra) Date: Sun, 10 Feb 2013 11:56:46 +0100 Subject: [PATCH 2 of 2 V4] hgweb: teach archive how to handle file patterns In-Reply-To: References: Message-ID: # HG changeset patch # User Angel Ezquerra # Date 1360493525 -3600 # Node ID fb655ad16f6675265da9d472ded7140a223fb283 # Parent be3e96a41d0f4b7a1f1dd443f5261d6eeb66626a hgweb: teach archive how to handle file patterns The archive web command now takes into account the "file" request entry, if one is provided. The provided "file" is processed as a "path" pattern by default, which makes it easy to only archive a certain file or directory. However, it is possible to specify a different type of pattern, such as relglob by specifying it explicitly on the query URL. Note that only "safe" patterns are allowed. Safe patterns are 'path', 'relpath', 'glog' and 'relglob'. Other pattern types are not allowed because they could be expensive to calculate. With this change hgweb can to process requests such as: 1. http://mercurial.selenic.com/hg/archive/tip.zip/mercurial/templates This will download all files on the mercurial/templates directory as a zip file 2. http://mercurial.selenic.com/hg/archive/tip.tar.gz/relglob:*.py This will download all *.py files in the repository into a tar.gz file. An so forth. Note that this is a first step to add support for downloading directories from the web interface. Currently the only way to use this feature is by manually constructing the URL that you want to download. We will have to modify the archiveentry map entry on the different templates so that it adds the current folder path to the archive links. This revision also adds a two tests for this feature to test-archive.t. The first tests the selective archive feature and the second tests that the server rejects "unsafe" patterns. diff --git a/mercurial/hgweb/webcommands.py b/mercurial/hgweb/webcommands.py --- a/mercurial/hgweb/webcommands.py +++ b/mercurial/hgweb/webcommands.py @@ -803,6 +803,17 @@ if cnode == key or key == 'tip': arch_version = short(cnode) name = "%s-%s" % (reponame, arch_version) + + ctx = webutil.changectx(web.repo, req) + pats = [] + file = req.form.get('file', None) + defaultpat = 'path' + if file: + pats = [req.form['file'][0]] + if not scmutil.patsaresafe(pats, defaultpat): + msg = 'Archive pattern not allowed: %s' % pats[0] + raise ErrorResponse(HTTP_FORBIDDEN, msg) + mimetype, artype, extension, encoding = web.archive_specs[type_] headers = [ ('Content-Disposition', 'attachment; filename=%s%s' % (name, extension)) @@ -812,9 +823,9 @@ req.headers.extend(headers) req.respond(HTTP_OK, mimetype) - ctx = webutil.changectx(web.repo, req) + matchfn = scmutil.match(ctx, pats, default=defaultpat) archival.archive(web.repo, req, cnode, artype, prefix=name, - matchfn=scmutil.match(ctx, []), + matchfn=matchfn, subrepos=web.configbool("web", "archivesubrepos")) return [] diff --git a/mercurial/scmutil.py b/mercurial/scmutil.py --- a/mercurial/scmutil.py +++ b/mercurial/scmutil.py @@ -682,6 +682,15 @@ return l +def patsaresafe(pats, defaultpattype): + for pat in pats: + pattype = defaultpattype + if ':' in pat: + pattype = pat.split(':')[0] + if pattype.lower() not in ('path', 'relpath', 'glog', 'relglob'): + return False + return True + def expandpats(pats): if not util.expandglobs: return list(pats) diff --git a/tests/test-archive.t b/tests/test-archive.t --- a/tests/test-archive.t +++ b/tests/test-archive.t @@ -100,6 +100,13 @@ testing: test-archive-2c0277f05ed4/baz/bletch OK testing: test-archive-2c0277f05ed4/foo OK No errors detected in compressed data of archive.zip. + $ python getarchive.py "$TIP" gz baz | gunzip | tar tf - 2>/dev/null + test-archive-2c0277f05ed4/baz/bletch + +test that we reject unsafe patterns + + $ python getarchive.py "$TIP" gz relre:baz + HTTP Error 403: Archive pattern not allowed: relre:baz $ "$TESTDIR/killdaemons.py" $DAEMON_PIDS From durham at fb.com Sun Feb 10 05:07:17 2013 From: durham at fb.com (Durham Goode) Date: Sun, 10 Feb 2013 03:07:17 -0800 Subject: [PATCH 1 of 6] blackbox: adds a blackbox extension Message-ID: <30544b5277d09002d6ca.1360494437@dev350.prn1.facebook.com> # HG changeset patch # User Durham Goode # Date 1360429429 28800 # Node ID 30544b5277d09002d6cac8c363652f71bb807516 # Parent 57b7531a5705a099637f6d6bedd4de509fb2a441 blackbox: adds a blackbox extension Adds a blackbox extension that listens to ui.log() and writes the messages to .hg/blackbox.log. Future commits will use ui.log() to log commands, unhandled exceptions, incoming changes, and hooks. The extension defaults to logging everything, but can be configured via blackbox.trackedevents to only log certain events. Log lines are of the format: "date time user> message" Example log line: 2013/02/09 08:35:19 durham> 1 incoming changes - new heads: d84ced58aaa diff --git a/hgext/blackbox.py b/hgext/blackbox.py new file mode 100644 --- /dev/null +++ b/hgext/blackbox.py @@ -0,0 +1,68 @@ +"""log repository events to a blackbox for debugging + +Logs event information to .hg/blackbox.log to help debug and diagnose problems. +The events that get logged can be configured via the blackbox.trackedevents +config key. Examples: + + [blackbox] + trackedevents=* + + [blackbox] + trackedevents=command,commandfinished,commandexception,exthook,pythonhook + + [blackbox] + trackedevents=incoming + +""" + +from mercurial import util, cmdutil +from mercurial.i18n import _ +import os, getpass, re, string + +cmdtable = {} +command = cmdutil.command(cmdtable) +testedwith='internal' +lastblackbox=None + +def wrapui(ui): + class blackboxui(ui.__class__): + @util.propertycache + def trackedevents(self): + events = ui.config('blackbox', 'trackedevents', '*') + return string.split(events, ',') + + def log(self, command, msg): + global lastblackbox + super(blackboxui, self).log(command, msg) + + if not '*' in self.trackedevents and \ + not command in self.trackedevents: + return + + if '_blackbox' in self.__dict__: + blackbox = self._blackbox + else: + # certain ui instances exist outside the context of + # a repo, so just default to the last blackbox that + # was seen. + blackbox = lastblackbox + + if blackbox: + date = util.datestr(None, '%Y/%m/%d %H:%M:%S') + user = getpass.getuser() + blackbox.write('%s %s> %s\n' % (date, user, msg)) + lastblackbox = blackbox + + def setrepo(self, repo): + self._blackbox = repo.opener('blackbox.log', 'a') + + ui.__class__ = blackboxui + +def uisetup(ui): + wrapui(ui) + +def reposetup(ui, repo): + if not repo.local(): + return + + ui.setrepo(repo) From durham at fb.com Sun Feb 10 05:07:18 2013 From: durham at fb.com (Durham Goode) Date: Sun, 10 Feb 2013 03:07:18 -0800 Subject: [PATCH 2 of 6] blackbox: log the commands that are run In-Reply-To: <30544b5277d09002d6ca.1360494437@dev350.prn1.facebook.com> References: <30544b5277d09002d6ca.1360494437@dev350.prn1.facebook.com> Message-ID: <54a25c702a6fface978f.1360494438@dev350.prn1.facebook.com> # HG changeset patch # User Durham Goode # Date 1360429454 28800 # Node ID 54a25c702a6fface978fd1eeb0e6c7140bc9ab8b # Parent 30544b5277d09002d6cac8c363652f71bb807516 blackbox: log the commands that are run Uses ui.log to log which commands are run, their exit code, the time taken, and any unhandled exceptions thrown. Example log lines: 2013/02/09 08:35:19 durham> add foo 2013/02/09 08:35:19 durham> add exited 0 after 0.02 seconds Updates the progress tests because they use a mocked time.time() which these changes affect. diff --git a/mercurial/dispatch.py b/mercurial/dispatch.py --- a/mercurial/dispatch.py +++ b/mercurial/dispatch.py @@ -247,6 +247,7 @@ (_("** Mercurial Distributed SCM (version %s)\n") % myver) + (_("** Extensions loaded: %s\n") % ", ".join([x[0] for x in extensions.extensions()]))) + ui.log("commandexception", "%s\n%s" % (warning, traceback.format_exc())) ui.warn(warning) raise @@ -736,12 +737,18 @@ ui.warn(_("warning: --repository ignored\n")) msg = ' '.join(' ' in a and repr(a) or a for a in fullargs) - ui.log("command", msg + "\n") + ui.log("command", msg) d = lambda: util.checksignature(func)(ui, *args, **cmdoptions) + starttime = time.time() + ret = None try: - return runcommand(lui, repo, cmd, fullargs, ui, options, d, + ret = runcommand(lui, repo, cmd, fullargs, ui, options, d, cmdpats, cmdoptions) + return ret finally: + duration = time.time() - starttime + ui.log("commandfinish", "%s exited %s after %0.2f seconds" % + (cmd, ret, duration)) if repo and repo != req.repo: repo.close() diff --git a/tests/test-progress.t b/tests/test-progress.t --- a/tests/test-progress.t +++ b/tests/test-progress.t @@ -167,6 +167,7 @@ $ hg -y loop 8 \r (no-eol) (esc) + loop [====> ] 1/8 1m18s\r (no-eol) (esc) loop [=========> ] 2/8 1m07s\r (no-eol) (esc) loop [===============> ] 3/8 56s\r (no-eol) (esc) loop [=====================> ] 4/8 45s\r (no-eol) (esc) @@ -203,6 +204,7 @@ Time estimates should not fail when there's no end point: $ hg -y loop -- -4 \r (no-eol) (esc) - loop [ <=> ] 2\r (no-eol) (esc) - loop [ <=> ] 3\r (no-eol) (esc) + loop [ <=> ] 1\r (no-eol) (esc) + loop [ <=> ] 2\r (no-eol) (esc) + loop [ <=> ] 3\r (no-eol) (esc) \r (no-eol) (esc) From durham at fb.com Sun Feb 10 05:07:20 2013 From: durham at fb.com (Durham Goode) Date: Sun, 10 Feb 2013 03:07:20 -0800 Subject: [PATCH 4 of 6] blackbox: log incoming changes via ui.log() In-Reply-To: <30544b5277d09002d6ca.1360494437@dev350.prn1.facebook.com> References: <30544b5277d09002d6ca.1360494437@dev350.prn1.facebook.com> Message-ID: # HG changeset patch # User Durham Goode # Date 1360429488 28800 # Node ID ee0ffe8ee86585a9842c841f7c389b037f118282 # Parent eae69575df6cc5e429bfd6affbd957b6f3670fa4 blackbox: log incoming changes via ui.log() Logs incoming changes to a repo to ui.log(). Includes the number of changes and the hashes of the heads after the new changes. Example log line: 2013/02/09 08:35:19 durham> 1 incoming changes - new heads: cb9a9f314b8b Currently the blackbox logs the unix user that is performing the push/pull. It would be nice to log the http authorized user as well so it works with hgweb, but that's outside the scope of this commit. diff --git a/mercurial/localrepo.py b/mercurial/localrepo.py --- a/mercurial/localrepo.py +++ b/mercurial/localrepo.py @@ -2408,6 +2408,11 @@ for n in added: self.hook("incoming", node=hex(n), source=srctype, url=url) + + heads = self.heads() + self.ui.log("incoming", + "%s incoming changes - new heads: %s" % + (len(added), ', '.join([hex(c[:6]) for c in heads]))) self._afterlock(runhooks) finally: From durham at fb.com Sun Feb 10 05:07:19 2013 From: durham at fb.com (Durham Goode) Date: Sun, 10 Feb 2013 03:07:19 -0800 Subject: [PATCH 3 of 6] blackbox: logs python and extension hooks via ui.log() In-Reply-To: <30544b5277d09002d6ca.1360494437@dev350.prn1.facebook.com> References: <30544b5277d09002d6ca.1360494437@dev350.prn1.facebook.com> Message-ID: # HG changeset patch # User Durham Goode # Date 1360429472 28800 # Node ID eae69575df6cc5e429bfd6affbd957b6f3670fa4 # Parent 54a25c702a6fface978fd1eeb0e6c7140bc9ab8b blackbox: logs python and extension hooks via ui.log() Logs python and extension hooks to ui.log() for viewing in the blackbox. Example log lines: 2013/02/09 08:35:19 durham> pythonhook-preupdate: hgext.eol.preupdate finished in 0.01 seconds 2013/02/09 08:35:19 durham> exthook-update: echo hooked finished in 0.02 seconds diff --git a/mercurial/hook.py b/mercurial/hook.py --- a/mercurial/hook.py +++ b/mercurial/hook.py @@ -6,7 +6,7 @@ # GNU General Public License version 2 or any later version. from i18n import _ -import os, sys +import os, sys, time, types import extensions, util, demandimport def _pythonhook(ui, repo, name, hname, funcname, args, throw): @@ -20,6 +20,8 @@ be run as hooks without wrappers to convert return values.''' ui.note(_("calling hook %s: %s\n") % (hname, funcname)) + starttime = time.time() + obj = funcname if not util.safehasattr(obj, '__call__'): d = funcname.rfind('.') @@ -92,6 +94,12 @@ return True finally: sys.stdout, sys.stderr, sys.stdin = old + duration = time.time() - starttime + readablefunc = funcname + if isinstance(funcname, types.FunctionType): + readablefunc = funcname.__module__ + "." + funcname.__name__ + ui.log('pythonhook', 'pythonhook-%s: %s finished in %0.2f seconds' % + (name, readablefunc, duration)) if r: if throw: raise util.Abort(_('%s hook failed') % hname) @@ -101,6 +109,7 @@ def _exthook(ui, repo, name, cmd, args, throw): ui.note(_("running hook %s: %s\n") % (name, cmd)) + starttime = time.time() env = {} for k, v in args.iteritems(): if util.safehasattr(v, '__call__'): @@ -121,6 +130,10 @@ r = util.system(cmd, environ=env, cwd=cwd, out=ui) else: r = util.system(cmd, environ=env, cwd=cwd, out=ui.fout) + + duration = time.time() - starttime + ui.log('exthook', 'exthook-%s: %s finished in %0.2f seconds' % + (name, cmd, duration)) if r: desc, r = util.explainexit(r) if throw: From durham at fb.com Sun Feb 10 05:07:21 2013 From: durham at fb.com (Durham Goode) Date: Sun, 10 Feb 2013 03:07:21 -0800 Subject: [PATCH 5 of 6] blackbox: adds a 'blackbox' command for viewing recent logs In-Reply-To: <30544b5277d09002d6ca.1360494437@dev350.prn1.facebook.com> References: <30544b5277d09002d6ca.1360494437@dev350.prn1.facebook.com> Message-ID: <4192cc153d6f8d529723.1360494441@dev350.prn1.facebook.com> # HG changeset patch # User Durham Goode # Date 1360429786 28800 # Node ID 4192cc153d6f8d529723c9df20255693b73e723a # Parent ee0ffe8ee86585a9842c841f7c389b037f118282 blackbox: adds a 'blackbox' command for viewing recent logs Adds a 'hg blackbox' command for viewing the latest entries in the blackbox log. By default it shows the last 10 entries, but -l allows the user to specify. diff --git a/hgext/blackbox.py b/hgext/blackbox.py --- a/hgext/blackbox.py +++ b/hgext/blackbox.py @@ -66,3 +66,31 @@ return ui.setrepo(repo) + + at command('^blackbox|bb', + [('l', 'limit', 10, _('the number of events to show')), + ], + _('hg blackbox [OPTION]...')) +def blackbox(ui, repo, *revs, **opts): + '''view the recent repository events + ''' + + if not os.path.exists(repo.join('blackbox.log')): + return + + limit = opts.get('limit') + blackbox = repo.opener('blackbox.log', 'r') + lines = blackbox.read().split('\n') + + count = 0 + output = [] + for line in reversed(lines): + if count >= limit: + break + + # count the commands by matching lines like: 2013/01/23 19:13:36 root> + if re.match('^\d{4}/\d{2}/\d{2} \d{2}:\d{2}:\d{2} .*> .*', line): + count = count + 1 + output.append(line) + + ui.status('\n'.join(reversed(output))) From durham at fb.com Sun Feb 10 05:07:22 2013 From: durham at fb.com (Durham Goode) Date: Sun, 10 Feb 2013 03:07:22 -0800 Subject: [PATCH 6 of 6] blackbox: tests for the blackbox extension In-Reply-To: <30544b5277d09002d6ca.1360494437@dev350.prn1.facebook.com> References: <30544b5277d09002d6ca.1360494437@dev350.prn1.facebook.com> Message-ID: <932a1aea1b315a2b1c6e.1360494442@dev350.prn1.facebook.com> # HG changeset patch # User Durham Goode # Date 1360445730 28800 # Node ID 932a1aea1b315a2b1c6e7dadfea803afd59b704e # Parent 4192cc153d6f8d529723c9df20255693b73e723a blackbox: tests for the blackbox extension A few tests to cover the blackbox extension. Covers commands, hooks, and incoming changes. diff --git a/tests/test-blackbox.t b/tests/test-blackbox.t new file mode 100644 --- /dev/null +++ b/tests/test-blackbox.t @@ -0,0 +1,54 @@ +setup + + $ cat >> $HGRCPATH < [extensions] + > blackbox= + > EOF + $ hg init blackboxtest + $ cd blackboxtest + +command, exit codes, and duration + + $ echo a > a + $ hg add a + $ hg blackbox + *> add a (glob) + *> add exited 0 after * seconds (glob) + +extension and python hooks - use the eol extension for a pythonhook + + $ echo '[extensions]' >> .hg/hgrc + $ echo 'eol=' >> .hg/hgrc + $ echo '[hooks]' >> .hg/hgrc + $ echo 'update = echo hooked' >> .hg/hgrc + $ hg update + hooked + 0 files updated, 0 files merged, 0 files removed, 0 files unresolved + $ hg blackbox -l 4 + *> update (glob) + *> pythonhook-preupdate: hgext.eol.preupdate finished in * seconds (glob) + *> exthook-update: echo hooked finished in * seconds (glob) + *> update exited False after * seconds (glob) + +incoming change tracking + + $ hg clone . ../blackboxtest2 + updating to branch default + 0 files updated, 0 files merged, 0 files removed, 0 files unresolved + $ hg commit -ma + $ cd ../blackboxtest2 + $ hg pull + pulling from $TESTTMP/blackboxtest + requesting all changes + adding changesets + adding manifests + adding file changes + added 1 changesets with 1 changes to 1 files + (run 'hg update' to get a working copy) + $ hg bb -l 3 + *> pull (glob) + *> 1 incoming changes - new heads: cb9a9f314b8b (glob) + *> pull exited None after * seconds (glob) + +cleanup + $ cd .. From raf at durin42.com Sun Feb 10 05:08:41 2013 From: raf at durin42.com (Augie Fackler) Date: Sun, 10 Feb 2013 11:08:41 +0000 Subject: [PATCH 11 of 11] merge: don't fiddle with name lookups or i18n in hot loops In-Reply-To: References: <8cf626e958d3dd67e45b.1360418801@australite.local> <994e4c0ed9a6d2ff25aa.1360418811@australite.local> Message-ID: <55EAC0A6-3C4E-47BD-BAF6-832A530313C8@durin42.com> On Feb 10, 2013, at 8:09 AM, Idan Kamara wrote: > On Sun, Feb 10, 2013 at 2:28 AM, Bryan O'Sullivan > wrote: >> Patches are in crew now. > > Someone takes the time to look over your work (on a Saturday..), > raises some unsettled concerns, but you decide to push it anyway? > > Not cool. Relax - I reviewed this in person for Bryan, and he addressed both your and my comments before pushing. From idankk86 at gmail.com Sun Feb 10 05:25:30 2013 From: idankk86 at gmail.com (Idan Kamara) Date: Sun, 10 Feb 2013 13:25:30 +0200 Subject: [PATCH 11 of 11] merge: don't fiddle with name lookups or i18n in hot loops In-Reply-To: <55EAC0A6-3C4E-47BD-BAF6-832A530313C8@durin42.com> References: <8cf626e958d3dd67e45b.1360418801@australite.local> <994e4c0ed9a6d2ff25aa.1360418811@australite.local> <55EAC0A6-3C4E-47BD-BAF6-832A530313C8@durin42.com> Message-ID: On Sun, Feb 10, 2013 at 1:08 PM, Augie Fackler wrote: > > > On Feb 10, 2013, at 8:09 AM, Idan Kamara wrote: > > > On Sun, Feb 10, 2013 at 2:28 AM, Bryan O'Sullivan > > wrote: > >> Patches are in crew now. > > > > Someone takes the time to look over your work (on a Saturday..), > > raises some unsettled concerns, but you decide to push it anyway? > > > > Not cool. > > Relax - I reviewed this in person for Bryan, and he addressed both your > and my comments before pushing. No, he didn't. And had he given me the chance to reply to his last response, I would have shown it: diff --git a/mercurial/worker.py b/mercurial/worker.py --- a/mercurial/worker.py +++ b/mercurial/worker.py @@ -68,7 +68,7 @@ args - arguments to split into chunks, to pass to individual workers ''' - if worthwhile(ui, costperarg, len(args)): + if True: #worthwhile(ui, costperarg, len(args)): return _platformworker(ui, func, staticargs, args) return func(*staticargs + (args,)) @@ -80,6 +80,7 @@ if pid == 0: try: os.close(rfd) + raise util.Abort('child %d raises error' % os.getpid()) for i, item in func(*(staticargs + (pargs,))): os.write(wfd, '%d %s\n' % (i, item)) os._exit(0) diff --git a/tests/test-parallel.t b/tests/test-parallel.t new file mode 100644 --- /dev/null +++ b/tests/test-parallel.t @@ -0,0 +1,12 @@ + $ hg init + $ echo a >> a + $ hg ci -qAm. + $ cat < import os, sys + > print 'master is', os.getpid() + > sys.stdout.flush() + > from mercurial import dispatch + > req = dispatch.request(['update', '0', '-q']) + > dispatch.dispatch(req) + > print 'hi from', os.getpid() + > EOF Running this prints: --- /home/idan/dev/hg/default/tests/test-parallel.t +++ /home/idan/dev/hg/default/tests/test-parallel.t.err @@ -10,3 +10,21 @@ > dispatch.dispatch(req) > print 'hi from', os.getpid() > EOF + master is 1441 + abort: child 1442 raises error + abort: child 1443 raises error + abort: child 1444 raises error + abort: child 1445 raises error + abort: child 1446 raises error + abort: child 1447 raises error + abort: child 1448 raises error + abort: child 1449 raises error + hi from 1446 + hi from 1443 + hi from 1444 + hi from 1445 + hi from 1448 + hi from 1447 + hi from 1449 + hi from 1442 + hi from 1441 Which is clearly wrong since the child should exit on all exceptions. And the only reason the sys.exit I had a problem with is 'working' is thanks to this: http://selenic.com/repo/hg/file/0027a5cec9d0/mercurial/dispatch.py#l201 -------------- next part -------------- An HTML attachment was scrubbed... URL: From brodie at sf.io Sun Feb 10 05:43:50 2013 From: brodie at sf.io (Brodie Rao) Date: Sun, 10 Feb 2013 11:43:50 +0000 Subject: [PATCH] serve: introduce --get and --post for easy testing of hgweb In-Reply-To: <86f6b4786d8d292843a9.1360452156@localhost.localdomain> References: <86f6b4786d8d292843a9.1360452156@localhost.localdomain> Message-ID: (Resending, forgot to CC the list.) On Sat, Feb 9, 2013 at 11:22 PM, Mads Kiilerich wrote: > # HG changeset patch > # User Mads Kiilerich > # Date 1359297965 -3600 > # Node ID 86f6b4786d8d292843a9509b0c99f8e855ef4e9d > # Parent 19f90544863eadb00baf80ef21811d41b2beb54b > serve: introduce --get and --post for easy testing of hgweb > > These options can be useful both in the test suite and for other kinds of hgweb > testing. > > diff --git a/mercurial/commands.py b/mercurial/commands.py > --- a/mercurial/commands.py > +++ b/mercurial/commands.py > @@ -8,7 +8,7 @@ > from node import hex, bin, nullid, nullrev, short > from lock import release > from i18n import _, gettext > -import os, re, difflib, time, tempfile, errno > +import os, re, difflib, time, tempfile, errno, sys > import hg, scmutil, util, revlog, extensions, copies, error, bookmarks > import patch, help, encoding, templatekw, discovery > import archival, changegroup, cmdutil, hbisect > @@ -5251,7 +5251,9 @@ > ('t', 'templates', '', _('web templates to use'), _('TEMPLATE')), > ('', 'style', '', _('template style to use'), _('STYLE')), > ('6', 'ipv6', None, _('use IPv6 in addition to IPv4')), > - ('', 'certificate', '', _('SSL certificate file'), _('FILE'))], > + ('', 'certificate', '', _('SSL certificate file'), _('FILE')), > + ('', 'get', '', _('just GET url'), _('URL')), > + ('', 'post', '', _('just POST url'), _('URL'))], Do these options need to be exposed by default? I feel like they might be better as debug options. I also think the descriptions are a little too terse. Maybe something like "GET specified URL and exit"? Other than that, this looks useful. > _('[OPTION]...')) > def serve(ui, repo, **opts): > """start stand-alone webserver > @@ -5275,6 +5277,9 @@ > a port number of 0; in this case, the server will print the port > number it uses. > > + --get and --post will process a single hgweb request and show the output > + without starting a server. Headers will be shown in verbose mode. > + > Returns 0 on success. > """ > > @@ -5320,6 +5325,45 @@ > > app = hgweb.hgweb(o, baseui=ui) > > + get = opts.get('get') > + post = opts.get('post') > + if get or post: > + url = util.url(get or post) > + > + environ = dict(os.environ.iteritems()) > + environ['REQUEST_METHOD'] = get and 'GET' or 'POST' > + environ['wsgi.url_scheme'] = url.scheme or 'http' > + environ['SERVER_NAME'] = url.host or 'localhost' > + environ['SERVER_PORT'] = url.port or (url.scheme == 'https' and '443' or '80') > + environ['SCRIPT_NAME'] = '' > + environ['PATH_INFO'] = '/' + url.path > + environ['QUERY_STRING'] = url.query or '' > + > + environ['wsgi.input'] = sys.stdin > + environ['wsgi.errors'] = sys.stderr > + environ['wsgi.version'] = (1, 0) > + environ['wsgi.multithread'] = False > + environ['wsgi.multiprocess'] = True > + environ['wsgi.run_once'] = True > + > + def start_response(status, response_headers, exc_info=None): > + if exc_info: > + raise exc_info[0](exc_info[1], exc_info[2]) > + # this is for stdout - don't use \r\n as HTTP mandates > + ui.note(status + '\n') > + for header in response_headers: > + if header[0] == 'ETag' and not ui.debugflag: > + continue > + ui.note('%s: %s\n' % header) > + ui.note('\n') > + return ui.write > + > + content = app(environ, start_response) > + for chunk in content: > + ui.write(chunk) > + getattr(content, 'close', lambda : None)() > + return > + > class service(object): > def init(self): > util.setsignalhandler() > diff --git a/tests/test-hgweb-commands.t b/tests/test-hgweb-commands.t > --- a/tests/test-hgweb-commands.t > +++ b/tests/test-hgweb-commands.t > @@ -1366,73 +1366,46 @@ > > $ hg phase -fs 4 > $ hg bookmark -r4 secret > - $ cat > hgweb.cgi < - > from mercurial import demandimport; demandimport.enable() > - > from mercurial.hgweb import hgweb > - > from mercurial.hgweb import wsgicgi > - > app = hgweb('.', 'test') > - > wsgicgi.launch(app) > - > HGWEB > - $ . "$TESTDIR/cgienv" > - $ PATH_INFO=/bookmarks; export PATH_INFO > - $ QUERY_STRING='style=raw' > - $ python hgweb.cgi | grep -v ETag: > - Status: 200 Script output follows\r (esc) > - Content-Type: text/plain; charset=ascii\r (esc) > - \r (esc) > + $ hg serve --get 'http://server/bookmarks?style=raw' -v > + 200 Script output follows > + Content-Type: text/plain; charset=ascii > + > > listbookmarks hides secret bookmarks > > - $ PATH_INFO=/; export PATH_INFO > - $ QUERY_STRING='cmd=listkeys&namespace=bookmarks' > - $ python hgweb.cgi > - Status: 200 Script output follows\r (esc) > - Content-Type: application/mercurial-0.1\r (esc) > - Content-Length: 0\r (esc) > - \r (esc) > + $ hg serve --get 'http://server/?cmd=listkeys&namespace=bookmarks' -v > + 200 Script output follows > + Content-Type: application/mercurial-0.1 > + Content-Length: 0 > + > > search works with filtering > > - $ PATH_INFO=/log; export PATH_INFO > - $ QUERY_STRING='rev=babar' > - $ python hgweb.cgi > search > - $ grep Status search > - Status: 200 Script output follows\r (esc) > + $ hg serve --get 'http://server/log/?rev=babar/' -v | head -n1 > + 200 Script output follows > > summary works with filtering (issue3810) > > - $ PATH_INFO=/summary; export PATH_INFO > - $ QUERY_STRING='style=monoblue'; export QUERY_STRING > - $ python hgweb.cgi > summary.out > - $ grep "^Status" summary.out > - Status: 200 Script output follows\r (esc) > + $ hg serve --get 'http://server/summary?style=monoblue' -v | head -n1 > + 200 Script output follows > > proper status for filtered revision > > - > (missing rev) > > - $ PATH_INFO=/rev/5; export PATH_INFO > - $ QUERY_STRING='style=raw' > - $ python hgweb.cgi #> search > - Status: 404 Not Found\r (esc) > - ETag: *\r (glob) (esc) > - Content-Type: text/plain; charset=ascii\r (esc) > - \r (esc) > + $ hg serve --get 'http://server/rev/5?style=raw' -v > + 404 Not Found > + Content-Type: text/plain; charset=ascii > + > > error: unknown revision '5' > > - > - > (filtered rev) > > - $ PATH_INFO=/rev/4; export PATH_INFO > - $ QUERY_STRING='style=raw' > - $ python hgweb.cgi #> search > - Status: 404 Not Found\r (esc) > - ETag: *\r (glob) (esc) > - Content-Type: text/plain; charset=ascii\r (esc) > - \r (esc) > + $ hg serve --get 'http://server/rev/4?style=raw' -v > + 404 Not Found > + Content-Type: text/plain; charset=ascii > + > > error: unknown revision '4' > > _______________________________________________ > Mercurial-devel mailing list > Mercurial-devel at selenic.com > http://selenic.com/mailman/listinfo/mercurial-devel From brodie at sf.io Sun Feb 10 05:45:06 2013 From: brodie at sf.io (Brodie Rao) Date: Sun, 10 Feb 2013 11:45:06 +0000 Subject: [PATCH] commit: add --reuse-message for keeping the old commit message during amend In-Reply-To: <96e2d74e5f7b32221480.1360409715@dev350.prn1.facebook.com> References: <96e2d74e5f7b32221480.1360409715@dev350.prn1.facebook.com> Message-ID: On Sat, Feb 9, 2013 at 11:35 AM, Durham Goode wrote: > # HG changeset patch > # User Durham Goode > # Date 1360352769 28800 > # Node ID 96e2d74e5f7b32221480fc7932c9555c84f10670 > # Parent e2b176cf28e374eb146c3e131871631ab9ace537 > commit: add --reuse-message for keeping the old commit message during amend > > When people do 'hg commit --amend', most of the time they don't want to change > the commit message. This adds a flag to do that without prompting the user. > > I imagine most people will use it in an alias such as: > > amend=commit --amend --reuse-message What happens if you specify --reuse-message without --amend? Should that raise an error? > > diff --git a/mercurial/cmdutil.py b/mercurial/cmdutil.py > --- a/mercurial/cmdutil.py > +++ b/mercurial/cmdutil.py > @@ -1702,7 +1702,7 @@ > date = opts.get('date') or old.date() > editmsg = False > if not message: > - editmsg = True > + editmsg = not opts.get('reuse_message') > message = old.description() > > pureextra = extra.copy() > diff --git a/mercurial/commands.py b/mercurial/commands.py > --- a/mercurial/commands.py > +++ b/mercurial/commands.py > @@ -1241,6 +1241,8 @@ > ('', 'close-branch', None, > _('mark a branch as closed, hiding it from the branch list')), > ('', 'amend', None, _('amend the parent of the working dir')), > + ('', 'reuse-message', None, > + _('used with amend to reuse the previous commit message')), > ] + walkopts + commitopts + commitopts2 + subrepoopts, > _('[OPTION]... [FILE]...')) > def commit(ui, repo, *pats, **opts): > diff --git a/tests/test-commit-amend.t b/tests/test-commit-amend.t > --- a/tests/test-commit-amend.t > +++ b/tests/test-commit-amend.t > @@ -518,3 +518,14 @@ > date: Thu Jan 01 00:00:00 1970 +0000 > summary: babar > > + > +Test amend with reuse-message flag > +--------------------------------------------------------------------- > +Verify that the editor doesn't appear > + $ hg rm a > + $ HGEDITOR="\"sh\" \"`pwd`/editor.sh\"" hg ci --amend --reuse-message > + $ hg log -r . --template "Description: {desc}\n" --stat > + Description: a'' > + a | 7 ------- > + 1 files changed, 0 insertions(+), 7 deletions(-) > + > diff --git a/tests/test-debugcomplete.t b/tests/test-debugcomplete.t > --- a/tests/test-debugcomplete.t > +++ b/tests/test-debugcomplete.t > @@ -197,7 +197,7 @@ > add: include, exclude, subrepos, dry-run > annotate: rev, follow, no-follow, text, user, file, date, number, changeset, line-number, ignore-all-space, ignore-space-change, ignore-blank-lines, include, exclude > clone: noupdate, updaterev, rev, branch, pull, uncompressed, ssh, remotecmd, insecure > - commit: addremove, close-branch, amend, include, exclude, message, logfile, date, user, subrepos > + commit: addremove, close-branch, amend, reuse-message, include, exclude, message, logfile, date, user, subrepos > diff: rev, change, text, git, nodates, show-function, reverse, ignore-all-space, ignore-space-change, ignore-blank-lines, unified, stat, include, exclude, subrepos > export: output, switch-parent, rev, text, git, nodates > forget: include, exclude > diff --git a/tests/test-qrecord.t b/tests/test-qrecord.t > --- a/tests/test-qrecord.t > +++ b/tests/test-qrecord.t > @@ -61,6 +61,7 @@ > --close-branch mark a branch as closed, hiding it from the branch > list > --amend amend the parent of the working dir > + --reuse-message used with amend to reuse the previous commit message > -I --include PATTERN [+] include names matching the given patterns > -X --exclude PATTERN [+] exclude names matching the given patterns > -m --message TEXT use text as commit message > _______________________________________________ > Mercurial-devel mailing list > Mercurial-devel at selenic.com > http://selenic.com/mailman/listinfo/mercurial-devel From mercurial-bugs at selenic.com Sun Feb 10 00:53:12 2013 From: mercurial-bugs at selenic.com (mercurial-bugs at selenic.com) Date: Sun, 10 Feb 2013 06:53:12 +0000 Subject: [Bug 3815] New: test-check-code-hg.t uses extensions enabled in the local repository Message-ID: http://bz.selenic.com/show_bug.cgi?id=3815 Priority: normal Bug ID: 3815 CC: mercurial-devel at selenic.com Assignee: bugzilla at selenic.com Summary: test-check-code-hg.t uses extensions enabled in the local repository Severity: bug Classification: Unclassified OS: Linux Reporter: thomas at intevation.de Hardware: PC Status: UNCONFIRMED Version: 2.5.1 Component: Mercurial Product: Mercurial While running tests with 2.5.1: --- /home/thomas/hg/repos/tah/tests/test-check-code-hg.t +++ /home/thomas/hg/repos/tah/tests/test-check-code-hg.t.err @@ -5,7 +5,9 @@ > echo "skipped: not a Mercurial working dir" >&2 > exit 80 > fi + *** failed to import extension evolve from ~/hg/repos/mutable-history/hgext/evolve.py: [Errno 2] No such file or directory: '$TESTTMP/hg/repos/mutable-history/hgext/evolve.py' New errors are not allowed. Warnings are strongly discouraged. $ hg manifest | xargs "$check_code" --warnings --nolineno --per-file=0 + *** failed to import extension evolve from ~/hg/repos/mutable-history/hgext/evolve.py: [Errno 2] No such file or directory: '$TESTTMP/hg/repos/mutable-history/hgext/evolve.py' the repository's .hg/hgrc contains: [phases] publishing = false [extensions] rebase = evolve = ~/hg/repos/mutable-history/hgext/evolve.py $HOME is changed to $TESTTMP during the tests, this triggers the error. I should probably not use ~ here, because other users (who trust my account) might want to clone the repository and will get the same error, but the issue here is that the test uses the settings of the local .hg/hgrc, which I think it should not do. All other tests run fine. -- You are receiving this mail because: You are on the CC list for the bug. From brodie at sf.io Sun Feb 10 05:53:43 2013 From: brodie at sf.io (Brodie Rao) Date: Sun, 10 Feb 2013 11:53:43 +0000 Subject: [PATCH] export: show 'Date' header in a format that also is readable for humans In-Reply-To: <055060daf58dbe46c667.1360402284@localhost.localdomain> References: <055060daf58dbe46c667.1360402284@localhost.localdomain> Message-ID: On Sat, Feb 9, 2013 at 9:31 AM, Mads Kiilerich wrote: > # HG changeset patch > # User Mads Kiilerich > # Date 1360360457 -3600 > # Node ID 055060daf58dbe46c667053cbb04409b202ee9cd > # Parent 97761496c65ae836d6b0983a3f48959dd3112364 > export: show 'Date' header in a format that also is readable for humans > > 'export' is the official export format and used by patchbomb, but it would only > show date as a timestamp that most humans might find it hard to relate to. It > would be very convenient when reviewing a patch to be able to see what > timestamp the patch will end up with. > > Mercurial has always used util.parsedate for parsing these headers. It can > handle 'all' date formats, so we could just as well use a readable one. Are there any third party utilities that parse these headers? I wonder if this might cause other tools to break. > 'export' will now use the format used by 'log' - which is the format described > as 'Unix date format' in the templating help. We assume that all parsers of '# > HG changeset patch'es can handle that. > > diff --git a/mercurial/cmdutil.py b/mercurial/cmdutil.py > --- a/mercurial/cmdutil.py > +++ b/mercurial/cmdutil.py > @@ -569,7 +569,7 @@ > > write("# HG changeset patch\n") > write("# User %s\n" % ctx.user()) > - write("# Date %d %d\n" % ctx.date()) > + write("# Date %s\n" % util.datestr(ctx.date())) > if branch and branch != 'default': > write("# Branch %s\n" % branch) > write("# Node ID %s\n" % hex(node)) > diff --git a/tests/test-alias.t b/tests/test-alias.t > --- a/tests/test-alias.t > +++ b/tests/test-alias.t > @@ -180,7 +180,7 @@ > $ cat 0.diff > # HG changeset patch > # User test > - # Date 0 0 > + # Date Thu Jan 01 00:00:00 1970 +0000 > # Node ID e63c23eaa88ae77967edcf4ea194d31167c478b0 > # Parent 0000000000000000000000000000000000000000 > foo > @@ -224,7 +224,7 @@ > 2 > > $ hg tglog > - @ 1:7e7f92de180e: 'bar' > + @ 1:c199fc2b9f8e: 'bar' > | > o 0:e63c23eaa88a: 'foo' > > @@ -237,15 +237,15 @@ > idalias idaliaslong idaliasshell identify import incoming init > [255] > $ hg id > - 7e7f92de180e tip > + c199fc2b9f8e tip > $ hg ida > hg: command 'ida' is ambiguous: > idalias idaliaslong idaliasshell > [255] > $ hg idalias > - 7e7f92de180e tip > + c199fc2b9f8e tip > $ hg idaliasl > - 7e7f92de180e tip > + c199fc2b9f8e tip > $ hg idaliass > test > $ hg parentsshell > diff --git a/tests/test-export.t b/tests/test-export.t > --- a/tests/test-export.t > +++ b/tests/test-export.t > @@ -107,7 +107,7 @@ > $ hg export -- -2 > # HG changeset patch > # User test > - # Date 0 0 > + # Date Thu Jan 01 00:00:00 1970 +0000 > # Node ID 5f17a83f5fbd9414006a5e563eab4c8a00729efd > # Parent 747d3c68f8ec44bb35816bfcd59aeb50b9654c2f > foo-10 > @@ -153,7 +153,7 @@ > $ hg export --color always --nodates tip > # HG changeset patch > # User test > - # Date 0 0 > + # Date Thu Jan 01 00:00:00 1970 +0000 > # Node ID * (glob) > # Parent * (glob) > !"#$%&(,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~ > diff --git a/tests/test-graft.t b/tests/test-graft.t > --- a/tests/test-graft.t > +++ b/tests/test-graft.t > @@ -83,7 +83,7 @@ > $ hg export tip --git > # HG changeset patch > # User foo > - # Date 0 0 > + # Date Thu Jan 01 00:00:00 1970 +0000 > # Node ID ef0ef43d49e79e81ddafdc7997401ba0041efc82 > # Parent 68795b066622ca79a25816a662041d8f78f3cd9e > 2 > @@ -323,7 +323,7 @@ > $ hg export tip --git > # HG changeset patch > # User bar > - # Date 0 0 > + # Date Thu Jan 01 00:00:00 1970 +0000 > # Node ID 64ecd9071ce83c6e62f538d8ce7709d53f32ebf7 > # Parent 4bdb9a9d0b84ffee1d30f0dfc7744cade17aa19c > 1 > @@ -350,7 +350,7 @@ > $ hg export tip --git > # HG changeset patch > # User test > - # Date 0 0 > + # Date Thu Jan 01 00:00:00 1970 +0000 > # Node ID 2e80e1351d6ed50302fe1e05f8bd1d4d412b6e11 > # Parent e5a51ae854a8bbaaf25cc5c6a57ff46042dadbb4 > 2 > diff --git a/tests/test-histedit-fold.t b/tests/test-histedit-fold.t > --- a/tests/test-histedit-fold.t > +++ b/tests/test-histedit-fold.t > @@ -294,7 +294,7 @@ > $ hg export tip > # HG changeset patch > # User test > - # Date 0 0 > + # Date Thu Jan 01 00:00:00 1970 +0000 > # Node ID 10c647b2cdd54db0603ecb99b2ff5ce66d5a5323 > # Parent 0189ba417d34df9dda55f88b637dcae9917b5964 > +4 > diff --git a/tests/test-import.t b/tests/test-import.t > --- a/tests/test-import.t > +++ b/tests/test-import.t > @@ -34,7 +34,7 @@ > $ hg --cwd b import ../exported-tip.patch > applying ../exported-tip.patch > > -message and committer should be same > +message and committer and date should be same > > $ hg --cwd b tip > changeset: 1:1d4bd90af0e4 > @@ -852,7 +852,7 @@ > $ hg export --git tip > # HG changeset patch > # User User B > - # Date 0 0 > + # Date Thu Jan 01 00:00:00 1970 +0000 > # Node ID eb56ab91903632294ac504838508cb370c0901d2 > # Parent 0000000000000000000000000000000000000000 > from: tricky! > diff --git a/tests/test-issue1175.t b/tests/test-issue1175.t > --- a/tests/test-issue1175.t > +++ b/tests/test-issue1175.t > @@ -43,7 +43,7 @@ > $ hg export --git tip > # HG changeset patch > # User test > - # Date 0 0 > + # Date Thu Jan 01 00:00:00 1970 +0000 > # Node ID 89e8e4be0de296fa3d6dd7825ccc44d7dc0f1f3b > # Parent 7fc86ba705e717a721dbc361bf8c9bc05a18ca2f > 5 > diff --git a/tests/test-keyword.t b/tests/test-keyword.t > --- a/tests/test-keyword.t > +++ b/tests/test-keyword.t > @@ -527,7 +527,7 @@ > $ cat .hg/patches/mqtest.diff > # HG changeset patch > # User User Name > - # Date 1 0 > + # Date Thu Jan 01 00:00:01 1970 +0000 > # Node ID 40a904bbbe4cd4ab0a1f28411e35db26341a40ad > # Parent ef63ca68695bc9495032c6fda1350c71e6d256e9 > cndiff > diff --git a/tests/test-patchbomb.t b/tests/test-patchbomb.t > --- a/tests/test-patchbomb.t > +++ b/tests/test-patchbomb.t > @@ -26,7 +26,7 @@ > > # HG changeset patch > # User test > - # Date 1 0 > + # Date Thu Jan 01 00:00:01 1970 +0000 > # Node ID 8580ff50825a50c8f716709acdf8de0deddcd6ab > # Parent 0000000000000000000000000000000000000000 > a > @@ -97,7 +97,7 @@ > > # HG changeset patch > # User test > - # Date 1 0 > + # Date Thu Jan 01 00:00:01 1970 +0000 > # Node ID 8580ff50825a50c8f716709acdf8de0deddcd6ab > # Parent 0000000000000000000000000000000000000000 > a > @@ -125,7 +125,7 @@ > > # HG changeset patch > # User test > - # Date 2 0 > + # Date Thu Jan 01 00:00:02 1970 +0000 > # Node ID 97d72e5f12c7e84f85064aa72e5a297142c36ed9 > # Parent 8580ff50825a50c8f716709acdf8de0deddcd6ab > b > @@ -257,7 +257,7 @@ > > # HG changeset patch > # User test > - # Date 4 0 > + # Date Thu Jan 01 00:00:04 1970 +0000 > # Node ID 909a00e13e9d78b575aeee23dddbada46d5a143f > # Parent ff2c9fa2018b15fa74b33363bda9527323e2a99f > utf-8 content > @@ -297,21 +297,22 @@ > To: foo > Cc: bar > > - IyBIRyBjaGFuZ2VzZXQgcGF0Y2gKIyBVc2VyIHRlc3QKIyBEYXRlIDQgMAojIE5vZGUgSUQgOTA5 > - YTAwZTEzZTlkNzhiNTc1YWVlZTIzZGRkYmFkYTQ2ZDVhMTQzZgojIFBhcmVudCAgZmYyYzlmYTIw > - MThiMTVmYTc0YjMzMzYzYmRhOTUyNzMyM2UyYTk5Zgp1dGYtOCBjb250ZW50CgpkaWZmIC1yIGZm > - MmM5ZmEyMDE4YiAtciA5MDlhMDBlMTNlOWQgZGVzY3JpcHRpb24KLS0tIC9kZXYvbnVsbAlUaHUg > - SmFuIDAxIDAwOjAwOjAwIDE5NzAgKzAwMDAKKysrIGIvZGVzY3JpcHRpb24JVGh1IEphbiAwMSAw > - MDowMDowNCAxOTcwICswMDAwCkBAIC0wLDAgKzEsMyBAQAorYSBtdWx0aWxpbmUKKworZGVzY3Jp > - cHRpb24KZGlmZiAtciBmZjJjOWZhMjAxOGIgLXIgOTA5YTAwZTEzZTlkIHV0ZgotLS0gL2Rldi9u > - dWxsCVRodSBKYW4gMDEgMDA6MDA6MDAgMTk3MCArMDAwMAorKysgYi91dGYJVGh1IEphbiAwMSAw > - MDowMDowNCAxOTcwICswMDAwCkBAIC0wLDAgKzEsMSBAQAoraMO2bW1hIQo= > + IyBIRyBjaGFuZ2VzZXQgcGF0Y2gKIyBVc2VyIHRlc3QKIyBEYXRlIFRodSBKYW4gMDEgMDA6MDA6 > + MDQgMTk3MCArMDAwMAojIE5vZGUgSUQgOTA5YTAwZTEzZTlkNzhiNTc1YWVlZTIzZGRkYmFkYTQ2 > + ZDVhMTQzZgojIFBhcmVudCAgZmYyYzlmYTIwMThiMTVmYTc0YjMzMzYzYmRhOTUyNzMyM2UyYTk5 > + Zgp1dGYtOCBjb250ZW50CgpkaWZmIC1yIGZmMmM5ZmEyMDE4YiAtciA5MDlhMDBlMTNlOWQgZGVz > + Y3JpcHRpb24KLS0tIC9kZXYvbnVsbAlUaHUgSmFuIDAxIDAwOjAwOjAwIDE5NzAgKzAwMDAKKysr > + IGIvZGVzY3JpcHRpb24JVGh1IEphbiAwMSAwMDowMDowNCAxOTcwICswMDAwCkBAIC0wLDAgKzEs > + MyBAQAorYSBtdWx0aWxpbmUKKworZGVzY3JpcHRpb24KZGlmZiAtciBmZjJjOWZhMjAxOGIgLXIg > + OTA5YTAwZTEzZTlkIHV0ZgotLS0gL2Rldi9udWxsCVRodSBKYW4gMDEgMDA6MDA6MDAgMTk3MCAr > + MDAwMAorKysgYi91dGYJVGh1IEphbiAwMSAwMDowMDowNCAxOTcwICswMDAwCkBAIC0wLDAgKzEs > + MSBAQAoraMO2bW1hIQo= > > > $ python -c 'print open("mbox").read().split("\n\n")[1].decode("base64")' > # HG changeset patch > # User test > - # Date 4 0 > + # Date Thu Jan 01 00:00:04 1970 +0000 > # Node ID 909a00e13e9d78b575aeee23dddbada46d5a143f > # Parent ff2c9fa2018b15fa74b33363bda9527323e2a99f > utf-8 content > @@ -356,7 +357,7 @@ > > # HG changeset patch > # User test > - # Date 4 0 > + # Date Thu Jan 01 00:00:04 1970 +0000 > # Node ID a2ea8fc83dd8b93cfd86ac97b28287204ab806e1 > # Parent 909a00e13e9d78b575aeee23dddbada46d5a143f > long line > @@ -406,7 +407,7 @@ > > # HG changeset patch > # User test > - # Date 4 0 > + # Date Thu Jan 01 00:00:04 1970 +0000 > # Node ID a2ea8fc83dd8b93cfd86ac97b28287204ab806e1 > # Parent 909a00e13e9d78b575aeee23dddbada46d5a143f > long line > @@ -464,7 +465,7 @@ > > # HG changeset patch > # User test > - # Date 5 0 > + # Date Thu Jan 01 00:00:05 1970 +0000 > # Node ID 240fb913fc1b7ff15ddb9f33e73d82bf5277c720 > # Parent a2ea8fc83dd8b93cfd86ac97b28287204ab806e1 > isolatin 8-bit encoding > @@ -512,7 +513,7 @@ > > # HG changeset patch > # User test > - # Date 3 0 > + # Date Thu Jan 01 00:00:03 1970 +0000 > # Node ID ff2c9fa2018b15fa74b33363bda9527323e2a99f > # Parent 97d72e5f12c7e84f85064aa72e5a297142c36ed9 > c > @@ -589,7 +590,7 @@ > > # HG changeset patch > # User test > - # Date 1 0 > + # Date Thu Jan 01 00:00:01 1970 +0000 > # Node ID 8580ff50825a50c8f716709acdf8de0deddcd6ab > # Parent 0000000000000000000000000000000000000000 > a > @@ -621,7 +622,7 @@ > > # HG changeset patch > # User test > - # Date 2 0 > + # Date Thu Jan 01 00:00:02 1970 +0000 > # Node ID 97d72e5f12c7e84f85064aa72e5a297142c36ed9 > # Parent 8580ff50825a50c8f716709acdf8de0deddcd6ab > b > @@ -658,7 +659,7 @@ > > # HG changeset patch > # User test > - # Date 3 0 > + # Date Thu Jan 01 00:00:03 1970 +0000 > # Node ID ff2c9fa2018b15fa74b33363bda9527323e2a99f > # Parent 97d72e5f12c7e84f85064aa72e5a297142c36ed9 > c > @@ -697,7 +698,7 @@ > > # HG changeset patch > # User test > - # Date 4 0 > + # Date Thu Jan 01 00:00:04 1970 +0000 > # Node ID a2ea8fc83dd8b93cfd86ac97b28287204ab806e1 > # Parent 909a00e13e9d78b575aeee23dddbada46d5a143f > long line > @@ -770,7 +771,7 @@ > > # HG changeset patch > # User test > - # Date 1 0 > + # Date Thu Jan 01 00:00:01 1970 +0000 > # Node ID 8580ff50825a50c8f716709acdf8de0deddcd6ab > # Parent 0000000000000000000000000000000000000000 > a > @@ -804,7 +805,7 @@ > > # HG changeset patch > # User test > - # Date 2 0 > + # Date Thu Jan 01 00:00:02 1970 +0000 > # Node ID 97d72e5f12c7e84f85064aa72e5a297142c36ed9 > # Parent 8580ff50825a50c8f716709acdf8de0deddcd6ab > b > @@ -838,7 +839,7 @@ > > # HG changeset patch > # User test > - # Date 4 0 > + # Date Thu Jan 01 00:00:04 1970 +0000 > # Node ID a2ea8fc83dd8b93cfd86ac97b28287204ab806e1 > # Parent 909a00e13e9d78b575aeee23dddbada46d5a143f > long line > @@ -901,7 +902,7 @@ > > # HG changeset patch > # User test > - # Date 3 0 > + # Date Thu Jan 01 00:00:03 1970 +0000 > # Node ID ff2c9fa2018b15fa74b33363bda9527323e2a99f > # Parent 97d72e5f12c7e84f85064aa72e5a297142c36ed9 > c > @@ -948,7 +949,7 @@ > > # HG changeset patch > # User test > - # Date 4 0 > + # Date Thu Jan 01 00:00:04 1970 +0000 > # Node ID a2ea8fc83dd8b93cfd86ac97b28287204ab806e1 > # Parent 909a00e13e9d78b575aeee23dddbada46d5a143f > long line > @@ -1001,7 +1002,7 @@ > > # HG changeset patch > # User test > - # Date 3 0 > + # Date Thu Jan 01 00:00:03 1970 +0000 > # Node ID ff2c9fa2018b15fa74b33363bda9527323e2a99f > # Parent 97d72e5f12c7e84f85064aa72e5a297142c36ed9 > c > @@ -1020,7 +1021,7 @@ > > # HG changeset patch > # User test > - # Date 3 0 > + # Date Thu Jan 01 00:00:03 1970 +0000 > # Node ID ff2c9fa2018b15fa74b33363bda9527323e2a99f > # Parent 97d72e5f12c7e84f85064aa72e5a297142c36ed9 > c > @@ -1086,7 +1087,7 @@ > > # HG changeset patch > # User test > - # Date 1 0 > + # Date Thu Jan 01 00:00:01 1970 +0000 > # Node ID 8580ff50825a50c8f716709acdf8de0deddcd6ab > # Parent 0000000000000000000000000000000000000000 > a > @@ -1129,7 +1130,7 @@ > > # HG changeset patch > # User test > - # Date 2 0 > + # Date Thu Jan 01 00:00:02 1970 +0000 > # Node ID 97d72e5f12c7e84f85064aa72e5a297142c36ed9 > # Parent 8580ff50825a50c8f716709acdf8de0deddcd6ab > b > @@ -1172,7 +1173,7 @@ > > # HG changeset patch > # User test > - # Date 4 0 > + # Date Thu Jan 01 00:00:04 1970 +0000 > # Node ID a2ea8fc83dd8b93cfd86ac97b28287204ab806e1 > # Parent 909a00e13e9d78b575aeee23dddbada46d5a143f > long line > @@ -1240,7 +1241,7 @@ > > # HG changeset patch > # User test > - # Date 3 0 > + # Date Thu Jan 01 00:00:03 1970 +0000 > # Node ID ff2c9fa2018b15fa74b33363bda9527323e2a99f > # Parent 97d72e5f12c7e84f85064aa72e5a297142c36ed9 > c > @@ -1290,7 +1291,7 @@ > > # HG changeset patch > # User test > - # Date 3 0 > + # Date Thu Jan 01 00:00:03 1970 +0000 > # Node ID ff2c9fa2018b15fa74b33363bda9527323e2a99f > # Parent 97d72e5f12c7e84f85064aa72e5a297142c36ed9 > c > @@ -1341,7 +1342,7 @@ > > # HG changeset patch > # User test > - # Date 1 0 > + # Date Thu Jan 01 00:00:01 1970 +0000 > # Node ID 8580ff50825a50c8f716709acdf8de0deddcd6ab > # Parent 0000000000000000000000000000000000000000 > a > @@ -1369,7 +1370,7 @@ > > # HG changeset patch > # User test > - # Date 2 0 > + # Date Thu Jan 01 00:00:02 1970 +0000 > # Node ID 97d72e5f12c7e84f85064aa72e5a297142c36ed9 > # Parent 8580ff50825a50c8f716709acdf8de0deddcd6ab > b > @@ -1403,7 +1404,7 @@ > > # HG changeset patch > # User test > - # Date 3 0 > + # Date Thu Jan 01 00:00:03 1970 +0000 > # Node ID ff2c9fa2018b15fa74b33363bda9527323e2a99f > # Parent 97d72e5f12c7e84f85064aa72e5a297142c36ed9 > c > @@ -1437,7 +1438,7 @@ > > # HG changeset patch > # User test > - # Date 3 0 > + # Date Thu Jan 01 00:00:03 1970 +0000 > # Node ID ff2c9fa2018b15fa74b33363bda9527323e2a99f > # Parent 97d72e5f12c7e84f85064aa72e5a297142c36ed9 > c > @@ -1479,7 +1480,7 @@ > > # HG changeset patch > # User test > - # Date 3 0 > + # Date Thu Jan 01 00:00:03 1970 +0000 > # Node ID ff2c9fa2018b15fa74b33363bda9527323e2a99f > # Parent 97d72e5f12c7e84f85064aa72e5a297142c36ed9 > c > @@ -1535,7 +1536,7 @@ > > # HG changeset patch > # User test > - # Date 1 0 > + # Date Thu Jan 01 00:00:01 1970 +0000 > # Node ID 8580ff50825a50c8f716709acdf8de0deddcd6ab > # Parent 0000000000000000000000000000000000000000 > a > @@ -1569,7 +1570,7 @@ > > # HG changeset patch > # User test > - # Date 2 0 > + # Date Thu Jan 01 00:00:02 1970 +0000 > # Node ID 97d72e5f12c7e84f85064aa72e5a297142c36ed9 > # Parent 8580ff50825a50c8f716709acdf8de0deddcd6ab > b > @@ -1606,7 +1607,7 @@ > > # HG changeset patch > # User test > - # Date 0 0 > + # Date Thu Jan 01 00:00:00 1970 +0000 > # Node ID 7aead2484924c445ad8ce2613df91f52f9e502ed > # Parent 045ca29b1ea20e4940411e695e20e521f2f0f98e > Added tag two, two.diff for changeset ff2c9fa2018b > @@ -1645,7 +1646,7 @@ > > # HG changeset patch > # User test > - # Date 1 0 > + # Date Thu Jan 01 00:00:01 1970 +0000 > # Node ID 8580ff50825a50c8f716709acdf8de0deddcd6ab > # Parent 0000000000000000000000000000000000000000 > a > @@ -1673,7 +1674,7 @@ > > # HG changeset patch > # User test > - # Date 2 0 > + # Date Thu Jan 01 00:00:02 1970 +0000 > # Node ID 97d72e5f12c7e84f85064aa72e5a297142c36ed9 > # Parent 8580ff50825a50c8f716709acdf8de0deddcd6ab > b > @@ -1727,7 +1728,7 @@ > > # HG changeset patch > # User test > - # Date 1 0 > + # Date Thu Jan 01 00:00:01 1970 +0000 > # Node ID 8580ff50825a50c8f716709acdf8de0deddcd6ab > # Parent 0000000000000000000000000000000000000000 > a > @@ -1755,7 +1756,7 @@ > > # HG changeset patch > # User test > - # Date 2 0 > + # Date Thu Jan 01 00:00:02 1970 +0000 > # Node ID 97d72e5f12c7e84f85064aa72e5a297142c36ed9 > # Parent 8580ff50825a50c8f716709acdf8de0deddcd6ab > b > @@ -1788,7 +1789,7 @@ > > # HG changeset patch > # User test > - # Date 3 0 > + # Date Thu Jan 01 00:00:03 1970 +0000 > # Node ID ff2c9fa2018b15fa74b33363bda9527323e2a99f > # Parent 97d72e5f12c7e84f85064aa72e5a297142c36ed9 > c > @@ -1839,7 +1840,7 @@ > > # HG changeset patch > # User test > - # Date 1 0 > + # Date Thu Jan 01 00:00:01 1970 +0000 > # Node ID 8580ff50825a50c8f716709acdf8de0deddcd6ab > # Parent 0000000000000000000000000000000000000000 > a > @@ -1867,7 +1868,7 @@ > > # HG changeset patch > # User test > - # Date 2 0 > + # Date Thu Jan 01 00:00:02 1970 +0000 > # Node ID 97d72e5f12c7e84f85064aa72e5a297142c36ed9 > # Parent 8580ff50825a50c8f716709acdf8de0deddcd6ab > b > @@ -1900,7 +1901,7 @@ > > # HG changeset patch > # User test > - # Date 3 0 > + # Date Thu Jan 01 00:00:03 1970 +0000 > # Node ID ff2c9fa2018b15fa74b33363bda9527323e2a99f > # Parent 97d72e5f12c7e84f85064aa72e5a297142c36ed9 > c > @@ -1951,7 +1952,7 @@ > > # HG changeset patch > # User test > - # Date 1 0 > + # Date Thu Jan 01 00:00:01 1970 +0000 > # Node ID 8580ff50825a50c8f716709acdf8de0deddcd6ab > # Parent 0000000000000000000000000000000000000000 > a > @@ -1979,7 +1980,7 @@ > > # HG changeset patch > # User test > - # Date 2 0 > + # Date Thu Jan 01 00:00:02 1970 +0000 > # Node ID 97d72e5f12c7e84f85064aa72e5a297142c36ed9 > # Parent 8580ff50825a50c8f716709acdf8de0deddcd6ab > b > @@ -2016,7 +2017,7 @@ > > # HG changeset patch > # User test > - # Date 1 0 > + # Date Thu Jan 01 00:00:01 1970 +0000 > # Node ID 8580ff50825a50c8f716709acdf8de0deddcd6ab > # Parent 0000000000000000000000000000000000000000 > a > @@ -2055,7 +2056,7 @@ > > # HG changeset patch > # User test > - # Date 1 0 > + # Date Thu Jan 01 00:00:01 1970 +0000 > # Node ID 8580ff50825a50c8f716709acdf8de0deddcd6ab > # Parent 0000000000000000000000000000000000000000 > a > @@ -2143,7 +2144,7 @@ > > # HG changeset patch > # User test > - # Date 3 0 > + # Date Thu Jan 01 00:00:03 1970 +0000 > # Node ID ff2c9fa2018b15fa74b33363bda9527323e2a99f > # Parent 97d72e5f12c7e84f85064aa72e5a297142c36ed9 > c > @@ -2170,7 +2171,7 @@ > > # HG changeset patch > # User test > - # Date 4 0 > + # Date Thu Jan 01 00:00:04 1970 +0000 > # Node ID 909a00e13e9d78b575aeee23dddbada46d5a143f > # Parent ff2c9fa2018b15fa74b33363bda9527323e2a99f > utf-8 content > @@ -2204,7 +2205,7 @@ > > # HG changeset patch > # User test > - # Date 4 0 > + # Date Thu Jan 01 00:00:04 1970 +0000 > # Node ID a2ea8fc83dd8b93cfd86ac97b28287204ab806e1 > # Parent 909a00e13e9d78b575aeee23dddbada46d5a143f > long line > @@ -2247,7 +2248,7 @@ > > # HG changeset patch > # User test > - # Date 5 0 > + # Date Thu Jan 01 00:00:05 1970 +0000 > # Node ID 240fb913fc1b7ff15ddb9f33e73d82bf5277c720 > # Parent a2ea8fc83dd8b93cfd86ac97b28287204ab806e1 > isolatin 8-bit encoding > @@ -2274,7 +2275,7 @@ > > # HG changeset patch > # User test > - # Date 0 0 > + # Date Thu Jan 01 00:00:00 1970 +0000 > # Node ID 5d5ef15dfe5e7bd3a4ee154b5fff76c7945ec433 > # Parent 240fb913fc1b7ff15ddb9f33e73d82bf5277c720 > Added tag zero, zero.foo for changeset 8580ff50825a > @@ -2302,7 +2303,7 @@ > > # HG changeset patch > # User test > - # Date 4 0 > + # Date Thu Jan 01 00:00:04 1970 +0000 > # Branch test > # Node ID 2f9fa9b998c5fe3ac2bd9a2b14bfcbeecbc7c268 > # Parent 97d72e5f12c7e84f85064aa72e5a297142c36ed9 > @@ -2337,7 +2338,7 @@ > > # HG changeset patch > # User test > - # Date 4 0 > + # Date Thu Jan 01 00:00:04 1970 +0000 > # Branch test > # Node ID 2f9fa9b998c5fe3ac2bd9a2b14bfcbeecbc7c268 > # Parent 97d72e5f12c7e84f85064aa72e5a297142c36ed9 > diff --git a/tests/test-rebase-collapse.t b/tests/test-rebase-collapse.t > --- a/tests/test-rebase-collapse.t > +++ b/tests/test-rebase-collapse.t > @@ -568,7 +568,7 @@ > $ hg export tip > # HG changeset patch > # User user1 > - # Date 0 0 > + # Date Thu Jan 01 00:00:00 1970 +0000 > # Node ID f338eb3c2c7cc5b5915676a2376ba7ac558c5213 > # Parent 41acb9dca9eb976e84cd21fcb756b4afa5a35c09 > E > diff --git a/tests/test-rebase-mq.t b/tests/test-rebase-mq.t > --- a/tests/test-rebase-mq.t > +++ b/tests/test-rebase-mq.t > @@ -101,7 +101,7 @@ > $ cat .hg/patches/f.patch > # HG changeset patch > # User test > - # Date ?????????? ? (glob) > + # Date * (glob) > # Node ID ???????????????????????????????????????? (glob) > # Parent bac9ed9960d8992bcad75864a879fa76cadaf1b0 > P0 > @@ -123,7 +123,7 @@ > $ cat .hg/patches/f2.patch > # HG changeset patch > # User test > - # Date ?????????? ? (glob) > + # Date * (glob) > # Node ID ???????????????????????????????????????? (glob) > # Parent ???????????????????????????????????????? (glob) > P1 > @@ -208,7 +208,7 @@ > $ cat .hg/patches/f_git.patch > # HG changeset patch > # User test > - # Date ?????????? ? (glob) > + # Date * (glob) > # Node ID ???????????????????????????????????????? (glob) > # Parent bac9ed9960d8992bcad75864a879fa76cadaf1b0 > P0 (git) > @@ -223,7 +223,7 @@ > $ cat .hg/patches/f.patch > # HG changeset patch > # User test > - # Date ?????????? ? (glob) > + # Date * (glob) > # Node ID ???????????????????????????????????????? (glob) > # Parent ???????????????????????????????????????? (glob) > P1 > _______________________________________________ > Mercurial-devel mailing list > Mercurial-devel at selenic.com > http://selenic.com/mailman/listinfo/mercurial-devel From durham at fb.com Sun Feb 10 05:56:39 2013 From: durham at fb.com (Durham Goode) Date: Sun, 10 Feb 2013 11:56:39 +0000 Subject: [PATCH 1 of 3] pathauditor: add isvalidpath() method In-Reply-To: <1360413772.3873.41.camel@calx> Message-ID: <2B10A89294DA6740AC6155F56842F9CE05659CF7@PRN-MBX01-2.TheFacebook.com> >> # HG changeset patch >> # User Durham Goode >> # Date 1360103054 28800 >> # Node ID f2a1cf2cbb4ac88f922c5bcb5792c2c7c4c236d5 >> # Parent c6377e34cb1ed79cb142f01652b0acfa09ef8c1f >> pathauditor: add isvalidpath() method >> >> The pathauditor currently throws exceptions when it encounters an >>invalid >> path. This change adds a method to allow people to treat it as a >>boolean. >> This is currently used by scmutil.addremove and in a subsequent patch it >> will be used by dirstate.walk > >Can we name this check()? I'll rename it. >Does it make sense to invert things so that the check is done in check() >and __call__() calls check() and raises an exception on failure? I don't think it makes sense in this case. __call__() throws different exceptions based on how it fails, so making the algorithm return True/False and throwing a single kind of exception would give less information. From hg at intevation.org Sun Feb 10 06:00:06 2013 From: hg at intevation.org (Mercurial Commits) Date: Sun, 10 Feb 2013 13:00:06 +0100 Subject: mercurial/crew@18635: 12 outgoing changesets Message-ID: <1360497606.705802.17240.nullmailer@hg.intevation.org> 12 outgoing changesets in mercurial/crew: http://hg.intevation.org/mercurial/crew/rev/6204e4d4dd6d changeset: 18635:6204e4d4dd6d bookmark: @ tag: tip parent: 18634:0027a5cec9d0 parent: 18633:a8648f32b8ed user: Augie Fackler date: Sun Feb 10 04:04:22 2013 -0600 summary: Merge crew and main. http://hg.intevation.org/mercurial/crew/rev/a8648f32b8ed changeset: 18633:a8648f32b8ed user: Bryan O'Sullivan date: Sat Feb 09 15:51:32 2013 -0800 summary: merge: don't fiddle with name lookups or i18n in hot loops http://hg.intevation.org/mercurial/crew/rev/5774732bb5e5 changeset: 18632:5774732bb5e5 user: Bryan O'Sullivan date: Sat Feb 09 15:51:32 2013 -0800 summary: merge: apply non-interactive working dir updates in parallel http://hg.intevation.org/mercurial/crew/rev/047110c0e2a8 changeset: 18631:047110c0e2a8 user: Bryan O'Sullivan date: Sat Feb 09 15:51:32 2013 -0800 summary: worker: allow a function to be run in multiple worker processes http://hg.intevation.org/mercurial/crew/rev/ac4dbceeb14a changeset: 18630:ac4dbceeb14a user: Bryan O'Sullivan date: Sat Feb 09 15:51:32 2013 -0800 summary: worker: partition a list (of tasks) into equal-sized chunks http://hg.intevation.org/mercurial/crew/rev/dcb27c153a40 changeset: 18629:dcb27c153a40 user: Bryan O'Sullivan date: Sat Feb 09 15:51:26 2013 -0800 summary: worker: estimate whether it's worth running a task in parallel http://hg.intevation.org/mercurial/crew/rev/fed06dd07665 changeset: 18628:fed06dd07665 user: Bryan O'Sullivan date: Sat Feb 09 15:22:12 2013 -0800 summary: worker: count the number of CPUs http://hg.intevation.org/mercurial/crew/rev/4b5d37ca3c11 changeset: 18627:4b5d37ca3c11 user: Bryan O'Sullivan date: Sat Feb 09 15:22:10 2013 -0800 summary: tests: getremove test output changes (fold into previous patch) http://hg.intevation.org/mercurial/crew/rev/6390dd22b12f changeset: 18626:6390dd22b12f user: Bryan O'Sullivan date: Sat Feb 09 15:22:09 2013 -0800 summary: merge: report non-interactive progress in chunks http://hg.intevation.org/mercurial/crew/rev/3e20079117c5 changeset: 18625:3e20079117c5 user: Bryan O'Sullivan date: Sat Feb 09 15:22:08 2013 -0800 summary: merge: handle subrepo merges and .hgsubstate specially http://hg.intevation.org/mercurial/crew/rev/e2dc5397bc82 changeset: 18624:e2dc5397bc82 user: Bryan O'Sullivan date: Sat Feb 09 15:22:04 2013 -0800 summary: tests: update test output (will be folded into parent) http://hg.intevation.org/mercurial/crew/rev/9b9e2d9e83a1 changeset: 18623:9b9e2d9e83a1 user: Bryan O'Sullivan date: Sat Feb 09 15:21:58 2013 -0800 summary: merge: split out mostly-non-interactive working dir updates -- Repository URL: http://hg.intevation.org/mercurial/crew From brodie at sf.io Sun Feb 10 06:09:45 2013 From: brodie at sf.io (Brodie Rao) Date: Sun, 10 Feb 2013 12:09:45 +0000 Subject: [PATCH 1 of 6] blackbox: adds a blackbox extension In-Reply-To: <30544b5277d09002d6ca.1360494437@dev350.prn1.facebook.com> References: <30544b5277d09002d6ca.1360494437@dev350.prn1.facebook.com> Message-ID: On Sun, Feb 10, 2013 at 11:07 AM, Durham Goode wrote: > # HG changeset patch > # User Durham Goode > # Date 1360429429 28800 > # Node ID 30544b5277d09002d6cac8c363652f71bb807516 > # Parent 57b7531a5705a099637f6d6bedd4de509fb2a441 > blackbox: adds a blackbox extension > > Adds a blackbox extension that listens to ui.log() and writes the messages to > .hg/blackbox.log. Future commits will use ui.log() to log commands, unhandled > exceptions, incoming changes, and hooks. The extension defaults to logging > everything, but can be configured via blackbox.trackedevents to only log > certain events. Log lines are of the format: "date time user> message" > > Example log line: > 2013/02/09 08:35:19 durham> 1 incoming changes - new heads: d84ced58aaa > > diff --git a/hgext/blackbox.py b/hgext/blackbox.py > new file mode 100644 > --- /dev/null > +++ b/hgext/blackbox.py > @@ -0,0 +1,68 @@ > +"""log repository events to a blackbox for debugging > + > +Logs event information to .hg/blackbox.log to help debug and diagnose problems. > +The events that get logged can be configured via the blackbox.trackedevents > +config key. Examples: > + > + [blackbox] > + trackedevents=* > + > + [blackbox] > + trackedevents=command,commandfinished,commandexception,exthook,pythonhook > + > + [blackbox] > + trackedevents=incoming Minor nit: I think the style we normally use is "option = value" and "option = list, of, values". Also, what about calling this "track" instead of "trackedevents"? > + > +""" > + > +from mercurial import util, cmdutil > +from mercurial.i18n import _ > +import os, getpass, re, string > + > +cmdtable = {} > +command = cmdutil.command(cmdtable) > +testedwith='internal' > +lastblackbox=None There should be spaces between = here. Running check-code should catch this. > + > +def wrapui(ui): > + class blackboxui(ui.__class__): > + @util.propertycache > + def trackedevents(self): > + events = ui.config('blackbox', 'trackedevents', '*') > + return string.split(events, ',') I think you should be using ui.configlist() here. > + > + def log(self, command, msg): > + global lastblackbox > + super(blackboxui, self).log(command, msg) > + > + if not '*' in self.trackedevents and \ > + not command in self.trackedevents: > + return Don't use line continuations (the backslash); group the condition in parentheses. > + > + if '_blackbox' in self.__dict__: This seems like a weird way of checking this (it isn't the case here, but Python objects don't always have __dict__). I think you want util.safehasattr(). > + blackbox = self._blackbox > + else: > + # certain ui instances exist outside the context of > + # a repo, so just default to the last blackbox that > + # was seen. > + blackbox = lastblackbox > + > + if blackbox: > + date = util.datestr(None, '%Y/%m/%d %H:%M:%S') > + user = getpass.getuser() > + blackbox.write('%s %s> %s\n' % (date, user, msg)) > + lastblackbox = blackbox > + > + def setrepo(self, repo): > + self._blackbox = repo.opener('blackbox.log', 'a') > + > + ui.__class__ = blackboxui > + > +def uisetup(ui): > + wrapui(ui) > + > +def reposetup(ui, repo): > + if not repo.local(): > + return I don't follow this. Can you explain why you need to bail when the repo isn't local? > + > + ui.setrepo(repo) > _______________________________________________ > Mercurial-devel mailing list > Mercurial-devel at selenic.com > http://selenic.com/mailman/listinfo/mercurial-devel From mads at kiilerich.com Sun Feb 10 06:12:12 2013 From: mads at kiilerich.com (Mads Kiilerich) Date: Sun, 10 Feb 2013 13:12:12 +0100 Subject: [PATCH] export: show 'Date' header in a format that also is readable for humans In-Reply-To: References: <055060daf58dbe46c667.1360402284@localhost.localdomain> Message-ID: <51178E9C.2000104@kiilerich.com> On 02/10/2013 12:53 PM, Brodie Rao wrote: > On Sat, Feb 9, 2013 at 9:31 AM, Mads Kiilerich wrote: >> # HG changeset patch >> # User Mads Kiilerich >> # Date 1360360457 -3600 >> # Node ID 055060daf58dbe46c667053cbb04409b202ee9cd >> # Parent 97761496c65ae836d6b0983a3f48959dd3112364 >> export: show 'Date' header in a format that also is readable for humans >> >> 'export' is the official export format and used by patchbomb, but it would only >> show date as a timestamp that most humans might find it hard to relate to. It >> would be very convenient when reviewing a patch to be able to see what >> timestamp the patch will end up with. >> >> Mercurial has always used util.parsedate for parsing these headers. It can >> handle 'all' date formats, so we could just as well use a readable one. > Are there any third party utilities that parse these headers? I wonder > if this might cause other tools to break. Yes, that is a valid concern, but we don't expect that. Parsers should read it as Mercurial do, and Mercurial has always been able to handle all formats. So I will put it in 'default' and we can wait and see if it really becomes a problem. /Mads From brodie at sf.io Sun Feb 10 06:13:38 2013 From: brodie at sf.io (Brodie Rao) Date: Sun, 10 Feb 2013 12:13:38 +0000 Subject: [PATCH 5 of 6] blackbox: adds a 'blackbox' command for viewing recent logs In-Reply-To: <4192cc153d6f8d529723.1360494441@dev350.prn1.facebook.com> References: <30544b5277d09002d6ca.1360494437@dev350.prn1.facebook.com> <4192cc153d6f8d529723.1360494441@dev350.prn1.facebook.com> Message-ID: On Sun, Feb 10, 2013 at 11:07 AM, Durham Goode wrote: > # HG changeset patch > # User Durham Goode > # Date 1360429786 28800 > # Node ID 4192cc153d6f8d529723c9df20255693b73e723a > # Parent ee0ffe8ee86585a9842c841f7c389b037f118282 > blackbox: adds a 'blackbox' command for viewing recent logs > > Adds a 'hg blackbox' command for viewing the latest entries in the blackbox log. > By default it shows the last 10 entries, but -l allows the user to specify. > > diff --git a/hgext/blackbox.py b/hgext/blackbox.py > --- a/hgext/blackbox.py > +++ b/hgext/blackbox.py > @@ -66,3 +66,31 @@ > return > > ui.setrepo(repo) > + > + at command('^blackbox|bb', I don't think this command warrants a short alias like bb. Will it be run that often? > + [('l', 'limit', 10, _('the number of events to show')), > + ], > + _('hg blackbox [OPTION]...')) > +def blackbox(ui, repo, *revs, **opts): > + '''view the recent repository events > + ''' > + > + if not os.path.exists(repo.join('blackbox.log')): > + return > + > + limit = opts.get('limit') > + blackbox = repo.opener('blackbox.log', 'r') > + lines = blackbox.read().split('\n') > + > + count = 0 > + output = [] > + for line in reversed(lines): > + if count >= limit: > + break > + > + # count the commands by matching lines like: 2013/01/23 19:13:36 root> > + if re.match('^\d{4}/\d{2}/\d{2} \d{2}:\d{2}:\d{2} .*> .*', line): > + count = count + 1 This should be "count += 1". > + output.append(line) > + > + ui.status('\n'.join(reversed(output))) > _______________________________________________ > Mercurial-devel mailing list > Mercurial-devel at selenic.com > http://selenic.com/mailman/listinfo/mercurial-devel From danchr at gmail.com Sun Feb 10 06:17:16 2013 From: danchr at gmail.com (Dan Villiom Podlaski Christiansen) Date: Sun, 10 Feb 2013 12:17:16 +0000 Subject: [PATCH] hgweb: consistent author name width Message-ID: # HG changeset patch # User Dan Villiom Podlaski Christiansen # Date 1360498471 -3600 # Node ID e7546ba396cf2bf468fe7ade5a8dffbd0d34c544 # Parent 4df1d3ee8ad0c306cd33dab7ab4d0dd600690b94 hgweb: consistent author name width Paper & coal use a sligtly shorter name length of 12em in the log view than gitweb's 15em. Names too long for 12em is not entirely unheard of, and hence increasing the length is appropriate; hgweb should remain usable on 1024x768. diff --git a/mercurial/templates/static/style-coal.css b/mercurial/templates/static/style-coal.css --- a/mercurial/templates/static/style-coal.css +++ b/mercurial/templates/static/style-coal.css @@ -191,7 +191,7 @@ h3 { } .bigtable tr { border: none; } .bigtable .age { width: 6em; } -.bigtable .author { width: 12em; } +.bigtable .author { width: 15em; } .bigtable .description { } .bigtable .description .base { font-size: 70%; float: right; line-height: 1.66; } .bigtable .node { width: 5em; font-family: monospace;} diff --git a/mercurial/templates/static/style-paper.css b/mercurial/templates/static/style-paper.css --- a/mercurial/templates/static/style-paper.css +++ b/mercurial/templates/static/style-paper.css @@ -188,7 +188,7 @@ h3 { } .bigtable tr { border: none; } .bigtable .age { width: 7em; } -.bigtable .author { width: 12em; } +.bigtable .author { width: 15em; } .bigtable .description { } .bigtable .description .base { font-size: 70%; float: right; line-height: 1.66; } .bigtable .node { width: 5em; font-family: monospace;} From mads at kiilerich.com Sun Feb 10 06:18:44 2013 From: mads at kiilerich.com (Mads Kiilerich) Date: Sun, 10 Feb 2013 13:18:44 +0100 Subject: [PATCH] serve: introduce --get and --post for easy testing of hgweb In-Reply-To: References: <86f6b4786d8d292843a9.1360452156@localhost.localdomain> Message-ID: <51179024.6030600@kiilerich.com> On 02/10/2013 12:43 PM, Brodie Rao wrote: > (Resending, forgot to CC the list.) > > On Sat, Feb 9, 2013 at 11:22 PM, Mads Kiilerich wrote: >> # HG changeset patch >> # User Mads Kiilerich >> # Date 1359297965 -3600 >> # Node ID 86f6b4786d8d292843a9509b0c99f8e855ef4e9d >> # Parent 19f90544863eadb00baf80ef21811d41b2beb54b >> serve: introduce --get and --post for easy testing of hgweb >> >> These options can be useful both in the test suite and for other kinds of hgweb >> testing. >> >> diff --git a/mercurial/commands.py b/mercurial/commands.py >> --- a/mercurial/commands.py >> +++ b/mercurial/commands.py >> @@ -8,7 +8,7 @@ >> from node import hex, bin, nullid, nullrev, short >> from lock import release >> from i18n import _, gettext >> -import os, re, difflib, time, tempfile, errno >> +import os, re, difflib, time, tempfile, errno, sys >> import hg, scmutil, util, revlog, extensions, copies, error, bookmarks >> import patch, help, encoding, templatekw, discovery >> import archival, changegroup, cmdutil, hbisect >> @@ -5251,7 +5251,9 @@ >> ('t', 'templates', '', _('web templates to use'), _('TEMPLATE')), >> ('', 'style', '', _('template style to use'), _('STYLE')), >> ('6', 'ipv6', None, _('use IPv6 in addition to IPv4')), >> - ('', 'certificate', '', _('SSL certificate file'), _('FILE'))], >> + ('', 'certificate', '', _('SSL certificate file'), _('FILE')), >> + ('', 'get', '', _('just GET url'), _('URL')), >> + ('', 'post', '', _('just POST url'), _('URL'))], > Do these options need to be exposed by default? I feel like they might > be better as debug options. Perhaps? But it is not that it is exposing Mercurial internals as most other debug commands do. Showing them directly in the help makes them more directly available for people with problems with their hgweb configuration and with systematic debugging. Other opinions? /Mads From angel.ezquerra at gmail.com Sun Feb 10 06:21:24 2013 From: angel.ezquerra at gmail.com (Angel Ezquerra) Date: Sun, 10 Feb 2013 13:21:24 +0100 Subject: [PATCH 0 of 3 V3] [PATCH 0 of 3 ] interhg: bring (most of the) extension functionality into core and remove the interhg extension Message-ID: From angel.ezquerra at gmail.com Sun Feb 10 06:21:26 2013 From: angel.ezquerra at gmail.com (Angel Ezquerra) Date: Sun, 10 Feb 2013 13:21:26 +0100 Subject: [PATCH 2 of 3 V3] hgweb: apply the websub filter to revision descriptions In-Reply-To: References: Message-ID: # HG changeset patch # User Angel Ezquerra # Date 1360424901 -3600 # Node ID f9bee14db21432fa90dd2c10cd6880286946d917 # Parent 272d2887163db074c89818ea0dfdffbe39eb7747 hgweb: apply the websub filter to revision descriptions In order to use this, add a [websub] section to your configuration and add websub expressions such as: italic = s/\b_(\S+)_\b/\1<\/i>/ bold = s/\*\b(\S+)\b\*/\1<\/b>/ issues = s|issue(\d+)|issue\1|i bugzilla = s!((?:bug|b=|(?=#?\d{4,}))(?:\s*#?)(\d+))!\1!i This also adds documentation (proofed by Kevin!) to the config help section. diff --git a/mercurial/help/config.txt b/mercurial/help/config.txt --- a/mercurial/help/config.txt +++ b/mercurial/help/config.txt @@ -1463,3 +1463,36 @@ ``templates`` Where to find the HTML templates. Default is install path. + +``websub`` +---------- + +Web substitution filter definition. You can use this section to +define a set of regular expression substitution patterns which +let you automatically modify the hgweb server output. + +The default hgweb templates only apply these substitution patterns +on the revision description fields. You can apply them anywhere +you want when you create your own templates by adding calls to the +"websub" filter (usually after calling the "escape" filter). + +This can be used, for example, to convert issue references to links +to your issue tracker, or to convert "markdown-like" syntax into +HTML (see the examples below). + +Each entry in this section names a substitution filter. +The value of each entry defines the substitution expression itself. +The websub expressions follow the old interhg extension syntax, +which in turn imitates the Unix sed replacement syntax:: + + pattername = s/SEARCH_REGEX/REPLACE_EXPRESSION/[i] + +You can use any separator other than "/". The final "i" is optional +and indicates that the search must be case insensitive. + +Examples:: + + [websub] + issues = s|issue(\d+)|issue\1|i + italic = s/\b_(\S+)_\b/\1<\/i>/ + bold = s/\*\b(\S+)\b\*/\1<\/b>/ diff --git a/mercurial/templates/gitweb/changelogentry.tmpl b/mercurial/templates/gitweb/changelogentry.tmpl --- a/mercurial/templates/gitweb/changelogentry.tmpl +++ b/mercurial/templates/gitweb/changelogentry.tmpl @@ -8,7 +8,7 @@ {author|obfuscate} [{date|rfc822date}] rev {rev}
    -{desc|strip|escape|addbreaks|nonempty} +{desc|strip|escape|websub|addbreaks|nonempty}

    diff --git a/mercurial/templates/gitweb/changeset.tmpl b/mercurial/templates/gitweb/changeset.tmpl --- a/mercurial/templates/gitweb/changeset.tmpl +++ b/mercurial/templates/gitweb/changeset.tmpl @@ -41,7 +41,7 @@
    -{desc|strip|escape|addbreaks|nonempty} +{desc|strip|escape|websub|addbreaks|nonempty}
    diff --git a/mercurial/templates/gitweb/fileannotate.tmpl b/mercurial/templates/gitweb/fileannotate.tmpl --- a/mercurial/templates/gitweb/fileannotate.tmpl +++ b/mercurial/templates/gitweb/fileannotate.tmpl @@ -56,7 +56,7 @@
    -{desc|strip|escape|addbreaks|nonempty} +{desc|strip|escape|websub|addbreaks|nonempty}
    diff --git a/mercurial/templates/gitweb/filerevision.tmpl b/mercurial/templates/gitweb/filerevision.tmpl --- a/mercurial/templates/gitweb/filerevision.tmpl +++ b/mercurial/templates/gitweb/filerevision.tmpl @@ -56,7 +56,7 @@
    -{desc|strip|escape|addbreaks|nonempty} +{desc|strip|escape|websub|addbreaks|nonempty}
    diff --git a/mercurial/templates/monoblue/changelogentry.tmpl b/mercurial/templates/monoblue/changelogentry.tmpl --- a/mercurial/templates/monoblue/changelogentry.tmpl +++ b/mercurial/templates/monoblue/changelogentry.tmpl @@ -2,5 +2,5 @@
    • {date|rfc822date}
    • by {author|obfuscate} [{date|rfc822date}] rev {rev}
    • -
    • {desc|strip|escape|addbreaks|nonempty}
    • +
    • {desc|strip|escape|websub|addbreaks|nonempty}
    diff --git a/mercurial/templates/monoblue/changeset.tmpl b/mercurial/templates/monoblue/changeset.tmpl --- a/mercurial/templates/monoblue/changeset.tmpl +++ b/mercurial/templates/monoblue/changeset.tmpl @@ -52,7 +52,7 @@ {child%changesetchild} -

    {desc|strip|escape|addbreaks|nonempty}

    +

    {desc|strip|escape|websub|addbreaks|nonempty}

    {files} diff --git a/mercurial/templates/monoblue/fileannotate.tmpl b/mercurial/templates/monoblue/fileannotate.tmpl --- a/mercurial/templates/monoblue/fileannotate.tmpl +++ b/mercurial/templates/monoblue/fileannotate.tmpl @@ -57,7 +57,7 @@
    {permissions|permissions}
    -

    {desc|strip|escape|addbreaks|nonempty}

    +

    {desc|strip|escape|websub|addbreaks|nonempty}

    {annotate%annotateline} diff --git a/mercurial/templates/monoblue/filerevision.tmpl b/mercurial/templates/monoblue/filerevision.tmpl --- a/mercurial/templates/monoblue/filerevision.tmpl +++ b/mercurial/templates/monoblue/filerevision.tmpl @@ -57,7 +57,7 @@
    {permissions|permissions}
    -

    {desc|strip|escape|addbreaks|nonempty}

    +

    {desc|strip|escape|websub|addbreaks|nonempty}

    {text%fileline} diff --git a/mercurial/templates/paper/changeset.tmpl b/mercurial/templates/paper/changeset.tmpl --- a/mercurial/templates/paper/changeset.tmpl +++ b/mercurial/templates/paper/changeset.tmpl @@ -40,7 +40,7 @@ files, or words in the commit message
    -
    {desc|strip|escape|nonempty}
    +
    {desc|strip|escape|websub|nonempty}
    diff --git a/mercurial/templates/paper/fileannotate.tmpl b/mercurial/templates/paper/fileannotate.tmpl --- a/mercurial/templates/paper/fileannotate.tmpl +++ b/mercurial/templates/paper/fileannotate.tmpl @@ -46,7 +46,7 @@ files, or words in the commit message -
    {desc|strip|escape|nonempty}
    +
    {desc|strip|escape|websub|nonempty}
    diff --git a/mercurial/templates/paper/filecomparison.tmpl b/mercurial/templates/paper/filecomparison.tmpl --- a/mercurial/templates/paper/filecomparison.tmpl +++ b/mercurial/templates/paper/filecomparison.tmpl @@ -45,7 +45,7 @@ files, or words in the commit message -
    {desc|strip|escape|nonempty}
    +
    {desc|strip|escape|websub|nonempty}
    diff --git a/mercurial/templates/paper/filediff.tmpl b/mercurial/templates/paper/filediff.tmpl --- a/mercurial/templates/paper/filediff.tmpl +++ b/mercurial/templates/paper/filediff.tmpl @@ -45,7 +45,7 @@ files, or words in the commit message -
    {desc|strip|escape|nonempty}
    +
    {desc|strip|escape|websub|nonempty}
    diff --git a/mercurial/templates/paper/filerevision.tmpl b/mercurial/templates/paper/filerevision.tmpl --- a/mercurial/templates/paper/filerevision.tmpl +++ b/mercurial/templates/paper/filerevision.tmpl @@ -44,7 +44,7 @@ files, or words in the commit message -
    {desc|strip|escape|nonempty}
    +
    {desc|strip|escape|websub|nonempty}
    diff --git a/mercurial/templates/spartan/changeset.tmpl b/mercurial/templates/spartan/changeset.tmpl --- a/mercurial/templates/spartan/changeset.tmpl +++ b/mercurial/templates/spartan/changeset.tmpl @@ -39,7 +39,7 @@ - +
    description:{desc|strip|escape|addbreaks|nonempty}{desc|strip|escape|websub|addbreaks|nonempty}
    diff --git a/mercurial/templates/spartan/fileannotate.tmpl b/mercurial/templates/spartan/fileannotate.tmpl --- a/mercurial/templates/spartan/fileannotate.tmpl +++ b/mercurial/templates/spartan/fileannotate.tmpl @@ -38,7 +38,7 @@ description: - {desc|strip|escape|addbreaks|nonempty} + {desc|strip|escape|websub|addbreaks|nonempty} diff --git a/mercurial/templates/spartan/filerevision.tmpl b/mercurial/templates/spartan/filerevision.tmpl --- a/mercurial/templates/spartan/filerevision.tmpl +++ b/mercurial/templates/spartan/filerevision.tmpl @@ -36,7 +36,7 @@ {permissions|permissions} description: - {desc|strip|escape|addbreaks|nonempty} + {desc|strip|escape|websub|addbreaks|nonempty} From angel.ezquerra at gmail.com Sun Feb 10 06:21:25 2013 From: angel.ezquerra at gmail.com (Angel Ezquerra) Date: Sun, 10 Feb 2013 13:21:25 +0100 Subject: [PATCH 1 of 3 V3] hgweb: add websub template filter In-Reply-To: References: Message-ID: <272d2887163db074c898.1360498885@Angel-PC.localdomain> # HG changeset patch # User Angel Ezquerra # Date 1360343132 -3600 # Node ID 272d2887163db074c89818ea0dfdffbe39eb7747 # Parent 08772c198c3ad5e12b83141b7d92e9557f6675ca hgweb: add websub template filter The purpose of this new filter is to make it possible to partially replace the functionality of the interhg extension. The idea is to be able to define regular expression based substitutions on a new "websub" config section. hgweb will then be able to apply these substitutions wherever the "websub" filter is used on a template. This first revision just adds the code necessary to load the websub expressions and adds the websub filter, but it does not add any calls to the websub filter itself on any of the templates. That will be done on the following revisions. diff --git a/mercurial/hgweb/hgweb_mod.py b/mercurial/hgweb/hgweb_mod.py --- a/mercurial/hgweb/hgweb_mod.py +++ b/mercurial/hgweb/hgweb_mod.py @@ -8,11 +8,13 @@ import os from mercurial import ui, hg, hook, error, encoding, templater, util, repoview +from mercurial.templatefilters import websub +from mercurial.i18n import _ from common import get_stat, ErrorResponse, permhooks, caching from common import HTTP_OK, HTTP_NOT_MODIFIED, HTTP_BAD_REQUEST from common import HTTP_NOT_FOUND, HTTP_SERVER_ERROR from request import wsgirequest -import webcommands, protocol, webutil +import webcommands, protocol, webutil, re perms = { 'changegroup': 'pull', @@ -73,6 +75,7 @@ # a repo owner may set web.templates in .hg/hgrc to get any file # readable by the user running the CGI script self.templatepath = self.config('web', 'templates') + self.websubtable = self.loadwebsub() # The CGI scripts are often run by a user different from the repo owner. # Trust the settings from the .hg/hgrc files by default. @@ -258,6 +261,45 @@ return [''] return tmpl('error', error=inst.message) + def loadwebsub(self): + websubtable = [] + websubdefs = self.repo.ui.configitems('websub') + for key, pattern in websubdefs: + # grab the delimiter from the character after the "s" + unesc = pattern[1] + delim = re.escape(unesc) + + # identify portions of the pattern, taking care to avoid escaped + # delimiters. the replace format and flags are optional, but + # delimiters are required. + match = re.match( + r'^s%s(.+)(?:(?<=\\\\)|(? References: Message-ID: <8c8f60f3245521457928.1360498887@Angel-PC.localdomain> # HG changeset patch # User Angel Ezquerra # Date 1360404042 -3600 # Node ID 8c8f60f32455214579282ba2d67e36b704227455 # Parent f9bee14db21432fa90dd2c10cd6880286946d917 extensions: obsolete and remove interhg extension With the addition of the websub filter extension this extension is no longer needed. We maintain a sort of backwards compatibility by reading the [interhg] section and using it as we would use the [websub] section. diff --git a/mercurial/extensions.py b/mercurial/extensions.py --- a/mercurial/extensions.py +++ b/mercurial/extensions.py @@ -11,7 +11,7 @@ _extensions = {} _order = [] -_ignore = ['hbisect', 'bookmarks', 'parentrevspec'] +_ignore = ['hbisect', 'bookmarks', 'parentrevspec', 'interhg'] def extensions(): for name in _order: diff --git a/mercurial/hgweb/hgweb_mod.py b/mercurial/hgweb/hgweb_mod.py --- a/mercurial/hgweb/hgweb_mod.py +++ b/mercurial/hgweb/hgweb_mod.py @@ -264,6 +264,8 @@ def loadwebsub(self): websubtable = [] websubdefs = self.repo.ui.configitems('websub') + # we must maintain interhg backwards compatibility + websubdefs += self.repo.ui.configitems('interhg') for key, pattern in websubdefs: # grab the delimiter from the character after the "s" unesc = pattern[1] diff --git a/tests/test-interhg.t b/tests/test-websub.t rename from tests/test-interhg.t rename to tests/test-websub.t --- a/tests/test-interhg.t +++ b/tests/test-websub.t @@ -5,11 +5,15 @@ $ cat > .hg/hgrc < [extensions] + > # this is only necessary to check that the mapping from + > # interhg to websub works > interhg = > - > [interhg] + > [websub] > issues = s|Issue(\d+)|Issue\1| > + > [interhg] + > # check that we maintain some interhg backwards compatibility... > # yes, 'x' is a weird delimiter... > markbugs = sxbugxbugx > EOF @@ -23,9 +27,8 @@ log - $ "$TESTDIR/get-with-headers.py" localhost:$HGPORT '' | grep bts - Issue123: fixed the bug!default tip - + $ "$TESTDIR/get-with-headers.py" localhost:$HGPORT "rev/tip" | grep bts +
    Issue123: fixed the bug!
    errors $ cat errors.log From mercurial-bugs at selenic.com Sun Feb 10 01:23:09 2013 From: mercurial-bugs at selenic.com (mercurial-bugs at selenic.com) Date: Sun, 10 Feb 2013 07:23:09 +0000 Subject: [Bug 3816] New: httplib do not have FakeSocket when Python doesn't have ssl Message-ID: http://bz.selenic.com/show_bug.cgi?id=3816 Priority: normal Bug ID: 3816 CC: mercurial-devel at selenic.com Assignee: bugzilla at selenic.com Summary: httplib do not have FakeSocket when Python doesn't have ssl Severity: bug Classification: Unclassified OS: Linux Reporter: mads at kiilerich.com Hardware: PC Status: UNCONFIRMED Version: unspecified Component: Mercurial Product: Mercurial make -C doc make[1]: Entering directory `/home/mk/hg/doc' /tmp/xxx/bin/python gendoc.py > hg.1.gendoc.txt.tmp Traceback (most recent call last): File "gendoc.py", line 8, in from mercurial.commands import table, globalopts File "../mercurial/commands.py", line 12, in import hg, scmutil, util, revlog, extensions, copies, error, bookmarks File "../mercurial/hg.py", line 12, in import localrepo, bundlerepo, unionrepo, httppeer, sshpeer, statichttprepo File "../mercurial/httppeer.py", line 11, in import changegroup, statichttprepo, error, httpconnection, url, util, wireproto File "../mercurial/statichttprepo.py", line 11, in import changelog, byterange, url, error File "../mercurial/url.py", line 13, in import httpconnection as httpconnectionmod File "../mercurial/httpconnection.py", line 16, in from mercurial import httpclient File "../mercurial/httpclient/__init__.py", line 49, in import socketutil File "../mercurial/httpclient/socketutil.py", line 82, in class FakeSocket(httplib.FakeSocket): AttributeError: 'module' object has no attribute 'FakeSocket' make[1]: *** [hg.1.gendoc.txt] Error 1 -- You are receiving this mail because: You are on the CC list for the bug. From brodie at sf.io Sun Feb 10 06:24:40 2013 From: brodie at sf.io (Brodie Rao) Date: Sun, 10 Feb 2013 12:24:40 +0000 Subject: [PATCH 6 of 6] blackbox: tests for the blackbox extension In-Reply-To: <932a1aea1b315a2b1c6e.1360494442@dev350.prn1.facebook.com> References: <30544b5277d09002d6ca.1360494437@dev350.prn1.facebook.com> <932a1aea1b315a2b1c6e.1360494442@dev350.prn1.facebook.com> Message-ID: On Sun, Feb 10, 2013 at 11:07 AM, Durham Goode wrote: > # HG changeset patch > # User Durham Goode > # Date 1360445730 28800 > # Node ID 932a1aea1b315a2b1c6e7dadfea803afd59b704e > # Parent 4192cc153d6f8d529723c9df20255693b73e723a > blackbox: tests for the blackbox extension > > A few tests to cover the blackbox extension. Covers commands, hooks, and > incoming changes. > > diff --git a/tests/test-blackbox.t b/tests/test-blackbox.t > new file mode 100644 > --- /dev/null > +++ b/tests/test-blackbox.t > @@ -0,0 +1,54 @@ > +setup > + > + $ cat >> $HGRCPATH < + > [extensions] > + > blackbox= > + > EOF > + $ hg init blackboxtest > + $ cd blackboxtest > + > +command, exit codes, and duration > + > + $ echo a > a > + $ hg add a > + $ hg blackbox > + *> add a (glob) > + *> add exited 0 after * seconds (glob) I think it's a little confusing that the date is completely globbed out here. Can you make the date stable and add it to the test? > + > +extension and python hooks - use the eol extension for a pythonhook > + > + $ echo '[extensions]' >> .hg/hgrc > + $ echo 'eol=' >> .hg/hgrc > + $ echo '[hooks]' >> .hg/hgrc > + $ echo 'update = echo hooked' >> .hg/hgrc > + $ hg update > + hooked > + 0 files updated, 0 files merged, 0 files removed, 0 files unresolved > + $ hg blackbox -l 4 > + *> update (glob) > + *> pythonhook-preupdate: hgext.eol.preupdate finished in * seconds (glob) > + *> exthook-update: echo hooked finished in * seconds (glob) > + *> update exited False after * seconds (glob) > + > +incoming change tracking > + > + $ hg clone . ../blackboxtest2 > + updating to branch default > + 0 files updated, 0 files merged, 0 files removed, 0 files unresolved > + $ hg commit -ma > + $ cd ../blackboxtest2 > + $ hg pull > + pulling from $TESTTMP/blackboxtest > + requesting all changes > + adding changesets > + adding manifests > + adding file changes > + added 1 changesets with 1 changes to 1 files > + (run 'hg update' to get a working copy) > + $ hg bb -l 3 > + *> pull (glob) > + *> 1 incoming changes - new heads: cb9a9f314b8b (glob) > + *> pull exited None after * seconds (glob) > + > +cleanup > + $ cd .. > _______________________________________________ > Mercurial-devel mailing list > Mercurial-devel at selenic.com > http://selenic.com/mailman/listinfo/mercurial-devel From cryo at cyanite.org Sun Feb 10 08:19:36 2013 From: cryo at cyanite.org (Sune Foldager) Date: Sun, 10 Feb 2013 15:19:36 +0100 Subject: [PATCH] serve: introduce --get and --post for easy testing of hgweb In-Reply-To: <51179024.6030600@kiilerich.com> References: <86f6b4786d8d292843a9.1360452156@localhost.localdomain> <51179024.6030600@kiilerich.com> Message-ID: <20130210141935.GA30274@cyanite.org> On 2013-02-10 13:18, Mads Kiilerich wrote: >On 02/10/2013 12:43 PM, Brodie Rao wrote: >>(Resending, forgot to CC the list.) >> >>On Sat, Feb 9, 2013 at 11:22 PM, Mads Kiilerich wrote: >>># HG changeset patch >>># User Mads Kiilerich >>># Date 1359297965 -3600 >>># Node ID 86f6b4786d8d292843a9509b0c99f8e855ef4e9d >>># Parent 19f90544863eadb00baf80ef21811d41b2beb54b >>>serve: introduce --get and --post for easy testing of hgweb >>> >>>These options can be useful both in the test suite and for other kinds of hgweb >>>testing. >>> >>>diff --git a/mercurial/commands.py b/mercurial/commands.py >>>--- a/mercurial/commands.py >>>+++ b/mercurial/commands.py >>>@@ -8,7 +8,7 @@ >>> from node import hex, bin, nullid, nullrev, short >>> from lock import release >>> from i18n import _, gettext >>>-import os, re, difflib, time, tempfile, errno >>>+import os, re, difflib, time, tempfile, errno, sys >>> import hg, scmutil, util, revlog, extensions, copies, error, bookmarks >>> import patch, help, encoding, templatekw, discovery >>> import archival, changegroup, cmdutil, hbisect >>>@@ -5251,7 +5251,9 @@ >>> ('t', 'templates', '', _('web templates to use'), _('TEMPLATE')), >>> ('', 'style', '', _('template style to use'), _('STYLE')), >>> ('6', 'ipv6', None, _('use IPv6 in addition to IPv4')), >>>- ('', 'certificate', '', _('SSL certificate file'), _('FILE'))], >>>+ ('', 'certificate', '', _('SSL certificate file'), _('FILE')), >>>+ ('', 'get', '', _('just GET url'), _('URL')), >>>+ ('', 'post', '', _('just POST url'), _('URL'))], >>Do these options need to be exposed by default? I feel like they might >>be better as debug options. > >Perhaps? But it is not that it is exposing Mercurial internals as >most other debug commands do. But "just GET url" is a bit weird, I agree with Brodie. I mean, what does that even mean? /Sune From martin at geisler.net Sun Feb 10 08:26:22 2013 From: martin at geisler.net (Martin Geisler) Date: Sun, 10 Feb 2013 15:26:22 +0100 Subject: [PATCH 2 of 6] blackbox: log the commands that are run In-Reply-To: <54a25c702a6fface978f.1360494438@dev350.prn1.facebook.com> (sfid-20130210_122011_709964_AA03D0FA) (Durham Goode's message of "Sun, 10 Feb 2013 03:07:18 -0800") References: <30544b5277d09002d6ca.1360494437@dev350.prn1.facebook.com> <54a25c702a6fface978f.1360494438@dev350.prn1.facebook.com> Message-ID: <87txpkqm7l.fsf@go.home> Durham Goode writes: > # HG changeset patch > # User Durham Goode > # Date 1360429454 28800 > # Node ID 54a25c702a6fface978fd1eeb0e6c7140bc9ab8b > # Parent 30544b5277d09002d6cac8c363652f71bb807516 > blackbox: log the commands that are run > > Uses ui.log to log which commands are run, their exit code, the time taken, > and any unhandled exceptions thrown. > > Example log lines: > 2013/02/09 08:35:19 durham> add foo > 2013/02/09 08:35:19 durham> add exited 0 after 0.02 seconds > > Updates the progress tests because they use a mocked time.time() which these > changes affect. > > diff --git a/mercurial/dispatch.py b/mercurial/dispatch.py > --- a/mercurial/dispatch.py > +++ b/mercurial/dispatch.py > @@ -247,6 +247,7 @@ > (_("** Mercurial Distributed SCM (version %s)\n") % myver) + > (_("** Extensions loaded: %s\n") % > ", ".join([x[0] for x in extensions.extensions()]))) > + ui.log("commandexception", "%s\n%s" % (warning, traceback.format_exc())) The idea is nice and I think we should have such an extension. The standard logging library works by taking the format string and the arguments separately: that way you can check if the message will be logged first and then only spend time formatting it if so. It would be cool if we could change the signature of ui.log to that standard too. -- Martin Geisler From durham at fb.com Sun Feb 10 08:29:35 2013 From: durham at fb.com (Durham Goode) Date: Sun, 10 Feb 2013 06:29:35 -0800 Subject: [PATCH 0 of 3] V2 of dirstate.walk patches Message-ID: Update the dirstate.walk patches based on feedback. Patch 1 - renamed isvalidpath() to check() Patch 2 - Adjusted the commit description to not use 'symlink directory' terminology. From durham at fb.com Sun Feb 10 08:29:36 2013 From: durham at fb.com (Durham Goode) Date: Sun, 10 Feb 2013 06:29:36 -0800 Subject: [PATCH 1 of 3] pathauditor: add check() method In-Reply-To: References: Message-ID: <814455d55e1f3505442e.1360506576@dev350.prn1.facebook.com> # HG changeset patch # User Durham Goode # Date 1360103054 28800 # Node ID 814455d55e1f3505442ef96a96f7188f42698d3f # Parent 57b7531a5705a099637f6d6bedd4de509fb2a441 pathauditor: add check() method The pathauditor currently throws exceptions when it encounters an invalid path. This change adds a method to allow people to treat it as a boolean. This is currently used by scmutil.addremove and in a subsequent patch it will be used by dirstate.walk diff --git a/mercurial/scmutil.py b/mercurial/scmutil.py --- a/mercurial/scmutil.py +++ b/mercurial/scmutil.py @@ -184,6 +184,13 @@ # want to add "foo/bar/baz" before checking if there's a "foo/.hg" self.auditeddir.update(prefixes) + def check(self, path): + try: + self(path) + return True + except (OSError, util.Abort): + return False + class abstractvfs(object): """Abstract base class; cannot be instantiated""" @@ -745,11 +752,7 @@ ctx = repo[None] walkresults = repo.dirstate.walk(m, sorted(ctx.substate), True, False) for abs in sorted(walkresults): - good = True - try: - audit_path(abs) - except (OSError, util.Abort): - good = False + good = audit_path.check(abs) st = walkresults[abs] dstate = repo.dirstate[abs] From durham at fb.com Sun Feb 10 08:29:37 2013 From: durham at fb.com (Durham Goode) Date: Sun, 10 Feb 2013 06:29:37 -0800 Subject: [PATCH 2 of 3] dirstate: walk returns None for files that have a symlink in their path In-Reply-To: References: Message-ID: <574375cb530f2ec3c9ab.1360506577@dev350.prn1.facebook.com> # HG changeset patch # User Durham Goode # Date 1360016835 28800 # Node ID 574375cb530f2ec3c9abfec42327460fac4eacf2 # Parent 814455d55e1f3505442ef96a96f7188f42698d3f dirstate: walk returns None for files that have a symlink in their path Previously dirstate.walk would return a stat object for files in the dmap that have a symlink to a directory in their path. Now it will return None to indicate that they are no longer considered part of the repository. This currently only affects walks that traverse the entire directory tree (ex: hg status) and not walks that only list the contents of the dmap (ex: hg diff). In a situation like this: mkdir foo && touch foo/a && hg commit -Am "a" mv foo bar ln -s bar foo 'hg status' will now show '! foo/a', whereas before it incorrectly considered 'foo/a' to be unchanged. In addition to making 'hg status' report the correct information, this will allow callers to dirstate.walk to not have to detect symlinks themselves, which can be very expensive. diff --git a/mercurial/dirstate.py b/mercurial/dirstate.py --- a/mercurial/dirstate.py +++ b/mercurial/dirstate.py @@ -677,9 +677,26 @@ # step 3: report unseen items in the dmap hash if not skipstep3 and not exact: visit = sorted([f for f in dmap if f not in results and matchfn(f)]) - nf = iter(visit).next - for st in util.statfiles([join(i) for i in visit]): - results[nf()] = st + if unknown: + # unknown == True means we walked the full directory tree above. + # So if a file is not seen it was either a) not matching matchfn + # b) ignored, c) missing, or d) under a symlink directory. + audit_path = scmutil.pathauditor(self._root) + + for nf in iter(visit): + # Report ignored items in the dmap as long as they are not + # under a symlink directory. + if ignore(nf) and audit_path.isvalidpath(nf): + results[nf] = util.statfiles([join(nf)])[0] + else: + # It's either missing or under a symlink directory + results[nf] = None + else: + # We may not have walked the full directory tree above, + # so stat everything we missed. + nf = iter(visit).next + for st in util.statfiles([join(i) for i in visit]): + results[nf()] = st for s in subrepos: del results[s] del results['.hg'] diff --git a/tests/test-symlinks.t b/tests/test-symlinks.t --- a/tests/test-symlinks.t +++ b/tests/test-symlinks.t @@ -149,6 +149,10 @@ adding foo/a $ mv foo bar $ ln -s bar foo + $ hg status + ! foo/a + ? bar/a + ? foo now addremove should remove old files From durham at fb.com Sun Feb 10 08:29:38 2013 From: durham at fb.com (Durham Goode) Date: Sun, 10 Feb 2013 06:29:38 -0800 Subject: [PATCH 3 of 3] addremove: don't audit the path for paths already in the dirstate In-Reply-To: References: Message-ID: <9e92bbb4ec6be418981d.1360506578@dev350.prn1.facebook.com> # HG changeset patch # User Durham Goode # Date 1360103779 28800 # Node ID 9e92bbb4ec6be418981d7854ab75e42789cd29c4 # Parent 574375cb530f2ec3c9abfec42327460fac4eacf2 addremove: don't audit the path for paths already in the dirstate Now that dirstate.walk returns None for paths under symlink directories, addremove doesn't need to validate each path it sees to look for files under symlinks. On a large repository this brings addremove from 6.3 seconds down to 3.65 (42%) since addremove no longer has to stat every directory of every file to determine if the file is inside a symlink directory. I put it through our benchmark and see no perf hit to any other commands. diff --git a/mercurial/dirstate.py b/mercurial/dirstate.py --- a/mercurial/dirstate.py +++ b/mercurial/dirstate.py @@ -686,7 +686,7 @@ for nf in iter(visit): # Report ignored items in the dmap as long as they are not # under a symlink directory. - if ignore(nf) and audit_path.isvalidpath(nf): + if ignore(nf) and audit_path.check(nf): results[nf] = util.statfiles([join(nf)])[0] else: # It's either missing or under a symlink directory diff --git a/mercurial/scmutil.py b/mercurial/scmutil.py --- a/mercurial/scmutil.py +++ b/mercurial/scmutil.py @@ -752,17 +752,14 @@ ctx = repo[None] walkresults = repo.dirstate.walk(m, sorted(ctx.substate), True, False) for abs in sorted(walkresults): - good = audit_path.check(abs) - st = walkresults[abs] dstate = repo.dirstate[abs] - if good and dstate == '?': + if dstate == '?' and audit_path.check(abs): unknown.append(abs) if repo.ui.verbose or not m.exact(abs): rel = m.rel(abs) repo.ui.status(_('adding %s\n') % ((pats and rel) or abs)) - elif (dstate != 'r' and - (not good or not st or + elif (dstate != 'r' and (not st or (stat.S_ISDIR(st.st_mode) and not stat.S_ISLNK(st.st_mode)))): deleted.append(abs) if repo.ui.verbose or not m.exact(abs): From durham at fb.com Sun Feb 10 08:42:30 2013 From: durham at fb.com (Durham Goode) Date: Sun, 10 Feb 2013 06:42:30 -0800 Subject: [PATCH 0 of 3] V3 of dirstate.walk patches Message-ID: V2 had a chunk in the wrong patch :( From durham at fb.com Sun Feb 10 08:42:31 2013 From: durham at fb.com (Durham Goode) Date: Sun, 10 Feb 2013 06:42:31 -0800 Subject: [PATCH 1 of 3] pathauditor: add check() method In-Reply-To: References: Message-ID: <814455d55e1f3505442e.1360507351@dev350.prn1.facebook.com> # HG changeset patch # User Durham Goode # Date 1360103054 28800 # Node ID 814455d55e1f3505442ef96a96f7188f42698d3f # Parent 57b7531a5705a099637f6d6bedd4de509fb2a441 pathauditor: add check() method The pathauditor currently throws exceptions when it encounters an invalid path. This change adds a method to allow people to treat it as a boolean. This is currently used by scmutil.addremove and in a subsequent patch it will be used by dirstate.walk diff --git a/mercurial/scmutil.py b/mercurial/scmutil.py --- a/mercurial/scmutil.py +++ b/mercurial/scmutil.py @@ -184,6 +184,13 @@ # want to add "foo/bar/baz" before checking if there's a "foo/.hg" self.auditeddir.update(prefixes) + def check(self, path): + try: + self(path) + return True + except (OSError, util.Abort): + return False + class abstractvfs(object): """Abstract base class; cannot be instantiated""" @@ -745,11 +752,7 @@ ctx = repo[None] walkresults = repo.dirstate.walk(m, sorted(ctx.substate), True, False) for abs in sorted(walkresults): - good = True - try: - audit_path(abs) - except (OSError, util.Abort): - good = False + good = audit_path.check(abs) st = walkresults[abs] dstate = repo.dirstate[abs] From durham at fb.com Sun Feb 10 08:42:32 2013 From: durham at fb.com (Durham Goode) Date: Sun, 10 Feb 2013 06:42:32 -0800 Subject: [PATCH 2 of 3] dirstate: walk returns None for files that have a symlink in their path In-Reply-To: References: Message-ID: <6342bd478cbe84999aab.1360507352@dev350.prn1.facebook.com> # HG changeset patch # User Durham Goode # Date 1360016835 28800 # Node ID 6342bd478cbe84999aab99fc05c24717de73b5e5 # Parent 814455d55e1f3505442ef96a96f7188f42698d3f dirstate: walk returns None for files that have a symlink in their path Previously dirstate.walk would return a stat object for files in the dmap that have a symlink to a directory in their path. Now it will return None to indicate that they are no longer considered part of the repository. This currently only affects walks that traverse the entire directory tree (ex: hg status) and not walks that only list the contents of the dmap (ex: hg diff). In a situation like this: mkdir foo && touch foo/a && hg commit -Am "a" mv foo bar ln -s bar foo 'hg status' will now show '! foo/a', whereas before it incorrectly considered 'foo/a' to be unchanged. In addition to making 'hg status' report the correct information, this will allow callers to dirstate.walk to not have to detect symlinks themselves, which can be very expensive. diff --git a/mercurial/dirstate.py b/mercurial/dirstate.py --- a/mercurial/dirstate.py +++ b/mercurial/dirstate.py @@ -677,9 +677,26 @@ # step 3: report unseen items in the dmap hash if not skipstep3 and not exact: visit = sorted([f for f in dmap if f not in results and matchfn(f)]) - nf = iter(visit).next - for st in util.statfiles([join(i) for i in visit]): - results[nf()] = st + if unknown: + # unknown == True means we walked the full directory tree above. + # So if a file is not seen it was either a) not matching matchfn + # b) ignored, c) missing, or d) under a symlink directory. + audit_path = scmutil.pathauditor(self._root) + + for nf in iter(visit): + # Report ignored items in the dmap as long as they are not + # under a symlink directory. + if ignore(nf) and audit_path.check(nf): + results[nf] = util.statfiles([join(nf)])[0] + else: + # It's either missing or under a symlink directory + results[nf] = None + else: + # We may not have walked the full directory tree above, + # so stat everything we missed. + nf = iter(visit).next + for st in util.statfiles([join(i) for i in visit]): + results[nf()] = st for s in subrepos: del results[s] del results['.hg'] diff --git a/tests/test-symlinks.t b/tests/test-symlinks.t --- a/tests/test-symlinks.t +++ b/tests/test-symlinks.t @@ -149,6 +149,10 @@ adding foo/a $ mv foo bar $ ln -s bar foo + $ hg status + ! foo/a + ? bar/a + ? foo now addremove should remove old files From durham at fb.com Sun Feb 10 08:42:33 2013 From: durham at fb.com (Durham Goode) Date: Sun, 10 Feb 2013 06:42:33 -0800 Subject: [PATCH 3 of 3] addremove: don't audit the path for paths already in the dirstate In-Reply-To: References: Message-ID: <2d86e4cb01afea6559a9.1360507353@dev350.prn1.facebook.com> # HG changeset patch # User Durham Goode # Date 1360103779 28800 # Node ID 2d86e4cb01afea6559a957473888681697b584e7 # Parent 6342bd478cbe84999aab99fc05c24717de73b5e5 addremove: don't audit the path for paths already in the dirstate Now that dirstate.walk returns None for paths under symlink directories, addremove doesn't need to validate each path it sees to look for files under symlinks. On a large repository this brings addremove from 6.3 seconds down to 3.65 (42%) since addremove no longer has to stat every directory of every file to determine if the file is inside a symlink directory. I put it through our benchmark and see no perf hit to any other commands. diff --git a/mercurial/scmutil.py b/mercurial/scmutil.py --- a/mercurial/scmutil.py +++ b/mercurial/scmutil.py @@ -752,17 +752,14 @@ ctx = repo[None] walkresults = repo.dirstate.walk(m, sorted(ctx.substate), True, False) for abs in sorted(walkresults): - good = audit_path.check(abs) - st = walkresults[abs] dstate = repo.dirstate[abs] - if good and dstate == '?': + if dstate == '?' and audit_path.check(abs): unknown.append(abs) if repo.ui.verbose or not m.exact(abs): rel = m.rel(abs) repo.ui.status(_('adding %s\n') % ((pats and rel) or abs)) - elif (dstate != 'r' and - (not good or not st or + elif (dstate != 'r' and (not st or (stat.S_ISDIR(st.st_mode) and not stat.S_ISLNK(st.st_mode)))): deleted.append(abs) if repo.ui.verbose or not m.exact(abs): From mpm at selenic.com Sun Feb 10 09:08:24 2013 From: mpm at selenic.com (Matt Mackall) Date: Sun, 10 Feb 2013 15:08:24 +0000 Subject: [PATCH 3 of 3] addremove: don't audit the path for paths already in the dirstate In-Reply-To: <2d86e4cb01afea6559a9.1360507353@dev350.prn1.facebook.com> References: <2d86e4cb01afea6559a9.1360507353@dev350.prn1.facebook.com> Message-ID: <1360508904.3873.48.camel@calx> On Sun, 2013-02-10 at 06:42 -0800, Durham Goode wrote: > # HG changeset patch > # User Durham Goode > # Date 1360103779 28800 > # Node ID 2d86e4cb01afea6559a957473888681697b584e7 > # Parent 6342bd478cbe84999aab99fc05c24717de73b5e5 > addremove: don't audit the path for paths already in the dirstate These are applied, thanks. -- Mathematics is the supreme nostalgia of our time. From sid0 at fb.com Sun Feb 10 09:24:00 2013 From: sid0 at fb.com (Siddharth Agarwal) Date: Sun, 10 Feb 2013 15:24:00 +0000 Subject: [PATCH] dirstate: disable gc while parsing the dirstate Message-ID: <8c50a5734bb2b8833eb4.1360509840@sid0x220> # HG changeset patch # User Siddharth Agarwal # Date 1360509284 0 # Node ID 8c50a5734bb2b8833eb425db95ce26073322d31d # Parent 6fc7952d6819acbc212cdde688edc256c9bd4b2e dirstate: disable gc while parsing the dirstate diff --git a/mercurial/dirstate.py b/mercurial/dirstate.py --- a/mercurial/dirstate.py +++ b/mercurial/dirstate.py @@ -9,7 +9,7 @@ import errno from node import nullid from i18n import _ import scmutil, util, ignore, osutil, parsers, encoding -import os, stat, errno +import os, stat, errno, gc propertycache = util.propertycache filecache = scmutil.filecache @@ -285,7 +285,19 @@ class dirstate(object): if not st: return + # Python's garbage collector triggers a GC each time a certain number + # of container objects (the number being defined by + # gc.get_threshold()) are allocated. parse_dirstate creates a tuple + # for each file in the dirstate. The C version then immediately marks + # them as not to be tracked by the collector. However, this has no + # effect on when GCs are triggered, only on what objects the GC looks + # into. This means that O(number of files) GCs are unavoidable. + # Depending on when in the process's lifetime the dirstate is parsed, + # this can get very expensive. As a workaround, disable GC while + # parsing the dirstate. + gc.disable() p = parsers.parse_dirstate(self._map, self._copymap, st) + gc.enable() if not self._dirtypl: self._pl = p From brodie at sf.io Sun Feb 10 09:28:24 2013 From: brodie at sf.io (Brodie Rao) Date: Sun, 10 Feb 2013 15:28:24 +0000 Subject: [PATCH] dirstate: disable gc while parsing the dirstate In-Reply-To: <8c50a5734bb2b8833eb4.1360509840@sid0x220> References: <8c50a5734bb2b8833eb4.1360509840@sid0x220> Message-ID: On Sun, Feb 10, 2013 at 3:24 PM, Siddharth Agarwal wrote: > # HG changeset patch > # User Siddharth Agarwal > # Date 1360509284 0 > # Node ID 8c50a5734bb2b8833eb425db95ce26073322d31d > # Parent 6fc7952d6819acbc212cdde688edc256c9bd4b2e > dirstate: disable gc while parsing the dirstate > > diff --git a/mercurial/dirstate.py b/mercurial/dirstate.py > --- a/mercurial/dirstate.py > +++ b/mercurial/dirstate.py > @@ -9,7 +9,7 @@ import errno > from node import nullid > from i18n import _ > import scmutil, util, ignore, osutil, parsers, encoding > -import os, stat, errno > +import os, stat, errno, gc > > propertycache = util.propertycache > filecache = scmutil.filecache > @@ -285,7 +285,19 @@ class dirstate(object): > if not st: > return > > + # Python's garbage collector triggers a GC each time a certain number > + # of container objects (the number being defined by > + # gc.get_threshold()) are allocated. parse_dirstate creates a tuple > + # for each file in the dirstate. The C version then immediately marks > + # them as not to be tracked by the collector. However, this has no > + # effect on when GCs are triggered, only on what objects the GC looks > + # into. This means that O(number of files) GCs are unavoidable. > + # Depending on when in the process's lifetime the dirstate is parsed, > + # this can get very expensive. As a workaround, disable GC while > + # parsing the dirstate. > + gc.disable() > p = parsers.parse_dirstate(self._map, self._copymap, st) > + gc.enable() > if not self._dirtypl: > self._pl = p Can you provide some before and after performance numbers? > > _______________________________________________ > Mercurial-devel mailing list > Mercurial-devel at selenic.com > http://selenic.com/mailman/listinfo/mercurial-devel From durham at fb.com Sun Feb 10 09:31:46 2013 From: durham at fb.com (Durham Goode) Date: Sun, 10 Feb 2013 15:31:46 +0000 Subject: [PATCH 1 of 6] blackbox: adds a blackbox extension In-Reply-To: Message-ID: <2B10A89294DA6740AC6155F56842F9CE05659DFF@PRN-MBX01-2.TheFacebook.com> Thanks for the comments. >Also, what about calling this "track" instead of "trackedevents"? I went through the existing config options and 'track' does seem to be more consistent. Will do. >There should be spaces between = here. Running check-code should catch >this. Check-code didn't catch this. >> +def reposetup(ui, repo): >> + if not repo.local(): >> + return > >I don't follow this. Can you explain why you need to bail when the >repo isn't local? When talking to remote repos, mercurial creates a httppeer repo as a representation of the remote repo. The httppeer doesn't have a .hg directory to dump a blackbox.log in, so we don't do the blackbox setup for those kinds of repos. I'll add a comment explaining that. From durham at fb.com Sun Feb 10 09:43:31 2013 From: durham at fb.com (Durham Goode) Date: Sun, 10 Feb 2013 15:43:31 +0000 Subject: [PATCH] dirstate: disable gc while parsing the dirstate In-Reply-To: <8c50a5734bb2b8833eb4.1360509840@sid0x220> Message-ID: <2B10A89294DA6740AC6155F56842F9CE05659E23@PRN-MBX01-2.TheFacebook.com> >+ gc.disable() > p = parsers.parse_dirstate(self._map, self._copymap, st) >+ gc.enable() > if not self._dirtypl: > self._pl = p Probably needs to be in a try/finally? From mpm at selenic.com Sun Feb 10 09:45:52 2013 From: mpm at selenic.com (Matt Mackall) Date: Sun, 10 Feb 2013 15:45:52 +0000 Subject: [PATCH] export: show 'Date' header in a format that also is readable for humans In-Reply-To: <51178E9C.2000104@kiilerich.com> References: <055060daf58dbe46c667.1360402284@localhost.localdomain> <51178E9C.2000104@kiilerich.com> Message-ID: <1360511152.3873.51.camel@calx> On Sun, 2013-02-10 at 13:12 +0100, Mads Kiilerich wrote: > On 02/10/2013 12:53 PM, Brodie Rao wrote: > > On Sat, Feb 9, 2013 at 9:31 AM, Mads Kiilerich wrote: > >> # HG changeset patch > >> # User Mads Kiilerich > >> # Date 1360360457 -3600 > >> # Node ID 055060daf58dbe46c667053cbb04409b202ee9cd > >> # Parent 97761496c65ae836d6b0983a3f48959dd3112364 > >> export: show 'Date' header in a format that also is readable for humans > >> > >> 'export' is the official export format and used by patchbomb, but it would only > >> show date as a timestamp that most humans might find it hard to relate to. It > >> would be very convenient when reviewing a patch to be able to see what > >> timestamp the patch will end up with. > >> > >> Mercurial has always used util.parsedate for parsing these headers. It can > >> handle 'all' date formats, so we could just as well use a readable one. > > Are there any third party utilities that parse these headers? I wonder > > if this might cause other tools to break. > > Yes, that is a valid concern, but we don't expect that. Parsers should > read it as Mercurial do, and Mercurial has always been able to handle > all formats. > > So I will put it in 'default' and we can wait and see if it really > becomes a problem. After a bit of poking, I've discovered this in Git: hg) this=0 for hg in "$@" do this=$(( $this + 1 )) msgnum=$(printf "%0${prec}d" $this) # hg stores changeset metadata in #-commented lines preceding # the commit message and diff(s). The only metadata we care about # are the User and Date (Node ID and Parent are hashes which are # only relevant to the hg repository and thus not useful to us) # Since we cannot guarantee that the commit message is in # git-friendly format, we put no Subject: line and just consume # all of the message as the body LANG=C LC_ALL=C perl -M'POSIX qw(strftime)' -ne 'BEGIN { $subject = 0 } if ($subject) { print ; } elsif (/^\# User /) { s/\# User/From:/ ; print ; } elsif (/^\# Date /) { my ($hashsign, $str, $time, $tz) = split ; $tz = sprintf "%+05d", (0-$tz)/36; print "Date: " . strftime("%a, %d %b %Y %H:%M:%S ", localtime($time)) . "$tz\n"; } elsif (/^\# /) { next ; } else { print "\n", $_ ; $subject = 1; } ' <"$hg" >"$dotest/$msgnum" || clean_abort so we're going to try something different. -- Mathematics is the supreme nostalgia of our time. From mpm at selenic.com Sun Feb 10 09:47:04 2013 From: mpm at selenic.com (Matt Mackall) Date: Sun, 10 Feb 2013 15:47:04 +0000 Subject: [PATCH] dirstate: disable gc while parsing the dirstate In-Reply-To: <2B10A89294DA6740AC6155F56842F9CE05659E23@PRN-MBX01-2.TheFacebook.com> References: <2B10A89294DA6740AC6155F56842F9CE05659E23@PRN-MBX01-2.TheFacebook.com> Message-ID: <1360511224.3873.52.camel@calx> On Sun, 2013-02-10 at 15:43 +0000, Durham Goode wrote: > >+ gc.disable() > > p = parsers.parse_dirstate(self._map, self._copymap, st) > >+ gc.enable() > > if not self._dirtypl: > > self._pl = p > > Probably needs to be in a try/finally? Yes, you're correct. -- Mathematics is the supreme nostalgia of our time. From sid0 at fb.com Sun Feb 10 09:53:01 2013 From: sid0 at fb.com (Siddharth Agarwal) Date: Sun, 10 Feb 2013 15:53:01 +0000 Subject: [PATCH] dirstate: disable gc while parsing the dirstate In-Reply-To: References: <8c50a5734bb2b8833eb4.1360509840@sid0x220> Message-ID: <5117C25D.3020208@fb.com> On 02/10/2013 03:28 PM, Brodie Rao wrote: > Can you provide some before and after performance numbers? It fixes a perf regression a patch I'm going to bomb shortly introduces (because it indirectly delays parsing the manifest a bit). For a repo with 150,000 files, it speeds up a no-op update from 2.13 seconds to 1.98. From sid0 at fb.com Sun Feb 10 10:06:39 2013 From: sid0 at fb.com (Siddharth Agarwal) Date: Sun, 10 Feb 2013 16:06:39 +0000 Subject: [PATCH] dirstate: disable gc while parsing the dirstate In-Reply-To: <5117C25D.3020208@fb.com> References: <8c50a5734bb2b8833eb4.1360509840@sid0x220> <5117C25D.3020208@fb.com> Message-ID: <5117C58F.4030602@fb.com> On 02/10/2013 03:53 PM, Siddharth Agarwal wrote: > On 02/10/2013 03:28 PM, Brodie Rao wrote: >> Can you provide some before and after performance numbers? > > It fixes a perf regression a patch I'm going to bomb shortly > introduces (because it indirectly delays parsing the manifest a bit). Sorry, I meant parsing the *dirstate*. From mpm at selenic.com Sun Feb 10 10:43:41 2013 From: mpm at selenic.com (Matt Mackall) Date: Sun, 10 Feb 2013 16:43:41 +0000 Subject: [PATCH 1 of 2] hgweb: make 'branches' template split branches by status In-Reply-To: References: Message-ID: <1360514621.3873.61.camel@calx> On Mon, 2013-02-04 at 13:56 -0200, Antonio Zanardo wrote: > # HG changeset patch > # User Antonio Zanardo > # Date 1359989550 7200 > # Node ID c4dd3efdf2246f8d80813ea84d7c9f0b45eb046c > # Parent 7068089c95a2ff3c1b536bbb52ca6bc1f06fc06e > hgweb: make 'branches' template split branches by status > > This is the initial work on webcommands.py branches() to allow hgweb templates > to split branches list by status or entirely hide closed branches, for example. Huh, so what is the current state here? It appears that we: - list all branch heads - sort by open vs closed - sort by rev - display open / closed / inactive This is.. unfortunate. We should probably not show closed branches at all and we've long considered active/inactive to be a meaningless and outdated concept (starting the day we introduced closed branches). We should instead: - list only open branch heads - sort by rev This can in fact be done today purely in templates, with something like: {ifeq(status, 'closed', '', '{branch}....'} And we can have separate lists using something like the above as well. Perhaps an on-click method to show closed branches would be better than a session variable. -- Mathematics is the supreme nostalgia of our time. From sid0 at fb.com Sun Feb 10 10:57:33 2013 From: sid0 at fb.com (Siddharth Agarwal) Date: Sun, 10 Feb 2013 16:57:33 +0000 Subject: [PATCH 0 of 3 V2] Parse manifests in the right order during a merge Message-ID: Patch 1 is V2 of a patch I bombed earlier, and 2 and 3 are new. From sid0 at fb.com Sun Feb 10 10:57:34 2013 From: sid0 at fb.com (Siddharth Agarwal) Date: Sun, 10 Feb 2013 16:57:34 +0000 Subject: [PATCH 1 of 3 V2] dirstate: disable gc while parsing the dirstate In-Reply-To: References: Message-ID: # HG changeset patch # User Siddharth Agarwal # Date 1360513394 0 # Node ID f068418a1e6c8ece794a6f0ef7c1c1008eca7a44 # Parent 6fc7952d6819acbc212cdde688edc256c9bd4b2e dirstate: disable gc while parsing the dirstate This prevents a performance regression an upcoming patch would otherwise introduce because it indirectly delays parsing the dirstate a bit. diff --git a/mercurial/dirstate.py b/mercurial/dirstate.py --- a/mercurial/dirstate.py +++ b/mercurial/dirstate.py @@ -9,7 +9,7 @@ import errno from node import nullid from i18n import _ import scmutil, util, ignore, osutil, parsers, encoding -import os, stat, errno +import os, stat, errno, gc propertycache = util.propertycache filecache = scmutil.filecache @@ -285,7 +285,23 @@ class dirstate(object): if not st: return - p = parsers.parse_dirstate(self._map, self._copymap, st) + # Python's garbage collector triggers a GC each time a certain number + # of container objects (the number being defined by + # gc.get_threshold()) are allocated. parse_dirstate creates a tuple + # for each file in the dirstate. The C version then immediately marks + # them as not to be tracked by the collector. However, this has no + # effect on when GCs are triggered, only on what objects the GC looks + # into. This means that O(number of files) GCs are unavoidable. + # Depending on when in the process's lifetime the dirstate is parsed, + # this can get very expensive. As a workaround, disable GC while + # parsing the dirstate. + gcenabled = gc.isenabled() + gc.disable() + try: + p = parsers.parse_dirstate(self._map, self._copymap, st) + finally: + if gcenabled: + gc.enable() if not self._dirtypl: self._pl = p From sid0 at fb.com Sun Feb 10 10:57:35 2013 From: sid0 at fb.com (Siddharth Agarwal) Date: Sun, 10 Feb 2013 16:57:35 +0000 Subject: [PATCH 2 of 3 V2] merge: run _forgetremoved after manifestmerge In-Reply-To: References: Message-ID: # HG changeset patch # User Siddharth Agarwal # Date 1360498606 0 # Node ID fad0293bfdb045488c2b65b6448da54628ada8e5 # Parent f068418a1e6c8ece794a6f0ef7c1c1008eca7a44 merge: run _forgetremoved after manifestmerge _forgetremoved can trigger manifest construction, but we only want it to happen after manifestmerge, so that our attempt to read the manifests in the right order in an upcoming patch actually works. diff --git a/mercurial/merge.py b/mercurial/merge.py --- a/mercurial/merge.py +++ b/mercurial/merge.py @@ -515,12 +515,12 @@ def calculateupdates(repo, tctx, mctx, a _checkcollision(mctx, None) else: _checkcollision(mctx, (tctx, ancestor)) - if tctx.rev() is None: - actions += _forgetremoved(tctx, mctx, branchmerge) actions += manifestmerge(repo, tctx, mctx, ancestor, branchmerge, force, partial) + if tctx.rev() is None: + actions += _forgetremoved(tctx, mctx, branchmerge) return actions def recordupdates(repo, actions, branchmerge): From sid0 at fb.com Sun Feb 10 10:57:36 2013 From: sid0 at fb.com (Siddharth Agarwal) Date: Sun, 10 Feb 2013 16:57:36 +0000 Subject: [PATCH 3 of 3 V2] manifestmerge: fix order in which manifests are fetched In-Reply-To: References: Message-ID: <37777a929dc6945b3ac7.1360515456@sid0x220> # HG changeset patch # User Siddharth Agarwal # Date 1360515301 0 # Node ID 37777a929dc6945b3ac7718649a84ecf10d7e0ac # Parent fad0293bfdb045488c2b65b6448da54628ada8e5 manifestmerge: fix order in which manifests are fetched If the manifest of an earlier revision on the same delta chain is read before that of a later revision, the revlog remembers that we parsed the earlier revision and continues applying deltas from there onwards. If manifests are parsed the other way round, we have to start over from the fulltext. For a fresh clone of mozilla-central, updating from 29dd80c95b7d to its parent aab96936a177 requires approximately 400 fewer zlib.decompress calls, which results in a speedup from 1.10 seconds to 1.05. diff --git a/mercurial/merge.py b/mercurial/merge.py --- a/mercurial/merge.py +++ b/mercurial/merge.py @@ -196,6 +196,7 @@ def manifestmerge(repo, wctx, p2, pa, br overwrite = force and not branchmerge actions, copy, movewithdir = [], {}, {} + followcopies = False if overwrite: pa = wctx elif pa == p2: # backwards @@ -203,6 +204,13 @@ def manifestmerge(repo, wctx, p2, pa, br elif not branchmerge and not wctx.dirty(missing=True): pass elif pa and repo.ui.configbool("merge", "followcopies", True): + followcopies = True + + # manifests fetched in order are going to be faster, so prime the caches + [x.manifest() for x in + sorted(wctx.parents() + [p2, pa], key=lambda x: x.rev())] + + if followcopies: ret = copies.mergecopies(repo, wctx, p2, pa) copy, movewithdir, diverge, renamedelete = ret for of, fl in diverge.iteritems(): From mads at kiilerich.com Sun Feb 10 11:12:57 2013 From: mads at kiilerich.com (Mads Kiilerich) Date: Sun, 10 Feb 2013 18:12:57 +0100 Subject: [PATCH] unionrepo: read-only operations on a union of two localrepos Message-ID: <148096565f16fe72a571.1360516377@localhost.localdomain> # HG changeset patch # User Mads Kiilerich # Date 1358520849 -3600 # Fri Jan 18 15:54:09 2013 +0100 # Node ID 148096565f16fe72a5711ef1a584e80d2b10be14 # Parent fdd29121eb6cba51c276b59baf1ffc544b4d2d45 unionrepo: read-only operations on a union of two localrepos unionrepo is just like bundlerepo without bundles. The implementation is very similar to bundlerepo, but I don't see any obvious way to generalize it. Some most obvious use cases for this would be log and diff across local repos, as a kind of preview of pulls, for instance: $ hg -R union:repo1+repo2 heads $ hg -R union:repo1+repo2 log -r REPO1REV -r REPO2REV $ hg -R union:repo1+repo2 log -r '::REPO1REV-::REPO2REV' $ hg -R union:repo1+repo2 log -r 'ancestor(REPO1REV,REPO2REV)' $ hg -R union:repo1+repo2 diff -r REPO1REV -r REPO2REV This is going to be used in RhodeCode, and Bitbucket already uses something similar. Having a core implementation would be beneficial. diff --git a/mercurial/hg.py b/mercurial/hg.py --- a/mercurial/hg.py +++ b/mercurial/hg.py @@ -9,8 +9,8 @@ from i18n import _ from lock import release from node import hex, nullid -import localrepo, bundlerepo, httppeer, sshpeer, statichttprepo, bookmarks -import lock, util, extensions, error, node, scmutil, phases, url +import localrepo, bundlerepo, unionrepo, httppeer, sshpeer, statichttprepo +import bookmarks, lock, util, extensions, error, node, scmutil, phases, url import cmdutil, discovery import merge as mergemod import verify as verifymod @@ -64,6 +64,7 @@ schemes = { 'bundle': bundlerepo, + 'union': unionrepo, 'file': _local, 'http': httppeer, 'https': httppeer, diff --git a/mercurial/unionrepo.py b/mercurial/unionrepo.py new file mode 100644 --- /dev/null +++ b/mercurial/unionrepo.py @@ -0,0 +1,208 @@ +# unionrepo.py - repository class for viewing union of repository changesets +# +# Derived from bundlerepo.py +# Copyright 2006, 2007 Benoit Boissinot +# Copyright 2013 Unity Technologies, Mads Kiilerich +# +# This software may be used and distributed according to the terms of the +# GNU General Public License version 2 or any later version. + +"""Repository class for "in-memory pull" of one local repository to another, +allowing operations like diff and log with revsets. +""" + +from node import nullid +from i18n import _ +import os +import util, mdiff, cmdutil, scmutil +import localrepo, changelog, manifest, filelog, revlog + +class unionrevlog(revlog.revlog): + def __init__(self, opener, indexfile, revlog2, linkmapper): + # How it works: + # To retrieve a revision, we just need to know the node id so we can + # look it up in revlog2. + # + # To differentiate a rev in the second revlog from a rev in the revlog, + # we check revision against repotiprev. + opener = scmutil.readonlyvfs(opener) + revlog.revlog.__init__(self, opener, indexfile) + self.revlog2 = revlog2 + + n = len(self) + self.repotiprev = n - 1 + self.bundlerevs = set() # used by 'bundle()' revset expression + for rev2 in self.revlog2: + rev = self.revlog2.index[rev2] + # rev numbers - in revlog2, very different from self.rev + _start, _csize, _rsize, _base, linkrev, p1rev, p2rev, node = rev + + if linkmapper is None: # link is to same revlog + assert linkrev == rev2 # we never link back + link = n + else: # rev must be mapped from repo2 cl to unified cl by linkmapper + link = linkmapper(linkrev) + + if node in self.nodemap: + # this happens for the common revlog revisions + self.bundlerevs.add(self.nodemap[node]) + continue + + p1node = self.revlog2.node(p1rev) + p2node = self.revlog2.node(p2rev) + + e = (None, None, None, None, + link, self.rev(p1node), self.rev(p2node), node) + self.index.insert(-1, e) + self.nodemap[node] = n + self.bundlerevs.add(n) + n += 1 + + def _chunk(self, rev): + if rev <= self.repotiprev: + return revlog.revlog._chunk(self, rev) + return self.revlog2._chunk(self.node(rev)) + + def revdiff(self, rev1, rev2): + """return or calculate a delta between two revisions""" + if rev1 > self.repotiprev and rev2 > self.repotiprev: + return self.revlog2.revdiff( + self.revlog2.rev(self.node(rev1)), + self.revlog2.rev(self.node(rev2))) + elif rev1 <= self.repotiprev and rev2 <= self.repotiprev: + return revlog.revlog.revdiff(self, rev1, rev2) + + return mdiff.textdiff(self.revision(self.node(rev1)), + self.revision(self.node(rev2))) + + def revision(self, nodeorrev): + """return an uncompressed revision of a given node or revision + number. + """ + if isinstance(nodeorrev, int): + rev = nodeorrev + node = self.node(rev) + else: + node = nodeorrev + rev = self.rev(node) + + if node == nullid: + return "" + + if rev > self.repotiprev: + text = self.revlog2.revision(node) + self._cache = (node, rev, text) + else: + text = revlog.revlog.revision(self, rev) + # already cached + return text + + def addrevision(self, text, transaction, link, p1=None, p2=None, d=None): + raise NotImplementedError + def addgroup(self, revs, linkmapper, transaction): + raise NotImplementedError + def strip(self, rev, minlink): + raise NotImplementedError + def checksize(self): + raise NotImplementedError + +class unionchangelog(unionrevlog, changelog.changelog): + def __init__(self, opener, opener2): + changelog.changelog.__init__(self, opener) + linkmapper = None + changelog2 = changelog.changelog(opener2) + unionrevlog.__init__(self, opener, self.indexfile, changelog2, + linkmapper) + +class unionmanifest(unionrevlog, manifest.manifest): + def __init__(self, opener, opener2, linkmapper): + manifest.manifest.__init__(self, opener) + manifest2 = manifest.manifest(opener2) + unionrevlog.__init__(self, opener, self.indexfile, manifest2, + linkmapper) + +class unionfilelog(unionrevlog, filelog.filelog): + def __init__(self, opener, path, opener2, linkmapper, repo): + filelog.filelog.__init__(self, opener, path) + filelog2 = filelog.filelog(opener2, path) + unionrevlog.__init__(self, opener, self.indexfile, filelog2, + linkmapper) + self._repo = repo + + def _file(self, f): + self._repo.file(f) + +class unionpeer(localrepo.localpeer): + def canpush(self): + return False + +class unionrepository(localrepo.localrepository): + def __init__(self, ui, path, path2): + localrepo.localrepository.__init__(self, ui, path) + self.ui.setconfig('phases', 'publish', False) + + self._url = 'union:%s+%s' % (util.expandpath(path), + util.expandpath(path2)) + self.repo2 = localrepo.localrepository(ui, path2) + + @localrepo.unfilteredpropertycache + def changelog(self): + return unionchangelog(self.sopener, self.repo2.sopener) + + def _clrev(self, rev2): + """map from repo2 changelog rev to temporary rev in self.changelog""" + node = self.repo2.changelog.node(rev2) + return self.changelog.rev(node) + + @localrepo.unfilteredpropertycache + def manifest(self): + return unionmanifest(self.sopener, self.repo2.sopener, + self._clrev) + + def url(self): + return self._url + + def file(self, f): + return unionfilelog(self.sopener, f, self.repo2.sopener, + self._clrev, self) + + def close(self): + self.repo2.close() + + def cancopy(self): + return False + + def peer(self): + return unionpeer(self) + + def getcwd(self): + return os.getcwd() # always outside the repo + +def instance(ui, path, create): + if create: + raise util.Abort(_('cannot create new union repository')) + parentpath = ui.config("bundle", "mainreporoot", "") + if not parentpath: + # try to find the correct path to the working directory repo + parentpath = cmdutil.findrepo(os.getcwd()) + if parentpath is None: + parentpath = '' + if parentpath: + # Try to make the full path relative so we get a nice, short URL. + # In particular, we don't want temp dir names in test outputs. + cwd = os.getcwd() + if parentpath == cwd: + parentpath = '' + else: + cwd = os.path.join(cwd,'') + if parentpath.startswith(cwd): + parentpath = parentpath[len(cwd):] + if path.startswith('union:'): + s = path.split(":", 1)[1].split("+", 1) + if len(s) == 1: + repopath, repopath2 = parentpath, s[0] + else: + repopath, repopath2 = s + else: + repopath, repopath2 = parentpath, path + return unionrepository(ui, repopath, repopath2) diff --git a/tests/test-unionrepo.t b/tests/test-unionrepo.t new file mode 100644 --- /dev/null +++ b/tests/test-unionrepo.t @@ -0,0 +1,148 @@ +Test unionrepo functionality + +Create one repository + + $ hg init repo1 + $ cd repo1 + $ touch repo1-0 + $ echo repo1-0 > f + $ hg ci -Aqmrepo1-0 + $ touch repo1-1 + $ echo repo1-1 >> f + $ hg ci -Aqmrepo1-1 + $ touch repo1-2 + $ echo repo1-2 >> f + $ hg ci -Aqmrepo1-2 + $ hg log --template '{rev}:{node|short} {desc|firstline}\n' + 2:68c0685446a3 repo1-2 + 1:8a58db72e69d repo1-1 + 0:f093fec0529b repo1-0 + $ tip1=`hg id -q` + $ cd .. + +- and a clone with a not-completely-trivial history + + $ hg clone -q repo1 --rev 0 repo2 + $ cd repo2 + $ touch repo2-1 + $ sed '1irepo2-1 at top' f > f.tmp + $ mv f.tmp f + $ hg ci -Aqmrepo2-1 + $ touch repo2-2 + $ hg pull -q ../repo1 -r 1 + $ hg merge -q + $ hg ci -Aqmrepo2-2-merge + $ touch repo2-3 + $ echo repo2-3 >> f + $ hg ci -mrepo2-3 + $ hg log --template '{rev}:{node|short} {desc|firstline}\n' + 4:2f0d178c469c repo2-3 + 3:9e6fb3e0b9da repo2-2-merge + 2:8a58db72e69d repo1-1 + 1:c337dba826e7 repo2-1 + 0:f093fec0529b repo1-0 + $ cd .. + +revisions from repo2 appear as appended / pulled to repo1 + + $ hg -R union:repo1+repo2 log --template '{rev}:{node|short} {desc|firstline}\n' + 5:2f0d178c469c repo2-3 + 4:9e6fb3e0b9da repo2-2-merge + 3:c337dba826e7 repo2-1 + 2:68c0685446a3 repo1-2 + 1:8a58db72e69d repo1-1 + 0:f093fec0529b repo1-0 + +manifest can be retrieved for revisions in both repos + + $ hg -R union:repo1+repo2 mani -r $tip1 + f + repo1-0 + repo1-1 + repo1-2 + $ hg -R union:repo1+repo2 mani -r 4 + f + repo1-0 + repo1-1 + repo2-1 + repo2-2 + +files can be retrieved form both repos + + $ hg -R repo1 cat repo1/f -r2 + repo1-0 + repo1-1 + repo1-2 + + $ hg -R union:repo1+repo2 cat -r$tip1 repo1/f + repo1-0 + repo1-1 + repo1-2 + + $ hg -R union:repo1+repo2 cat -r4 $TESTTMP/repo1/f + repo2-1 at top + repo1-0 + repo1-1 + +files can be compared across repos + + $ hg -R union:repo1+repo2 diff -r$tip1 -rtip + diff -r 68c0685446a3 -r 2f0d178c469c f + --- a/f Thu Jan 01 00:00:00 1970 +0000 + +++ b/f Thu Jan 01 00:00:00 1970 +0000 + @@ -1,3 +1,4 @@ + +repo2-1 at top + repo1-0 + repo1-1 + -repo1-2 + +repo2-3 + +heads from both repos are found correctly + + $ hg -R union:repo1+repo2 heads --template '{rev}:{node|short} {desc|firstline}\n' + 5:2f0d178c469c repo2-3 + 2:68c0685446a3 repo1-2 + +revsets works across repos + + $ hg -R union:repo1+repo2 id -r "ancestor($tip1, 5)" + 8a58db72e69d + +annotate works - an indication that linkrevs works + + $ hg --cwd repo1 -R union:../repo2 annotate $TESTTMP/repo1/f -r tip + 3: repo2-1 at top + 0: repo1-0 + 1: repo1-1 + 5: repo2-3 + +union repos can be cloned ... and clones works correctly + + $ hg clone -U union:repo1+repo2 repo3 + requesting all changes + adding changesets + adding manifests + adding file changes + added 6 changesets with 11 changes to 6 files (+1 heads) + + $ hg -R repo3 paths + default = union:repo1+repo2 + + $ hg -R repo3 verify + checking changesets + checking manifests + crosschecking files in changesets and manifests + checking files + 6 files, 6 changesets, 11 total revisions + + $ hg -R repo3 heads --template '{rev}:{node|short} {desc|firstline}\n' + 5:2f0d178c469c repo2-3 + 2:68c0685446a3 repo1-2 + + $ hg -R repo3 log --template '{rev}:{node|short} {desc|firstline}\n' + 5:2f0d178c469c repo2-3 + 4:9e6fb3e0b9da repo2-2-merge + 3:c337dba826e7 repo2-1 + 2:68c0685446a3 repo1-2 + 1:8a58db72e69d repo1-1 + 0:f093fec0529b repo1-0 From mpm at selenic.com Sun Feb 10 11:18:27 2013 From: mpm at selenic.com (Matt Mackall) Date: Sun, 10 Feb 2013 17:18:27 +0000 Subject: [PATCH 3 of 3 V3] extensions: obsolete and remove interhg extension In-Reply-To: <8c8f60f3245521457928.1360498887@Angel-PC.localdomain> References: <8c8f60f3245521457928.1360498887@Angel-PC.localdomain> Message-ID: <1360516707.3873.62.camel@calx> On Sun, 2013-02-10 at 13:21 +0100, Angel Ezquerra wrote: > # HG changeset patch > # User Angel Ezquerra > # Date 1360404042 -3600 > # Node ID 8c8f60f32455214579282ba2d67e36b704227455 > # Parent f9bee14db21432fa90dd2c10cd6880286946d917 > extensions: obsolete and remove interhg extension These are applied to default, thanks. -- Mathematics is the supreme nostalgia of our time. From hg at intevation.org Sun Feb 10 12:40:06 2013 From: hg at intevation.org (Mercurial Commits) Date: Sun, 10 Feb 2013 19:40:06 +0100 Subject: mercurial@18629: 6 new changesets Message-ID: <1360521606.778065.29844.nullmailer@hg.intevation.org> 6 new changesets in mercurial: http://selenic.com/repo/hg//rev/4db216b1c154 changeset: 18624:4db216b1c154 user: Durham Goode date: Tue Feb 05 14:24:14 2013 -0800 summary: pathauditor: add check() method http://selenic.com/repo/hg//rev/2cbd27f4f3c4 changeset: 18625:2cbd27f4f3c4 user: Durham Goode date: Mon Feb 04 14:27:15 2013 -0800 summary: dirstate: walk returns None for files that have a symlink in their path http://selenic.com/repo/hg//rev/b114e41c4df3 changeset: 18626:b114e41c4df3 user: Durham Goode date: Tue Feb 05 14:36:19 2013 -0800 summary: addremove: don't audit the path for paths already in the dirstate http://selenic.com/repo/hg//rev/4e949b8e0930 changeset: 18627:4e949b8e0930 user: Angel Ezquerra date: Fri Feb 08 18:05:32 2013 +0100 summary: hgweb: add websub template filter http://selenic.com/repo/hg//rev/52305554fd6e changeset: 18628:52305554fd6e user: Angel Ezquerra date: Sat Feb 09 16:48:21 2013 +0100 summary: hgweb: apply the websub filter to revision descriptions http://selenic.com/repo/hg//rev/013fcd112f13 changeset: 18629:013fcd112f13 tag: tip user: Angel Ezquerra date: Sat Feb 09 11:00:42 2013 +0100 summary: extensions: obsolete and remove interhg extension -- Repository URL: http://selenic.com/repo/hg/ From hgbuildbot at kublai.com Sun Feb 10 13:34:34 2013 From: hgbuildbot at kublai.com (hgbuildbot at kublai.com) Date: Sun, 10 Feb 2013 11:34:34 -0800 Subject: buildbot failure in Mercurial on hg tests Message-ID: <20130210193435.A07C1380B1@hgbuildbot.cs.ubc.ca> The Buildbot has detected a new failure on builder hg tests while building hg. Full details are available at: http://hgbuildbot.kublai.com/builders/hg%20tests/builds/493 Buildbot URL: http://hgbuildbot.kublai.com/ Buildslave for this Build: p64.osuosl.test Build Reason: scheduler Build Source Stamp: [branch default] 013fcd112f13f31a35ea6a40d8cd1c6923cdaf20 Blamelist: Angel Ezquerra ,Durham Goode BUILD FAILED: failed pure sincerely, -The Buildbot From durham at fb.com Sun Feb 10 14:44:36 2013 From: durham at fb.com (Durham Goode) Date: Sun, 10 Feb 2013 12:44:36 -0800 Subject: [PATCH] dirstate: fix generator/list error when using python 2.7 Message-ID: <9c384e0ef7f5c860ea77.1360529076@dev350.prn1.facebook.com> # HG changeset patch # User Durham Goode # Date 1360527819 28800 # Node ID 9c384e0ef7f5c860ea774bbdc5e0c30e3e7421e8 # Parent 013fcd112f13f31a35ea6a40d8cd1c6923cdaf20 dirstate: fix generator/list error when using python 2.7 util.statfiles returns a generator on python 2.7 with c extensions disabled. This caused util.statfiles(...) [0] to break in tests. Since we're only stat'ing one file, I just changed it to call lstat directly. diff --git a/mercurial/dirstate.py b/mercurial/dirstate.py --- a/mercurial/dirstate.py +++ b/mercurial/dirstate.py @@ -687,7 +687,11 @@ # Report ignored items in the dmap as long as they are not # under a symlink directory. if ignore(nf) and audit_path.check(nf): - results[nf] = util.statfiles([join(nf)])[0] + try: + results[nf] = lstat(join(nf)) + except OSError: + # file doesn't exist + results[nf] = None else: # It's either missing or under a symlink directory results[nf] = None From taktaktaktaktaktaktaktaktaktak at gmail.com Sun Feb 10 15:47:34 2013 From: taktaktaktaktaktaktaktaktaktak at gmail.com (Levi Bard) Date: Sun, 10 Feb 2013 22:47:34 +0100 Subject: [PATCH] obsolete: consider successors along with descendants when updating Message-ID: <8d89080a98d69606ac26.1360532854@retina-monoteam> # HG changeset patch # User Levi Bard # Date 1360532614 -3600 # Node ID 8d89080a98d69606ac264282e2ba3e33b056bcac # Parent 013fcd112f13f31a35ea6a40d8cd1c6923cdaf20 obsolete: consider successors along with descendants when updating Currently, if you pull --update a group of changesets that obsoletes the current changeset, mercurial refuses to update because the pulled tip is not a descendant. This change causes mercurial to consider successors as well as descendants when determining whether to update. diff -r 013fcd112f13 -r 8d89080a98d6 mercurial/merge.py --- a/mercurial/merge.py Sat Feb 09 11:00:42 2013 +0100 +++ b/mercurial/merge.py Sun Feb 10 22:43:34 2013 +0100 @@ -7,6 +7,7 @@ from node import nullid, nullrev, hex, bin from i18n import _ +from mercurial import obsolete import error, util, filemerge, copies, subrepo import errno, os, shutil @@ -632,6 +633,9 @@ elif not overwrite: if pa == p1 or pa == p2: # linear pass # all good + elif repo.obsstore and \ + node in obsolete.allsuccessors(repo.obsstore, [p1.node()]): + pa = p1 # allow updating to successors of obsolete nodes elif wc.dirty(missing=True): raise util.Abort(_("crosses branches (merge branches or use" " --clean to discard changes)")) diff -r 013fcd112f13 -r 8d89080a98d6 tests/test-pull-update.t --- a/tests/test-pull-update.t Sat Feb 09 11:00:42 2013 +0100 +++ b/tests/test-pull-update.t Sun Feb 10 22:43:34 2013 +0100 @@ -1,3 +1,12 @@ + $ cat << EOF >> $HGRCPATH + > [extensions] + > obs=$TESTTMP/obs.py + > EOF + $ cat > obs.py << EOF + > import mercurial.obsolete + > mercurial.obsolete._enabled = True + > EOF + $ hg init t $ cd t $ echo 1 > foo @@ -60,3 +69,64 @@ 1 files updated, 0 files merged, 0 files removed, 0 files unresolved $ cd .. + +Test no-argument update to a successor of an obsoleted changeset + + $ hg init blah + $ cd blah + $ echo 1 > a + $ hg add a + $ hg commit -m0 + $ echo 2 > a + $ hg commit -m1 + $ cd .. + $ hg clone blah meh + updating to branch default + 1 files updated, 0 files merged, 0 files removed, 0 files unresolved + $ cd blah + $ echo 3 > a + $ hg commit --amend -m3 + $ cd ../meh + $ hg pull --update ../blah + pulling from ../blah + searching for changes + adding changesets + adding manifests + adding file changes + added 1 changesets with 1 changes to 1 files (+1 heads) + 1 files updated, 0 files merged, 0 files removed, 0 files unresolved + $ cd .. + +Test refusal to update to a non-successor of an obsoleted changeset + + $ rm -rf blah meh + $ hg init blah + $ cd blah + $ echo 1 > a + $ hg add a + $ hg commit -m0 + $ echo 2 > a + $ hg commit -m1 + $ cd .. + $ hg clone blah meh + updating to branch default + 1 files updated, 0 files merged, 0 files removed, 0 files unresolved + $ cd blah + $ echo 3 > a + $ hg commit --amend -m3 + $ hg update 0 + 1 files updated, 0 files merged, 0 files removed, 0 files unresolved + $ echo 4 > a + $ hg commit -m4 + created new head + $ cd ../meh + $ hg pull --update ../blah + pulling from ../blah + searching for changes + adding changesets + adding manifests + adding file changes + added 2 changesets with 2 changes to 1 files (+2 heads) + not updating: crosses branches (merge branches or update --check to force update) + $ cd .. + From bos at serpentine.com Sun Feb 10 17:39:47 2013 From: bos at serpentine.com (Bryan O'Sullivan) Date: Sun, 10 Feb 2013 15:39:47 -0800 Subject: [PATCH 3 of 3 V2] manifestmerge: fix order in which manifests are fetched In-Reply-To: <37777a929dc6945b3ac7.1360515456@sid0x220> References: <37777a929dc6945b3ac7.1360515456@sid0x220> Message-ID: On Sun, Feb 10, 2013 at 8:57 AM, Siddharth Agarwal wrote: > manifestmerge: fix order in which manifests are fetched > Series crewed, thanks. -------------- next part -------------- An HTML attachment was scrubbed... URL: From dschleimer at fb.com Sun Feb 10 17:29:51 2013 From: dschleimer at fb.com (David Schleimer) Date: Sun, 10 Feb 2013 15:29:51 -0800 Subject: [PATCH 01 of 19] localrepo: create context used for actual commit earlier Message-ID: <07bdd03d86dcce1558d7.1360538991@dev010.prn1.facebook.com> # HG changeset patch # User David Schleimer # Date 1360330567 28800 # Node ID 07bdd03d86dcce1558d793c29c062e05e5cf02da # Parent cd01b0fef1b0bae101c66c8acd9ba7c013548390 localrepo: create context used for actual commit earlier localrepo.commit creates a workingctx, calls self.status, does some munging on the changes status returns, does some validation on those changes, and then creates a new workingctx from the changes. This moves the creation of the new workginctx ahead of some validation, with the intention of refactoring some of that validation logic into the workingctx, so that it can be reused elsewhere. diff --git a/mercurial/localrepo.py b/mercurial/localrepo.py --- a/mercurial/localrepo.py +++ b/mercurial/localrepo.py @@ -1230,6 +1230,8 @@ elif f not in self.dirstate: fail(f, _("file not tracked!")) + cctx = context.workingctx(self, text, user, date, extra, changes) + if (not force and not extra.get("close") and not merge and not (changes[0] or changes[1] or changes[2]) and wctx.branch() == wctx.p1().branch()): @@ -1244,7 +1246,6 @@ raise util.Abort(_("unresolved merge conflicts " "(see hg help resolve)")) - cctx = context.workingctx(self, text, user, date, extra, changes) if editor: cctx._text = editor(self, cctx, subs) edited = (text != cctx._text) From dschleimer at fb.com Sun Feb 10 17:29:54 2013 From: dschleimer at fb.com (David Schleimer) Date: Sun, 10 Feb 2013 15:29:54 -0800 Subject: [PATCH 04 of 19] commit: refactor mergestate management into workingctx In-Reply-To: <07bdd03d86dcce1558d7.1360538991@dev010.prn1.facebook.com> References: <07bdd03d86dcce1558d7.1360538991@dev010.prn1.facebook.com> Message-ID: # HG changeset patch # User David Schleimer # Date 1360330569 28800 # Node ID f5a6e68310f238e490c6157cf2e4c9725baa1691 # Parent ae3daa803078b08571d1ad602d5d32c92e15475d commit: refactor mergestate management into workingctx This pulls the logic around validating that there are no unresolved conflicts at commit time into the workingctx. It also pulls the state necessary for that detection, and the post-cleanup logic for that state into the workingcontext object. diff --git a/mercurial/context.py b/mercurial/context.py --- a/mercurial/context.py +++ b/mercurial/context.py @@ -10,6 +10,7 @@ import ancestor, mdiff, error, util, scmutil, subrepo, patch, encoding, phases import copies import match as matchmod +import merge as mergemod import os, errno, stat import obsolete as obsmod import repoview @@ -816,10 +817,16 @@ self._unknown = changes[4] self._ignored = changes[5] self._clean = changes[6] + + self._ms = mergemod.mergestate(self._repo) + self._unresolved = [f for f in changes[0] + if f in self._ms and self._ms[f] == 'u'] else: self._unknown = None self._ignored = None self._clean = None + self._ms = None + self._unresolved = None self._extra = {} if extra: @@ -952,6 +959,11 @@ if clean: self._clean = stat[6] self._status = stat[:4] + + self._ms = mergemod.mergestate(self._repo) + self._unresolved = [f for f in stat[0] + if f in self._ms and self._ms[f] == 'u'] + return stat def manifest(self): @@ -982,6 +994,9 @@ def clean(self): assert self._clean is not None # must call status first return self._clean + def unresolved(self): + assert self._unresolved is not None # must call status first + return self._unresolved def branch(self): return encoding.tolocal(self._extra['branch']) def closesbranch(self): @@ -1153,6 +1168,7 @@ for f in self.removed(): self._repo.dirstate.drop(f) self._repo.dirstate.setparents(node) + self._ms.reset() def dirs(self): return set(self._repo.dirstate.dirs()) diff --git a/mercurial/localrepo.py b/mercurial/localrepo.py --- a/mercurial/localrepo.py +++ b/mercurial/localrepo.py @@ -11,7 +11,6 @@ import lock, transaction, store, encoding, base85 import scmutil, util, extensions, hook, error, revset import match as matchmod -import merge as mergemod import tags as tagsmod from lock import release import weakref, errno, os, time, inspect @@ -1240,11 +1239,9 @@ if merge and cctx.deleted(): raise util.Abort(_("cannot commit merge with missing files")) - ms = mergemod.mergestate(self) - for f in changes[0]: - if f in ms and ms[f] == 'u': - raise util.Abort(_("unresolved merge conflicts " - "(see hg help resolve)")) + if cctx.unresolved(): + raise util.Abort(_("unresolved merge conflicts " + "(see hg help resolve)")) if editor: cctx._text = editor(self, cctx, subs) @@ -1280,7 +1277,6 @@ # update bookmarks, dirstate and mergestate bookmarks.update(self, [p1, p2], ret) cctx.markcommitted(ret) - ms.reset() finally: wlock.release() From dschleimer at fb.com Sun Feb 10 17:29:53 2013 From: dschleimer at fb.com (David Schleimer) Date: Sun, 10 Feb 2013 15:29:53 -0800 Subject: [PATCH 03 of 19] commit: factor out post-commit cleanup into workingctx In-Reply-To: <07bdd03d86dcce1558d7.1360538991@dev010.prn1.facebook.com> References: <07bdd03d86dcce1558d7.1360538991@dev010.prn1.facebook.com> Message-ID: # HG changeset patch # User David Schleimer # Date 1360330568 28800 # Node ID ae3daa803078b08571d1ad602d5d32c92e15475d # Parent e13d648bab573f580b7c160c61985bd0cbb66364 commit: factor out post-commit cleanup into workingctx This pulls some of the logic for the cleanup that needs to happen after a commit has been made otu of localrepo.commit and into workingctx. This is part of a larger refactoring effort that will eventually allow us to perform some types of merges in-memory. diff --git a/mercurial/context.py b/mercurial/context.py --- a/mercurial/context.py +++ b/mercurial/context.py @@ -1138,6 +1138,22 @@ finally: wlock.release() + def markcommitted(self, node): + """Perform post-commit cleanup necessary after commiting this workingctx + + Specifically, this updates backing stores this working context + wraps to reflect the fact that the changes reflected by this + workingctx have been committed. For example, it marks + modified and added files as normal in the dirstate. + + """ + + for f in self.modified() + self.added(): + self._repo.dirstate.normal(f) + for f in self.removed(): + self._repo.dirstate.drop(f) + self._repo.dirstate.setparents(node) + def dirs(self): return set(self._repo.dirstate.dirs()) diff --git a/mercurial/localrepo.py b/mercurial/localrepo.py --- a/mercurial/localrepo.py +++ b/mercurial/localrepo.py @@ -1279,11 +1279,7 @@ # update bookmarks, dirstate and mergestate bookmarks.update(self, [p1, p2], ret) - for f in changes[0] + changes[1]: - self.dirstate.normal(f) - for f in changes[2]: - self.dirstate.drop(f) - self.dirstate.setparents(ret) + cctx.markcommitted(ret) ms.reset() finally: wlock.release() From dschleimer at fb.com Sun Feb 10 17:29:56 2013 From: dschleimer at fb.com (David Schleimer) Date: Sun, 10 Feb 2013 15:29:56 -0800 Subject: [PATCH 06 of 19] context: allow updating the date of a workingctx In-Reply-To: <07bdd03d86dcce1558d7.1360538991@dev010.prn1.facebook.com> References: <07bdd03d86dcce1558d7.1360538991@dev010.prn1.facebook.com> Message-ID: <9ad2e26501309255cd08.1360538996@dev010.prn1.facebook.com> # HG changeset patch # User David Schleimer # Date 1360330569 28800 # Node ID 9ad2e26501309255cd0877eec64822e11ae4a540 # Parent 56ec15753a5264b0713bf5cafa484f342d1803c7 context: allow updating the date of a workingctx This is not currently used, but will be used by future patches as part of an effort to unify workingctx and memctx, with an eventual goal of supporitng in-memory merges for graft. diff --git a/mercurial/context.py b/mercurial/context.py --- a/mercurial/context.py +++ b/mercurial/context.py @@ -972,6 +972,8 @@ return self._user or self._repo.ui.username() def date(self): return self._date + def setdate(self, date): + self._date = date def description(self): return self._text def setdescription(self, text): From dschleimer at fb.com Sun Feb 10 17:29:57 2013 From: dschleimer at fb.com (David Schleimer) Date: Sun, 10 Feb 2013 15:29:57 -0800 Subject: [PATCH 07 of 19] context: supporting updating the user of a workingctx In-Reply-To: <07bdd03d86dcce1558d7.1360538991@dev010.prn1.facebook.com> References: <07bdd03d86dcce1558d7.1360538991@dev010.prn1.facebook.com> Message-ID: <60a9efb86ef6d91bf13d.1360538997@dev010.prn1.facebook.com> # HG changeset patch # User David Schleimer # Date 1360330570 28800 # Node ID 60a9efb86ef6d91bf13d131cade4158b81fa2a58 # Parent 9ad2e26501309255cd0877eec64822e11ae4a540 context: supporting updating the user of a workingctx This is not currently used, but will be used by future patches as part of an effort to unify workingctx and memctx, with an eventual goal of supporitng in-memory merges for graft. diff --git a/mercurial/context.py b/mercurial/context.py --- a/mercurial/context.py +++ b/mercurial/context.py @@ -970,6 +970,8 @@ return self._manifest def user(self): return self._user or self._repo.ui.username() + def setuser(self, user): + self._user = user def date(self): return self._date def setdate(self, date): From dschleimer at fb.com Sun Feb 10 17:29:58 2013 From: dschleimer at fb.com (David Schleimer) Date: Sun, 10 Feb 2013 15:29:58 -0800 Subject: [PATCH 08 of 19] context: support updating extra in workingctx In-Reply-To: <07bdd03d86dcce1558d7.1360538991@dev010.prn1.facebook.com> References: <07bdd03d86dcce1558d7.1360538991@dev010.prn1.facebook.com> Message-ID: <62d93c48151c79f5e08c.1360538998@dev010.prn1.facebook.com> # HG changeset patch # User David Schleimer # Date 1360330570 28800 # Node ID 62d93c48151c79f5e08c3e22b79e52052283ce66 # Parent 60a9efb86ef6d91bf13d131cade4158b81fa2a58 context: support updating extra in workingctx This refactors the munging we do on the extra info in the constructor for wrokingctx into a setextra function that can be used to update the extra information after construction. This refactoring is in aid of future efficiency work relating to in-memory merging. diff --git a/mercurial/context.py b/mercurial/context.py --- a/mercurial/context.py +++ b/mercurial/context.py @@ -829,16 +829,7 @@ self._unresolved = None self._extra = {} - if extra: - self._extra = extra.copy() - if 'branch' not in self._extra: - try: - branch = encoding.fromlocal(self._repo.dirstate.branch()) - except UnicodeDecodeError: - raise util.Abort(_('branch name not in UTF-8!')) - self._extra['branch'] = branch - if self._extra['branch'] == '': - self._extra['branch'] = 'default' + self.setextra(extra) def __str__(self): return str(self._parents[0]) + "+" @@ -1009,6 +1000,18 @@ return 'close' in self._extra def extra(self): return self._extra + def setextra(self, extra): + if extra: + self._extra = extra.copy() + if 'branch' not in self._extra: + try: + branch = encoding.fromlocal(self._repo.dirstate.branch()) + except UnicodeDecodeError: + raise util.Abort(_('branch name not in UTF-8!')) + self._extra['branch'] = branch + if self._extra['branch'] == '': + self._extra['branch'] = 'default' + def tags(self): t = [] From dschleimer at fb.com Sun Feb 10 17:29:55 2013 From: dschleimer at fb.com (David Schleimer) Date: Sun, 10 Feb 2013 15:29:55 -0800 Subject: [PATCH 05 of 19] localrepo: update commit to use setter and getter for description In-Reply-To: <07bdd03d86dcce1558d7.1360538991@dev010.prn1.facebook.com> References: <07bdd03d86dcce1558d7.1360538991@dev010.prn1.facebook.com> Message-ID: <56ec15753a5264b0713b.1360538995@dev010.prn1.facebook.com> # HG changeset patch # User David Schleimer # Date 1360330569 28800 # Node ID 56ec15753a5264b0713bf5cafa484f342d1803c7 # Parent f5a6e68310f238e490c6157cf2e4c9725baa1691 localrepo: update commit to use setter and getter for description In addition to removing a reference to a private variable, this is a step towards being able to update a context with all the metadata needed to pass it to localrepo.commitctx. This will eventually allow merge to return context objects instead of statistics, which supports some interesting optimizations. diff --git a/mercurial/context.py b/mercurial/context.py --- a/mercurial/context.py +++ b/mercurial/context.py @@ -974,6 +974,8 @@ return self._date def description(self): return self._text + def setdescription(self, text): + self._text = text def files(self): return sorted(self._status[0] + self._status[1] + self._status[2]) diff --git a/mercurial/localrepo.py b/mercurial/localrepo.py --- a/mercurial/localrepo.py +++ b/mercurial/localrepo.py @@ -1244,8 +1244,8 @@ "(see hg help resolve)")) if editor: - cctx._text = editor(self, cctx, subs) - edited = (text != cctx._text) + cctx.setdescription(editor(self, cctx, subs)) + edited = (text != cctx.description()) # commit subs and write new state if subs: @@ -1253,14 +1253,14 @@ sub = wctx.sub(s) self.ui.status(_('committing subrepository %s\n') % subrepo.subrelpath(sub)) - sr = sub.commit(cctx._text, user, date) + sr = sub.commit(cctx.description(), user, date) newstate[s] = (newstate[s][0], sr) subrepo.writestate(self, newstate) # Save commit message in case this transaction gets rolled back # (e.g. by a pretxncommit hook). Leave the content alone on # the assumption that the user will use the same editor again. - msgfn = self.savecommitmessage(cctx._text) + msgfn = self.savecommitmessage(cctx.description()) p1, p2 = self.dirstate.parents() hookp1, hookp2 = hex(p1), (p2 != nullid and hex(p2) or '') From dschleimer at fb.com Sun Feb 10 17:30:00 2013 From: dschleimer at fb.com (David Schleimer) Date: Sun, 10 Feb 2013 15:30:00 -0800 Subject: [PATCH 10 of 19] commit: pull substate writing into workingctx In-Reply-To: <07bdd03d86dcce1558d7.1360538991@dev010.prn1.facebook.com> References: <07bdd03d86dcce1558d7.1360538991@dev010.prn1.facebook.com> Message-ID: # HG changeset patch # User David Schleimer # Date 1360330572 28800 # Node ID b26b1130ee3a34fe74a6302a3b08bbfd446c975b # Parent 84e89fe78426b02aeb09add9a63a04e1e7459ec0 commit: pull substate writing into workingctx This pulls the logic for committing dirty subrepos and writing out the substate during localrepo.commit() into the workging context. This is part of a larger refactoring effort to unify working-copy commits and in-memory commits. Among other things, this will allow for optimizations in graft, rebase, and similar commands. diff --git a/mercurial/context.py b/mercurial/context.py --- a/mercurial/context.py +++ b/mercurial/context.py @@ -1199,6 +1199,15 @@ return subs, commitsubs, newstate + def commitsubstate(self, commitsubs, newstate): + for s in sorted(commitsubs): + sub = self.sub(s) + self._repo.ui.status(_('committing subrepository %s\n') % + subrepo.subrelpath(sub)) + sr = sub.commit(self.description(), self._user, self._date) + newstate[s] = (newstate[s][0], sr) + subrepo.writestate(self._repo, newstate) + def markcommitted(self, node): """Perform post-commit cleanup necessary after commiting this workingctx diff --git a/mercurial/localrepo.py b/mercurial/localrepo.py --- a/mercurial/localrepo.py +++ b/mercurial/localrepo.py @@ -1167,7 +1167,6 @@ subs, commitsubs, newstate = wctx.commitablesubstate(match, force) - if subs: if (not match('.hgsub') and '.hgsub' in (wctx.modified() + wctx.added())): @@ -1221,13 +1220,7 @@ # commit subs and write new state if subs: - for s in sorted(commitsubs): - sub = wctx.sub(s) - self.ui.status(_('committing subrepository %s\n') % - subrepo.subrelpath(sub)) - sr = sub.commit(cctx.description(), user, date) - newstate[s] = (newstate[s][0], sr) - subrepo.writestate(self, newstate) + cctx.commitsubstate(commitsubs, newstate) # Save commit message in case this transaction gets rolled back # (e.g. by a pretxncommit hook). Leave the content alone on From dschleimer at fb.com Sun Feb 10 17:29:59 2013 From: dschleimer at fb.com (David Schleimer) Date: Sun, 10 Feb 2013 15:29:59 -0800 Subject: [PATCH 09 of 19] commit: refactor subrepo state building into working context In-Reply-To: <07bdd03d86dcce1558d7.1360538991@dev010.prn1.facebook.com> References: <07bdd03d86dcce1558d7.1360538991@dev010.prn1.facebook.com> Message-ID: <84e89fe78426b02aeb09.1360538999@dev010.prn1.facebook.com> # HG changeset patch # User David Schleimer # Date 1360330572 28800 # Node ID 84e89fe78426b02aeb09add9a63a04e1e7459ec0 # Parent 62d93c48151c79f5e08c3e22b79e52052283ce66 commit: refactor subrepo state building into working context This moves the logic for building a new substate into the working context. In particular, this is the logic that decides which subrepos need to be committed before the main commit can proceed, validates that we aren't about to commit without including a modified subrepo, figures out whether we need to write out a new substate, and builds said new substate. This is part of a larger refactoring effort that moves logic into the working context. The long-term goal of that refactoring is to unify how we commit from the working copy and from memory. Among other things, this will support optimizations in graft, rebase, and similar commands. diff --git a/mercurial/context.py b/mercurial/context.py --- a/mercurial/context.py +++ b/mercurial/context.py @@ -1162,6 +1162,44 @@ finally: wlock.release() + def commitablesubstate(self, match, force): + subs = [] + commitsubs = set() + newstate = self.substate.copy() + oldstate = self.p1().substate + + # compare current state to last committed state + # build new substate based on last committed state + for s in sorted(newstate.keys()): + if not match(s): + # ignore working copy, use old state if present + if s in oldstate: + newstate[s] = oldstate[s] + continue + if not force: + raise util.Abort( + _("commit with new subrepo %s excluded") % s) + if self.sub(s).dirty(True): + if not self._repo.ui.configbool('ui', 'commitsubrepos'): + raise util.Abort( + _("uncommitted changes in subrepo %s") % s, + hint=_("use --subrepos for recursive commit")) + subs.append(s) + commitsubs.add(s) + else: + bs = self.sub(s).basestate() + newstate[s] = (newstate[s][0], bs, newstate[s][2]) + if oldstate.get(s, (None, None, None))[1] != bs: + subs.append(s) + + # check for removed subrepos + for p in self.parents(): + r = [s for s in p.substate if s not in newstate] + subs += [s for s in r if match(s)] + + return subs, commitsubs, newstate + + def markcommitted(self, node): """Perform post-commit cleanup necessary after commiting this workingctx diff --git a/mercurial/localrepo.py b/mercurial/localrepo.py --- a/mercurial/localrepo.py +++ b/mercurial/localrepo.py @@ -1155,10 +1155,8 @@ if force: changes[0].extend(changes[6]) # mq may commit unchanged files + subs = [] # check subrepos - subs = [] - commitsubs = set() - newstate = wctx.substate.copy() # only manage subrepos and .hgsubstate if .hgsub is present if '.hgsub' in wctx: # we'll decide whether to track this ourselves, thanks @@ -1167,35 +1165,9 @@ if '.hgsubstate' in changes[2]: changes[2].remove('.hgsubstate') - # compare current state to last committed state - # build new substate based on last committed state - oldstate = wctx.p1().substate - for s in sorted(newstate.keys()): - if not match(s): - # ignore working copy, use old state if present - if s in oldstate: - newstate[s] = oldstate[s] - continue - if not force: - raise util.Abort( - _("commit with new subrepo %s excluded") % s) - if wctx.sub(s).dirty(True): - if not self.ui.configbool('ui', 'commitsubrepos'): - raise util.Abort( - _("uncommitted changes in subrepo %s") % s, - hint=_("use --subrepos for recursive commit")) - subs.append(s) - commitsubs.add(s) - else: - bs = wctx.sub(s).basestate() - newstate[s] = (newstate[s][0], bs, newstate[s][2]) - if oldstate.get(s, (None, None, None))[1] != bs: - subs.append(s) + subs, commitsubs, newstate = wctx.commitablesubstate(match, + force) - # check for removed subrepos - for p in wctx.parents(): - r = [s for s in p.substate if s not in newstate] - subs += [s for s in r if match(s)] if subs: if (not match('.hgsub') and '.hgsub' in (wctx.modified() + wctx.added())): From dschleimer at fb.com Sun Feb 10 17:30:02 2013 From: dschleimer at fb.com (David Schleimer) Date: Sun, 10 Feb 2013 15:30:02 -0800 Subject: [PATCH 12 of 19] localrepo: don't use raw context when checking for an empty commit In-Reply-To: <07bdd03d86dcce1558d7.1360538991@dev010.prn1.facebook.com> References: <07bdd03d86dcce1558d7.1360538991@dev010.prn1.facebook.com> Message-ID: # HG changeset patch # User David Schleimer # Date 1360330572 28800 # Node ID cb00b77bc8e24c68b5b4df5e484f7c005f12d2d1 # Parent 272e90e44133f13219edd88cf9d3ecbb87886563 localrepo: don't use raw context when checking for an empty commit This switches one of the cases in the if statement checking for empty commits to use the commitable context instead of the raw working context. The point of this change is that there is now a clear distinction between the part of localrepo.commit() where we are operating on the raw context and the part where we are operating on the commitable context. This is turn will make it proactical for future patches to split up the function. This is part of a larger refactoring effort to make memctx more useful, and make it easier to smoothly commit in memory. diff --git a/mercurial/localrepo.py b/mercurial/localrepo.py --- a/mercurial/localrepo.py +++ b/mercurial/localrepo.py @@ -1204,7 +1204,7 @@ if (not force and not extra.get("close") and not merge and not cctx.files() - and wctx.branch() == wctx.p1().branch()): + and cctx.branch() == cctx.p1().branch()): return None if merge and cctx.deleted(): From dschleimer at fb.com Sun Feb 10 17:30:03 2013 From: dschleimer at fb.com (David Schleimer) Date: Sun, 10 Feb 2013 15:30:03 -0800 Subject: [PATCH 13 of 19] context: separateworkingctx stats and raw status In-Reply-To: <07bdd03d86dcce1558d7.1360538991@dev010.prn1.facebook.com> References: <07bdd03d86dcce1558d7.1360538991@dev010.prn1.facebook.com> Message-ID: <1bae6048dd1028bb6b75.1360539003@dev010.prn1.facebook.com> # HG changeset patch # User David Schleimer # Date 1360413190 28800 # Node ID 1bae6048dd1028bb6b7506ec1ecb73bd819e7449 # Parent cb00b77bc8e24c68b5b4df5e484f7c005f12d2d1 context: separateworkingctx stats and raw status Split the workingctx _status property cache into _status, which is possibly filtered, and _rawstatus which is never filtered. By default, _status proxies to _rawstatus, and then replaces itself with the results. Calling status() will update the _status property. Subsequent changes will change status() to sometimes result in filtered changes getting written to _status. the point of this change is to make sure the workingctx will have access to the unfiltered status. diff --git a/mercurial/context.py b/mercurial/context.py --- a/mercurial/context.py +++ b/mercurial/context.py @@ -919,6 +919,11 @@ @propertycache def _status(self): + '''A (possibly) filtered view of the status this context represents''' + return self._rawstatus() + + def _rawstatus(self): + '''an unfiltered view of the status the context represents''' return self._repo.status()[:4] @propertycache From dschleimer at fb.com Sun Feb 10 17:30:04 2013 From: dschleimer at fb.com (David Schleimer) Date: Sun, 10 Feb 2013 15:30:04 -0800 Subject: [PATCH 14 of 19] context: support matches in workingctx.status In-Reply-To: <07bdd03d86dcce1558d7.1360538991@dev010.prn1.facebook.com> References: <07bdd03d86dcce1558d7.1360538991@dev010.prn1.facebook.com> Message-ID: <730f81cd4b340348dfc5.1360539004@dev010.prn1.facebook.com> # HG changeset patch # User David Schleimer # Date 1360424562 28800 # Node ID 730f81cd4b340348dfc5d2eb571f3b13e01c73e4 # Parent 1bae6048dd1028bb6b7506ec1ecb73bd819e7449 context: support matches in workingctx.status This makes it possible to get a filtered view of the workingcopy via workingctx.status(). This is currently unused, but subsequent patches will use this to pull validation steps out of localrepo.commit and into the workingctx. This in turn will make it practical to unify workingctx and memctx, making memctx more useful. diff --git a/mercurial/context.py b/mercurial/context.py --- a/mercurial/context.py +++ b/mercurial/context.py @@ -941,12 +941,15 @@ p = p[:-1] return [changectx(self._repo, x) for x in p] - def status(self, ignored=False, clean=False, unknown=False): + def status(self, ignored=False, clean=False, unknown=False, match=None): """Explicit status query Unless this method is used to query the working copy status, the _status property will implicitly read the status using its default arguments.""" - stat = self._repo.status(ignored=ignored, clean=clean, unknown=unknown) + stat = self._repo.status(ignored=ignored, + clean=clean, + unknown=unknown, + match=match) self._unknown = self._ignored = self._clean = None if unknown: self._unknown = stat[4] From dschleimer at fb.com Sun Feb 10 17:30:06 2013 From: dschleimer at fb.com (David Schleimer) Date: Sun, 10 Feb 2013 15:30:06 -0800 Subject: [PATCH 16 of 19] localrepo: use workingcontext members instead of changes array during commit In-Reply-To: <07bdd03d86dcce1558d7.1360538991@dev010.prn1.facebook.com> References: <07bdd03d86dcce1558d7.1360538991@dev010.prn1.facebook.com> Message-ID: <486ffe802a0386d1aafa.1360539006@dev010.prn1.facebook.com> # HG changeset patch # User David Schleimer # Date 1360512756 28800 # Node ID 486ffe802a0386d1aafa666d67363e937756e1e7 # Parent d45c2924e79b417059dfc166e2364e85d4fd09a7 localrepo: use workingcontext members instead of changes array during commit This changes localrepo.commit from building an array of changes, and constructing a new workingcontext from that array to constructiong a workingcotext, calling it's status method to fill in it's lists of changes, and hten munging those lists. this is preperatory to moving the actual munging logic into workingcontext. I also believe this diff is a readability improvement, since it uses named methods rather than integer list indeces to access the various file lists. The long-term point of this is to move commit logic out of localrepo and into workgincontext, so that other code can extend workingcontext and have access to that logic. diff --git a/mercurial/localrepo.py b/mercurial/localrepo.py --- a/mercurial/localrepo.py +++ b/mercurial/localrepo.py @@ -1151,19 +1151,20 @@ raise util.Abort(_('cannot partially commit a merge ' '(do not specify files or patterns)')) - changes = self.status(match=match, clean=force) + wctx.status(match=match, clean=force) if force: - changes[0].extend(changes[6]) # mq may commit unchanged files + # mq may commit unchanged files + wctx.modified().extend(wctx.clean()) subs = [] # check subrepos # only manage subrepos and .hgsubstate if .hgsub is present if '.hgsub' in wctx: # we'll decide whether to track this ourselves, thanks - if '.hgsubstate' in changes[0]: - changes[0].remove('.hgsubstate') - if '.hgsubstate' in changes[2]: - changes[2].remove('.hgsubstate') + if '.hgsubstate' in wctx.modified(): + wctx.modified().remove('.hgsubstate') + if '.hgsubstate' in wctx.removed(): + wctx.removed().remove('.hgsubstate') subs, commitsubs, newstate = wctx.commitablesubstate(match, force) @@ -1174,23 +1175,23 @@ '.hgsub' in (rawchanges[0] + rawchanges[1])): raise util.Abort( _("can't commit subrepos without .hgsub")) - changes[0].insert(0, '.hgsubstate') + wctx.modified().insert(0, '.hgsubstate') - elif '.hgsub' in changes[2]: + elif '.hgsub' in wctx.removed(): # clean up .hgsubstate when .hgsub is removed if ('.hgsubstate' in wctx and - '.hgsubstate' not in changes[0] + changes[1] + changes[2]): - changes[2].insert(0, '.hgsubstate') + '.hgsubstate' not in wctx.files()): + wctx.removed().insert(0, '.hgsubstate') # make sure all explicit patterns are matched if not force and match.files(): - matched = set(changes[0] + changes[1] + changes[2]) + matched = set(wctx.files()) for f in match.files(): f = self.dirstate.normalize(f) if f == '.' or f in matched or f in wctx.substate: continue - if f in changes[3]: # missing + if f in wctx.deleted(): # missing fail(f, _('file not found!')) if f in vdirs: # visited directory d = f + '/' @@ -1202,7 +1203,7 @@ elif f not in self.dirstate: fail(f, _("file not tracked!")) - cctx = context.workingctx(self, changes=changes) + cctx = wctx if (not force and not extra.get("close") and not merge and not cctx.files() From dschleimer at fb.com Sun Feb 10 17:30:05 2013 From: dschleimer at fb.com (David Schleimer) Date: Sun, 10 Feb 2013 15:30:05 -0800 Subject: [PATCH 15 of 19] commit: use workingctx._rawstatus for subrepo-realted commit validation In-Reply-To: <07bdd03d86dcce1558d7.1360538991@dev010.prn1.facebook.com> References: <07bdd03d86dcce1558d7.1360538991@dev010.prn1.facebook.com> Message-ID: # HG changeset patch # User David Schleimer # Date 1360511456 28800 # Node ID d45c2924e79b417059dfc166e2364e85d4fd09a7 # Parent 730f81cd4b340348dfc5d2eb571f3b13e01c73e4 commit: use workingctx._rawstatus for subrepo-realted commit validation This changes a little bit of the validation we do during the commit process to use workingctx._rawstatus to check for a .hgsub that has been modified but not matched. This is preparatory to moving the validation logic into workingctx with the intention of making that logic more accessible. diff --git a/mercurial/localrepo.py b/mercurial/localrepo.py --- a/mercurial/localrepo.py +++ b/mercurial/localrepo.py @@ -1168,8 +1168,10 @@ subs, commitsubs, newstate = wctx.commitablesubstate(match, force) if subs: + rawchanges = wctx._rawstatus() if (not match('.hgsub') and - '.hgsub' in (wctx.modified() + wctx.added())): + # 0 = modified, 1 = added + '.hgsub' in (rawchanges[0] + rawchanges[1])): raise util.Abort( _("can't commit subrepos without .hgsub")) changes[0].insert(0, '.hgsubstate') From dschleimer at fb.com Sun Feb 10 17:30:07 2013 From: dschleimer at fb.com (David Schleimer) Date: Sun, 10 Feb 2013 15:30:07 -0800 Subject: [PATCH 17 of 19] commit: move commit subrepo preparation fully into workingctx In-Reply-To: <07bdd03d86dcce1558d7.1360538991@dev010.prn1.facebook.com> References: <07bdd03d86dcce1558d7.1360538991@dev010.prn1.facebook.com> Message-ID: <06702855099328ba716c.1360539007@dev010.prn1.facebook.com> # HG changeset patch # User David Schleimer # Date 1360518119 28800 # Node ID 06702855099328ba716cd3096706357b379f6b50 # Parent 486ffe802a0386d1aafa666d67363e937756e1e7 commit: move commit subrepo preparation fully into workingctx This moves the last of ht elogic for munging changes related to subrepos during the commit process out of localrepo.commit and into workingcontext. This should hopefully make it easier for other code to access. In particular, it should make it possible for other code to subclass workingcontext and perform commits using this logic. the long-term plan is to have memctx soubclass workingctx to take advantage of this. diff --git a/mercurial/context.py b/mercurial/context.py --- a/mercurial/context.py +++ b/mercurial/context.py @@ -828,6 +828,8 @@ self._ms = None self._unresolved = None + self._commitsubs = [] + self._extra = {} self.setextra(extra) @@ -1170,6 +1172,47 @@ finally: wlock.release() + def preparesubstate(self, match, force): + """Prepare the substate in this workingcontext for commit. + + Specifically, this builds the substate info needed to commit + subrepos, and makes sure that the match object matches the + subrepo state files if subrepos are in use. + + It also attaches the information needed to later commit + subrepos via commitsubstate to this workingctx. + + Returns a list of subrepos included in the commit + """ + # check subrepos + # only manage subrepos and .hgsubstate if .hgsub is present + subs = [] + if '.hgsub' in self: + # we'll decide whether to track this ourselves, thanks + if '.hgsubstate' in self.modified(): + self.modified().remove('.hgsubstate') + if '.hgsubstate' in self.removed(): + self.removed().remove('.hgsubstate') + + commitable = self.commitablesubstate(match, force) + subs, self._commitsubs, self.substate = commitable + if subs: + rawchanges = self._rawstatus() + if (not match('.hgsub') and + # 0 = modified, 1 = added + '.hgsub' in (rawchanges[0] + rawchanges[1])): + raise util.Abort( + _("can't commit subrepos without .hgsub")) + self.modified().insert(0, '.hgsubstate') + + elif '.hgsub' in self.removed(): + # clean up .hgsubstate when .hgsub is removed + if ('.hgsubstate' in self and + '.hgsubstate' not in self.files()): + self.removed().insert(0, '.hgsubstate') + + return subs + def commitablesubstate(self, match, force): subs = [] commitsubs = set() @@ -1207,14 +1250,14 @@ return subs, commitsubs, newstate - def commitsubstate(self, commitsubs, newstate): - for s in sorted(commitsubs): + def commitsubstate(self): + for s in sorted(self._commitsubs): sub = self.sub(s) self._repo.ui.status(_('committing subrepository %s\n') % subrepo.subrelpath(sub)) sr = sub.commit(self.description(), self._user, self._date) - newstate[s] = (newstate[s][0], sr) - subrepo.writestate(self._repo, newstate) + self.substate[s] = (self.substate[s][0], sr) + subrepo.writestate(self._repo, self.substate) def markcommitted(self, node): diff --git a/mercurial/localrepo.py b/mercurial/localrepo.py --- a/mercurial/localrepo.py +++ b/mercurial/localrepo.py @@ -1156,32 +1156,7 @@ # mq may commit unchanged files wctx.modified().extend(wctx.clean()) - subs = [] - # check subrepos - # only manage subrepos and .hgsubstate if .hgsub is present - if '.hgsub' in wctx: - # we'll decide whether to track this ourselves, thanks - if '.hgsubstate' in wctx.modified(): - wctx.modified().remove('.hgsubstate') - if '.hgsubstate' in wctx.removed(): - wctx.removed().remove('.hgsubstate') - - subs, commitsubs, newstate = wctx.commitablesubstate(match, - force) - if subs: - rawchanges = wctx._rawstatus() - if (not match('.hgsub') and - # 0 = modified, 1 = added - '.hgsub' in (rawchanges[0] + rawchanges[1])): - raise util.Abort( - _("can't commit subrepos without .hgsub")) - wctx.modified().insert(0, '.hgsubstate') - - elif '.hgsub' in wctx.removed(): - # clean up .hgsubstate when .hgsub is removed - if ('.hgsubstate' in wctx and - '.hgsubstate' not in wctx.files()): - wctx.removed().insert(0, '.hgsubstate') + subs = wctx.preparesubstate(match, force) # make sure all explicit patterns are matched if not force and match.files(): @@ -1228,7 +1203,7 @@ # commit subs and write new state if subs: - cctx.commitsubstate(commitsubs, newstate) + cctx.commitsubstate() # Save commit message in case this transaction gets rolled back # (e.g. by a pretxncommit hook). Leave the content alone on From dschleimer at fb.com Sun Feb 10 17:30:08 2013 From: dschleimer at fb.com (David Schleimer) Date: Sun, 10 Feb 2013 15:30:08 -0800 Subject: [PATCH 18 of 19] commit: move commit preparation from localrepo.commit to workingctx In-Reply-To: <07bdd03d86dcce1558d7.1360538991@dev010.prn1.facebook.com> References: <07bdd03d86dcce1558d7.1360538991@dev010.prn1.facebook.com> Message-ID: <7a150f3cfd3ea54a11db.1360539008@dev010.prn1.facebook.com> # HG changeset patch # User David Schleimer # Date 1360534411 28800 # Node ID 7a150f3cfd3ea54a11dbe5754671d3e82420d40b # Parent 06702855099328ba716cd3096706357b379f6b50 commit: move commit preparation from localrepo.commit to workingctx This moves the logic for change filtering, subrepo munging, and subrepo-related validation out of localrepo and into workingcontext. The long-term goal is to make this logic more accessible to other code. diff --git a/mercurial/context.py b/mercurial/context.py --- a/mercurial/context.py +++ b/mercurial/context.py @@ -1213,6 +1213,60 @@ return subs + def preparecommit(self, match, force): + """Prepare this workingcontext for commit. + + Includes validation, subrepo state munging, and change + filtering. + """ + merge = len(self.parents()) > 1 + + def fail(f, msg): + raise util.Abort('%s: %s' % (f, msg)) + + if not match: + match = matchmod.always(self._repo.root, '') + + if not force: + vdirs = [] + match.dir = vdirs.append + match.bad = fail + + if (not force and merge and match and + (match.files() or match.anypats())): + raise util.Abort(_('cannot partially commit a merge ' + '(do not specify files or patterns)')) + + self.status(match=match, clean=force) + + if force: + # mq may commit unchanged files + self.modified().extend(self.clean()) + + subs = self.preparesubstate(match, force) + + # make sure all explicit patterns are matched + if not force and match.files(): + matched = set(self.files()) + + for f in match.files(): + f = self._repo.dirstate.normalize(f) + if f == '.' or f in matched or f in self.substate: + continue + if f in self.deleted(): # missing + fail(f, _('file not found!')) + if f in vdirs: # visited directory + d = f + '/' + for mf in matched: + if mf.startswith(d): + break + else: + fail(f, _("no match under directory!")) + elif f not in self._repo.dirstate: + fail(f, _("file not tracked!")) + + return subs + def commitablesubstate(self, match, force): subs = [] commitsubs = set() diff --git a/mercurial/localrepo.py b/mercurial/localrepo.py --- a/mercurial/localrepo.py +++ b/mercurial/localrepo.py @@ -1130,54 +1130,12 @@ supplied, it is called to get a commit message. """ - def fail(f, msg): - raise util.Abort('%s: %s' % (f, msg)) - - if not match: - match = matchmod.always(self.root, '') - - if not force: - vdirs = [] - match.dir = vdirs.append - match.bad = fail - wlock = self.wlock() try: wctx = self[None] merge = len(wctx.parents()) > 1 - if (not force and merge and match and - (match.files() or match.anypats())): - raise util.Abort(_('cannot partially commit a merge ' - '(do not specify files or patterns)')) - - wctx.status(match=match, clean=force) - if force: - # mq may commit unchanged files - wctx.modified().extend(wctx.clean()) - - subs = wctx.preparesubstate(match, force) - - # make sure all explicit patterns are matched - if not force and match.files(): - matched = set(wctx.files()) - - for f in match.files(): - f = self.dirstate.normalize(f) - if f == '.' or f in matched or f in wctx.substate: - continue - if f in wctx.deleted(): # missing - fail(f, _('file not found!')) - if f in vdirs: # visited directory - d = f + '/' - for mf in matched: - if mf.startswith(d): - break - else: - fail(f, _("no match under directory!")) - elif f not in self.dirstate: - fail(f, _("file not tracked!")) - + subs = wctx.preparecommit(match, force) cctx = wctx if (not force and not extra.get("close") and not merge From dschleimer at fb.com Sun Feb 10 17:30:09 2013 From: dschleimer at fb.com (David Schleimer) Date: Sun, 10 Feb 2013 15:30:09 -0800 Subject: [PATCH 19 of 19] commit: get rid of no-longer needed variable in localrepo.commit In-Reply-To: <07bdd03d86dcce1558d7.1360538991@dev010.prn1.facebook.com> References: <07bdd03d86dcce1558d7.1360538991@dev010.prn1.facebook.com> Message-ID: # HG changeset patch # User David Schleimer # Date 1360536813 28800 # Node ID ec28a1ffc921ff4f156152d9ba0960d912d8ebb2 # Parent 7a150f3cfd3ea54a11dbe5754671d3e82420d40b commit: get rid of no-longer needed variable in localrepo.commit Since we moved to modifying a single workingcontext instead of creating a new one with munged changes, we now have an extra variable in localrepo.commit. This diff cleans it up. diff --git a/mercurial/localrepo.py b/mercurial/localrepo.py --- a/mercurial/localrepo.py +++ b/mercurial/localrepo.py @@ -1136,44 +1136,43 @@ merge = len(wctx.parents()) > 1 subs = wctx.preparecommit(match, force) - cctx = wctx if (not force and not extra.get("close") and not merge - and not cctx.files() - and cctx.branch() == cctx.p1().branch()): + and not wctx.files() + and wctx.branch() == wctx.p1().branch()): return None - if merge and cctx.deleted(): + if merge and wctx.deleted(): raise util.Abort(_("cannot commit merge with missing files")) - if cctx.unresolved(): + if wctx.unresolved(): raise util.Abort(_("unresolved merge conflicts " "(see hg help resolve)")) - cctx.setuser(user) - cctx.setdate(date) - cctx.setextra(extra) + wctx.setuser(user) + wctx.setdate(date) + wctx.setextra(extra) - cctx.setdescription(text) + wctx.setdescription(text) if editor: - cctx.setdescription(editor(self, cctx, subs)) - edited = (text != cctx.description()) + wctx.setdescription(editor(self, wctx, subs)) + edited = (text != wctx.description()) # commit subs and write new state if subs: - cctx.commitsubstate() + wctx.commitsubstate() # Save commit message in case this transaction gets rolled back # (e.g. by a pretxncommit hook). Leave the content alone on # the assumption that the user will use the same editor again. - msgfn = self.savecommitmessage(cctx.description()) + msgfn = self.savecommitmessage(wctx.description()) p1, p2 = self.dirstate.parents() hookp1, hookp2 = hex(p1), (p2 != nullid and hex(p2) or '') try: self.hook("precommit", throw=True, parent1=hookp1, parent2=hookp2) - ret = self.commitctx(cctx, True) + ret = self.commitctx(wctx, True) except: # re-raises if edited: self.ui.write( @@ -1182,7 +1181,7 @@ # update bookmarks, dirstate and mergestate bookmarks.update(self, [p1, p2], ret) - cctx.markcommitted(ret) + wctx.markcommitted(ret) finally: wlock.release() From dschleimer at fb.com Sun Feb 10 17:30:01 2013 From: dschleimer at fb.com (David Schleimer) Date: Sun, 10 Feb 2013 15:30:01 -0800 Subject: [PATCH 11 of 19] localrepo: use setters instead of constructor for commit metadata In-Reply-To: <07bdd03d86dcce1558d7.1360538991@dev010.prn1.facebook.com> References: <07bdd03d86dcce1558d7.1360538991@dev010.prn1.facebook.com> Message-ID: <272e90e44133f13219ed.1360539001@dev010.prn1.facebook.com> # HG changeset patch # User David Schleimer # Date 1360330572 28800 # Node ID 272e90e44133f13219edd88cf9d3ecbb87886563 # Parent b26b1130ee3a34fe74a6302a3b08bbfd446c975b localrepo: use setters instead of constructor for commit metadata Instead of including the commit metadata in the constructor for the context actually used for commit, we later use setters to update the context with that metadata. This will allow us to use the commitable context for another sanity checks, and will make it easier to split the logic in localrepo.commit() into multiple functions. This is part of a larger refactoring effort to make memctx easier to use. diff --git a/mercurial/localrepo.py b/mercurial/localrepo.py --- a/mercurial/localrepo.py +++ b/mercurial/localrepo.py @@ -1200,7 +1200,7 @@ elif f not in self.dirstate: fail(f, _("file not tracked!")) - cctx = context.workingctx(self, text, user, date, extra, changes) + cctx = context.workingctx(self, changes=changes) if (not force and not extra.get("close") and not merge and not cctx.files() @@ -1214,6 +1214,11 @@ raise util.Abort(_("unresolved merge conflicts " "(see hg help resolve)")) + cctx.setuser(user) + cctx.setdate(date) + cctx.setextra(extra) + + cctx.setdescription(text) if editor: cctx.setdescription(editor(self, cctx, subs)) edited = (text != cctx.description()) From dschleimer at fb.com Sun Feb 10 17:29:52 2013 From: dschleimer at fb.com (David Schleimer) Date: Sun, 10 Feb 2013 15:29:52 -0800 Subject: [PATCH 02 of 19] localrepo: use workingctx for validation in commit In-Reply-To: <07bdd03d86dcce1558d7.1360538991@dev010.prn1.facebook.com> References: <07bdd03d86dcce1558d7.1360538991@dev010.prn1.facebook.com> Message-ID: # HG changeset patch # User David Schleimer # Date 1360330568 28800 # Node ID e13d648bab573f580b7c160c61985bd0cbb66364 # Parent 07bdd03d86dcce1558d793c29c062e05e5cf02da localrepo: use workingctx for validation in commit This changes localrepo.commit to use the workingctx it creates form the munged output of localrepo.status while running some precommit validation. Specifically, it uses functions that were already present on the workingctx. I believe this is a net readabilty improvement, and that this makes these lines consistent with the refactoring in a subsequent patch that pulls some of the validation logic into workingctx so that it can be reused elsewhere. diff --git a/mercurial/localrepo.py b/mercurial/localrepo.py --- a/mercurial/localrepo.py +++ b/mercurial/localrepo.py @@ -1233,11 +1233,11 @@ cctx = context.workingctx(self, text, user, date, extra, changes) if (not force and not extra.get("close") and not merge - and not (changes[0] or changes[1] or changes[2]) + and not cctx.files() and wctx.branch() == wctx.p1().branch()): return None - if merge and changes[3]: + if merge and cctx.deleted(): raise util.Abort(_("cannot commit merge with missing files")) ms = mergemod.mergestate(self) From mercurial-bugs at selenic.com Sun Feb 10 13:29:57 2013 From: mercurial-bugs at selenic.com (mercurial-bugs at selenic.com) Date: Sun, 10 Feb 2013 19:29:57 +0000 Subject: [Bug 3817] New: divergent bookmarks don't notice when a pull resolves the divergence Message-ID: http://bz.selenic.com/show_bug.cgi?id=3817 Priority: normal Bug ID: 3817 CC: mercurial-devel at selenic.com Assignee: bugzilla at selenic.com Summary: divergent bookmarks don't notice when a pull resolves the divergence Severity: bug Classification: Unclassified OS: All Reporter: durin42 at gmail.com Hardware: PC Status: UNCONFIRMED Version: 2.5.1 Component: Mercurial Product: Mercurial In tonight's hilarious mergestorm, I pulled from mpm while I had one change queued in my @ bookmark. When I pulled from mpm, I got a divergent @mpm mark, and then pulling from crew gave me a divergent @crew. Before I could merge, tonfa pushed a merge to crew, so I pulled again - the @mpm divergent marker stuck around, as a linear ancestor of @crew. -- You are receiving this mail because: You are on the CC list for the bug. From bboissin at gmail.com Sun Feb 10 18:37:56 2013 From: bboissin at gmail.com (Benoit Boissinot) Date: Mon, 11 Feb 2013 01:37:56 +0100 Subject: [PATCH] dirstate: fix generator/list error when using python 2.7 In-Reply-To: <9c384e0ef7f5c860ea77.1360529076@dev350.prn1.facebook.com> References: <9c384e0ef7f5c860ea77.1360529076@dev350.prn1.facebook.com> Message-ID: On Sun, Feb 10, 2013 at 9:44 PM, Durham Goode wrote: > # HG changeset patch > # User Durham Goode > # Date 1360527819 28800 > # Node ID 9c384e0ef7f5c860ea774bbdc5e0c30e3e7421e8 > # Parent 013fcd112f13f31a35ea6a40d8cd1c6923cdaf20 > dirstate: fix generator/list error when using python 2.7 > > util.statfiles returns a generator on python 2.7 with c extensions > disabled. > This caused util.statfiles(...) [0] to break in tests. Since we're only > stat'ing one file, I just changed it to call lstat directly. > > diff --git a/mercurial/dirstate.py b/mercurial/dirstate.py > --- a/mercurial/dirstate.py > +++ b/mercurial/dirstate.py > @@ -687,7 +687,11 @@ > # Report ignored items in the dmap as long as they > are not > # under a symlink directory. > if ignore(nf) and audit_path.check(nf): > - results[nf] = util.statfiles([join(nf)])[0] > + try: > + results[nf] = lstat(join(nf)) > + except OSError: > + # file doesn't exist > If that's what you actually want to catch (like what was done previously), you need to check errno for ENOENT > + results[nf] = None > else: > # It's either missing or under a symlink directory > results[nf] = None > _______________________________________________ > Mercurial-devel mailing list > Mercurial-devel at selenic.com > http://selenic.com/mailman/listinfo/mercurial-devel > -------------- next part -------------- An HTML attachment was scrubbed... URL: From kbullock+mercurial at ringworld.org Sun Feb 10 20:55:18 2013 From: kbullock+mercurial at ringworld.org (Kevin Bullock) Date: Mon, 11 Feb 2013 02:55:18 +0000 Subject: [PATCH 0 of 3] V3 of dirstate.walk patches In-Reply-To: References: Message-ID: On 10 Feb 2013, at 2:42 PM, Durham Goode wrote: > V2 had a chunk in the wrong patch :( Plz to use --flag V3 to flag each patch in the series. pacem in terris / ??? / ?????? / ????????? / ?? Kevin R. Bullock From kbullock+mercurial at ringworld.org Sun Feb 10 21:04:06 2013 From: kbullock+mercurial at ringworld.org (Kevin Bullock) Date: Mon, 11 Feb 2013 03:04:06 +0000 Subject: [PATCH] obsolete: consider successors along with descendants when updating In-Reply-To: <8d89080a98d69606ac26.1360532854@retina-monoteam> References: <8d89080a98d69606ac26.1360532854@retina-monoteam> Message-ID: <410BFEE8-BF1A-46B6-A6E3-8D6D003BBF54@ringworld.org> On 10 Feb 2013, at 9:47 PM, Levi Bard wrote: > # HG changeset patch > # User Levi Bard > # Date 1360532614 -3600 > # Node ID 8d89080a98d69606ac264282e2ba3e33b056bcac > # Parent 013fcd112f13f31a35ea6a40d8cd1c6923cdaf20 > obsolete: consider successors along with descendants when updating > > Currently, if you pull --update a group of changesets that obsoletes > the current changeset, mercurial refuses to update because the pulled tip > is not a descendant. This change causes mercurial to consider successors > as well as descendants when determining whether to update. > > diff -r 013fcd112f13 -r 8d89080a98d6 mercurial/merge.py > --- a/mercurial/merge.py Sat Feb 09 11:00:42 2013 +0100 > +++ b/mercurial/merge.py Sun Feb 10 22:43:34 2013 +0100 > @@ -7,6 +7,7 @@ > > from node import nullid, nullrev, hex, bin > from i18n import _ > +from mercurial import obsolete > import error, util, filemerge, copies, subrepo > import errno, os, shutil > > @@ -632,6 +633,9 @@ > elif not overwrite: > if pa == p1 or pa == p2: # linear > pass # all good > + elif repo.obsstore and \ > + node in obsolete.allsuccessors(repo.obsstore, [p1.node()]): Wrap condition in parens instead of continuing the line with \. > + pa = p1 # allow updating to successors of obsolete nodes Huh, that's really all it takes? pacem in terris / ??? / ?????? / ????????? / ?? Kevin R. Bullock From kbullock+mercurial at ringworld.org Sun Feb 10 21:12:21 2013 From: kbullock+mercurial at ringworld.org (Kevin Bullock) Date: Mon, 11 Feb 2013 03:12:21 +0000 Subject: [PATCH 04 of 19] commit: refactor mergestate management into workingctx In-Reply-To: References: <07bdd03d86dcce1558d7.1360538991@dev010.prn1.facebook.com> Message-ID: <8506E3B5-56B5-4D5D-BCB7-7EC9574059D9@ringworld.org> On 10 Feb 2013, at 11:29 PM, David Schleimer wrote: > # HG changeset patch > # User David Schleimer > # Date 1360330569 28800 > # Node ID f5a6e68310f238e490c6157cf2e4c9725baa1691 > # Parent ae3daa803078b08571d1ad602d5d32c92e15475d > commit: refactor mergestate management into workingctx > > This pulls the logic around validating that there are no unresolved > conflicts at commit time into the workingctx. It also pulls the state > necessary for that detection, and the post-cleanup logic for that > state into the workingcontext object. > > diff --git a/mercurial/context.py b/mercurial/context.py > --- a/mercurial/context.py > +++ b/mercurial/context.py > @@ -10,6 +10,7 @@ > import ancestor, mdiff, error, util, scmutil, subrepo, patch, encoding, phases > import copies > import match as matchmod > +import merge as mergemod > import os, errno, stat > import obsolete as obsmod > import repoview > @@ -816,10 +817,16 @@ > self._unknown = changes[4] > self._ignored = changes[5] > self._clean = changes[6] > + > + self._ms = mergemod.mergestate(self._repo) > + self._unresolved = [f for f in changes[0] > + if f in self._ms and self._ms[f] == 'u'] > else: > self._unknown = None > self._ignored = None > self._clean = None > + self._ms = None > + self._unresolved = None > > self._extra = {} > if extra: > @@ -952,6 +959,11 @@ > if clean: > self._clean = stat[6] > self._status = stat[:4] > + > + self._ms = mergemod.mergestate(self._repo) > + self._unresolved = [f for f in stat[0] > + if f in self._ms and self._ms[f] == 'u'] Non-trivial duplicate code, can a brother get a helper function? pacem in terris / ??? / ?????? / ????????? / ?? Kevin R. Bullock From kbullock+mercurial at ringworld.org Sun Feb 10 21:22:11 2013 From: kbullock+mercurial at ringworld.org (Kevin Bullock) Date: Mon, 11 Feb 2013 03:22:11 +0000 Subject: [PATCH 09 of 19] commit: refactor subrepo state building into working context In-Reply-To: <84e89fe78426b02aeb09.1360538999@dev010.prn1.facebook.com> References: <07bdd03d86dcce1558d7.1360538991@dev010.prn1.facebook.com> <84e89fe78426b02aeb09.1360538999@dev010.prn1.facebook.com> Message-ID: On 10 Feb 2013, at 11:29 PM, David Schleimer wrote: > # HG changeset patch > # User David Schleimer > # Date 1360330572 28800 > # Node ID 84e89fe78426b02aeb09add9a63a04e1e7459ec0 > # Parent 62d93c48151c79f5e08c3e22b79e52052283ce66 > commit: refactor subrepo state building into working context > > This moves the logic for building a new substate into the working > context. In particular, this is the logic that decides which subrepos > need to be committed before the main commit can proceed, validates > that we aren't about to commit without including a modified subrepo, > figures out whether we need to write out a new substate, and builds > said new substate. > > This is part of a larger refactoring effort that moves logic into the > working context. The long-term goal of that refactoring is to unify > how we commit from the working copy and from memory. Among other > things, this will support optimizations in graft, rebase, and similar > commands. > > diff --git a/mercurial/context.py b/mercurial/context.py > --- a/mercurial/context.py > +++ b/mercurial/context.py > @@ -1162,6 +1162,44 @@ > finally: > wlock.release() > > + def commitablesubstate(self, match, force): > + subs = [] > + commitsubs = set() > + newstate = self.substate.copy() > + oldstate = self.p1().substate > + > + # compare current state to last committed state > + # build new substate based on last committed state Not sure if method does what it says on the tin. Maybe this is a good time to pull this comment up into a docstring describing this blob of code? > diff --git a/mercurial/localrepo.py b/mercurial/localrepo.py > --- a/mercurial/localrepo.py > +++ b/mercurial/localrepo.py > @@ -1155,10 +1155,8 @@ > if force: > changes[0].extend(changes[6]) # mq may commit unchanged files > > + subs = [] > # check subrepos > - subs = [] WAT pacem in terris / ??? / ?????? / ????????? / ?? Kevin R. Bullock From kbullock+mercurial at ringworld.org Sun Feb 10 21:23:29 2013 From: kbullock+mercurial at ringworld.org (Kevin Bullock) Date: Mon, 11 Feb 2013 03:23:29 +0000 Subject: [PATCH 10 of 19] commit: pull substate writing into workingctx In-Reply-To: References: <07bdd03d86dcce1558d7.1360538991@dev010.prn1.facebook.com> Message-ID: <5B8DE2B6-F264-4964-8272-0CBC94C3BE7D@ringworld.org> On 10 Feb 2013, at 11:30 PM, David Schleimer wrote: > # HG changeset patch > # User David Schleimer > # Date 1360330572 28800 > # Node ID b26b1130ee3a34fe74a6302a3b08bbfd446c975b > # Parent 84e89fe78426b02aeb09add9a63a04e1e7459ec0 > commit: pull substate writing into workingctx > > [...] > diff --git a/mercurial/localrepo.py b/mercurial/localrepo.py > --- a/mercurial/localrepo.py > +++ b/mercurial/localrepo.py > @@ -1167,7 +1167,6 @@ > > subs, commitsubs, newstate = wctx.commitablesubstate(match, > force) > - Bzzzzt, unrelated whitespace. pacem in terris / ??? / ?????? / ????????? / ?? Kevin R. Bullock From kbullock+mercurial at ringworld.org Sun Feb 10 21:28:20 2013 From: kbullock+mercurial at ringworld.org (Kevin Bullock) Date: Mon, 11 Feb 2013 03:28:20 +0000 Subject: [PATCH 13 of 19] context: separateworkingctx stats and raw status In-Reply-To: <1bae6048dd1028bb6b75.1360539003@dev010.prn1.facebook.com> References: <07bdd03d86dcce1558d7.1360538991@dev010.prn1.facebook.com> <1bae6048dd1028bb6b75.1360539003@dev010.prn1.facebook.com> Message-ID: <24D36E1F-344E-4B29-BD9C-475A81DE4E85@ringworld.org> On 10 Feb 2013, at 11:30 PM, David Schleimer wrote: > # HG changeset patch > # User David Schleimer > # Date 1360413190 28800 > # Node ID 1bae6048dd1028bb6b7506ec1ecb73bd819e7449 > # Parent cb00b77bc8e24c68b5b4df5e484f7c005f12d2d1 > context: separateworkingctx stats and raw status > > Split the workingctx _status property cache into _status, which is > possibly filtered, and _rawstatus which is never filtered. By > default, _status proxies to _rawstatus, and then replaces itself with > the results. Calling status() will update the _status property. > Subsequent changes will change status() to sometimes result in > filtered changes getting written to _status. the point of this change > is to make sure the workingctx will have access to the unfiltered > status. "Filtered" and "unfiltered" are terms that are throwing me off in this context, because we use those terms for the repo and changelog already. Can we be more explicit about how we're describing the new function? pacem in terris / ??? / ?????? / ????????? / ?? Kevin R. Bullock From dschleimer at fb.com Mon Feb 11 05:40:35 2013 From: dschleimer at fb.com (David Schleimer) Date: Mon, 11 Feb 2013 11:40:35 +0000 Subject: [PATCH 04 of 19] commit: refactor mergestate management into workingctx In-Reply-To: <8506E3B5-56B5-4D5D-BCB7-7EC9574059D9@ringworld.org> References: <07bdd03d86dcce1558d7.1360538991@dev010.prn1.facebook.com> <8506E3B5-56B5-4D5D-BCB7-7EC9574059D9@ringworld.org> Message-ID: > Non-trivial duplicate code, can a brother get a helper function? Done, but I'm going to hold off on resending this giant series until I can get some more feedback, in an effort to avoid blowing up Matt's inbox too much. --David From hg at intevation.org Mon Feb 11 06:00:10 2013 From: hg at intevation.org (Mercurial Commits) Date: Mon, 11 Feb 2013 13:00:10 +0100 Subject: mercurial/crew@18656: 27 outgoing changesets Message-ID: <1360584010.428745.31691.nullmailer@hg.intevation.org> 27 outgoing changesets in mercurial/crew: http://hg.intevation.org/mercurial/crew/rev/8eb3408bf005 changeset: 18656:8eb3408bf005 bookmark: @ tag: tip user: Kevin Bullock date: Sun Feb 10 23:01:12 2013 +0000 summary: import: don't rollback on failed import --exact (issue3616) http://hg.intevation.org/mercurial/crew/rev/882681bc3166 changeset: 18655:882681bc3166 parent: 18653:170142161672 parent: 18654:d9ff580fcaa2 user: Bryan O'Sullivan date: Sun Feb 10 16:22:32 2013 -0800 summary: Merge http://hg.intevation.org/mercurial/crew/rev/d9ff580fcaa2 changeset: 18654:d9ff580fcaa2 parent: 18651:e556659340f0 parent: 18648:013fcd112f13 user: Bryan O'Sullivan date: Sun Feb 10 16:21:30 2013 -0800 summary: Merge http://hg.intevation.org/mercurial/crew/rev/170142161672 changeset: 18653:170142161672 parent: 18652:a5e94bee77ed parent: 18651:e556659340f0 user: Benoit Boissinot date: Mon Feb 11 01:21:24 2013 +0100 summary: merge crew and main http://hg.intevation.org/mercurial/crew/rev/a5e94bee77ed changeset: 18652:a5e94bee77ed parent: 18642:76b69cccb07a parent: 18648:013fcd112f13 user: Benoit Boissinot date: Mon Feb 11 01:17:50 2013 +0100 summary: merge crew and main http://hg.intevation.org/mercurial/crew/rev/e556659340f0 changeset: 18651:e556659340f0 user: Siddharth Agarwal date: Sun Feb 10 16:55:01 2013 +0000 summary: manifestmerge: fix order in which manifests are fetched http://hg.intevation.org/mercurial/crew/rev/de0bd4bfc6d7 changeset: 18650:de0bd4bfc6d7 user: Siddharth Agarwal date: Sun Feb 10 12:16:46 2013 +0000 summary: merge: run _forgetremoved after manifestmerge http://hg.intevation.org/mercurial/crew/rev/0969980308c7 changeset: 18649:0969980308c7 parent: 18642:76b69cccb07a user: Siddharth Agarwal date: Sun Feb 10 16:23:14 2013 +0000 summary: dirstate: disable gc while parsing the dirstate http://hg.intevation.org/mercurial/crew/rev/76b69cccb07a changeset: 18642:76b69cccb07a user: Mads Kiilerich date: Fri Feb 08 22:54:17 2013 +0100 summary: export: show 'Date' header in a format that also is readable for humans http://hg.intevation.org/mercurial/crew/rev/c1d23b4a66d5 changeset: 18641:c1d23b4a66d5 user: Mads Kiilerich date: Sun Feb 10 18:26:04 2013 +0100 summary: factotum: fix urllib2 import so it no longer relies on a demandimport bug http://hg.intevation.org/mercurial/crew/rev/c6a81e54c209 changeset: 18640:c6a81e54c209 user: Mads Kiilerich date: Sun Jan 27 03:32:09 2013 +0100 summary: hgweb: make the test suite use hgweb in a more WSGI compliant way http://hg.intevation.org/mercurial/crew/rev/76ff3a715cf2 changeset: 18639:76ff3a715cf2 user: Mads Kiilerich date: Sun Feb 10 18:24:29 2013 +0100 summary: hgweb: simplify internal staticfile return codes http://hg.intevation.org/mercurial/crew/rev/3e92772d5383 changeset: 18638:3e92772d5383 user: Mads Kiilerich date: Sun Feb 10 18:24:29 2013 +0100 summary: spelling: fix some minor issues found by spell checker http://hg.intevation.org/mercurial/crew/rev/cc28a84db8c9 changeset: 18637:cc28a84db8c9 user: Mads Kiilerich date: Fri Feb 08 23:26:00 2013 +0100 summary: bundlerepo: replace basemap with the base field in the index http://hg.intevation.org/mercurial/crew/rev/a40d608e2a7b changeset: 18636:a40d608e2a7b user: Mads Kiilerich date: Fri Feb 08 22:54:48 2013 +0100 summary: profiling: replace '+' markup of nested lines with indentation http://hg.intevation.org/mercurial/crew/rev/6204e4d4dd6d changeset: 18635:6204e4d4dd6d parent: 18634:0027a5cec9d0 parent: 18633:a8648f32b8ed user: Augie Fackler date: Sun Feb 10 04:04:22 2013 -0600 summary: Merge crew and main. http://hg.intevation.org/mercurial/crew/rev/a8648f32b8ed changeset: 18633:a8648f32b8ed user: Bryan O'Sullivan date: Sat Feb 09 15:51:32 2013 -0800 summary: merge: don't fiddle with name lookups or i18n in hot loops http://hg.intevation.org/mercurial/crew/rev/5774732bb5e5 changeset: 18632:5774732bb5e5 user: Bryan O'Sullivan date: Sat Feb 09 15:51:32 2013 -0800 summary: merge: apply non-interactive working dir updates in parallel http://hg.intevation.org/mercurial/crew/rev/047110c0e2a8 changeset: 18631:047110c0e2a8 user: Bryan O'Sullivan date: Sat Feb 09 15:51:32 2013 -0800 summary: worker: allow a function to be run in multiple worker processes http://hg.intevation.org/mercurial/crew/rev/ac4dbceeb14a changeset: 18630:ac4dbceeb14a user: Bryan O'Sullivan date: Sat Feb 09 15:51:32 2013 -0800 summary: worker: partition a list (of tasks) into equal-sized chunks http://hg.intevation.org/mercurial/crew/rev/dcb27c153a40 changeset: 18629:dcb27c153a40 user: Bryan O'Sullivan date: Sat Feb 09 15:51:26 2013 -0800 summary: worker: estimate whether it's worth running a task in parallel http://hg.intevation.org/mercurial/crew/rev/fed06dd07665 changeset: 18628:fed06dd07665 user: Bryan O'Sullivan date: Sat Feb 09 15:22:12 2013 -0800 summary: worker: count the number of CPUs http://hg.intevation.org/mercurial/crew/rev/4b5d37ca3c11 changeset: 18627:4b5d37ca3c11 user: Bryan O'Sullivan date: Sat Feb 09 15:22:10 2013 -0800 summary: tests: getremove test output changes (fold into previous patch) http://hg.intevation.org/mercurial/crew/rev/6390dd22b12f changeset: 18626:6390dd22b12f user: Bryan O'Sullivan date: Sat Feb 09 15:22:09 2013 -0800 summary: merge: report non-interactive progress in chunks http://hg.intevation.org/mercurial/crew/rev/3e20079117c5 changeset: 18625:3e20079117c5 user: Bryan O'Sullivan date: Sat Feb 09 15:22:08 2013 -0800 summary: merge: handle subrepo merges and .hgsubstate specially http://hg.intevation.org/mercurial/crew/rev/e2dc5397bc82 changeset: 18624:e2dc5397bc82 user: Bryan O'Sullivan date: Sat Feb 09 15:22:04 2013 -0800 summary: tests: update test output (will be folded into parent) http://hg.intevation.org/mercurial/crew/rev/9b9e2d9e83a1 changeset: 18623:9b9e2d9e83a1 user: Bryan O'Sullivan date: Sat Feb 09 15:21:58 2013 -0800 summary: merge: split out mostly-non-interactive working dir updates -- Repository URL: http://hg.intevation.org/mercurial/crew From kbullock+mercurial at ringworld.org Mon Feb 11 08:56:53 2013 From: kbullock+mercurial at ringworld.org (Kevin Bullock) Date: Mon, 11 Feb 2013 14:56:53 +0000 Subject: [PATCH 04 of 19] commit: refactor mergestate management into workingctx In-Reply-To: References: <07bdd03d86dcce1558d7.1360538991@dev010.prn1.facebook.com> <8506E3B5-56B5-4D5D-BCB7-7EC9574059D9@ringworld.org> Message-ID: <88E86FAB-19D7-48D3-9CEA-C23D6F1C65E9@ringworld.org> On 11 Feb 2013, at 11:40 AM, David Schleimer wrote: >> Non-trivial duplicate code, can a brother get a helper function? > > Done, but I'm going to hold off on resending this giant series until I can get some more feedback, in an effort to avoid blowing up Matt's inbox too much. If I get a chance this evening, and no-one else gets to it first, I'll queue up 1-3. That should make the re-send a bit less heavy. pacem in terris / ??? / ?????? / ????????? / ?? Kevin R. Bullock From mercurial-bugs at selenic.com Mon Feb 11 04:04:30 2013 From: mercurial-bugs at selenic.com (mercurial-bugs at selenic.com) Date: Mon, 11 Feb 2013 10:04:30 +0000 Subject: [Bug 3818] New: pushing a bookmark to a revision filtered locally print an error Message-ID: http://bz.selenic.com/show_bug.cgi?id=3818 Priority: normal Bug ID: 3818 CC: mercurial-devel at selenic.com Assignee: bugzilla at selenic.com Summary: pushing a bookmark to a revision filtered locally print an error Severity: bug Classification: Unclassified OS: Linux Reporter: pierre-yves.david at logilab.fr Hardware: PC Status: UNCONFIRMED Version: 2.5-rc Component: Mercurial Product: Mercurial If a bookmark is a revision that is known remotly but non served, something wrong happen remotly % 16:00 pyves at crater2 ~/src/mercurial-dev > hg push -B bettermerge pushing to ssh://hg-lab at hg-lab.logilab.org/wip/hg/ searching for changes no changes found hg bookmark -fr e75b8ee4c449 bettermerge hg push -B betterexporting bookmark bettermerge eremote: abort: 00changelog.i at ece3f2b2a36d: no node! abort: unexpected response: empty string zsh: exit 255 hg push -B bettermerge -- You are receiving this mail because: You are on the CC list for the bug. From pierre-yves.david at logilab.fr Mon Feb 11 09:25:48 2013 From: pierre-yves.david at logilab.fr (pierre-yves.david at logilab.fr) Date: Mon, 11 Feb 2013 16:25:48 +0100 Subject: [PATCH STABLE] mq: comply with filtering when injecting fake tags (issue3812) Message-ID: # HG changeset patch # User Pierre-Yves David # Date 1360596108 -3600 # Branch stable # Node ID ed7241a612835bb22759d93df4c1522961cd6823 # Parent 227479f61db9d169c1afea6fa0a9dce7288d4932 mq: comply with filtering when injecting fake tags (issue3812) mq was injecting fake tags whenever the revision were accessible to the filtering level. This issue impacts hgweb since it's common to have "secret" mq patches. As secret changeset are filtered by hgweb the tags computation could break. diff --git a/hgext/mq.py b/hgext/mq.py --- a/hgext/mq.py +++ b/hgext/mq.py @@ -3452,10 +3452,16 @@ def reposetup(ui, repo): except error.LookupError: self.ui.warn(_('mq status file refers to unknown node %s\n') % short(mqtags[-1][0])) return result + # do not add fake tags for filtered revision + included = self.changelog.hasnode + mqtags = [mqt for mqt in mqtags if included(mqt[0])] + if not mqtags: + return result + mqtags.append((mqtags[-1][0], 'qtip')) mqtags.append((mqtags[0][0], 'qbase')) mqtags.append((self.changelog.parents(mqtags[0][0])[0], 'qparent')) tags = result[0] for patch in mqtags: diff --git a/tests/test-mq.t b/tests/test-mq.t --- a/tests/test-mq.t +++ b/tests/test-mq.t @@ -1553,6 +1553,26 @@ Test that qfinish preserve phase when mq $ hg phase 'all()' 0: draft 1: secret 2: secret +Test that secret mq patch does not break hgweb + + $ cat > hgweb.cgi < from mercurial import demandimport; demandimport.enable() + > from mercurial.hgweb import hgweb + > from mercurial.hgweb import wsgicgi + > import cgitb + > cgitb.enable() + > app = hgweb('.', 'test') + > wsgicgi.launch(app) + > HGWEB + $ . "$TESTDIR/cgienv" + $ PATH_INFO=/tags; export PATH_INFO + $ QUERY_STRING='style=raw' + $ python hgweb.cgi | grep -v ETag: + Status: 200 Script output follows\r (esc) + Content-Type: text/plain; charset=ascii\r (esc) + \r (esc) + tip [0-9a-f]{40} (re) + $ cd .. From pierre-yves.david at logilab.fr Mon Feb 11 09:30:11 2013 From: pierre-yves.david at logilab.fr (pierre-yves.david at logilab.fr) Date: Mon, 11 Feb 2013 16:30:11 +0100 Subject: [PATCH STABLE] debugobsolete: improve command help Message-ID: <9c370f873d3570aecedd.1360596611@crater2.logilab.fr> # HG changeset patch # User Pierre-Yves David # Date 1360452522 0 # Node ID 9c370f873d3570aecedd6cc9ad480cdc19894623 # Parent 6204e4d4dd6d10834540357dbf1deac6636077c8 debugobsolete: improve command help The behavior without argument was not documented. diff --git a/mercurial/commands.py b/mercurial/commands.py --- a/mercurial/commands.py +++ b/mercurial/commands.py @@ -2104,11 +2104,13 @@ def debugknown(ui, repopath, *ids, **opt @command('debugobsolete', [('', 'flags', 0, _('markers flag')), ] + commitopts2, _('[OBSOLETED [REPLACEMENT] [REPL... ]')) def debugobsolete(ui, repo, precursor=None, *successors, **opts): - """create arbitrary obsolete marker""" + """create arbitrary obsolete marker + + With no arguments it it display the list obsolescence marker.""" def parsenodeid(s): try: # We do not use revsingle/revrange functions here to accept # arbitrary node identifiers, possibly not present in the # local repository. From thomas at intevation.de Mon Feb 11 09:39:46 2013 From: thomas at intevation.de (Thomas Arendsen Hein) Date: Mon, 11 Feb 2013 16:39:46 +0100 Subject: [PATCH STABLE] debugobsolete: improve command help In-Reply-To: <9c370f873d3570aecedd.1360596611@crater2.logilab.fr> References: <9c370f873d3570aecedd.1360596611@crater2.logilab.fr> Message-ID: <20130211163915.713148267.thomas@intevation.de> * pierre-yves.david at logilab.fr [20130211 16:30]: > # HG changeset patch > # User Pierre-Yves David > # Date 1360452522 0 > # Node ID 9c370f873d3570aecedd6cc9ad480cdc19894623 > # Parent 6204e4d4dd6d10834540357dbf1deac6636077c8 > debugobsolete: improve command help > > The behavior without argument was not documented. Pushed to crew-stable to test the disabled publishing in the crew repo. Thanks, Thomas -- thomas at intevation.de - http://intevation.de/~thomas/ - OpenPGP key: 0x5816791A Intevation GmbH, Neuer Graben 17, 49074 Osnabrueck - AG Osnabrueck, HR B 18998 Geschaeftsfuehrer: Frank Koormann, Bernhard Reiter, Dr. Jan-Oliver Wagner From hgbuildbot at kublai.com Mon Feb 11 10:27:19 2013 From: hgbuildbot at kublai.com (hgbuildbot at kublai.com) Date: Mon, 11 Feb 2013 08:27:19 -0800 Subject: buildbot success in Mercurial on hg tests (stable) Message-ID: <20130211162720.AC786387D5@hgbuildbot.cs.ubc.ca> The Buildbot has detected a restored build on builder hg tests (stable) while building hg. Full details are available at: http://hgbuildbot.kublai.com/builders/hg%20tests%20%28stable%29/builds/302 Buildbot URL: http://hgbuildbot.kublai.com/ Buildslave for this Build: p64.osuosl.test Build Reason: scheduler Build Source Stamp: [branch stable] d4a79e075303dafbe8d226d119f3e9ead1c48d53 Blamelist: Pierre-Yves David Build succeeded! sincerely, -The Buildbot From pierre-yves.david at ens-lyon.org Mon Feb 11 11:37:07 2013 From: pierre-yves.david at ens-lyon.org (Pierre-Yves David) Date: Mon, 11 Feb 2013 18:37:07 +0100 Subject: [PATCH] obsolete: consider successors along with descendants when updating In-Reply-To: <410BFEE8-BF1A-46B6-A6E3-8D6D003BBF54@ringworld.org> References: <8d89080a98d69606ac26.1360532854@retina-monoteam> <410BFEE8-BF1A-46B6-A6E3-8D6D003BBF54@ringworld.org> Message-ID: <169B86D3-0D0E-4ED5-8EC8-4C5E6BE85F93@ens-lyon.org> On 11 f?vr. 2013, at 04:04, Kevin Bullock wrote: > On 10 Feb 2013, at 9:47 PM, Levi Bard wrote: > >> # HG changeset patch >> # User Levi Bard >> # Date 1360532614 -3600 >> # Node ID 8d89080a98d69606ac264282e2ba3e33b056bcac >> # Parent 013fcd112f13f31a35ea6a40d8cd1c6923cdaf20 >> obsolete: consider successors along with descendants when updating >> >> Currently, if you pull --update a group of changesets that obsoletes >> the current changeset, mercurial refuses to update because the pulled tip >> is not a descendant. This change causes mercurial to consider successors >> as well as descendants when determining whether to update. >> >> diff -r 013fcd112f13 -r 8d89080a98d6 mercurial/merge.py >> --- a/mercurial/merge.py Sat Feb 09 11:00:42 2013 +0100 >> +++ b/mercurial/merge.py Sun Feb 10 22:43:34 2013 +0100 >> @@ -7,6 +7,7 @@ >> >> from node import nullid, nullrev, hex, bin >> from i18n import _ >> +from mercurial import obsolete >> import error, util, filemerge, copies, subrepo >> import errno, os, shutil >> >> @@ -632,6 +633,9 @@ >> elif not overwrite: >> if pa == p1 or pa == p2: # linear >> pass # all good >> + elif repo.obsstore and \ >> + node in obsolete.allsuccessors(repo.obsstore, [p1.node()]): > > Wrap condition in parens instead of continuing the line with \. > >> + pa = p1 # allow updating to successors of obsolete nodes > > Huh, that's really all it takes? The job was done for bookmark 6 months ago. If update target have the very same semantics than bookmarks target it should be good. I'll have a closer look at this patch soon?. -- Pierre-Yves From bos at serpentine.com Mon Feb 11 14:50:59 2013 From: bos at serpentine.com (Bryan O'Sullivan) Date: Mon, 11 Feb 2013 12:50:59 -0800 Subject: [PATCH 04 of 19] commit: refactor mergestate management into workingctx In-Reply-To: <88E86FAB-19D7-48D3-9CEA-C23D6F1C65E9@ringworld.org> References: <07bdd03d86dcce1558d7.1360538991@dev010.prn1.facebook.com> <8506E3B5-56B5-4D5D-BCB7-7EC9574059D9@ringworld.org> <88E86FAB-19D7-48D3-9CEA-C23D6F1C65E9@ringworld.org> Message-ID: On Mon, Feb 11, 2013 at 6:56 AM, Kevin Bullock < kbullock+mercurial at ringworld.org> wrote: > If I get a chance this evening, and no-one else gets to it first, I'll > queue up 1-3. That should make the re-send a bit less heavy. > I just pushed 1-3 to crew. Will take a look through the rest of the series now. -------------- next part -------------- An HTML attachment was scrubbed... URL: From bos at serpentine.com Mon Feb 11 14:54:35 2013 From: bos at serpentine.com (Bryan O'Sullivan) Date: Mon, 11 Feb 2013 12:54:35 -0800 Subject: [PATCH 06 of 19] context: allow updating the date of a workingctx In-Reply-To: <9ad2e26501309255cd08.1360538996@dev010.prn1.facebook.com> References: <07bdd03d86dcce1558d7.1360538991@dev010.prn1.facebook.com> <9ad2e26501309255cd08.1360538996@dev010.prn1.facebook.com> Message-ID: On Sun, Feb 10, 2013 at 3:29 PM, David Schleimer wrote: > supporitng ytpo -------------- next part -------------- An HTML attachment was scrubbed... URL: From bos at serpentine.com Mon Feb 11 14:55:32 2013 From: bos at serpentine.com (Bryan O'Sullivan) Date: Mon, 11 Feb 2013 12:55:32 -0800 Subject: [PATCH 08 of 19] context: support updating extra in workingctx In-Reply-To: <62d93c48151c79f5e08c.1360538998@dev010.prn1.facebook.com> References: <07bdd03d86dcce1558d7.1360538991@dev010.prn1.facebook.com> <62d93c48151c79f5e08c.1360538998@dev010.prn1.facebook.com> Message-ID: On Sun, Feb 10, 2013 at 3:29 PM, David Schleimer wrote: > wrokingctx Good patch, but got a typoe. -------------- next part -------------- An HTML attachment was scrubbed... URL: From bos at serpentine.com Mon Feb 11 14:58:46 2013 From: bos at serpentine.com (Bryan O'Sullivan) Date: Mon, 11 Feb 2013 12:58:46 -0800 Subject: [PATCH 12 of 19] localrepo: don't use raw context when checking for an empty commit In-Reply-To: References: <07bdd03d86dcce1558d7.1360538991@dev010.prn1.facebook.com> Message-ID: On Sun, Feb 10, 2013 at 3:30 PM, David Schleimer wrote: > This is turn will make it proactical for Couple of typos here. -------------- next part -------------- An HTML attachment was scrubbed... URL: From bos at serpentine.com Mon Feb 11 15:04:34 2013 From: bos at serpentine.com (Bryan O'Sullivan) Date: Mon, 11 Feb 2013 13:04:34 -0800 Subject: [PATCH 18 of 19] commit: move commit preparation from localrepo.commit to workingctx In-Reply-To: <7a150f3cfd3ea54a11db.1360539008@dev010.prn1.facebook.com> References: <07bdd03d86dcce1558d7.1360538991@dev010.prn1.facebook.com> <7a150f3cfd3ea54a11db.1360539008@dev010.prn1.facebook.com> Message-ID: On Sun, Feb 10, 2013 at 3:30 PM, David Schleimer wrote: > + Includes validation, subrepo state munging, and change > + filtering. > "Includes" implies that the method does more than just these things, which I don't think it does. Maybe use "Performs" instead? -------------- next part -------------- An HTML attachment was scrubbed... URL: From bos at serpentine.com Mon Feb 11 15:06:00 2013 From: bos at serpentine.com (Bryan O'Sullivan) Date: Mon, 11 Feb 2013 13:06:00 -0800 Subject: [PATCH 19 of 19] commit: get rid of no-longer needed variable in localrepo.commit In-Reply-To: References: <07bdd03d86dcce1558d7.1360538991@dev010.prn1.facebook.com> Message-ID: On Sun, Feb 10, 2013 at 3:30 PM, David Schleimer wrote: > commit: get rid of no-longer needed variable in localrepo.commit > Nice. There are a couple of typos in the descriptions of 16 and 17. With the basically trivial comments aside, the whole series looks good, and marks a considerable improvement over the code we currently have. -------------- next part -------------- An HTML attachment was scrubbed... URL: From bos at serpentine.com Mon Feb 11 15:12:32 2013 From: bos at serpentine.com (Bryan O'Sullivan) Date: Mon, 11 Feb 2013 13:12:32 -0800 Subject: [PATCH STABLE] mq: comply with filtering when injecting fake tags (issue3812) In-Reply-To: References: Message-ID: On Mon, Feb 11, 2013 at 7:25 AM, wrote: > mq: comply with filtering when injecting fake tags (issue3812) > Crewed, thanks. -------------- next part -------------- An HTML attachment was scrubbed... URL: From bos at serpentine.com Mon Feb 11 15:21:49 2013 From: bos at serpentine.com (Bryan O'Sullivan) Date: Mon, 11 Feb 2013 13:21:49 -0800 Subject: [PATCH] dirstate: fix generator/list error when using python 2.7 In-Reply-To: References: <9c384e0ef7f5c860ea77.1360529076@dev350.prn1.facebook.com> Message-ID: On Sun, Feb 10, 2013 at 4:37 PM, Benoit Boissinot wrote: > If that's what you actually want to catch (like what was done previously), > you need to check errno for ENOENT > Actually, Durham's patch doesn't change the semantics of the code. statfiles turns all lstat results that would cause OSError to be thrown into None entries in the result list. It's possible that the prior patch that he's modifying was wrong, but I don't think so (haven't thought about it deeply). Patch crewed as-is for now. -------------- next part -------------- An HTML attachment was scrubbed... URL: From bboissin at gmail.com Mon Feb 11 15:25:28 2013 From: bboissin at gmail.com (Benoit Boissinot) Date: Mon, 11 Feb 2013 22:25:28 +0100 Subject: [PATCH] dirstate: fix generator/list error when using python 2.7 In-Reply-To: References: <9c384e0ef7f5c860ea77.1360529076@dev350.prn1.facebook.com> Message-ID: On Mon, Feb 11, 2013 at 10:21 PM, Bryan O'Sullivan wrote: > On Sun, Feb 10, 2013 at 4:37 PM, Benoit Boissinot wrote: > >> If that's what you actually want to catch (like what was done >> previously), you need to check errno for ENOENT >> > > Actually, Durham's patch doesn't change the semantics of the code. > statfiles turns all lstat results that would cause OSError to be thrown > into None entries in the result list. > > It's possible that the prior patch that he's modifying was wrong, but I > don't think so (haven't thought about it deeply). > At least that's the behaviour of the pure python version (in posix.py). Might be a bug of the C code, or the python code being too defensive. > > Patch crewed as-is for now. > -------------- next part -------------- An HTML attachment was scrubbed... URL: From bos at serpentine.com Mon Feb 11 15:39:57 2013 From: bos at serpentine.com (Bryan O'Sullivan) Date: Mon, 11 Feb 2013 13:39:57 -0800 Subject: [PATCH 6 of 6] blackbox: tests for the blackbox extension In-Reply-To: References: <30544b5277d09002d6ca.1360494437@dev350.prn1.facebook.com> <932a1aea1b315a2b1c6e.1360494442@dev350.prn1.facebook.com> Message-ID: On Sun, Feb 10, 2013 at 4:24 AM, Brodie Rao wrote: > I think it's a little confusing that the date is completely globbed > out here. Can you make the date stable and add it to the test? > The date is in the output from blackbox. It doesn't make sense to me to add a hack to make those dates constant for testing. -------------- next part -------------- An HTML attachment was scrubbed... URL: From bos at serpentine.com Mon Feb 11 15:42:51 2013 From: bos at serpentine.com (Bryan O'Sullivan) Date: Mon, 11 Feb 2013 13:42:51 -0800 Subject: [PATCH 2 of 6] blackbox: log the commands that are run In-Reply-To: <87txpkqm7l.fsf@go.home> References: <30544b5277d09002d6ca.1360494437@dev350.prn1.facebook.com> <54a25c702a6fface978f.1360494438@dev350.prn1.facebook.com> <87txpkqm7l.fsf@go.home> Message-ID: On Sun, Feb 10, 2013 at 6:26 AM, Martin Geisler wrote: > The standard logging library works by taking the format string and the > arguments separately: that way you can check if the message will be > logged first and then only spend time formatting it if so. It would be > cool if we could change the signature of ui.log to that standard too. > I think that's a good idea. I already want to do that with our existing ui.note and such methods. -------------- next part -------------- An HTML attachment was scrubbed... URL: From bos at serpentine.com Mon Feb 11 15:47:45 2013 From: bos at serpentine.com (Bryan O'Sullivan) Date: Mon, 11 Feb 2013 13:47:45 -0800 Subject: [PATCH 2 of 5] dispatch: catch InterventionRequired and print the message with no prefix In-Reply-To: <24A5EB27-857D-4CB4-B6A1-729A3137E7F4@durin42.com> References: <4d997c5075c446963b6a.1360363790@augie-macbookair> <1c4102a7ec7c80a1baa9.1360363791@augie-macbookair> <51163554.5030202@kiilerich.com> <451256A9-57AB-41EF-9AC1-50D7807CEF7E@ringworld.org> <24A5EB27-857D-4CB4-B6A1-729A3137E7F4@durin42.com> Message-ID: On Sat, Feb 9, 2013 at 3:51 AM, Augie Fackler wrote: > Open to suggestions on that - I wanted a prefix but couldn't come up with > one that was clear and suitably pithy. > stopped? -------------- next part -------------- An HTML attachment was scrubbed... URL: From bos at serpentine.com Mon Feb 11 15:53:43 2013 From: bos at serpentine.com (Bryan O'Sullivan) Date: Mon, 11 Feb 2013 13:53:43 -0800 Subject: [PATCH] serve: introduce --get and --post for easy testing of hgweb In-Reply-To: <86f6b4786d8d292843a9.1360452156@localhost.localdomain> References: <86f6b4786d8d292843a9.1360452156@localhost.localdomain> Message-ID: On Sat, Feb 9, 2013 at 3:22 PM, Mads Kiilerich wrote: > serve: introduce --get and --post for easy testing of hgweb > > These options can be useful both in the test suite and for other kinds of > hgweb > testing. > Wouldn't it make sense to put this code in a Python file in the tests directory? It seems quite inappropriate to add these options to hgweb itself. -------------- next part -------------- An HTML attachment was scrubbed... URL: From bos at serpentine.com Mon Feb 11 15:55:01 2013 From: bos at serpentine.com (Bryan O'Sullivan) Date: Mon, 11 Feb 2013 13:55:01 -0800 Subject: [PATCH] hgweb: consistent author name width In-Reply-To: References: Message-ID: On Sun, Feb 10, 2013 at 4:17 AM, Dan Villiom Podlaski Christiansen < danchr at gmail.com> wrote: > hgweb: consistent author name width > Crewed, thanks. -------------- next part -------------- An HTML attachment was scrubbed... URL: From bos at serpentine.com Mon Feb 11 16:03:43 2013 From: bos at serpentine.com (Bryan O'Sullivan) Date: Mon, 11 Feb 2013 14:03:43 -0800 Subject: [PATCH 1 of 2] test-atomictempfile: convert to unit test In-Reply-To: <4a4b4c13211532f5bdf4.1360430220@idan> References: <4a4b4c13211532f5bdf4.1360430220@idan> Message-ID: <20130211220343.GA18833@gmail.com> On Sat, Feb 09, 2013 at 07:17:00PM +0200, Idan Kamara wrote: > test-atomictempfile: convert to unit test Crewed both patches (in the correct order), thanks. From bos at serpentine.com Mon Feb 11 18:15:51 2013 From: bos at serpentine.com (Bryan O'Sullivan) Date: Mon, 11 Feb 2013 16:15:51 -0800 Subject: [PATCH] scmutil: create directories in a race-safe way during update Message-ID: <4034b8d551b116b88292.1360628151@australite.local> # HG changeset patch # User Bryan O'Sullivan # Date 1360628112 28800 # Node ID 4034b8d551b116b882920466e1d209e475a62721 # Parent f12804d3ff801b989cb2aab1aad93047a8db46f1 scmutil: create directories in a race-safe way during update With the new parallel update code, it is possible for multiple workers to try to create a hierarchy of directories at the same time. This is hard to trigger in general, but most likely during initial checkout. To deal with these races, we introduce a new ensuredirs function whose contract is to ensure that a directory hierarchy exists - it will ignore a failure that implies that the desired directory already exists. diff --git a/mercurial/scmutil.py b/mercurial/scmutil.py --- a/mercurial/scmutil.py +++ b/mercurial/scmutil.py @@ -307,7 +307,7 @@ class vfs(abstractvfs): if basename: if atomictemp: if not os.path.isdir(dirname): - util.makedirs(dirname, self.createmode) + util.ensuredirs(dirname, self.createmode) return util.atomictempfile(f, mode, self.createmode) try: if 'w' in mode: @@ -326,7 +326,7 @@ class vfs(abstractvfs): raise nlink = 0 if not os.path.isdir(dirname): - util.makedirs(dirname, self.createmode) + util.ensuredirs(dirname, self.createmode) if nlink > 0: if self._trustnlink is None: self._trustnlink = nlink > 1 or util.checknlink(f) @@ -347,7 +347,7 @@ class vfs(abstractvfs): dirname = os.path.dirname(linkname) if not os.path.exists(dirname): - util.makedirs(dirname, self.createmode) + util.ensuredirs(dirname, self.createmode) if self._cansymlink: try: diff --git a/mercurial/util.py b/mercurial/util.py --- a/mercurial/util.py +++ b/mercurial/util.py @@ -880,6 +880,16 @@ def makedirs(name, mode=None): if mode is not None: os.chmod(name, mode) +def ensuredirs(name, mode=None): + """race-safe recursive directory creation""" + try: + makedirs(name, mode) + except OSError, err: + if err.errno == errno.EEXIST and os.path.isdir(name): + # someone else seems to have won a directory creation race + return + raise + def readfile(path): fp = open(path, 'rb') try: From bos at serpentine.com Mon Feb 11 19:02:18 2013 From: bos at serpentine.com (Bryan O'Sullivan) Date: Mon, 11 Feb 2013 17:02:18 -0800 Subject: [PATCH 11 of 11] merge: don't fiddle with name lookups or i18n in hot loops In-Reply-To: References: <8cf626e958d3dd67e45b.1360418801@australite.local> <994e4c0ed9a6d2ff25aa.1360418811@australite.local> <55EAC0A6-3C4E-47BD-BAF6-832A530313C8@durin42.com> Message-ID: On Sun, Feb 10, 2013 at 3:25 AM, Idan Kamara wrote: > No, he didn't. And had he given me the chance to reply to his last > response, I would have shown it: > Yep, that's a bug. But it's just a bug - I fixed another one in the new parallel code just a little while ago. > And the only reason the sys.exit I had a problem with is > 'working' is thanks to this: > > http://selenic.com/repo/hg/file/0027a5cec9d0/mercurial/dispatch.py#l201 > Correct, and that's deliberate. Perhaps you could tell me what you'd rather see, because I obviously think the use of sys.exit in this context is reasonable based on what I currently know. -------------- next part -------------- An HTML attachment was scrubbed... URL: From pierre-yves.david at ens-lyon.org Mon Feb 11 19:08:13 2013 From: pierre-yves.david at ens-lyon.org (Pierre-Yves David) Date: Tue, 12 Feb 2013 02:08:13 +0100 Subject: [PATCH] obsolete: consider successors along with descendants when updating (need rework) In-Reply-To: <8d89080a98d69606ac26.1360532854@retina-monoteam> References: <8d89080a98d69606ac26.1360532854@retina-monoteam> Message-ID: Status: Patches is currently "buggy" and need substantial rewrite On 10 f?vr. 2013, at 22:47, Levi Bard wrote: > # HG changeset patch > # User Levi Bard > # Date 1360532614 -3600 > # Node ID 8d89080a98d69606ac264282e2ba3e33b056bcac > # Parent 013fcd112f13f31a35ea6a40d8cd1c6923cdaf20 > obsolete: consider successors along with descendants when updating > > Currently, if you pull --update a group of changesets that obsoletes > the current changeset, mercurial refuses to update because the pulled tip > is not a descendant. This change causes mercurial to consider successors > as well as descendants when determining whether to update. You should probably mentions that bookmarks are doing the same. During our discussion about exchanging obsolescence marker we call the set of possible target "foreground", it is all possible descendant of all possible successors (recursively). This "foreground" is also were we what to be able to update to. You actually got that part wrong because you are not doing it recursively In this situation: A - B \ B' - C \ C' -D If you are on B you want to be able to update to D. I do not think your code handles that You needs to extract the while loop in bookmarks that contains `obsolete.allsuccessors` into a function and use that. note: We also have "background" which is all possibles ancestors of all possible descendant (recursively) but we do not care about it here. Thanks for working on that! Thats really very helpful for me to see such issue being resolved > > diff -r 013fcd112f13 -r 8d89080a98d6 mercurial/merge.py > --- a/mercurial/merge.py Sat Feb 09 11:00:42 2013 +0100 > +++ b/mercurial/merge.py Sun Feb 10 22:43:34 2013 +0100 > @@ -7,6 +7,7 @@ > > from node import nullid, nullrev, hex, bin > from i18n import _ > +from mercurial import obsolete > import error, util, filemerge, copies, subrepo > import errno, os, shutil > > @@ -632,6 +633,9 @@ > elif not overwrite: > if pa == p1 or pa == p2: # linear > pass # all good > + elif repo.obsstore and \ > + node in obsolete.allsuccessors(repo.obsstore, [p1.node()]): > + pa = p1 # allow updating to successors of obsolete nodes > elif wc.dirty(missing=True): > raise util.Abort(_("crosses branches (merge branches or use" > " --clean to discard changes)")) > diff -r 013fcd112f13 -r 8d89080a98d6 tests/test-pull-update.t > --- a/tests/test-pull-update.t Sat Feb 09 11:00:42 2013 +0100 > +++ b/tests/test-pull-update.t Sun Feb 10 22:43:34 2013 +0100 > @@ -1,3 +1,12 @@ > + $ cat << EOF >> $HGRCPATH > + > [extensions] > + > obs=$TESTTMP/obs.py > + > EOF > + $ cat > obs.py << EOF > + > import mercurial.obsolete > + > mercurial.obsolete._enabled = True > + > EOF > + > $ hg init t > $ cd t > $ echo 1 > foo > @@ -60,3 +69,64 @@ > 1 files updated, 0 files merged, 0 files removed, 0 files unresolved > > $ cd .. > + > +Test no-argument update to a successor of an obsoleted changeset You want to add hg log -G output in your test so that people can understand what's going on without compiling the whole test. > + > + $ hg init blah > + $ cd blah > + $ echo 1 > a > + $ hg add a > + $ hg commit -m0 > + $ echo 2 > a > + $ hg commit -m1 > + $ cd .. > + $ hg clone blah meh > + updating to branch default > + 1 files updated, 0 files merged, 0 files removed, 0 files unresolved > + $ cd blah > + $ echo 3 > a > + $ hg commit --amend -m3 > + $ cd ../meh > + $ hg pull --update ../blah > + pulling from ../blah > + searching for changes > + adding changesets > + adding manifests > + adding file changes > + added 1 changesets with 1 changes to 1 files (+1 heads) > + 1 files updated, 0 files merged, 0 files removed, 0 files unresolved > + $ cd .. > + > +Test refusal to update to a non-successor of an obsoleted changeset > + > + $ rm -rf blah meh > + $ hg init blah > + $ cd blah > + $ echo 1 > a > + $ hg add a > + $ hg commit -m0 > + $ echo 2 > a > + $ hg commit -m1 > + $ cd .. > + $ hg clone blah meh > + updating to branch default > + 1 files updated, 0 files merged, 0 files removed, 0 files unresolved > + $ cd blah > + $ echo 3 > a > + $ hg commit --amend -m3 > + $ hg update 0 > + 1 files updated, 0 files merged, 0 files removed, 0 files unresolved > + $ echo 4 > a > + $ hg commit -m4 > + created new head > + $ cd ../meh > + $ hg pull --update ../blah > + pulling from ../blah > + searching for changes > + adding changesets > + adding manifests > + adding file changes > + added 2 changesets with 2 changes to 1 files (+2 heads) > + not updating: crosses branches (merge branches or update --check to force update) > + $ cd .. > + > _______________________________________________ > Mercurial-devel mailing list > Mercurial-devel at selenic.com > http://selenic.com/mailman/listinfo/mercurial-devel From idankk86 at gmail.com Tue Feb 12 03:26:23 2013 From: idankk86 at gmail.com (Idan Kamara) Date: Tue, 12 Feb 2013 11:26:23 +0200 Subject: [PATCH 11 of 11] merge: don't fiddle with name lookups or i18n in hot loops In-Reply-To: References: <8cf626e958d3dd67e45b.1360418801@australite.local> <994e4c0ed9a6d2ff25aa.1360418811@australite.local> <55EAC0A6-3C4E-47BD-BAF6-832A530313C8@durin42.com> Message-ID: On Tue, Feb 12, 2013 at 3:02 AM, Bryan O'Sullivan wrote: > > On Sun, Feb 10, 2013 at 3:25 AM, Idan Kamara wrote: >> >> No, he didn't. And had he given me the chance to reply to his last >> response, I would have shown it: > > > Yep, that's a bug. But it's just a bug - I fixed another one in the new > parallel code just a little while ago. So we should exit on all exceptions, but we can't print a traceback since that's not desirable when not running from the command line (and it wasn't readable anyway since they got interleaved in one another). Maybe we should serialize the exceptions to the master and have him decide what to do (e.g. reraise)? > >> >> And the only reason the sys.exit I had a problem with is >> 'working' is thanks to this: >> >> http://selenic.com/repo/hg/file/0027a5cec9d0/mercurial/dispatch.py#l201 > > > Correct, and that's deliberate. Perhaps you could tell me what you'd > rather see, because I obviously think the use of sys.exit in this context is > reasonable based on what I currently know. I think raising util.Abort instead should do it. I wrote this test to check these things: import unittest, silenttestrunner, os from mercurial import worker, ui, util class testworker(unittest.TestCase): def testchilderror(self): def workerfunc(x): raise util.Abort g = worker._platformworker(ui.ui(), workerfunc, (), [1]) self.assertRaises(util.Abort, g.next) if __name__ == '__main__': silenttestrunner.main(__name__) It will currently fail on a StopIteration because the child doesn't exit, making it call g.next on a finished generator. So doing this fixes it: diff --git a/mercurial/worker.py b/mercurial/worker.py --- a/mercurial/worker.py +++ b/mercurial/worker.py @@ -83,7 +83,7 @@ for i, item in func(*(staticargs + (pargs,))): os.write(wfd, '%d %s\n' % (i, item)) os._exit(0) - except KeyboardInterrupt: + except: os._exit(255) os.close(wfd) fp = os.fdopen(rfd, 'rb', 0) @@ -96,7 +96,7 @@ for i in xrange(workers): problems |= os.wait()[1] if problems: - sys.exit(1) + raise util.Abort(_('child error')) try: for line in fp: l = line.split(' ', 1) -------------- next part -------------- An HTML attachment was scrubbed... URL: From diptongo at gmail.com Tue Feb 12 04:12:17 2013 From: diptongo at gmail.com (Isaac Jurado) Date: Tue, 12 Feb 2013 11:12:17 +0100 Subject: [PATCH 11 of 11] merge: don't fiddle with name lookups or i18n in hot loops In-Reply-To: References: <8cf626e958d3dd67e45b.1360418801@australite.local> <994e4c0ed9a6d2ff25aa.1360418811@australite.local> <55EAC0A6-3C4E-47BD-BAF6-832A530313C8@durin42.com> Message-ID: On Tue, Feb 12, 2013 at 10:26 AM, Idan Kamara wrote: > On Tue, Feb 12, 2013 at 3:02 AM, Bryan O'Sullivan > wrote: >> >> On Sun, Feb 10, 2013 at 3:25 AM, Idan Kamara wrote: >>> >>> No, he didn't. And had he given me the chance to reply to his last >>> response, I would have shown it: >> >> >> Yep, that's a bug. But it's just a bug - I fixed another one in the new >> parallel code just a little while ago. > > So we should exit on all exceptions, but we can't print a traceback > since that's not desirable when not running from the command line > (and it wasn't readable anyway since they got interleaved in one > another). > > Maybe we should serialize the exceptions to the master and have > him decide what to do (e.g. reraise)? That could be a problem if the serialized exception needs more than 512 bytes in size. The elegance of Bryan's design relies on the fact that the operating system ensures atomicity for small writes to the shared pipe. -- Isaac Jurado "The noblest pleasure is the joy of understanding" Leonardo da Vinci From idankk86 at gmail.com Tue Feb 12 04:35:01 2013 From: idankk86 at gmail.com (Idan Kamara) Date: Tue, 12 Feb 2013 12:35:01 +0200 Subject: [PATCH 11 of 11] merge: don't fiddle with name lookups or i18n in hot loops In-Reply-To: References: <8cf626e958d3dd67e45b.1360418801@australite.local> <994e4c0ed9a6d2ff25aa.1360418811@australite.local> <55EAC0A6-3C4E-47BD-BAF6-832A530313C8@durin42.com> Message-ID: On Tue, Feb 12, 2013 at 12:12 PM, Isaac Jurado wrote: > > On Tue, Feb 12, 2013 at 10:26 AM, Idan Kamara wrote: > > On Tue, Feb 12, 2013 at 3:02 AM, Bryan O'Sullivan > > wrote: > >> > >> On Sun, Feb 10, 2013 at 3:25 AM, Idan Kamara > >> wrote: > >>> > >>> No, he didn't. And had he given me the chance to reply to his last > >>> response, I would have shown it: > >> > >> > >> Yep, that's a bug. But it's just a bug - I fixed another one in the new > >> parallel code just a little while ago. > > > > So we should exit on all exceptions, but we can't print a traceback > > since that's not desirable when not running from the command line > > (and it wasn't readable anyway since they got interleaved in one > > another). > > > > Maybe we should serialize the exceptions to the master and have > > him decide what to do (e.g. reraise)? > > That could be a problem if the serialized exception needs more than > 512 bytes in size. The elegance of Bryan's design relies on the fact > that the operating system ensures atomicity for small writes to the > shared pipe. Ok, and since we'd like to include the traceback, we'll most likely need more than 512 bytes. So unless there's a trick to be made here, we'll need a pipe for every worker. It might be worth looking at multiprocessing.Pool, which does all this and has a chance of working sensibly on Windows too (there's a backport of it to 2.4-5). -------------- next part -------------- An HTML attachment was scrubbed... URL: From diptongo at gmail.com Tue Feb 12 05:01:11 2013 From: diptongo at gmail.com (Isaac Jurado) Date: Tue, 12 Feb 2013 12:01:11 +0100 Subject: [PATCH 11 of 11] merge: don't fiddle with name lookups or i18n in hot loops In-Reply-To: References: <8cf626e958d3dd67e45b.1360418801@australite.local> <994e4c0ed9a6d2ff25aa.1360418811@australite.local> <55EAC0A6-3C4E-47BD-BAF6-832A530313C8@durin42.com> Message-ID: On Tue, Feb 12, 2013 at 11:35 AM, Idan Kamara wrote: > On Tue, Feb 12, 2013 at 12:12 PM, Isaac Jurado wrote: >> >> On Tue, Feb 12, 2013 at 10:26 AM, Idan Kamara wrote: >> > >> > Maybe we should serialize the exceptions to the master and have >> > him decide what to do (e.g. reraise)? >> >> That could be a problem if the serialized exception needs more than >> 512 bytes in size. The elegance of Bryan's design relies on the fact >> that the operating system ensures atomicity for small writes to the >> shared pipe. > > Ok, and since we'd like to include the traceback, we'll most likely need > more than 512 bytes. So unless there's a trick to be made here, we'll > need a pipe for every worker. > > It might be worth looking at multiprocessing.Pool, which does all this > and has a chance of working sensibly on Windows too (there's a > backport of it to 2.4-5). As far as I know, the multiprocessing.Pool uses the same shared pipe design with two locks (read and write) so there is only one process operating on the pipe at a time. On win32 there is no write lock, though. I've never used the command server, so I need to ask: what does it do when it raises an exception? -- Isaac Jurado "The noblest pleasure is the joy of understanding" Leonardo da Vinci From laurens.nospam at grauw.nl Tue Feb 12 05:15:23 2013 From: laurens.nospam at grauw.nl (Laurens Holst) Date: Tue, 12 Feb 2013 12:15:23 +0100 Subject: [PATCH 2 of 5] dispatch: catch InterventionRequired and print the message with no prefix In-Reply-To: References: <4d997c5075c446963b6a.1360363790@augie-macbookair> <1c4102a7ec7c80a1baa9.1360363791@augie-macbookair> <51163554.5030202@kiilerich.com> <451256A9-57AB-41EF-9AC1-50D7807CEF7E@ringworld.org> <24A5EB27-857D-4CB4-B6A1-729A3137E7F4@durin42.com> Message-ID: <511A244B.1060800@grauw.nl> Op 11-02-13 22:47, Bryan O'Sullivan schreef: > On Sat, Feb 9, 2013 at 3:51 AM, Augie Fackler > wrote: > > Open to suggestions on that - I wanted a prefix but couldn't come > up with one that was clear and suitably pithy. > > > stopped? paused? suspended? needsinput? I like interrupted too, btw. It's fairly analogous to breakpoints in a debugger, might be able to use the terminology used there. ~Laurens -------------- next part -------------- An HTML attachment was scrubbed... URL: From idankk86 at gmail.com Tue Feb 12 05:15:30 2013 From: idankk86 at gmail.com (Idan Kamara) Date: Tue, 12 Feb 2013 13:15:30 +0200 Subject: [PATCH 11 of 11] merge: don't fiddle with name lookups or i18n in hot loops In-Reply-To: References: <8cf626e958d3dd67e45b.1360418801@australite.local> <994e4c0ed9a6d2ff25aa.1360418811@australite.local> <55EAC0A6-3C4E-47BD-BAF6-832A530313C8@durin42.com> Message-ID: On Tue, Feb 12, 2013 at 1:01 PM, Isaac Jurado wrote: > > On Tue, Feb 12, 2013 at 11:35 AM, Idan Kamara wrote: > > On Tue, Feb 12, 2013 at 12:12 PM, Isaac Jurado > > wrote: > >> > >> On Tue, Feb 12, 2013 at 10:26 AM, Idan Kamara > >> wrote: > >> > > >> > Maybe we should serialize the exceptions to the master and have > >> > him decide what to do (e.g. reraise)? > >> > >> That could be a problem if the serialized exception needs more than > >> 512 bytes in size. The elegance of Bryan's design relies on the fact > >> that the operating system ensures atomicity for small writes to the > >> shared pipe. > > > > Ok, and since we'd like to include the traceback, we'll most likely need > > more than 512 bytes. So unless there's a trick to be made here, we'll > > need a pipe for every worker. > > > > It might be worth looking at multiprocessing.Pool, which does all this > > and has a chance of working sensibly on Windows too (there's a > > backport of it to 2.4-5). > > As far as I know, the multiprocessing.Pool uses the same shared pipe > design with two locks (read and write) so there is only one process > operating on the pipe at a time. On win32 there is no write lock, > though. I tried to check this earlier (by looking at /proc//fd) and it seemed like each process in the pool had its own pipe, but either way, it doesn't matter. Assuming multiprocessing.Pool "just works" with no drastic performance loss, it could be beneficial to go that route for obvious reasons (also, a simple test shows it can transparently raise exceptions that came from the pool in the master). > > I've never used the command server, so I need to ask: what does it do > when it raises an exception? It's not specific to the command server. Uncaught exceptions are handled in dispatch, the module that is used to invoke top level commands. Then, they're transformed to an exit code which is returned to the caller: 'hg' simply calls sys.exit with it while other callers use it differently (command server sends it to the client and goes back to listening). -------------- next part -------------- An HTML attachment was scrubbed... URL: From pierre-yves.david at logilab.fr Tue Feb 12 05:36:24 2013 From: pierre-yves.david at logilab.fr (Pierre-Yves David) Date: Tue, 12 Feb 2013 12:36:24 +0100 Subject: [PATCH 6 of 6] blackbox: tests for the blackbox extension In-Reply-To: References: <30544b5277d09002d6ca.1360494437@dev350.prn1.facebook.com> <932a1aea1b315a2b1c6e.1360494442@dev350.prn1.facebook.com> Message-ID: <20130212113624.GA22193@crater2.logilab.fr> On Mon, Feb 11, 2013 at 01:39:57PM -0800, Bryan O'Sullivan wrote: > On Sun, Feb 10, 2013 at 4:24 AM, Brodie Rao wrote: > > > I think it's a little confusing that the date is completely globbed > > out here. Can you make the date stable and add it to the test? > > > > The date is in the output from blackbox. It doesn't make sense to me to add > a hack to make those dates constant for testing. Stable date does not make sense. Using regex instead of glob would be me accurate. > _______________________________________________ > Mercurial-devel mailing list > Mercurial-devel at selenic.com > http://selenic.com/mailman/listinfo/mercurial-devel -- Pierre-Yves David http://www.logilab.fr/ -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 198 bytes Desc: Digital signature URL: From pierre-yves.david at logilab.fr Tue Feb 12 05:41:18 2013 From: pierre-yves.david at logilab.fr (Pierre-Yves David) Date: Tue, 12 Feb 2013 12:41:18 +0100 Subject: [PATCH 1 of 6] blackbox: adds a blackbox extension In-Reply-To: References: <30544b5277d09002d6ca.1360494437@dev350.prn1.facebook.com> Message-ID: <20130212114118.GB22193@crater2.logilab.fr> On Sun, Feb 10, 2013 at 12:09:45PM +0000, Brodie Rao wrote: > > + > > + if '_blackbox' in self.__dict__: > > This seems like a weird way of checking this (it isn't the case here, > but Python objects don't always have __dict__). I think you want > util.safehasattr(). Has Brodie said: DON'T What you want to check is the existence of 'self._blackbox'. use `util.safehasattr()` (python on is broken) In the very rare case where you really want to check dict (existence in the local object namespace) use `vars` "if '_blockbox' in vars(self)" -- Pierre-Yves David http://www.logilab.fr/ -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 198 bytes Desc: Digital signature URL: From pierre-yves.david at logilab.fr Tue Feb 12 05:43:32 2013 From: pierre-yves.david at logilab.fr (Pierre-Yves David) Date: Tue, 12 Feb 2013 12:43:32 +0100 Subject: [PATCH 5 of 6] blackbox: adds a 'blackbox' command for viewing recent logs In-Reply-To: References: <30544b5277d09002d6ca.1360494437@dev350.prn1.facebook.com> <4192cc153d6f8d529723.1360494441@dev350.prn1.facebook.com> Message-ID: <20130212114332.GC22193@crater2.logilab.fr> On Sun, Feb 10, 2013 at 12:13:38PM +0000, Brodie Rao wrote: > On Sun, Feb 10, 2013 at 11:07 AM, Durham Goode wrote: > > # HG changeset patch > > # User Durham Goode > > # Date 1360429786 28800 > > # Node ID 4192cc153d6f8d529723c9df20255693b73e723a > > # Parent ee0ffe8ee86585a9842c841f7c389b037f118282 > > blackbox: adds a 'blackbox' command for viewing recent logs > > > > Adds a 'hg blackbox' command for viewing the latest entries in the blackbox log. > > By default it shows the last 10 entries, but -l allows the user to specify. > > > > diff --git a/hgext/blackbox.py b/hgext/blackbox.py > > --- a/hgext/blackbox.py > > +++ b/hgext/blackbox.py > > @@ -66,3 +66,31 @@ > > return > > > > ui.setrepo(repo) > > + > > + at command('^blackbox|bb', > > I don't think this command warrants a short alias like bb. Will it be > run that often? -1 for bb alias too. User can always defines it themself. For my part, I'm likely to use bb for a bickbucket related operation. -- Pierre-Yves David http://www.logilab.fr/ -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 198 bytes Desc: Digital signature URL: From hg at intevation.org Tue Feb 12 06:00:10 2013 From: hg at intevation.org (Mercurial Commits) Date: Tue, 12 Feb 2013 13:00:10 +0100 Subject: mercurial/crew@18668: 39 outgoing changesets (1 stable) Message-ID: <1360670410.684937.13411.nullmailer@hg.intevation.org> 39 outgoing changesets (1 stable) in mercurial/crew: http://hg.intevation.org/mercurial/crew/rev/4034b8d551b1 changeset: 18668:4034b8d551b1 bookmark: @ tag: tip user: Bryan O'Sullivan date: Mon Feb 11 16:15:12 2013 -0800 summary: scmutil: create directories in a race-safe way during update http://hg.intevation.org/mercurial/crew/rev/f12804d3ff80 changeset: 18667:f12804d3ff80 parent: 18666:fb9d1c2805ff parent: 18658:5e63a85299ba user: Bryan O'Sullivan date: Mon Feb 11 14:50:54 2013 -0800 summary: Merge http://hg.intevation.org/mercurial/crew/rev/fb9d1c2805ff changeset: 18666:fb9d1c2805ff user: Idan Kamara date: Sat Feb 09 19:02:45 2013 +0200 summary: test-atomictempfile: convert to unit test http://hg.intevation.org/mercurial/crew/rev/2cbfb8c497ee changeset: 18665:2cbfb8c497ee user: Idan Kamara date: Sat Feb 09 19:13:39 2013 +0200 summary: tests: add a test runner utility that prints nothing when all tests pass http://hg.intevation.org/mercurial/crew/rev/30d899febef8 changeset: 18664:30d899febef8 user: Dan Villiom Podlaski Christiansen date: Sun Feb 10 13:14:31 2013 +0100 summary: hgweb: consistent author name width http://hg.intevation.org/mercurial/crew/rev/05cf40f9b0ec changeset: 18663:05cf40f9b0ec user: Durham Goode date: Sun Feb 10 12:23:39 2013 -0800 summary: dirstate: fix generator/list error when using python 2.7 http://hg.intevation.org/mercurial/crew/rev/c5f7e83d47cd changeset: 18662:c5f7e83d47cd user: Pierre-Yves David date: Mon Feb 11 16:21:48 2013 +0100 summary: mq: comply with filtering when injecting fake tags (issue3812) http://hg.intevation.org/mercurial/crew/rev/4fb92f14a97a changeset: 18661:4fb92f14a97a user: David Schleimer date: Fri Feb 08 05:36:08 2013 -0800 summary: commit: factor out post-commit cleanup into workingctx http://hg.intevation.org/mercurial/crew/rev/7e6946ed5756 changeset: 18660:7e6946ed5756 user: David Schleimer date: Fri Feb 08 05:36:08 2013 -0800 summary: localrepo: use workingctx for validation in commit http://hg.intevation.org/mercurial/crew/rev/b946470efed9 changeset: 18659:b946470efed9 parent: 18656:8eb3408bf005 user: David Schleimer date: Fri Feb 08 05:36:07 2013 -0800 summary: localrepo: create context used for actual commit earlier http://hg.intevation.org/mercurial/crew/rev/5e63a85299ba changeset: 18658:5e63a85299ba parent: 18656:8eb3408bf005 parent: 18657:d4a79e075303 user: Thomas Arendsen Hein date: Mon Feb 11 16:57:46 2013 +0100 summary: merge with crew-stable http://hg.intevation.org/mercurial/crew/rev/d4a79e075303 changeset: 18657:d4a79e075303 branch: stable bookmark: crew-stable parent: 18617:227479f61db9 user: Pierre-Yves David date: Sat Feb 09 23:28:42 2013 +0000 summary: debugobsolete: improve command help http://hg.intevation.org/mercurial/crew/rev/8eb3408bf005 changeset: 18656:8eb3408bf005 user: Kevin Bullock date: Sun Feb 10 23:01:12 2013 +0000 summary: import: don't rollback on failed import --exact (issue3616) http://hg.intevation.org/mercurial/crew/rev/882681bc3166 changeset: 18655:882681bc3166 parent: 18653:170142161672 parent: 18654:d9ff580fcaa2 user: Bryan O'Sullivan date: Sun Feb 10 16:22:32 2013 -0800 summary: Merge http://hg.intevation.org/mercurial/crew/rev/d9ff580fcaa2 changeset: 18654:d9ff580fcaa2 parent: 18651:e556659340f0 parent: 18648:013fcd112f13 user: Bryan O'Sullivan date: Sun Feb 10 16:21:30 2013 -0800 summary: Merge http://hg.intevation.org/mercurial/crew/rev/170142161672 changeset: 18653:170142161672 parent: 18652:a5e94bee77ed parent: 18651:e556659340f0 user: Benoit Boissinot date: Mon Feb 11 01:21:24 2013 +0100 summary: merge crew and main http://hg.intevation.org/mercurial/crew/rev/a5e94bee77ed changeset: 18652:a5e94bee77ed parent: 18642:76b69cccb07a parent: 18648:013fcd112f13 user: Benoit Boissinot date: Mon Feb 11 01:17:50 2013 +0100 summary: merge crew and main http://hg.intevation.org/mercurial/crew/rev/e556659340f0 changeset: 18651:e556659340f0 user: Siddharth Agarwal date: Sun Feb 10 16:55:01 2013 +0000 summary: manifestmerge: fix order in which manifests are fetched http://hg.intevation.org/mercurial/crew/rev/de0bd4bfc6d7 changeset: 18650:de0bd4bfc6d7 user: Siddharth Agarwal date: Sun Feb 10 12:16:46 2013 +0000 summary: merge: run _forgetremoved after manifestmerge http://hg.intevation.org/mercurial/crew/rev/0969980308c7 changeset: 18649:0969980308c7 parent: 18642:76b69cccb07a user: Siddharth Agarwal date: Sun Feb 10 16:23:14 2013 +0000 summary: dirstate: disable gc while parsing the dirstate http://hg.intevation.org/mercurial/crew/rev/76b69cccb07a changeset: 18642:76b69cccb07a user: Mads Kiilerich date: Fri Feb 08 22:54:17 2013 +0100 summary: export: show 'Date' header in a format that also is readable for humans http://hg.intevation.org/mercurial/crew/rev/c1d23b4a66d5 changeset: 18641:c1d23b4a66d5 user: Mads Kiilerich date: Sun Feb 10 18:26:04 2013 +0100 summary: factotum: fix urllib2 import so it no longer relies on a demandimport bug http://hg.intevation.org/mercurial/crew/rev/c6a81e54c209 changeset: 18640:c6a81e54c209 user: Mads Kiilerich date: Sun Jan 27 03:32:09 2013 +0100 summary: hgweb: make the test suite use hgweb in a more WSGI compliant way http://hg.intevation.org/mercurial/crew/rev/76ff3a715cf2 changeset: 18639:76ff3a715cf2 user: Mads Kiilerich date: Sun Feb 10 18:24:29 2013 +0100 summary: hgweb: simplify internal staticfile return codes http://hg.intevation.org/mercurial/crew/rev/3e92772d5383 changeset: 18638:3e92772d5383 user: Mads Kiilerich date: Sun Feb 10 18:24:29 2013 +0100 summary: spelling: fix some minor issues found by spell checker http://hg.intevation.org/mercurial/crew/rev/cc28a84db8c9 changeset: 18637:cc28a84db8c9 user: Mads Kiilerich date: Fri Feb 08 23:26:00 2013 +0100 summary: bundlerepo: replace basemap with the base field in the index http://hg.intevation.org/mercurial/crew/rev/a40d608e2a7b changeset: 18636:a40d608e2a7b user: Mads Kiilerich date: Fri Feb 08 22:54:48 2013 +0100 summary: profiling: replace '+' markup of nested lines with indentation http://hg.intevation.org/mercurial/crew/rev/6204e4d4dd6d changeset: 18635:6204e4d4dd6d parent: 18634:0027a5cec9d0 parent: 18633:a8648f32b8ed user: Augie Fackler date: Sun Feb 10 04:04:22 2013 -0600 summary: Merge crew and main. http://hg.intevation.org/mercurial/crew/rev/a8648f32b8ed changeset: 18633:a8648f32b8ed user: Bryan O'Sullivan date: Sat Feb 09 15:51:32 2013 -0800 summary: merge: don't fiddle with name lookups or i18n in hot loops http://hg.intevation.org/mercurial/crew/rev/5774732bb5e5 changeset: 18632:5774732bb5e5 user: Bryan O'Sullivan date: Sat Feb 09 15:51:32 2013 -0800 summary: merge: apply non-interactive working dir updates in parallel http://hg.intevation.org/mercurial/crew/rev/047110c0e2a8 changeset: 18631:047110c0e2a8 user: Bryan O'Sullivan date: Sat Feb 09 15:51:32 2013 -0800 summary: worker: allow a function to be run in multiple worker processes http://hg.intevation.org/mercurial/crew/rev/ac4dbceeb14a changeset: 18630:ac4dbceeb14a user: Bryan O'Sullivan date: Sat Feb 09 15:51:32 2013 -0800 summary: worker: partition a list (of tasks) into equal-sized chunks http://hg.intevation.org/mercurial/crew/rev/dcb27c153a40 changeset: 18629:dcb27c153a40 user: Bryan O'Sullivan date: Sat Feb 09 15:51:26 2013 -0800 summary: worker: estimate whether it's worth running a task in parallel http://hg.intevation.org/mercurial/crew/rev/fed06dd07665 changeset: 18628:fed06dd07665 user: Bryan O'Sullivan date: Sat Feb 09 15:22:12 2013 -0800 summary: worker: count the number of CPUs http://hg.intevation.org/mercurial/crew/rev/4b5d37ca3c11 changeset: 18627:4b5d37ca3c11 user: Bryan O'Sullivan date: Sat Feb 09 15:22:10 2013 -0800 summary: tests: getremove test output changes (fold into previous patch) http://hg.intevation.org/mercurial/crew/rev/6390dd22b12f changeset: 18626:6390dd22b12f user: Bryan O'Sullivan date: Sat Feb 09 15:22:09 2013 -0800 summary: merge: report non-interactive progress in chunks http://hg.intevation.org/mercurial/crew/rev/3e20079117c5 changeset: 18625:3e20079117c5 user: Bryan O'Sullivan date: Sat Feb 09 15:22:08 2013 -0800 summary: merge: handle subrepo merges and .hgsubstate specially http://hg.intevation.org/mercurial/crew/rev/e2dc5397bc82 changeset: 18624:e2dc5397bc82 user: Bryan O'Sullivan date: Sat Feb 09 15:22:04 2013 -0800 summary: tests: update test output (will be folded into parent) http://hg.intevation.org/mercurial/crew/rev/9b9e2d9e83a1 changeset: 18623:9b9e2d9e83a1 user: Bryan O'Sullivan date: Sat Feb 09 15:21:58 2013 -0800 summary: merge: split out mostly-non-interactive working dir updates -- Repository URL: http://hg.intevation.org/mercurial/crew From markuszapke at gmx.net Tue Feb 12 06:09:43 2013 From: markuszapke at gmx.net (=?UTF-8?B?TWFya3VzIFphcGtlLUdyw7xuZGVtYW5u?=) Date: Tue, 12 Feb 2013 13:09:43 +0100 Subject: [PATCH RESEND] hgweb: add group authorization In-Reply-To: References: <51138D89.2060904@kiilerich.com> Message-ID: <511A3107.2020400@gmx.net> Markus Zapke-Gr?ndemann schrieb: > # HG changeset patch > # User Markus Zapke-Gr?ndemann > # Date 1360231888 -3600 > # Node ID d2dbfdee987a51efb6f4ad69e3b116aa22553326 > # Parent 2fefd1170bf269e26bb304553009f38e0117c342 > hgweb: add group authorization. Here is a description how to use group authorization. This is also part of the patch for the documentation. With the patch it is possible to use groups together with usernames in the allow_read, allow_write, deny_read and deny_write lists. A group name is prefixed by an @. Groups can either be groups defined in the groups_section (explained below) or Unix groups. If a group from the groups_section has the same name as an Unix group it is used instead. The groups_section Name of hgrc section used to define groups for authorization. Default is web.groups. Use the section to define the groups used by authorization. Example: [web] allow_read = @devs [web.groups] devs = alice, bob, clara, david Groups can contain other groups: [web] allow_read = @devs, @testers allow_push = @devs [web.groups] devs = alice, bob, clara, david ci = hudson testers = @ci, lisa, mario Regards Markus From thomas at intevation.de Tue Feb 12 06:23:54 2013 From: thomas at intevation.de (Thomas Arendsen Hein) Date: Tue, 12 Feb 2013 13:23:54 +0100 Subject: [PATCH] scmutil: create directories in a race-safe way during update In-Reply-To: <4034b8d551b116b88292.1360628151@australite.local> References: <4034b8d551b116b88292.1360628151@australite.local> Message-ID: <20130212131620.936360265.thomas@intevation.de> * Bryan O'Sullivan [20130212 01:16]: > # HG changeset patch > # User Bryan O'Sullivan > # Date 1360628112 28800 > # Node ID 4034b8d551b116b882920466e1d209e475a62721 > # Parent f12804d3ff801b989cb2aab1aad93047a8db46f1 > scmutil: create directories in a race-safe way during update > +def ensuredirs(name, mode=None): > + """race-safe recursive directory creation""" > + try: > + makedirs(name, mode) > + except OSError, err: > + if err.errno == errno.EEXIST and os.path.isdir(name): > + # someone else seems to have won a directory creation race > + return > + raise > + This is not completely race-safe as makedirs uses recursion, which can abort too early when one worker is much faster than the other: Concurrent runs of ensuredirs('a/b/c') and ensuredirs('a/b/d'), initially 'a' does not exist: Worker 1: | Worker 2: ---------------------------------+---------------------------- mkdir1('a/b/c') | mkdir1('a/b/d') -> ENOENT | -> ENOENT makedirs('a/b') | mkdir1('a/b') | -> ENOENT | | makedirs('a/b') | mkdir1('a/b') | -> ENOENT | makedirs('a') | mkdir1('a') | -> OK | mkdir2('a/b') | -> OK | mkdir2('d') makedirs('a') | mkdir2('a/b') | -> EEXIST | mkdir2('a/b/c') is not executed! | OSError with EEXIST is raised. | mkdir1 is the call to os.mkdir in the try part of makedirs(), mkdir2 is the call in the except part. Regards, Thomas -- thomas at intevation.de - http://intevation.de/~thomas/ - OpenPGP key: 0x5816791A Intevation GmbH, Neuer Graben 17, 49074 Osnabrueck - AG Osnabrueck, HR B 18998 Geschaeftsfuehrer: Frank Koormann, Bernhard Reiter, Dr. Jan-Oliver Wagner From pierre-yves.david at logilab.fr Tue Feb 12 07:38:29 2013 From: pierre-yves.david at logilab.fr (Pierre-Yves David) Date: Tue, 12 Feb 2013 14:38:29 +0100 Subject: [PATCH] commit: add --reuse-message for keeping the old commit message during amend In-Reply-To: References: <96e2d74e5f7b32221480.1360409715@dev350.prn1.facebook.com> Message-ID: <20130212133829.GE22193@crater2.logilab.fr> On Sun, Feb 10, 2013 at 11:45:06AM +0000, Brodie Rao wrote: > On Sat, Feb 9, 2013 at 11:35 AM, Durham Goode wrote: > > # HG changeset patch > > # User Durham Goode > > # Date 1360352769 28800 > > # Node ID 96e2d74e5f7b32221480fc7932c9555c84f10670 > > # Parent e2b176cf28e374eb146c3e131871631ab9ace537 > > commit: add --reuse-message for keeping the old commit message during amend > > > > When people do 'hg commit --amend', most of the time they don't want to change > > the commit message. This adds a flag to do that without prompting the user. > > > > I imagine most people will use it in an alias such as: > > > > amend=commit --amend --reuse-message > > What happens if you specify --reuse-message without --amend? Should > that raise an error? Pinging the question. -- Pierre-Yves David http://www.logilab.fr/ -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 198 bytes Desc: Digital signature URL: From pierre-yves.david at logilab.fr Tue Feb 12 07:51:30 2013 From: pierre-yves.david at logilab.fr (Pierre-Yves David) Date: Tue, 12 Feb 2013 14:51:30 +0100 Subject: [PATCH 13 of 19] context: separateworkingctx stats and raw status In-Reply-To: <24D36E1F-344E-4B29-BD9C-475A81DE4E85@ringworld.org> References: <07bdd03d86dcce1558d7.1360538991@dev010.prn1.facebook.com> <1bae6048dd1028bb6b75.1360539003@dev010.prn1.facebook.com> <24D36E1F-344E-4B29-BD9C-475A81DE4E85@ringworld.org> Message-ID: <20130212135130.GF22193@crater2.logilab.fr> On Mon, Feb 11, 2013 at 03:28:20AM +0000, Kevin Bullock wrote: > On 10 Feb 2013, at 11:30 PM, David Schleimer wrote: > > > # HG changeset patch > > # User David Schleimer > > # Date 1360413190 28800 > > # Node ID 1bae6048dd1028bb6b7506ec1ecb73bd819e7449 > > # Parent cb00b77bc8e24c68b5b4df5e484f7c005f12d2d1 > > context: separateworkingctx stats and raw status > > > > Split the workingctx _status property cache into _status, which is > > possibly filtered, and _rawstatus which is never filtered. By > > default, _status proxies to _rawstatus, and then replaces itself with > > the results. Calling status() will update the _status property. > > Subsequent changes will change status() to sometimes result in > > filtered changes getting written to _status. the point of this change > > is to make sure the workingctx will have access to the unfiltered > > status. > > "Filtered" and "unfiltered" are terms that are throwing me off in this context, because we use those terms for the repo and changelog already. Can we be more explicit about how we're describing the new function? > I think it is about "matching" here. Stuff that -X and -I does -- Pierre-Yves David http://www.logilab.fr/ -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 198 bytes Desc: Digital signature URL: From pierre-yves.david at logilab.fr Tue Feb 12 07:57:55 2013 From: pierre-yves.david at logilab.fr (Pierre-Yves David) Date: Tue, 12 Feb 2013 14:57:55 +0100 Subject: [PATCH 14 of 19] context: support matches in workingctx.status In-Reply-To: <730f81cd4b340348dfc5.1360539004@dev010.prn1.facebook.com> References: <07bdd03d86dcce1558d7.1360538991@dev010.prn1.facebook.com> <730f81cd4b340348dfc5.1360539004@dev010.prn1.facebook.com> Message-ID: <20130212135755.GG22193@crater2.logilab.fr> On Sun, Feb 10, 2013 at 03:30:04PM -0800, David Schleimer wrote: > # HG changeset patch > # User David Schleimer > # Date 1360424562 28800 > # Node ID 730f81cd4b340348dfc5d2eb571f3b13e01c73e4 > # Parent 1bae6048dd1028bb6b7506ec1ecb73bd819e7449 > context: support matches in workingctx.status > > This makes it possible to get a filtered view of the workingcopy via > workingctx.status(). This is currently unused, but subsequent patches > will use this to pull validation steps out of localrepo.commit and > into the workingctx. This in turn will make it practical to unify > workingctx and memctx, making memctx more useful. As Kevin said, if you could avoid using *filtered* *view* that would be a big win. Restricted or reduced maybe. -- Pierre-Yves David http://www.logilab.fr/ -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 198 bytes Desc: Digital signature URL: From pierre-yves.david at logilab.fr Tue Feb 12 07:59:15 2013 From: pierre-yves.david at logilab.fr (Pierre-Yves David) Date: Tue, 12 Feb 2013 14:59:15 +0100 Subject: [PATCH 16 of 19] localrepo: use workingcontext members instead of changes array during commit In-Reply-To: <486ffe802a0386d1aafa.1360539006@dev010.prn1.facebook.com> References: <07bdd03d86dcce1558d7.1360538991@dev010.prn1.facebook.com> <486ffe802a0386d1aafa.1360539006@dev010.prn1.facebook.com> Message-ID: <20130212135915.GH22193@crater2.logilab.fr> On Sun, Feb 10, 2013 at 03:30:06PM -0800, David Schleimer wrote: > This changes localrepo.commit from building an array of changes, and > constructing a new workingcontext from that array to constructiong a > workingcotext, calling it's status method to fill in it's lists of > changes, and hten munging those lists. this is preperatory to moving > the actual munging logic into workingcontext. I also believe this > diff is a readability improvement, since it uses named methods rather > than integer list indeces to access the various file lists. Yes big readability win down there. -- Pierre-Yves David http://www.logilab.fr/ -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 198 bytes Desc: Digital signature URL: From pierre-yves.david at logilab.fr Tue Feb 12 08:10:39 2013 From: pierre-yves.david at logilab.fr (Pierre-Yves David) Date: Tue, 12 Feb 2013 15:10:39 +0100 Subject: [PATCH 05 of 19] localrepo: update commit to use setter and getter for description In-Reply-To: <56ec15753a5264b0713b.1360538995@dev010.prn1.facebook.com> References: <07bdd03d86dcce1558d7.1360538991@dev010.prn1.facebook.com> <56ec15753a5264b0713b.1360538995@dev010.prn1.facebook.com> Message-ID: <20130212141039.GI22193@crater2.logilab.fr> On Sun, Feb 10, 2013 at 03:29:55PM -0800, David Schleimer wrote: > # HG changeset patch > # User David Schleimer > # Date 1360330569 28800 > # Node ID 56ec15753a5264b0713bf5cafa484f342d1803c7 > # Parent f5a6e68310f238e490c6157cf2e4c9725baa1691 > localrepo: update commit to use setter and getter for description 1) The setdescription name is really ugly. I do not have good non ugly alternative in mind yet This changes (and later related one) can be used in amend and histedit (at least). Consider updating them too. That would give you an easy way to validated your new method o:-) -- Pierre-Yves David http://www.logilab.fr/ -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 198 bytes Desc: Digital signature URL: From pierre-yves.david at logilab.fr Tue Feb 12 08:16:36 2013 From: pierre-yves.david at logilab.fr (Pierre-Yves David) Date: Tue, 12 Feb 2013 15:16:36 +0100 Subject: [PATCH v2] amend: support amending merge changesets (issue3778) In-Reply-To: References: Message-ID: <20130212141636.GJ22193@crater2.logilab.fr> On Sat, Feb 09, 2013 at 05:55:15PM +0000, Brodie Rao wrote: > # HG changeset patch > # User Brodie Rao > # Date 1360357714 0 > # Node ID a7a029fb74d698deccb925807672c7d7328ac1be > # Parent 2fefd1170bf269e26bb304553009f38e0117c342 > amend: support amending merge changesets (issue3778) This changesets look good to me, the test looks pretty solid. I've two minor comment that does not deserve a resent. > + $ hg log --config diff.git=1 -pr . note: you could probably set the config to git globally note: I would use export. -- Pierre-Yves David http://www.logilab.fr/ -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 198 bytes Desc: Digital signature URL: From pierre-yves.david at logilab.fr Tue Feb 12 08:17:43 2013 From: pierre-yves.david at logilab.fr (Pierre-Yves David) Date: Tue, 12 Feb 2013 15:17:43 +0100 Subject: [PATCH] commit: add --reuse-message for keeping the old commit message during amend In-Reply-To: <96e2d74e5f7b32221480.1360409715@dev350.prn1.facebook.com> References: <96e2d74e5f7b32221480.1360409715@dev350.prn1.facebook.com> Message-ID: <20130212141743.GK22193@crater2.logilab.fr> On Sat, Feb 09, 2013 at 03:35:15AM -0800, Durham Goode wrote: > # HG changeset patch > # User Durham Goode > # Date 1360352769 28800 > # Node ID 96e2d74e5f7b32221480fc7932c9555c84f10670 > # Parent e2b176cf28e374eb146c3e131871631ab9ace537 > commit: add --reuse-message for keeping the old commit message during amend > > When people do 'hg commit --amend', most of the time they don't want to change > the commit message. This adds a flag to do that without prompting the user. > > I imagine most people will use it in an alias such as: > > amend=commit --amend --reuse-message the git --reuse-measage have a different semantic. we *NEED* another name. -- Pierre-Yves David http://www.logilab.fr/ -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 198 bytes Desc: Digital signature URL: From idankk86 at gmail.com Tue Feb 12 08:33:23 2013 From: idankk86 at gmail.com (Idan Kamara) Date: Tue, 12 Feb 2013 16:33:23 +0200 Subject: [PATCH RFC] commit: add --reuse-message for keeping the old commit message during amend In-Reply-To: References: Message-ID: On Fri, Feb 8, 2013 at 11:34 PM, Durham Goode wrote: > > # HG changeset patch > # User Durham Goode > # Date 1360352769 28800 > # Node ID a761c31f54ca302d65b33199f6c9368890267eba > # Parent e2b176cf28e374eb146c3e131871631ab9ace537 > commit: add --reuse-message for keeping the old commit message during > amend > > When people do 'hg commit --amend', most of the time they don't want to > change > the commit message. This adds a flag to do that without prompting the > user. > > I imagine most people will use it in an alias such as: > > amend=commit --amend --reuse-message > > Questions: > - Anyone have a better name? 'reuse-message' matches git which is why it > was > chosen, but it seems a little long. What about something generic like --no-editor? It's not as explicit but we already have --editor which forces an editor, so this will do the opposite. It also opens up the possibility of appearing in other commands with similar semantics but without being directly related to amend. -------------- next part -------------- An HTML attachment was scrubbed... URL: From angel.ezquerra at gmail.com Tue Feb 12 08:40:50 2013 From: angel.ezquerra at gmail.com (Angel Ezquerra) Date: Tue, 12 Feb 2013 15:40:50 +0100 Subject: [PATCH] commit: add --reuse-message for keeping the old commit message during amend In-Reply-To: <20130212141743.GK22193@crater2.logilab.fr> References: <96e2d74e5f7b32221480.1360409715@dev350.prn1.facebook.com> <20130212141743.GK22193@crater2.logilab.fr> Message-ID: On Feb 12, 2013 3:17 PM, "Pierre-Yves David" wrote: > > On Sat, Feb 09, 2013 at 03:35:15AM -0800, Durham Goode wrote: > > # HG changeset patch > > # User Durham Goode > > # Date 1360352769 28800 > > # Node ID 96e2d74e5f7b32221480fc7932c9555c84f10670 > > # Parent e2b176cf28e374eb146c3e131871631ab9ace537 > > commit: add --reuse-message for keeping the old commit message during amend > > > > When people do 'hg commit --amend', most of the time they don't want to change > > the commit message. This adds a flag to do that without prompting the user. > > > > I imagine most people will use it in an alias such as: > > > > amend=commit --amend --reuse-message > > the git --reuse-measage have a different semantic. we *NEED* another name. > > -- > Pierre-Yves David What about "--keepmessage"? Angel -------------- next part -------------- An HTML attachment was scrubbed... URL: From diptongo at gmail.com Tue Feb 12 09:03:49 2013 From: diptongo at gmail.com (Isaac Jurado) Date: Tue, 12 Feb 2013 16:03:49 +0100 Subject: [PATCH 11 of 11] merge: don't fiddle with name lookups or i18n in hot loops In-Reply-To: References: <8cf626e958d3dd67e45b.1360418801@australite.local> <994e4c0ed9a6d2ff25aa.1360418811@australite.local> <55EAC0A6-3C4E-47BD-BAF6-832A530313C8@durin42.com> Message-ID: On Tue, Feb 12, 2013 at 12:15 PM, Idan Kamara wrote: > On Tue, Feb 12, 2013 at 1:01 PM, Isaac Jurado wrote: >> As far as I know, the multiprocessing.Pool uses the same shared pipe >> design with two locks (read and write) so there is only one process >> operating on the pipe at a time. On win32 there is no write lock, >> though. > > I tried to check this earlier (by looking at /proc//fd) and it seemed > like each process in the pool had its own pipe, but either way, it doesn't > matter. I didn't think about checking that (silly me), I just overviewed the code. > Assuming multiprocessing.Pool "just works" with no drastic performance > loss, it could be beneficial to go that route for obvious reasons (also, > a simple test shows it can transparently raise exceptions that came > from the pool in the master). To be honest, the multiprocessing module does some pretty weird things, like squences of peek + sleep or threading in the parent process to combine data from different pipes into one queue. I've always had the sensation of not really knowing what's going on behind the scenes. And for process management code, that really creeps me out. But it's just my humble opinion. > It's not specific to the command server. Uncaught exceptions are > handled in dispatch, the module that is used to invoke top level > commands. Then, they're transformed to an exit code which is returned > to the caller: 'hg' simply calls sys.exit with it while other callers use it > differently (command server sends it to the client and goes back to > listening). Right, so the communication is not really dropped. The command server uses pipes, is that right? -- Isaac Jurado "The noblest pleasure is the joy of understanding" Leonardo da Vinci From idankk86 at gmail.com Tue Feb 12 09:48:30 2013 From: idankk86 at gmail.com (Idan Kamara) Date: Tue, 12 Feb 2013 17:48:30 +0200 Subject: [PATCH 11 of 11] merge: don't fiddle with name lookups or i18n in hot loops In-Reply-To: References: <8cf626e958d3dd67e45b.1360418801@australite.local> <994e4c0ed9a6d2ff25aa.1360418811@australite.local> <55EAC0A6-3C4E-47BD-BAF6-832A530313C8@durin42.com> Message-ID: On Tue, Feb 12, 2013 at 5:03 PM, Isaac Jurado wrote: > > On Tue, Feb 12, 2013 at 12:15 PM, Idan Kamara wrote: > > On Tue, Feb 12, 2013 at 1:01 PM, Isaac Jurado > > wrote: > >> As far as I know, the multiprocessing.Pool uses the same shared pipe > >> design with two locks (read and write) so there is only one process > >> operating on the pipe at a time. On win32 there is no write lock, > >> though. > > > > I tried to check this earlier (by looking at /proc//fd) and it > > seemed > > like each process in the pool had its own pipe, but either way, it > > doesn't > > matter. > > I didn't think about checking that (silly me), I just overviewed the code. > > > Assuming multiprocessing.Pool "just works" with no drastic performance > > loss, it could be beneficial to go that route for obvious reasons (also, > > a simple test shows it can transparently raise exceptions that came > > from the pool in the master). > > To be honest, the multiprocessing module does some pretty weird > things, like squences of peek + sleep or threading in the parent > process to combine data from different pipes into one queue. I've > always had the sensation of not really knowing what's going on behind > the scenes. And for process management code, that really creeps me > out. But it's just my humble opinion. My experience with it is fairly superficial so you could be right. But it was just a suggestion that going with something that (should be) fairly well tested and cross-platform could help us in the long run. Perhaps someone who used it more extensively can weigh in. > > > It's not specific to the command server. Uncaught exceptions are > > handled in dispatch, the module that is used to invoke top level > > commands. Then, they're transformed to an exit code which is returned > > to the caller: 'hg' simply calls sys.exit with it while other callers > > use it > > differently (command server sends it to the client and goes back to > > listening). > > Right, so the communication is not really dropped. The command server > uses pipes, is that right? Yes, although there's at least one implementation out there (that I know of) that uses sockets. -------------- next part -------------- An HTML attachment was scrubbed... URL: From bos at serpentine.com Tue Feb 12 10:27:47 2013 From: bos at serpentine.com (Bryan O'Sullivan) Date: Tue, 12 Feb 2013 08:27:47 -0800 Subject: [PATCH 11 of 11] merge: don't fiddle with name lookups or i18n in hot loops In-Reply-To: References: <8cf626e958d3dd67e45b.1360418801@australite.local> <994e4c0ed9a6d2ff25aa.1360418811@australite.local> <55EAC0A6-3C4E-47BD-BAF6-832A530313C8@durin42.com> Message-ID: On Tue, Feb 12, 2013 at 7:48 AM, Idan Kamara wrote: > My experience with it is fairly superficial so you could be right. But > it was just a suggestion that going with something that (should be) > fairly well tested and cross-platform could help us in the long run. > multiprocessing is a non-starter for the simple reason that we still need to support Python < 2.6. It's also just kind of horrendous in every way, which I admit sways me. -------------- next part -------------- An HTML attachment was scrubbed... URL: From idankk86 at gmail.com Tue Feb 12 10:29:23 2013 From: idankk86 at gmail.com (Idan Kamara) Date: Tue, 12 Feb 2013 18:29:23 +0200 Subject: [PATCH 11 of 11] merge: don't fiddle with name lookups or i18n in hot loops In-Reply-To: References: <8cf626e958d3dd67e45b.1360418801@australite.local> <994e4c0ed9a6d2ff25aa.1360418811@australite.local> <55EAC0A6-3C4E-47BD-BAF6-832A530313C8@durin42.com> Message-ID: On Tue, Feb 12, 2013 at 6:27 PM, Bryan O'Sullivan wrote: > > On Tue, Feb 12, 2013 at 7:48 AM, Idan Kamara wrote: >> >> My experience with it is fairly superficial so you could be right. But >> it was just a suggestion that going with something that (should be) >> fairly well tested and cross-platform could help us in the long run. > > > multiprocessing is a non-starter for the simple reason that we still need > to support Python < 2.6. It's also just kind of horrendous in every way, > which I admit sways me. http://pypi.python.org/pypi/multiprocessing/ From bos at serpentine.com Tue Feb 12 11:03:34 2013 From: bos at serpentine.com (Bryan O'Sullivan) Date: Tue, 12 Feb 2013 09:03:34 -0800 Subject: [PATCH] scmutil: create directories in a race-safe way during update In-Reply-To: <20130212131620.936360265.thomas@intevation.de> References: <4034b8d551b116b88292.1360628151@australite.local> <20130212131620.936360265.thomas@intevation.de> Message-ID: On Tue, Feb 12, 2013 at 4:23 AM, Thomas Arendsen Hein wrote: > This is not completely race-safe as makedirs uses recursion, which > can abort too early when one worker is much faster than the other: > That's a good point. I'll take a second stab at it later this morning. -------------- next part -------------- An HTML attachment was scrubbed... URL: From bos at serpentine.com Tue Feb 12 11:58:51 2013 From: bos at serpentine.com (Bryan O'Sullivan) Date: Tue, 12 Feb 2013 09:58:51 -0800 Subject: [PATCH 05 of 19] localrepo: update commit to use setter and getter for description In-Reply-To: <20130212141039.GI22193@crater2.logilab.fr> References: <07bdd03d86dcce1558d7.1360538991@dev010.prn1.facebook.com> <56ec15753a5264b0713b.1360538995@dev010.prn1.facebook.com> <20130212141039.GI22193@crater2.logilab.fr> Message-ID: On Tue, Feb 12, 2013 at 6:10 AM, Pierre-Yves David < pierre-yves.david at logilab.fr> wrote: > 1) The setdescription name is really ugly. I do not have good non ugly > alternative in mind yet > I think the name is fine. That said, setdesc would also be fine. -------------- next part -------------- An HTML attachment was scrubbed... URL: From bos at serpentine.com Tue Feb 12 12:23:45 2013 From: bos at serpentine.com (Bryan O'Sullivan) Date: Tue, 12 Feb 2013 10:23:45 -0800 Subject: Google Summer of Code is on again this year Message-ID: Mentoring organizations need to have applications in between March 18 and March 29. http://www.google-melange.com/gsoc/events/google/gsoc2013 -------------- next part -------------- An HTML attachment was scrubbed... URL: From durham at fb.com Tue Feb 12 15:02:22 2013 From: durham at fb.com (Durham Goode) Date: Tue, 12 Feb 2013 21:02:22 +0000 Subject: [PATCH] commit: add --reuse-message for keeping the old commit message during amend In-Reply-To: <20130212133829.GE22193@crater2.logilab.fr> Message-ID: <2B10A89294DA6740AC6155F56842F9CE0565A365@PRN-MBX01-2.TheFacebook.com> I've added code locally that will abort with a message if they use it without --amend. It'll be part of the V2 patch. On 2/12/13 1:38 PM, "Pierre-Yves David" wrote: >On Sun, Feb 10, 2013 at 11:45:06AM +0000, Brodie Rao wrote: >> On Sat, Feb 9, 2013 at 11:35 AM, Durham Goode wrote: >> > # HG changeset patch >> > # User Durham Goode >> > # Date 1360352769 28800 >> > # Node ID 96e2d74e5f7b32221480fc7932c9555c84f10670 >> > # Parent e2b176cf28e374eb146c3e131871631ab9ace537 >> > commit: add --reuse-message for keeping the old commit message during >>amend >> > >> > When people do 'hg commit --amend', most of the time they don't want >>to change >> > the commit message. This adds a flag to do that without prompting >>the user. >> > >> > I imagine most people will use it in an alias such as: >> > >> > amend=commit --amend --reuse-message >> >> What happens if you specify --reuse-message without --amend? Should >> that raise an error? > >Pinging the question. > >-- >Pierre-Yves David > >http://www.logilab.fr/ > From durham at fb.com Tue Feb 12 15:08:32 2013 From: durham at fb.com (Durham Goode) Date: Tue, 12 Feb 2013 21:08:32 +0000 Subject: [PATCH RFC] commit: add --reuse-message for keeping the old commit message during amend In-Reply-To: Message-ID: <2B10A89294DA6740AC6155F56842F9CE0565A37B@PRN-MBX01-2.TheFacebook.com> > What about something generic like --no-editor? It's not as explicit > but we already have --editor which forces an editor, so this will do > the opposite. > > It also opens up the possibility of appearing in other commands with > similar semantics but without being directly related to amend. I think the name must imply some relationship with another commit, so it's semi intuitive that it's related to --amend. I think a user would be more likely to try --no-editor without --amend, and be confused when it failed. From simohe at besonet.ch Tue Feb 12 15:16:53 2013 From: simohe at besonet.ch (Simon Heimberg) Date: Tue, 12 Feb 2013 22:16:53 +0100 Subject: [PATCH] dispatch: also a separate warning message on aliases with --config Message-ID: <100c99318e8d112bc5d3.1360703813@lapsi.heimberg.home> # HG changeset patch # User Simon Heimberg # Date 1360703731 -3600 # Node ID 100c99318e8d112bc5d3f0d3508a500196f2a617 # Parent cbb8e2aa2162297859daeebbeabd40ed87797588 dispatch: also a separate warning message on aliases with --config As mentioned in bug 2043, --config is also not supported in an alias. So report this the same way as the other "early" options. Example with alias.broken = stat --config a.config=1 Before: $ hg broken abort: Option --config may not be abbreviated! After: $ hg broken error in definition for alias 'broken': --config may only be given on the command line diff -r cbb8e2aa2162 -r 100c99318e8d mercurial/dispatch.py --- a/mercurial/dispatch.py Mon Okt 15 23:28:45 2012 +0200 +++ b/mercurial/dispatch.py Die Feb 12 22:15:31 2013 +0100 @@ -333,7 +333,7 @@ self.cmdname = cmd = args.pop(0) args = map(util.expandpath, args) - for invalidarg in ("--cwd", "-R", "--repository", "--repo"): + for invalidarg in ("--cwd", "-R", "--repository", "--repo", "--config"): if _earlygetopt([invalidarg], args): def fn(ui, *args): ui.warn(_("error in definition for alias '%s': %s may only " diff -r cbb8e2aa2162 -r 100c99318e8d tests/test-alias.t --- a/tests/test-alias.t Mon Okt 15 23:28:45 2012 +0200 +++ b/tests/test-alias.t Die Feb 12 22:15:31 2013 +0100 @@ -17,6 +17,7 @@ > no-R = status -R elsewhere > no--repo = status --repo elsewhere > no--repository = status --repository elsewhere + > no--config = status --config a.config=1 > mylog = log > lognull = log -r null > shortlog = log --template '{rev} {node|short} | {date|isodate}\n' @@ -106,6 +107,8 @@ error in definition for alias 'no--repository': --repository may only be given on the command line $ hg help no--repository error in definition for alias 'no--repository': --repository may only be given on the command line + $ hg no--config + error in definition for alias 'no--config': --config may only be given on the command line optional repository From idankk86 at gmail.com Tue Feb 12 15:16:42 2013 From: idankk86 at gmail.com (Idan Kamara) Date: Tue, 12 Feb 2013 23:16:42 +0200 Subject: [PATCH RFC] commit: add --reuse-message for keeping the old commit message during amend In-Reply-To: <2B10A89294DA6740AC6155F56842F9CE0565A37B@PRN-MBX01-2.TheFacebook.com> References: <2B10A89294DA6740AC6155F56842F9CE0565A37B@PRN-MBX01-2.TheFacebook.com> Message-ID: On Tue, Feb 12, 2013 at 11:08 PM, Durham Goode wrote: >> What about something generic like --no-editor? It's not as explicit >> but we already have --editor which forces an editor, so this will do >> the opposite. >> >> It also opens up the possibility of appearing in other commands with >> similar semantics but without being directly related to amend. > > I think the name must imply some relationship with another commit, so it's > semi intuitive that it's related to --amend. I think a user would be more > likely to try --no-editor without --amend, and be confused when it failed. The help text should (regardless of the name) say that this option is only relevant when used with --amend. -------------- next part -------------- An HTML attachment was scrubbed... URL: From durham at fb.com Tue Feb 12 15:16:36 2013 From: durham at fb.com (Durham Goode) Date: Tue, 12 Feb 2013 21:16:36 +0000 Subject: [PATCH] commit: add --reuse-message for keeping the old commit message during amend In-Reply-To: Message-ID: <2B10A89294DA6740AC6155F56842F9CE0565A39F@PRN-MBX01-2.TheFacebook.com> >> >> the git --reuse-measage have a different semantic. we *NEED* another >>name. >> >> -- >> Pierre-Yves David > > What about "--keepmessage"? > Angel --keep-message was what I had in mind originally, but others thought using git's flag might make it easier for git refugees. I don't think the slightly different semantic means we can't use the same name. Both names are descriptive enough and both are long, so I don't think there's any real difference. -Durham From raf at durin42.com Tue Feb 12 15:47:37 2013 From: raf at durin42.com (Augie Fackler) Date: Tue, 12 Feb 2013 16:47:37 -0500 Subject: [PATCH] dispatch: also a separate warning message on aliases with --config In-Reply-To: <100c99318e8d112bc5d3.1360703813@lapsi.heimberg.home> References: <100c99318e8d112bc5d3.1360703813@lapsi.heimberg.home> Message-ID: <53E24870-AE57-4A1D-83D1-B5B6B2368979@durin42.com> Queued, thanks. On Feb 12, 2013, at 4:16 PM, Simon Heimberg wrote: > # HG changeset patch > # User Simon Heimberg > # Date 1360703731 -3600 > # Node ID 100c99318e8d112bc5d3f0d3508a500196f2a617 > # Parent cbb8e2aa2162297859daeebbeabd40ed87797588 > dispatch: also a separate warning message on aliases with --config > > As mentioned in bug 2043, --config is also not supported in an alias. So report > this the same way as the other "early" options. > > Example with alias.broken = stat --config a.config=1 > > Before: > $ hg broken > abort: Option --config may not be abbreviated! > > After: > $ hg broken > error in definition for alias 'broken': --config may only be given on the command line > > diff -r cbb8e2aa2162 -r 100c99318e8d mercurial/dispatch.py > --- a/mercurial/dispatch.py Mon Okt 15 23:28:45 2012 +0200 > +++ b/mercurial/dispatch.py Die Feb 12 22:15:31 2013 +0100 > @@ -333,7 +333,7 @@ > self.cmdname = cmd = args.pop(0) > args = map(util.expandpath, args) > > - for invalidarg in ("--cwd", "-R", "--repository", "--repo"): > + for invalidarg in ("--cwd", "-R", "--repository", "--repo", "--config"): > if _earlygetopt([invalidarg], args): > def fn(ui, *args): > ui.warn(_("error in definition for alias '%s': %s may only " > diff -r cbb8e2aa2162 -r 100c99318e8d tests/test-alias.t > --- a/tests/test-alias.t Mon Okt 15 23:28:45 2012 +0200 > +++ b/tests/test-alias.t Die Feb 12 22:15:31 2013 +0100 > @@ -17,6 +17,7 @@ >> no-R = status -R elsewhere >> no--repo = status --repo elsewhere >> no--repository = status --repository elsewhere > + > no--config = status --config a.config=1 >> mylog = log >> lognull = log -r null >> shortlog = log --template '{rev} {node|short} | {date|isodate}\n' > @@ -106,6 +107,8 @@ > error in definition for alias 'no--repository': --repository may only be given on the command line > $ hg help no--repository > error in definition for alias 'no--repository': --repository may only be given on the command line > + $ hg no--config > + error in definition for alias 'no--config': --config may only be given on the command line > > optional repository > > _______________________________________________ > Mercurial-devel mailing list > Mercurial-devel at selenic.com > http://selenic.com/mailman/listinfo/mercurial-devel From raf at durin42.com Tue Feb 12 15:48:32 2013 From: raf at durin42.com (Augie Fackler) Date: Tue, 12 Feb 2013 16:48:32 -0500 Subject: [PATCH RFC] commit: add --reuse-message for keeping the old commit message during amend In-Reply-To: References: <2B10A89294DA6740AC6155F56842F9CE0565A37B@PRN-MBX01-2.TheFacebook.com> Message-ID: <0B39C5AD-4CE4-4A34-A296-0694304B0A2E@durin42.com> On Feb 12, 2013, at 4:16 PM, Idan Kamara wrote: > On Tue, Feb 12, 2013 at 11:08 PM, Durham Goode wrote: >>> What about something generic like --no-editor? It's not as explicit >>> but we already have --editor which forces an editor, so this will do >>> the opposite. >>> >>> It also opens up the possibility of appearing in other commands with >>> similar semantics but without being directly related to amend. >> >> I think the name must imply some relationship with another commit, so it's >> semi intuitive that it's related to --amend. I think a user would be more >> likely to try --no-editor without --amend, and be confused when it failed. > > The help text should (regardless of the name) say that this option is only > relevant when used with --amend. Strawman alternative: a --fast-amend option that doesn't pop up an editor, so you can pass only one flag (that is, --fast-amend would be like --amend --reuse-message). > _______________________________________________ > Mercurial-devel mailing list > Mercurial-devel at selenic.com > http://selenic.com/mailman/listinfo/mercurial-devel From simohe at besonet.ch Tue Feb 12 17:05:29 2013 From: simohe at besonet.ch (Simon Heimberg) Date: Wed, 13 Feb 2013 00:05:29 +0100 Subject: [PATCH 0 of 4] detect unnecessary glob lines Message-ID: * Patch 4 checks for glob lines not containing any glob character (one of /*?). * Patch 3 fixes the found lines (before they pop up in test-check-code-hg.t because of patch 4) * Patch 2 reports the remaining unnecessary glob lines when running the tests on windows. (This is the system with "/" matching for "\". When it matches here, the glob is unnecessary.) * Patch 1 is a step in the direction of the next patch. All modified and mentioned tests pass. From simohe at besonet.ch Tue Feb 12 17:05:30 2013 From: simohe at besonet.ch (Simon Heimberg) Date: Wed, 13 Feb 2013 00:05:30 +0100 Subject: [PATCH 1 of 4] tests: quickly check if the glob line already matches the output In-Reply-To: References: Message-ID: <87f4812f32220895202a.1360710330@lapsi.heimberg.home> # HG changeset patch # User Simon Heimberg # Date 1350334939 -7200 # Node ID 87f4812f32220895202a185a92a7977bdee5f0a0 # Parent 6204e4d4dd6d10834540357dbf1deac6636077c8 tests: quickly check if the glob line already matches the output This happens when a path with "/" as only glob char is matched on a non windows platform. (Currently one third of all glob matches.) The the slowdown on windows and the speedup on other os and are neglectable. diff -r 6204e4d4dd6d -r 87f4812f3222 tests/run-tests.py --- a/tests/run-tests.py Son Feb 10 04:04:22 2013 -0600 +++ b/tests/run-tests.py Mon Okt 15 23:02:19 2012 +0200 @@ -541,6 +541,8 @@ def globmatch(el, l): # The only supported special characters are * and ? plus / which also # matches \ on windows. Escaping of these caracters is supported. + if el + '\n' == l: + return True i, n = 0, len(el) res = '' while i < n: From simohe at besonet.ch Tue Feb 12 17:05:31 2013 From: simohe at besonet.ch (Simon Heimberg) Date: Wed, 13 Feb 2013 00:05:31 +0100 Subject: [PATCH 2 of 4] tests: inform on Windows about unnecessary glob lines In-Reply-To: References: Message-ID: <282ccb8b49295d2fafb9.1360710331@lapsi.heimberg.home> # HG changeset patch # User Simon Heimberg # Date 1350336525 -7200 # Node ID 282ccb8b49295d2fafb987ca1d7a1e609c18f3fa # Parent 87f4812f32220895202a185a92a7977bdee5f0a0 tests: inform on Windows about unnecessary glob lines When glob lines directly match on windows, "/" (and not "\") was output in the path on the line. No glob matching is necessary in this case. The test output will look like this (when 5 tests have passed and no 4 has an unnecessary glob): ... Info, unnecessary glob: info about some/thing (glob) .. diff -r 87f4812f3222 -r 282ccb8b4929 tests/run-tests.py --- a/tests/run-tests.py Mon Okt 15 23:02:19 2012 +0200 +++ b/tests/run-tests.py Mon Okt 15 23:28:45 2012 +0200 @@ -542,6 +542,11 @@ # The only supported special characters are * and ? plus / which also # matches \ on windows. Escaping of these caracters is supported. if el + '\n' == l: + if os.name == 'nt': + # matching on "/" is not needed for this line + iolock.acquire() + print "\nInfo, unnecessary glob: %s (glob)" % el + iolock.release() return True i, n = 0, len(el) res = '' From simohe at besonet.ch Tue Feb 12 17:05:32 2013 From: simohe at besonet.ch (Simon Heimberg) Date: Wed, 13 Feb 2013 00:05:32 +0100 Subject: [PATCH 3 of 4] tests: remove glob from output lines containing no glob character In-Reply-To: References: Message-ID: # HG changeset patch # User Simon Heimberg # Date 1350336748 -7200 # Node ID a36b0c19bec9b4d43ab250b091fbddb614d75374 # Parent 282ccb8b49295d2fafb987ca1d7a1e609c18f3fa tests: remove glob from output lines containing no glob character diff -r 282ccb8b4929 -r a36b0c19bec9 tests/test-https.t --- a/tests/test-https.t Mon Okt 15 23:28:45 2012 +0200 +++ b/tests/test-https.t Mon Okt 15 23:32:28 2012 +0200 @@ -106,7 +106,7 @@ #if windows $ hg serve -p $HGPORT --certificate=$PRIV 2>&1 - abort: cannot start server at ':$HGPORT': (glob) + abort: cannot start server at ':$HGPORT':* (glob) [255] #else $ hg serve -p $HGPORT --certificate=$PRIV 2>&1 diff -r 282ccb8b4929 -r a36b0c19bec9 tests/test-walk.t --- a/tests/test-walk.t Mon Okt 15 23:28:45 2012 +0200 +++ b/tests/test-walk.t Mon Okt 15 23:32:28 2012 +0200 @@ -155,7 +155,7 @@ abort: path 'mammals/.hg' is inside nested repo 'mammals' (glob) [255] $ hg debugwalk ../.hg - abort: path contains illegal component: .hg (glob) + abort: path contains illegal component: .hg [255] $ cd .. @@ -187,10 +187,10 @@ abort: beans/../.. not under root '$TESTTMP/t' (glob) [255] $ hg debugwalk .hg - abort: path contains illegal component: .hg (glob) + abort: path contains illegal component: .hg [255] $ hg debugwalk beans/../.hg - abort: path contains illegal component: .hg (glob) + abort: path contains illegal component: .hg [255] $ hg debugwalk beans/../.hg/data abort: path contains illegal component: .hg/data (glob) From simohe at besonet.ch Tue Feb 12 17:05:33 2013 From: simohe at besonet.ch (Simon Heimberg) Date: Wed, 13 Feb 2013 00:05:33 +0100 Subject: [PATCH 4 of 4] code-check: warn about line glob match with no glob character (?*/) In-Reply-To: References: Message-ID: # HG changeset patch # User Simon Heimberg # Date 1350059530 -7200 # Node ID dca96b2ac9e1f536f69a9be658d9f4c72f6c6de0 # Parent a36b0c19bec9b4d43ab250b091fbddb614d75374 code-check: warn about line glob match with no glob character (?*/) diff -r a36b0c19bec9 -r dca96b2ac9e1 contrib/check-code.py --- a/contrib/check-code.py Mon Okt 15 23:32:28 2012 +0200 +++ b/contrib/check-code.py Fre Okt 12 18:32:10 2012 +0200 @@ -105,7 +105,10 @@ "use (glob) to match Windows paths too"), ], # warnings - [] + [ + (r'^ [^*?/\n]* \(glob\)$', + "warning: glob match with no glob character (?*/)"), + ] ] for i in [0, 1]: From durham at fb.com Tue Feb 12 17:12:52 2013 From: durham at fb.com (Durham Goode) Date: Tue, 12 Feb 2013 15:12:52 -0800 Subject: [PATCH 0 of 6 V2] blackbox: patches V2 Message-ID: Differences from V1 to V2: _() around log strings Change ui.log to use (msg, *args) style Remove 'bb' shortcut Use hardcoded date and user in tests Rename trackedevents config setting to just 'track' Add a comment explaining the repo.local() check Use util.safehasattr() instead of __dict__ From durham at fb.com Tue Feb 12 17:12:53 2013 From: durham at fb.com (Durham Goode) Date: Tue, 12 Feb 2013 15:12:53 -0800 Subject: [PATCH 1 of 6 V2] blackbox: adds a blackbox extension In-Reply-To: References: Message-ID: <248720a9332a9fac80d5.1360710773@dev350.prn1.facebook.com> # HG changeset patch # User Durham Goode # Date 1360706913 28800 # Tue Feb 12 14:08:33 2013 -0800 # Node ID 248720a9332a9fac80d5f1ab2e19b106cf44e90b # Parent 5b73c50e99dd6bdf5a5c59a0b4b09ced76b684ad blackbox: adds a blackbox extension Adds a blackbox extension that listens to ui.log() and writes the messages to .hg/blackbox.log. Future commits will use ui.log() to log commands, unhandled exceptions, incoming changes, and hooks. The extension defaults to logging everything, but can be configured via blackbox.track to only log certain events. Log lines are of the format: "date time user> message" Example log line: 2013/02/09 08:35:19 durham> 1 incoming changes - new heads: d84ced58aaa diff --git a/hgext/blackbox.py b/hgext/blackbox.py new file mode 100644 --- /dev/null +++ b/hgext/blackbox.py @@ -0,0 +1,70 @@ +"""log repository events to a blackbox for debugging + +Logs event information to .hg/blackbox.log to help debug and diagnose problems. +The events that get logged can be configured via the blackbox.track config key. +Examples: + + [blackbox] + track = * + + [blackbox] + track = command, commandfinish, commandexception, exthook, pythonhook + + [blackbox] + track = incoming + +""" + +from mercurial import util, cmdutil +from mercurial.i18n import _ +import os, getpass, re, string + +cmdtable = {} +command = cmdutil.command(cmdtable) +testedwith = 'internal' +lastblackbox = None + +def wrapui(ui): + class blackboxui(ui.__class__): + @util.propertycache + def track(self): + return ui.configlist('blackbox', 'track', ['*']) + + def log(self, event, *msg, **opts): + global lastblackbox + super(blackboxui, self).log(event, *msg, **opts) + + if not '*' in self.track and not event in self.track: + return + + if util.safehasattr(self, '_blackbox'): + blackbox = self._blackbox + else: + # certain ui instances exist outside the context of + # a repo, so just default to the last blackbox that + # was seen. + blackbox = lastblackbox + + if blackbox: + date = util.datestr(None, '%Y/%m/%d %H:%M:%S') + user = getpass.getuser() + formattedmsg = msg[0] % msg[1:] + blackbox.write('%s %s> %s' % (date, user, formattedmsg)) + lastblackbox = blackbox + + def setrepo(self, repo): + self._blackbox = repo.opener('blackbox.log', 'a') + + ui.__class__ = blackboxui + +def uisetup(ui): + wrapui(ui) + +def reposetup(ui, repo): + # During 'hg pull' a httppeer repo is created to represent the remote repo. + # It doesn't have a .hg directory to put a blackbox in, so we don't do + # the blackbox setup for it. + if not repo.local(): + return + + ui.setrepo(repo) diff --git a/mercurial/ui.py b/mercurial/ui.py --- a/mercurial/ui.py +++ b/mercurial/ui.py @@ -739,7 +739,7 @@ else: self.debug('%s:%s %s%s\n' % (topic, item, pos, unit)) - def log(self, service, message): + def log(self, service, *msg, **opts): '''hook for logging facility extensions service should be a readily-identifiable subsystem, which will From durham at fb.com Tue Feb 12 17:12:55 2013 From: durham at fb.com (Durham Goode) Date: Tue, 12 Feb 2013 15:12:55 -0800 Subject: [PATCH 3 of 6 V2] blackbox: logs python and extension hooks via ui.log() In-Reply-To: References: Message-ID: <0ad8fad9d10c58548d64.1360710775@dev350.prn1.facebook.com> # HG changeset patch # User Durham Goode # Date 1360429472 28800 # Sat Feb 09 09:04:32 2013 -0800 # Node ID 0ad8fad9d10c58548d6472a0787dd53a5a681383 # Parent 61c66397b9a01d8e08333db6b220f882fe10c209 blackbox: logs python and extension hooks via ui.log() Logs python and extension hooks to ui.log() for viewing in the blackbox. Example log lines: 2013/02/09 08:35:19 durham> pythonhook-preupdate: hgext.eol.preupdate finished in 0.01 seconds 2013/02/09 08:35:19 durham> exthook-update: echo hooked finished in 0.02 seconds diff --git a/mercurial/hook.py b/mercurial/hook.py --- a/mercurial/hook.py +++ b/mercurial/hook.py @@ -6,7 +6,7 @@ # GNU General Public License version 2 or any later version. from i18n import _ -import os, sys +import os, sys, time, types import extensions, util, demandimport def _pythonhook(ui, repo, name, hname, funcname, args, throw): @@ -20,6 +20,8 @@ be run as hooks without wrappers to convert return values.''' ui.note(_("calling hook %s: %s\n") % (hname, funcname)) + starttime = time.time() + obj = funcname if not util.safehasattr(obj, '__call__'): d = funcname.rfind('.') @@ -92,6 +94,12 @@ return True finally: sys.stdout, sys.stderr, sys.stdin = old + duration = time.time() - starttime + readablefunc = funcname + if isinstance(funcname, types.FunctionType): + readablefunc = funcname.__module__ + "." + funcname.__name__ + ui.log('pythonhook', _('pythonhook-%s: %s finished in %0.2f seconds\n'), + name, readablefunc, duration) if r: if throw: raise util.Abort(_('%s hook failed') % hname) @@ -101,6 +109,7 @@ def _exthook(ui, repo, name, cmd, args, throw): ui.note(_("running hook %s: %s\n") % (name, cmd)) + starttime = time.time() env = {} for k, v in args.iteritems(): if util.safehasattr(v, '__call__'): @@ -121,6 +130,10 @@ r = util.system(cmd, environ=env, cwd=cwd, out=ui) else: r = util.system(cmd, environ=env, cwd=cwd, out=ui.fout) + + duration = time.time() - starttime + ui.log('exthook', _('exthook-%s: %s finished in %0.2f seconds\n'), + name, cmd, duration) if r: desc, r = util.explainexit(r) if throw: From durham at fb.com Tue Feb 12 17:12:54 2013 From: durham at fb.com (Durham Goode) Date: Tue, 12 Feb 2013 15:12:54 -0800 Subject: [PATCH 2 of 6 V2] blackbox: log the commands that are run In-Reply-To: References: Message-ID: <61c66397b9a01d8e0833.1360710774@dev350.prn1.facebook.com> # HG changeset patch # User Durham Goode # Date 1360429454 28800 # Sat Feb 09 09:04:14 2013 -0800 # Node ID 61c66397b9a01d8e08333db6b220f882fe10c209 # Parent 248720a9332a9fac80d5f1ab2e19b106cf44e90b blackbox: log the commands that are run Uses ui.log to log which commands are run, their exit code, the time taken, and any unhandled exceptions thrown. Example log lines: 2013/02/09 08:35:19 durham> add foo 2013/02/09 08:35:19 durham> add exited 0 after 0.02 seconds Updates the progress tests because they use a mocked time.time() which these changes affect. diff --git a/mercurial/dispatch.py b/mercurial/dispatch.py --- a/mercurial/dispatch.py +++ b/mercurial/dispatch.py @@ -247,6 +247,7 @@ (_("** Mercurial Distributed SCM (version %s)\n") % myver) + (_("** Extensions loaded: %s\n") % ", ".join([x[0] for x in extensions.extensions()]))) + ui.log("commandexception", "%s\n%s\n", warning, traceback.format_exc()) ui.warn(warning) raise @@ -738,10 +739,16 @@ msg = ' '.join(' ' in a and repr(a) or a for a in fullargs) ui.log("command", msg + "\n") d = lambda: util.checksignature(func)(ui, *args, **cmdoptions) + starttime = time.time() + ret = None try: - return runcommand(lui, repo, cmd, fullargs, ui, options, d, + ret = runcommand(lui, repo, cmd, fullargs, ui, options, d, cmdpats, cmdoptions) + return ret finally: + duration = time.time() - starttime + ui.log("commandfinish", _("%s exited %s after %0.2f seconds\n"), + cmd, ret, duration) if repo and repo != req.repo: repo.close() diff --git a/tests/test-progress.t b/tests/test-progress.t --- a/tests/test-progress.t +++ b/tests/test-progress.t @@ -167,6 +167,7 @@ $ hg -y loop 8 \r (no-eol) (esc) + loop [====> ] 1/8 1m18s\r (no-eol) (esc) loop [=========> ] 2/8 1m07s\r (no-eol) (esc) loop [===============> ] 3/8 56s\r (no-eol) (esc) loop [=====================> ] 4/8 45s\r (no-eol) (esc) @@ -203,6 +204,7 @@ Time estimates should not fail when there's no end point: $ hg -y loop -- -4 \r (no-eol) (esc) - loop [ <=> ] 2\r (no-eol) (esc) - loop [ <=> ] 3\r (no-eol) (esc) + loop [ <=> ] 1\r (no-eol) (esc) + loop [ <=> ] 2\r (no-eol) (esc) + loop [ <=> ] 3\r (no-eol) (esc) \r (no-eol) (esc) From durham at fb.com Tue Feb 12 17:12:56 2013 From: durham at fb.com (Durham Goode) Date: Tue, 12 Feb 2013 15:12:56 -0800 Subject: [PATCH 4 of 6 V2] blackbox: log incoming changes via ui.log() In-Reply-To: References: Message-ID: <73e79367c0519b8552b5.1360710776@dev350.prn1.facebook.com> # HG changeset patch # User Durham Goode # Date 1360429488 28800 # Sat Feb 09 09:04:48 2013 -0800 # Node ID 73e79367c0519b8552b5a4d6ccfdccf9a4db926a # Parent 0ad8fad9d10c58548d6472a0787dd53a5a681383 blackbox: log incoming changes via ui.log() Logs incoming changes to a repo to ui.log(). Includes the number of changes and the hashes of the heads after the new changes. Example log line: 2013/02/09 08:35:19 durham> 1 incoming changes - new heads: cb9a9f314b8b Currently the blackbox logs the unix user that is performing the push/pull. It would be nice to log the http authorized user as well so it works with hgweb, but that's outside the scope of this commit. diff --git a/mercurial/localrepo.py b/mercurial/localrepo.py --- a/mercurial/localrepo.py +++ b/mercurial/localrepo.py @@ -2399,6 +2399,10 @@ for n in added: self.hook("incoming", node=hex(n), source=srctype, url=url) + + heads = self.heads() + self.ui.log("incoming", _("%s incoming changes - new heads: %s\n"), + len(added), ', '.join([hex(c[:6]) for c in heads])) self._afterlock(runhooks) finally: From durham at fb.com Tue Feb 12 17:12:57 2013 From: durham at fb.com (Durham Goode) Date: Tue, 12 Feb 2013 15:12:57 -0800 Subject: [PATCH 5 of 6 V2] blackbox: adds a 'blackbox' command for viewing recent logs In-Reply-To: References: Message-ID: <4e7e236ebc7dad934c79.1360710777@dev350.prn1.facebook.com> # HG changeset patch # User Durham Goode # Date 1360429786 28800 # Sat Feb 09 09:09:46 2013 -0800 # Node ID 4e7e236ebc7dad934c79fb2ee7665a78ffd712e5 # Parent 73e79367c0519b8552b5a4d6ccfdccf9a4db926a blackbox: adds a 'blackbox' command for viewing recent logs Adds a 'hg blackbox' command for viewing the latest entries in the blackbox log. By default it shows the last 10 entries, but -l allows the user to specify. diff --git a/hgext/blackbox.py b/hgext/blackbox.py --- a/hgext/blackbox.py +++ b/hgext/blackbox.py @@ -68,3 +68,31 @@ return ui.setrepo(repo) + + at command('^blackbox', + [('l', 'limit', 10, _('the number of events to show')), + ], + _('hg blackbox [OPTION]...')) +def blackbox(ui, repo, *revs, **opts): + '''view the recent repository events + ''' + + if not os.path.exists(repo.join('blackbox.log')): + return + + limit = opts.get('limit') + blackbox = repo.opener('blackbox.log', 'r') + lines = blackbox.read().split('\n') + + count = 0 + output = [] + for line in reversed(lines): + if count >= limit: + break + + # count the commands by matching lines like: 2013/01/23 19:13:36 root> + if re.match('^\d{4}/\d{2}/\d{2} \d{2}:\d{2}:\d{2} .*> .*', line): + count += 1 + output.append(line) + + ui.status('\n'.join(reversed(output))) From durham at fb.com Tue Feb 12 17:12:58 2013 From: durham at fb.com (Durham Goode) Date: Tue, 12 Feb 2013 15:12:58 -0800 Subject: [PATCH 6 of 6 V2] blackbox: tests for the blackbox extension In-Reply-To: References: Message-ID: # HG changeset patch # User Durham Goode # Date 1360445730 28800 # Sat Feb 09 13:35:30 2013 -0800 # Node ID fc1e598a1ba723af78442dccb9ef3dfc58e0ac0d # Parent 4e7e236ebc7dad934c79fb2ee7665a78ffd712e5 blackbox: tests for the blackbox extension A few tests to cover the blackbox extension. Covers commands, hooks, and incoming changes. diff --git a/tests/test-blackbox.t b/tests/test-blackbox.t new file mode 100644 --- /dev/null +++ b/tests/test-blackbox.t @@ -0,0 +1,67 @@ +setup + $ cat > mock.py < from mercurial import util + > import getpass + > + > def makedate(): + > return 0, 0 + > def getuser(): + > return 'bob' + > # mock the date and user apis so the output is always the same + > def uisetup(ui): + > util.makedate = makedate + > getpass.getuser = getuser + > EOF + $ cat >> $HGRCPATH < [extensions] + > blackbox= + > mock=`pwd`/mock.py + > EOF + $ hg init blackboxtest + $ cd blackboxtest + +command, exit codes, and duration + + $ echo a > a + $ hg add a + $ hg blackbox + 1970/01/01 00:00:00 bob> add a + 1970/01/01 00:00:00 bob> add exited 0 after * seconds (glob) + +extension and python hooks - use the eol extension for a pythonhook + + $ echo '[extensions]' >> .hg/hgrc + $ echo 'eol=' >> .hg/hgrc + $ echo '[hooks]' >> .hg/hgrc + $ echo 'update = echo hooked' >> .hg/hgrc + $ hg update + hooked + 0 files updated, 0 files merged, 0 files removed, 0 files unresolved + $ hg blackbox -l 4 + 1970/01/01 00:00:00 bob> update + 1970/01/01 00:00:00 bob> pythonhook-preupdate: hgext.eol.preupdate finished in * seconds (glob) + 1970/01/01 00:00:00 bob> exthook-update: echo hooked finished in * seconds (glob) + 1970/01/01 00:00:00 bob> update exited False after * seconds (glob) + +incoming change tracking + + $ hg clone . ../blackboxtest2 + updating to branch default + 0 files updated, 0 files merged, 0 files removed, 0 files unresolved + $ hg commit -ma + $ cd ../blackboxtest2 + $ hg pull + pulling from $TESTTMP/blackboxtest + requesting all changes + adding changesets + adding manifests + adding file changes + added 1 changesets with 1 changes to 1 files + (run 'hg update' to get a working copy) + $ hg blackbox -l 3 + 1970/01/01 00:00:00 bob> pull + 1970/01/01 00:00:00 bob> 1 incoming changes - new heads: cb9a9f314b8b (glob) + 1970/01/01 00:00:00 bob> pull exited None after * seconds (glob) + +cleanup + $ cd .. From durham at fb.com Tue Feb 12 17:18:08 2013 From: durham at fb.com (Durham Goode) Date: Tue, 12 Feb 2013 23:18:08 +0000 Subject: [PATCH 6 of 6] blackbox: tests for the blackbox extension In-Reply-To: <20130212113624.GA22193@crater2.logilab.fr> Message-ID: <2B10A89294DA6740AC6155F56842F9CE0565A546@PRN-MBX01-2.TheFacebook.com> On 2/12/13 11:36 AM, "Pierre-Yves David" wrote: >On Mon, Feb 11, 2013 at 01:39:57PM -0800, Bryan O'Sullivan wrote: >> On Sun, Feb 10, 2013 at 4:24 AM, Brodie Rao wrote: >> >> > I think it's a little confusing that the date is completely globbed >> > out here. Can you make the date stable and add it to the test? >> > >> >> The date is in the output from blackbox. It doesn't make sense to me to >>add >> a hack to make those dates constant for testing. > >Stable date does not make sense. Using regex instead of glob would be me >accurate. > I don't think the way we test the date/user string is particularly important. The latest patch series uses a fixed date and user so that if the test fails it's easy to visually compare the lines without a glob or regex uglying it up. From bboissin at gmail.com Tue Feb 12 17:21:23 2013 From: bboissin at gmail.com (Benoit Boissinot) Date: Wed, 13 Feb 2013 00:21:23 +0100 Subject: [PATCH 3 of 4] tests: remove glob from output lines containing no glob character In-Reply-To: References: Message-ID: On Wed, Feb 13, 2013 at 12:05 AM, Simon Heimberg wrote: > # HG changeset patch > # User Simon Heimberg > # Date 1350336748 -7200 > # Node ID a36b0c19bec9b4d43ab250b091fbddb614d75374 > # Parent 282ccb8b49295d2fafb987ca1d7a1e609c18f3fa > tests: remove glob from output lines containing no glob character > Message is a bit misleading (the first hunk doesn't remove (glob)). > > diff -r 282ccb8b4929 -r a36b0c19bec9 tests/test-https.t > --- a/tests/test-https.t Mon Okt 15 23:28:45 2012 +0200 > +++ b/tests/test-https.t Mon Okt 15 23:32:28 2012 +0200 > @@ -106,7 +106,7 @@ > > #if windows > $ hg serve -p $HGPORT --certificate=$PRIV 2>&1 > - abort: cannot start server at ':$HGPORT': (glob) > + abort: cannot start server at ':$HGPORT':* (glob) > [255] > #else > $ hg serve -p $HGPORT --certificate=$PRIV 2>&1 > diff -r 282ccb8b4929 -r a36b0c19bec9 tests/test-walk.t > --- a/tests/test-walk.t Mon Okt 15 23:28:45 2012 +0200 > +++ b/tests/test-walk.t Mon Okt 15 23:32:28 2012 +0200 > @@ -155,7 +155,7 @@ > abort: path 'mammals/.hg' is inside nested repo 'mammals' (glob) > [255] > $ hg debugwalk ../.hg > - abort: path contains illegal component: .hg (glob) > + abort: path contains illegal component: .hg > [255] > $ cd .. > > @@ -187,10 +187,10 @@ > abort: beans/../.. not under root '$TESTTMP/t' (glob) > [255] > $ hg debugwalk .hg > - abort: path contains illegal component: .hg (glob) > + abort: path contains illegal component: .hg > [255] > $ hg debugwalk beans/../.hg > - abort: path contains illegal component: .hg (glob) > + abort: path contains illegal component: .hg > [255] > $ hg debugwalk beans/../.hg/data > abort: path contains illegal component: .hg/data (glob) > _______________________________________________ > Mercurial-devel mailing list > Mercurial-devel at selenic.com > http://selenic.com/mailman/listinfo/mercurial-devel > -------------- next part -------------- An HTML attachment was scrubbed... URL: From bboissin at gmail.com Tue Feb 12 17:22:58 2013 From: bboissin at gmail.com (Benoit Boissinot) Date: Wed, 13 Feb 2013 00:22:58 +0100 Subject: [PATCH 0 of 4] detect unnecessary glob lines In-Reply-To: References: Message-ID: On Wed, Feb 13, 2013 at 12:05 AM, Simon Heimberg wrote: > * Patch 4 checks for glob lines not containing any glob character (one of > /*?). > * Patch 3 fixes the found lines (before they pop up in test-check-code-hg.t > because of patch 4) > * Patch 2 reports the remaining unnecessary glob lines when running the > tests > on windows. (This is the system with "/" matching for "\". When it > matches > here, the glob is unnecessary.) > * Patch 1 is a step in the direction of the next patch. > > All modified and mentioned tests pass. > Looks good (except for some typos) in some patch descriptions. Did you run the tests on windows? Cheers, Benoit -------------- next part -------------- An HTML attachment was scrubbed... URL: From bos at serpentine.com Tue Feb 12 17:29:44 2013 From: bos at serpentine.com (Bryan O'Sullivan) Date: Tue, 12 Feb 2013 15:29:44 -0800 Subject: [PATCH 1 of 6 V2] blackbox: adds a blackbox extension In-Reply-To: <248720a9332a9fac80d5.1360710773@dev350.prn1.facebook.com> References: <248720a9332a9fac80d5.1360710773@dev350.prn1.facebook.com> Message-ID: On Tue, Feb 12, 2013 at 3:12 PM, Durham Goode wrote: > + def log(self, event, *msg, **opts): > Where does this opts dict get used? -------------- next part -------------- An HTML attachment was scrubbed... URL: From mercurial-bugs at selenic.com Tue Feb 12 12:38:54 2013 From: mercurial-bugs at selenic.com (mercurial-bugs at selenic.com) Date: Tue, 12 Feb 2013 18:38:54 +0000 Subject: [Bug 3820] New: Race on push over ssh Message-ID: http://bz.selenic.com/show_bug.cgi?id=3820 Priority: normal Bug ID: 3820 CC: mercurial-devel at selenic.com Assignee: bugzilla at selenic.com Summary: Race on push over ssh Severity: bug Classification: Unclassified OS: Linux Reporter: bboissin at gmail.com Hardware: PC Status: UNCONFIRMED Version: 2.5.1 Component: Mercurial Product: Mercurial On crew, we (me and Bryan) managed to race on push an create new heads. Output from push from my side: tonfa at pouchy:~/dev/mercurial/crew$ hg push crew-push pushing to ssh://hg at hg.intevation.org/mercurial/crew searching for changes note: unsynced remote changes! remote: waiting for lock on repository /home/hg/pub/mercurial/crew held by 'hg:9393' remote: adding changesets remote: adding manifests remote: adding file changes remote: added 1 changesets with 1 changes to 1 files remote: waiting for lock on repository /home/hg/pub/mercurial/crew held by 'hg:9419' I then pulled tonfa at pouchy:~/dev/mercurial/crew$ hg pull pulling from http://hg.intevation.org/mercurial/crew+main searching for changes adding changesets adding manifests adding file changes added 3 changesets with 3 changes to 2 files (+1 heads) (run 'hg heads' to see heads, 'hg merge' to merge) tonfa at pouchy:~/dev/mercurial/crew$ hg heads changeset: 18652:e556659340f0 tag: tip user: Siddharth Agarwal date: Sun Feb 10 16:55:01 2013 +0000 summary: manifestmerge: fix order in which manifests are fetched changeset: 18649:a5e94bee77ed parent: 18642:76b69cccb07a parent: 18648:013fcd112f13 user: Benoit Boissinot date: Mon Feb 11 01:17:50 2013 +0100 summary: merge crew and main changeset: 18617:227479f61db9 branch: stable parent: 18580:9a06aab5981b user: Pierre-Yves David date: Sat Feb 09 17:54:01 2013 +0000 summary: outgoing: fix possible filtering crash in outgoing (issue3814) The bug might involve discovery+bookmarks interaction. -- You are receiving this mail because: You are on the CC list for the bug. From bos at serpentine.com Tue Feb 12 17:39:13 2013 From: bos at serpentine.com (Bryan O'Sullivan) Date: Tue, 12 Feb 2013 15:39:13 -0800 Subject: [PATCH 4 of 6 V2] blackbox: log incoming changes via ui.log() In-Reply-To: <73e79367c0519b8552b5.1360710776@dev350.prn1.facebook.com> References: <73e79367c0519b8552b5.1360710776@dev350.prn1.facebook.com> Message-ID: On Tue, Feb 12, 2013 at 3:12 PM, Durham Goode wrote: > Logs incoming changes to a repo to ui.log(). Includes the number of changes > and the hashes of the heads after the new changes. > I'm applying this, but the log message is a bit misleading. It says "new heads", when in fact it prints all the heads, new or not. If you could filter the list of heads so that it does not include heads that were already present, that would be a good followup patch. -------------- next part -------------- An HTML attachment was scrubbed... URL: From durham at fb.com Tue Feb 12 17:40:19 2013 From: durham at fb.com (Durham Goode) Date: Tue, 12 Feb 2013 23:40:19 +0000 Subject: [PATCH 1 of 6 V2] blackbox: adds a blackbox extension In-Reply-To: Message-ID: <2B10A89294DA6740AC6155F56842F9CE0565A5AF@PRN-MBX01-2.TheFacebook.com> On 2/12/13 3:29 PM, "Bryan O'Sullivan" wrote: > >On Tue, Feb 12, 2013 at 3:12 PM, Durham Goode wrote: > >> + def log(self, event, *msg, **opts): > >Where does this opts dict get used? > No where at the moment, but ui.status/warn/note/debug/etc have it, so I figured it was a pattern. Though now that I look, they only seem to write to opts. They never read from it. From bos at serpentine.com Tue Feb 12 18:03:56 2013 From: bos at serpentine.com (Bryan O'Sullivan) Date: Tue, 12 Feb 2013 16:03:56 -0800 Subject: [PATCH 6 of 6 V2] blackbox: tests for the blackbox extension In-Reply-To: References: Message-ID: On Tue, Feb 12, 2013 at 3:12 PM, Durham Goode wrote: > blackbox: tests for the blackbox extension > I've applied the series with some whitespace fixes, a copyright notice, and fixed a failing test. Thanks. Please do follow up with a patch that reduces the set of heads logged. -------------- next part -------------- An HTML attachment was scrubbed... URL: From mpm at selenic.com Tue Feb 12 22:50:23 2013 From: mpm at selenic.com (Matt Mackall) Date: Tue, 12 Feb 2013 22:50:23 -0600 Subject: [PATCH 6 of 6 V2] blackbox: tests for the blackbox extension In-Reply-To: References: Message-ID: <1360731023.12295.20.camel@calx> On Tue, 2013-02-12 at 16:03 -0800, Bryan O'Sullivan wrote: > On Tue, Feb 12, 2013 at 3:12 PM, Durham Goode wrote: > > > blackbox: tests for the blackbox extension > > > > I've applied the series with some whitespace fixes, a copyright notice, and > fixed a failing test. Thanks. # worker.py - master-slave parallelism support # # Copyright 2013 Facebook, Inc. Copyright notice probably ought to mention Nic Dumazet and not worker.py. -- Mathematics is the supreme nostalgia of our time. From mpm at selenic.com Tue Feb 12 22:56:02 2013 From: mpm at selenic.com (Matt Mackall) Date: Tue, 12 Feb 2013 22:56:02 -0600 Subject: [PATCH RFC] commit: add --reuse-message for keeping the old commit message during amend In-Reply-To: <0B39C5AD-4CE4-4A34-A296-0694304B0A2E@durin42.com> References: <2B10A89294DA6740AC6155F56842F9CE0565A37B@PRN-MBX01-2.TheFacebook.com> <0B39C5AD-4CE4-4A34-A296-0694304B0A2E@durin42.com> Message-ID: <1360731362.12295.24.camel@calx> On Tue, 2013-02-12 at 16:48 -0500, Augie Fackler wrote: > On Feb 12, 2013, at 4:16 PM, Idan Kamara wrote: > > > On Tue, Feb 12, 2013 at 11:08 PM, Durham Goode wrote: > >>> What about something generic like --no-editor? It's not as explicit > >>> but we already have --editor which forces an editor, so this will do > >>> the opposite. > >>> > >>> It also opens up the possibility of appearing in other commands with > >>> similar semantics but without being directly related to amend. > >> > >> I think the name must imply some relationship with another commit, so it's > >> semi intuitive that it's related to --amend. I think a user would be more > >> likely to try --no-editor without --amend, and be confused when it failed. > > > > The help text should (regardless of the name) say that this option is only > > relevant when used with --amend. > > Strawman alternative: a --fast-amend option that doesn't pop up an > editor, so you can pass only one flag (that is, --fast-amend would be > like --amend --reuse-message). I'm now inclined to think that 'hg commit --amend' will eventually be replaced by 'hg amend', which will have a different default. Then we'll deprecate --amend on commit. So I think we should leave this alone. But I don't think we've got quite enough experience here to add the new amend command yet. -- Mathematics is the supreme nostalgia of our time. From mpm at selenic.com Tue Feb 12 23:03:16 2013 From: mpm at selenic.com (Matt Mackall) Date: Tue, 12 Feb 2013 23:03:16 -0600 Subject: [PATCH 05 of 19] localrepo: update commit to use setter and getter for description In-Reply-To: References: <07bdd03d86dcce1558d7.1360538991@dev010.prn1.facebook.com> <56ec15753a5264b0713b.1360538995@dev010.prn1.facebook.com> <20130212141039.GI22193@crater2.logilab.fr> Message-ID: <1360731796.12295.25.camel@calx> On Tue, 2013-02-12 at 09:58 -0800, Bryan O'Sullivan wrote: > On Tue, Feb 12, 2013 at 6:10 AM, Pierre-Yves David < > pierre-yves.david at logilab.fr> wrote: > > > 1) The setdescription name is really ugly. I do not have good non ugly > > alternative in mind yet > > > > I think the name is fine. That said, setdesc would also be fine. The existing get method is description(), so setdesc is out. This is fine. -- Mathematics is the supreme nostalgia of our time. From bos at serpentine.com Tue Feb 12 23:08:12 2013 From: bos at serpentine.com (Bryan O'Sullivan) Date: Tue, 12 Feb 2013 21:08:12 -0800 Subject: [PATCH 6 of 6 V2] blackbox: tests for the blackbox extension In-Reply-To: <1360731023.12295.20.camel@calx> References: <1360731023.12295.20.camel@calx> Message-ID: On Tue, Feb 12, 2013 at 8:50 PM, Matt Mackall wrote: > Copyright notice probably ought to mention Nic Dumazet and not > worker.py. > Oops. Durham, does the patch include any of Nic's code? -------------- next part -------------- An HTML attachment was scrubbed... URL: From mpm at selenic.com Tue Feb 12 23:08:41 2013 From: mpm at selenic.com (Matt Mackall) Date: Tue, 12 Feb 2013 23:08:41 -0600 Subject: [PATCH 12 of 19] localrepo: don't use raw context when checking for an empty commit In-Reply-To: References: <07bdd03d86dcce1558d7.1360538991@dev010.prn1.facebook.com> Message-ID: <1360732121.12295.27.camel@calx> On Mon, 2013-02-11 at 12:58 -0800, Bryan O'Sullivan wrote: > On Sun, Feb 10, 2013 at 3:30 PM, David Schleimer wrote: > > > This is turn will make it proactical for > > > Couple of typos here. David might want to enable a spell-checker in his editor (I use flyspell in Emacs). But see: http://markmail.org/message/4jv2dsbjtfxemq7g -- Mathematics is the supreme nostalgia of our time. From mpm at selenic.com Tue Feb 12 23:16:25 2013 From: mpm at selenic.com (Matt Mackall) Date: Tue, 12 Feb 2013 23:16:25 -0600 Subject: [PATCH 14 of 19] context: support matches in workingctx.status In-Reply-To: <730f81cd4b340348dfc5.1360539004@dev010.prn1.facebook.com> References: <07bdd03d86dcce1558d7.1360538991@dev010.prn1.facebook.com> <730f81cd4b340348dfc5.1360539004@dev010.prn1.facebook.com> Message-ID: <1360732585.12295.31.camel@calx> On Sun, 2013-02-10 at 15:30 -0800, David Schleimer wrote: > # HG changeset patch > # User David Schleimer > # Date 1360424562 28800 > # Node ID 730f81cd4b340348dfc5d2eb571f3b13e01c73e4 > # Parent 1bae6048dd1028bb6b7506ec1ecb73bd819e7449 > context: support matches in workingctx.status > > This makes it possible to get a filtered view of the workingcopy via > workingctx.status(). This is currently unused, but subsequent patches > will use this to pull validation steps out of localrepo.commit and > into the workingctx. This in turn will make it practical to unify > workingctx and memctx, making memctx more useful. This and a few of the other patches move us further away from having having repo[None] cacheable. That's a little unfortunate. Perhaps we want to instead have a distinct commitctx type. > diff --git a/mercurial/context.py b/mercurial/context.py > --- a/mercurial/context.py > +++ b/mercurial/context.py > @@ -941,12 +941,15 @@ > p = p[:-1] > return [changectx(self._repo, x) for x in p] > > - def status(self, ignored=False, clean=False, unknown=False): > + def status(self, ignored=False, clean=False, unknown=False, match=None): > """Explicit status query > Unless this method is used to query the working copy status, the > _status property will implicitly read the status using its default > arguments.""" > - stat = self._repo.status(ignored=ignored, clean=clean, unknown=unknown) > + stat = self._repo.status(ignored=ignored, > + clean=clean, > + unknown=unknown, > + match=match) > self._unknown = self._ignored = self._clean = None > if unknown: > self._unknown = stat[4] > _______________________________________________ > Mercurial-devel mailing list > Mercurial-devel at selenic.com > http://selenic.com/mailman/listinfo/mercurial-devel -- Mathematics is the supreme nostalgia of our time. From simohe at besonet.ch Wed Feb 13 03:07:49 2013 From: simohe at besonet.ch (Simon He.) Date: Wed, 13 Feb 2013 10:07:49 +0100 Subject: AW: [PATCH 0 of 4] detect unnecessary glob lines In-Reply-To: References: Message-ID: <013201ce09c9$994e11f0$cbea35d0$@besonet.ch> No, I still do not know how to run tests on windows. The tests have passed on linux. (I should have written this, sorry.) I planned to check the output on the buildbot for messages about unnecessary glob lines. I will try to fix the typos and hope I will find all... Greetings, Simon On Wed, 13 Feb 2013 at 00:23 Benoit Boissinot wrote: > On Wed, Feb 13, 2013 at 12:05 AM, Simon Heimberg wrote: > * Patch 4 checks for glob lines not containing any glob character (one of /*?). > * Patch 3 fixes the found lines (before they pop up in test-check-code-hg.t > ? because of patch 4) > * Patch 2 reports the remaining unnecessary glob lines when running the tests > ? on windows. (This is the system with "/" matching for "\". When it matches > ? here, the glob is unnecessary.) > * Patch 1 is a step in the direction of the next patch. > > All modified and mentioned tests pass. > > Looks good (except for some typos) in some patch descriptions. Did you run the tests on windows? > > Cheers, > > Benoit From simohe at besonet.ch Wed Feb 13 03:12:02 2013 From: simohe at besonet.ch (Simon He.) Date: Wed, 13 Feb 2013 10:12:02 +0100 Subject: AW: [PATCH 3 of 4] tests: remove glob from output lines containing no glob character In-Reply-To: References: Message-ID: <013401ce09ca$2f728080$8e578180$@besonet.ch> Maybe the message is right but the first hunk is wrong. Not sure anymore why I did it this way. The change (in the first hunk) is: > #if windows > $ hg serve -p $HGPORT --certificate=$PRIV 2>&1 > - abort: cannot start server at ':$HGPORT': (glob) > + abort: cannot start server at ':$HGPORT':* (glob) > [255] > #else Not sure if really the asterisk is missing here. Probably we can just remove "(glob)". If not the test would have fallen all the time (on windows). Could somebody check this please? Greetings, Simon On Wed, 13 Feb 2013 at 00:21 Benoit Boissinot wrote: > On Wed, Feb 13, 2013 at 12:05 AM, Simon Heimberg wrote: > # HG changeset patch > # User Simon Heimberg > # Date 1350336748 -7200 > # Node ID a36b0c19bec9b4d43ab250b091fbddb614d75374 > # Parent ?282ccb8b49295d2fafb987ca1d7a1e609c18f3fa > tests: remove glob from output lines containing no glob character > > Message is a bit misleading (the first hunk doesn't remove (glob)).? > >> diff -r 282ccb8b4929 -r a36b0c19bec9 tests/test-https.t >> --- a/tests/test-https.t ? ? ? ?Mon Okt 15 23:28:45 2012 +0200 >> +++ b/tests/test-https.t ? ? ? ?Mon Okt 15 23:32:28 2012 +0200 >> @@ -106,7 +106,7 @@ >> >> ?#if windows >> ? ?$ hg serve -p $HGPORT --certificate=$PRIV 2>&1 >> - ?abort: cannot start server at ':$HGPORT': (glob) >> + ?abort: cannot start server at ':$HGPORT':* (glob) >> ? ?[255] >> ?#else >> ? ?$ hg serve -p $HGPORT --certificate=$PRIV 2>&1 >> diff -r 282ccb8b4929 -r a36b0c19bec9 tests/test-walk.t >> --- a/tests/test-walk.t Mon Okt 15 23:28:45 2012 +0200 >> +++ b/tests/test-walk.t Mon Okt 15 23:32:28 2012 +0200 >> @@ -155,7 +155,7 @@ >> ? ?abort: path 'mammals/.hg' is inside nested repo 'mammals' (glob) >> ? ?[255] >> ? ?$ hg debugwalk ../.hg >> - ?abort: path contains illegal component: .hg (glob) >> + ?abort: path contains illegal component: .hg >> ? ?[255] >> ? ?$ cd .. >> >> @@ -187,10 +187,10 @@ >>? ?abort: beans/../.. not under root '$TESTTMP/t' (glob) >>? ?[255] >>? ?$ hg debugwalk .hg >> - ?abort: path contains illegal component: .hg (glob) >> + ?abort: path contains illegal component: .hg >>? ?[255] >>? ?$ hg debugwalk beans/../.hg >> - ?abort: path contains illegal component: .hg (glob) >> + ?abort: path contains illegal component: .hg >>? ?[255] >>? ?$ hg debugwalk beans/../.hg/data >>? ?abort: path contains illegal component: .hg/data (glob) >> _______________________________________________ >> Mercurial-devel mailing list >> Mercurial-devel at selenic.com >> http://selenic.com/mailman/listinfo/mercurial-devel From bboissin at gmail.com Wed Feb 13 03:37:47 2013 From: bboissin at gmail.com (Benoit Boissinot) Date: Wed, 13 Feb 2013 10:37:47 +0100 Subject: [PATCH 0 of 4] detect unnecessary glob lines In-Reply-To: <013201ce09c9$994e11f0$cbea35d0$@besonet.ch> References: <013201ce09c9$994e11f0$cbea35d0$@besonet.ch> Message-ID: On Wed, Feb 13, 2013 at 10:07 AM, Simon He. wrote: > No, I still do not know how to run tests on windows. The tests have passed > on linux. (I should have written this, sorry.) > I planned to check the output on the buildbot for messages about > unnecessary > glob lines. > > I will try to fix the typos and hope I will find all... > I would have fixed them while applying the serie, no worry. I wonder if Adrian or Patrick would be able to run it on windows for you. Benoit -------------- next part -------------- An HTML attachment was scrubbed... URL: From simohe at besonet.ch Wed Feb 13 05:43:14 2013 From: simohe at besonet.ch (Simon Heimberg) Date: Wed, 13 Feb 2013 12:43:14 +0100 Subject: [PATCH STABLE] Tests: fix test on windows by appending glob to lines returning "\" in the path Message-ID: <000001ce09df$4f4e1f80$edea5e80$@besonet.ch> # HG changeset patch # User Simon Heimberg # Date 1360755357 -3600 # Node ID a9b334ae174bff56afe1c9fb060cf940d04295e7 # Parent 013fcd112f13f31a35ea6a40d8cd1c6923cdaf20 Tests: fix test on windows by appending glob to lines returning "\" in the path This lines were introduced in cd403d6d96ef and made the test fail on windows. diff -r 013fcd112f13 -r a9b334ae174b tests/test-obsolete.t --- a/tests/test-obsolete.t Sat Feb 09 11:00:42 2013 +0100 +++ b/tests/test-obsolete.t Wed Feb 13 12:35:57 2013 +0100 @@ -816,7 +816,7 @@ summary: A $ hg incoming - comparing with $TESTTMP/tmpe/repo-issue3805 + comparing with $TESTTMP/tmpe/repo-issue3805 (glob) searching for changes changeset: 2:3816541e5485 tag: tip @@ -826,7 +826,7 @@ summary: A $ hg incoming --bundle ../issue3805.hg - comparing with $TESTTMP/tmpe/repo-issue3805 + comparing with $TESTTMP/tmpe/repo-issue3805 (glob) searching for changes changeset: 2:3816541e5485 tag: tip @@ -836,7 +836,7 @@ summary: A $ hg outgoing - comparing with $TESTTMP/tmpe/repo-issue3805 + comparing with $TESTTMP/tmpe/repo-issue3805 (glob) searching for changes no changes found [1] From hg at intevation.org Wed Feb 13 06:00:12 2013 From: hg at intevation.org (Mercurial Commits) Date: Wed, 13 Feb 2013 13:00:12 +0100 Subject: mercurial/crew@18675: 46 outgoing changesets (1 stable) Message-ID: <1360756812.560593.26193.nullmailer@hg.intevation.org> 46 outgoing changesets (1 stable) in mercurial/crew: http://hg.intevation.org/mercurial/crew/rev/f816aa377e0d changeset: 18675:f816aa377e0d bookmark: @ tag: tip user: Bryan O'Sullivan date: Tue Feb 12 16:02:35 2013 -0800 summary: blackbox: fix a failing pyflakes test http://hg.intevation.org/mercurial/crew/rev/c61b49d059eb changeset: 18674:c61b49d059eb user: Durham Goode date: Sat Feb 09 13:35:30 2013 -0800 summary: blackbox: tests for the blackbox extension http://hg.intevation.org/mercurial/crew/rev/f27598902007 changeset: 18673:f27598902007 user: Durham Goode date: Sat Feb 09 09:09:46 2013 -0800 summary: blackbox: adds a 'blackbox' command for viewing recent logs http://hg.intevation.org/mercurial/crew/rev/b2b4ddc55caa changeset: 18672:b2b4ddc55caa user: Durham Goode date: Sat Feb 09 09:04:48 2013 -0800 summary: blackbox: log incoming changes via ui.log() http://hg.intevation.org/mercurial/crew/rev/1c305128e5b9 changeset: 18671:1c305128e5b9 user: Durham Goode date: Sat Feb 09 09:04:32 2013 -0800 summary: blackbox: logs python and extension hooks via ui.log() http://hg.intevation.org/mercurial/crew/rev/ddc7268da176 changeset: 18670:ddc7268da176 user: Durham Goode date: Sat Feb 09 09:04:14 2013 -0800 summary: blackbox: log the commands that are run http://hg.intevation.org/mercurial/crew/rev/18242716a014 changeset: 18669:18242716a014 user: Durham Goode date: Tue Feb 12 14:08:33 2013 -0800 summary: blackbox: adds a blackbox extension http://hg.intevation.org/mercurial/crew/rev/4034b8d551b1 changeset: 18668:4034b8d551b1 user: Bryan O'Sullivan date: Mon Feb 11 16:15:12 2013 -0800 summary: scmutil: create directories in a race-safe way during update http://hg.intevation.org/mercurial/crew/rev/f12804d3ff80 changeset: 18667:f12804d3ff80 parent: 18666:fb9d1c2805ff parent: 18658:5e63a85299ba user: Bryan O'Sullivan date: Mon Feb 11 14:50:54 2013 -0800 summary: Merge http://hg.intevation.org/mercurial/crew/rev/fb9d1c2805ff changeset: 18666:fb9d1c2805ff user: Idan Kamara date: Sat Feb 09 19:02:45 2013 +0200 summary: test-atomictempfile: convert to unit test http://hg.intevation.org/mercurial/crew/rev/2cbfb8c497ee changeset: 18665:2cbfb8c497ee user: Idan Kamara date: Sat Feb 09 19:13:39 2013 +0200 summary: tests: add a test runner utility that prints nothing when all tests pass http://hg.intevation.org/mercurial/crew/rev/30d899febef8 changeset: 18664:30d899febef8 user: Dan Villiom Podlaski Christiansen date: Sun Feb 10 13:14:31 2013 +0100 summary: hgweb: consistent author name width http://hg.intevation.org/mercurial/crew/rev/05cf40f9b0ec changeset: 18663:05cf40f9b0ec user: Durham Goode date: Sun Feb 10 12:23:39 2013 -0800 summary: dirstate: fix generator/list error when using python 2.7 http://hg.intevation.org/mercurial/crew/rev/c5f7e83d47cd changeset: 18662:c5f7e83d47cd user: Pierre-Yves David date: Mon Feb 11 16:21:48 2013 +0100 summary: mq: comply with filtering when injecting fake tags (issue3812) http://hg.intevation.org/mercurial/crew/rev/4fb92f14a97a changeset: 18661:4fb92f14a97a user: David Schleimer date: Fri Feb 08 05:36:08 2013 -0800 summary: commit: factor out post-commit cleanup into workingctx http://hg.intevation.org/mercurial/crew/rev/7e6946ed5756 changeset: 18660:7e6946ed5756 user: David Schleimer date: Fri Feb 08 05:36:08 2013 -0800 summary: localrepo: use workingctx for validation in commit http://hg.intevation.org/mercurial/crew/rev/b946470efed9 changeset: 18659:b946470efed9 parent: 18656:8eb3408bf005 user: David Schleimer date: Fri Feb 08 05:36:07 2013 -0800 summary: localrepo: create context used for actual commit earlier http://hg.intevation.org/mercurial/crew/rev/5e63a85299ba changeset: 18658:5e63a85299ba parent: 18656:8eb3408bf005 parent: 18657:d4a79e075303 user: Thomas Arendsen Hein date: Mon Feb 11 16:57:46 2013 +0100 summary: merge with crew-stable http://hg.intevation.org/mercurial/crew/rev/d4a79e075303 changeset: 18657:d4a79e075303 branch: stable bookmark: crew-stable parent: 18617:227479f61db9 user: Pierre-Yves David date: Sat Feb 09 23:28:42 2013 +0000 summary: debugobsolete: improve command help http://hg.intevation.org/mercurial/crew/rev/8eb3408bf005 changeset: 18656:8eb3408bf005 user: Kevin Bullock date: Sun Feb 10 23:01:12 2013 +0000 summary: import: don't rollback on failed import --exact (issue3616) http://hg.intevation.org/mercurial/crew/rev/882681bc3166 changeset: 18655:882681bc3166 parent: 18653:170142161672 parent: 18654:d9ff580fcaa2 user: Bryan O'Sullivan date: Sun Feb 10 16:22:32 2013 -0800 summary: Merge http://hg.intevation.org/mercurial/crew/rev/d9ff580fcaa2 changeset: 18654:d9ff580fcaa2 parent: 18651:e556659340f0 parent: 18648:013fcd112f13 user: Bryan O'Sullivan date: Sun Feb 10 16:21:30 2013 -0800 summary: Merge http://hg.intevation.org/mercurial/crew/rev/170142161672 changeset: 18653:170142161672 parent: 18652:a5e94bee77ed parent: 18651:e556659340f0 user: Benoit Boissinot date: Mon Feb 11 01:21:24 2013 +0100 summary: merge crew and main http://hg.intevation.org/mercurial/crew/rev/a5e94bee77ed changeset: 18652:a5e94bee77ed parent: 18642:76b69cccb07a parent: 18648:013fcd112f13 user: Benoit Boissinot date: Mon Feb 11 01:17:50 2013 +0100 summary: merge crew and main http://hg.intevation.org/mercurial/crew/rev/e556659340f0 changeset: 18651:e556659340f0 user: Siddharth Agarwal date: Sun Feb 10 16:55:01 2013 +0000 summary: manifestmerge: fix order in which manifests are fetched http://hg.intevation.org/mercurial/crew/rev/de0bd4bfc6d7 changeset: 18650:de0bd4bfc6d7 user: Siddharth Agarwal date: Sun Feb 10 12:16:46 2013 +0000 summary: merge: run _forgetremoved after manifestmerge http://hg.intevation.org/mercurial/crew/rev/0969980308c7 changeset: 18649:0969980308c7 parent: 18642:76b69cccb07a user: Siddharth Agarwal date: Sun Feb 10 16:23:14 2013 +0000 summary: dirstate: disable gc while parsing the dirstate http://hg.intevation.org/mercurial/crew/rev/76b69cccb07a changeset: 18642:76b69cccb07a user: Mads Kiilerich date: Fri Feb 08 22:54:17 2013 +0100 summary: export: show 'Date' header in a format that also is readable for humans http://hg.intevation.org/mercurial/crew/rev/c1d23b4a66d5 changeset: 18641:c1d23b4a66d5 user: Mads Kiilerich date: Sun Feb 10 18:26:04 2013 +0100 summary: factotum: fix urllib2 import so it no longer relies on a demandimport bug http://hg.intevation.org/mercurial/crew/rev/c6a81e54c209 changeset: 18640:c6a81e54c209 user: Mads Kiilerich date: Sun Jan 27 03:32:09 2013 +0100 summary: hgweb: make the test suite use hgweb in a more WSGI compliant way http://hg.intevation.org/mercurial/crew/rev/76ff3a715cf2 changeset: 18639:76ff3a715cf2 user: Mads Kiilerich date: Sun Feb 10 18:24:29 2013 +0100 summary: hgweb: simplify internal staticfile return codes http://hg.intevation.org/mercurial/crew/rev/3e92772d5383 changeset: 18638:3e92772d5383 user: Mads Kiilerich date: Sun Feb 10 18:24:29 2013 +0100 summary: spelling: fix some minor issues found by spell checker http://hg.intevation.org/mercurial/crew/rev/cc28a84db8c9 changeset: 18637:cc28a84db8c9 user: Mads Kiilerich date: Fri Feb 08 23:26:00 2013 +0100 summary: bundlerepo: replace basemap with the base field in the index http://hg.intevation.org/mercurial/crew/rev/a40d608e2a7b changeset: 18636:a40d608e2a7b user: Mads Kiilerich date: Fri Feb 08 22:54:48 2013 +0100 summary: profiling: replace '+' markup of nested lines with indentation http://hg.intevation.org/mercurial/crew/rev/6204e4d4dd6d changeset: 18635:6204e4d4dd6d parent: 18634:0027a5cec9d0 parent: 18633:a8648f32b8ed user: Augie Fackler date: Sun Feb 10 04:04:22 2013 -0600 summary: Merge crew and main. http://hg.intevation.org/mercurial/crew/rev/a8648f32b8ed changeset: 18633:a8648f32b8ed user: Bryan O'Sullivan date: Sat Feb 09 15:51:32 2013 -0800 summary: merge: don't fiddle with name lookups or i18n in hot loops http://hg.intevation.org/mercurial/crew/rev/5774732bb5e5 changeset: 18632:5774732bb5e5 user: Bryan O'Sullivan date: Sat Feb 09 15:51:32 2013 -0800 summary: merge: apply non-interactive working dir updates in parallel http://hg.intevation.org/mercurial/crew/rev/047110c0e2a8 changeset: 18631:047110c0e2a8 user: Bryan O'Sullivan date: Sat Feb 09 15:51:32 2013 -0800 summary: worker: allow a function to be run in multiple worker processes http://hg.intevation.org/mercurial/crew/rev/ac4dbceeb14a changeset: 18630:ac4dbceeb14a user: Bryan O'Sullivan date: Sat Feb 09 15:51:32 2013 -0800 summary: worker: partition a list (of tasks) into equal-sized chunks http://hg.intevation.org/mercurial/crew/rev/dcb27c153a40 changeset: 18629:dcb27c153a40 user: Bryan O'Sullivan date: Sat Feb 09 15:51:26 2013 -0800 summary: worker: estimate whether it's worth running a task in parallel http://hg.intevation.org/mercurial/crew/rev/fed06dd07665 changeset: 18628:fed06dd07665 user: Bryan O'Sullivan date: Sat Feb 09 15:22:12 2013 -0800 summary: worker: count the number of CPUs http://hg.intevation.org/mercurial/crew/rev/4b5d37ca3c11 changeset: 18627:4b5d37ca3c11 user: Bryan O'Sullivan date: Sat Feb 09 15:22:10 2013 -0800 summary: tests: getremove test output changes (fold into previous patch) http://hg.intevation.org/mercurial/crew/rev/6390dd22b12f changeset: 18626:6390dd22b12f user: Bryan O'Sullivan date: Sat Feb 09 15:22:09 2013 -0800 summary: merge: report non-interactive progress in chunks http://hg.intevation.org/mercurial/crew/rev/3e20079117c5 changeset: 18625:3e20079117c5 user: Bryan O'Sullivan date: Sat Feb 09 15:22:08 2013 -0800 summary: merge: handle subrepo merges and .hgsubstate specially http://hg.intevation.org/mercurial/crew/rev/e2dc5397bc82 changeset: 18624:e2dc5397bc82 user: Bryan O'Sullivan date: Sat Feb 09 15:22:04 2013 -0800 summary: tests: update test output (will be folded into parent) http://hg.intevation.org/mercurial/crew/rev/9b9e2d9e83a1 changeset: 18623:9b9e2d9e83a1 user: Bryan O'Sullivan date: Sat Feb 09 15:21:58 2013 -0800 summary: merge: split out mostly-non-interactive working dir updates -- Repository URL: http://hg.intevation.org/mercurial/crew From mercurial-bugs at selenic.com Wed Feb 13 05:07:55 2013 From: mercurial-bugs at selenic.com (mercurial-bugs at selenic.com) Date: Wed, 13 Feb 2013 11:07:55 +0000 Subject: [Bug 3821] New: Files modified after an update Message-ID: http://bz.selenic.com/show_bug.cgi?id=3821 Priority: normal Bug ID: 3821 CC: mercurial-devel at selenic.com Assignee: bugzilla at selenic.com Summary: Files modified after an update Severity: bug Classification: Unclassified OS: Linux Reporter: pourriel at sbgodin.fr Hardware: PC Status: UNCONFIRMED Version: 2.2.2 Component: Mercurial Product: Mercurial Created attachment 1713 --> http://bz.selenic.com/attachment.cgi?id=1713&action=edit the full output made by the commands After an update to a previous revset, some files are marked as modified by the update. I can even commit, even it there's nothing inside. Here is an example involving one single file inside a repository you may know a bit: $ cd /tmp $ hg clone http://selenic.com/hg/ mercurial (...) $ cd mercurial (...) $ hg update 1094 $ hg status M mercurial/dirstate.py $ hg diff (nothing) $ $ hg --version Mercurial Distributed SCM (version 2.2.2) (...) -- You are receiving this mail because: You are on the CC list for the bug. From kbullock+mercurial at ringworld.org Wed Feb 13 10:24:57 2013 From: kbullock+mercurial at ringworld.org (Kevin Bullock) Date: Wed, 13 Feb 2013 10:24:57 -0600 Subject: [PATCH 2 of 5] dispatch: catch InterventionRequired and print the message with no prefix In-Reply-To: <511A244B.1060800@grauw.nl> References: <4d997c5075c446963b6a.1360363790@augie-macbookair> <1c4102a7ec7c80a1baa9.1360363791@augie-macbookair> <51163554.5030202@kiilerich.com> <451256A9-57AB-41EF-9AC1-50D7807CEF7E@ringworld.org> <24A5EB27-857D-4CB4-B6A1-729A3137E7F4@durin42.com> <511A244B.1060800@grauw.nl> Message-ID: On Feb 12, 2013, at 5:15 AM, Laurens Holst wrote: > Op 11-02-13 22:47, Bryan O'Sullivan schreef: >> On Sat, Feb 9, 2013 at 3:51 AM, Augie Fackler wrote: >> Open to suggestions on that - I wanted a prefix but couldn't come up with one that was clear and suitably pithy. >> >> stopped? > > paused? > > suspended? stopped, suspended, interrupted all sound okay to me. pacem in terris / ??? / ?????? / ????????? / ?? Kevin R. Bullock From pierre-yves.david at logilab.fr Wed Feb 13 10:34:27 2013 From: pierre-yves.david at logilab.fr (Pierre-Yves David) Date: Wed, 13 Feb 2013 17:34:27 +0100 Subject: [PATCH 2 of 5] dispatch: catch InterventionRequired and print the message with no prefix In-Reply-To: References: <4d997c5075c446963b6a.1360363790@augie-macbookair> <1c4102a7ec7c80a1baa9.1360363791@augie-macbookair> <51163554.5030202@kiilerich.com> <451256A9-57AB-41EF-9AC1-50D7807CEF7E@ringworld.org> <24A5EB27-857D-4CB4-B6A1-729A3137E7F4@durin42.com> <511A244B.1060800@grauw.nl> Message-ID: <20130213163427.GA1061@crater2.logilab.fr> On Wed, Feb 13, 2013 at 10:24:57AM -0600, Kevin Bullock wrote: > On Feb 12, 2013, at 5:15 AM, Laurens Holst wrote: > > > Op 11-02-13 22:47, Bryan O'Sullivan schreef: > >> On Sat, Feb 9, 2013 at 3:51 AM, Augie Fackler wrote: > >> Open to suggestions on that - I wanted a prefix but couldn't come up with one that was clear and suitably pithy. > >> > >> stopped? > > > > paused? > > > > suspended? > > stopped, suspended, interrupted all sound okay to me. "interrupted" is very similar to what mercurial print on SIGINT we can not use it. "suspended" ring a SIGSTOP bell for me. I'm not a fan of stop but it sound ok - "pause" sound ok to me too. - "stall" ? - "delay" ? - "block" note: what we really want to say is: HALP ME HUMAN I'M JUST A COMPUTER -- Pierre-Yves David http://www.logilab.fr/ -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 198 bytes Desc: Digital signature URL: From mercurial-bugs at selenic.com Wed Feb 13 06:40:40 2013 From: mercurial-bugs at selenic.com (mercurial-bugs at selenic.com) Date: Wed, 13 Feb 2013 12:40:40 +0000 Subject: [Bug 3822] New: graft: file moves sometimes changed to deletion+addition Message-ID: http://bz.selenic.com/show_bug.cgi?id=3822 Priority: normal Bug ID: 3822 CC: mercurial-devel at selenic.com Assignee: bugzilla at selenic.com Summary: graft: file moves sometimes changed to deletion+addition Severity: bug Classification: Unclassified OS: Windows Reporter: tosobody at gmail.com Hardware: PC Status: UNCONFIRMED Version: earlier Component: Mercurial Product: Mercurial Mercurial version: 2.1.1 Steps: 1. In several changesets I moved and renamed several files. Some of the files were also changed. 2. These changesets (among others) were grafted from default to three branches (all branched from default). In all three cases the grafted changesets were the same ones in the same sequence. Results: The same move/rename in the same changeset grafted ok in some cases, and transformed to deletion+addition in other cases. Notes: There seems to be only one possible correlation (but no guaranty, I did not check every case): The move/rename might be changed to a deletion+addition for that file and that graft, where no merge conflict appeared. There is no correlation with: * The changesets * The files * The file locations * The branches grafted to * Being the only change in a changeset or other changes, too * Being the only move in a changeset or other moves, too * Being move+change or only move * move or rename * move in a move chain or not * type of graft: The graft to oldest branch was with: hg graft 72464 72467 72468 ... 73396::73411 73421::73423 The graft to the middle one with (same changsets, but global ID, no ::): hg graft -D f39...dcc 5da...613 ... d24...e83 af1...ebc The graft to the newest branch (as above, without -D): hg graft f39...dcc 5da...613 ... d24...e83 af1...ebc * ... several other things I checked, but forgot -- You are receiving this mail because: You are on the CC list for the bug. From durham at fb.com Wed Feb 13 12:30:35 2013 From: durham at fb.com (Durham Goode) Date: Wed, 13 Feb 2013 18:30:35 +0000 Subject: [PATCH 6 of 6 V2] blackbox: tests for the blackbox extension In-Reply-To: Message-ID: <2B10A89294DA6740AC6155F56842F9CE0565A88A@PRN-MBX01-2.TheFacebook.com> On 2/12/13 9:08 PM, "Bryan O'Sullivan" wrote: > > > >On Tue, Feb 12, 2013 at 8:50 PM, Matt Mackall wrote: > >Copyright notice probably ought to mention Nic Dumazet and not >worker.py. > > > > > > >Oops. Durham, does the patch include any of Nic's code? > > > I started off with Nic's code (though only a few lines remain), so I think it's good to put him in the copyright as well. From bos at serpentine.com Wed Feb 13 12:55:14 2013 From: bos at serpentine.com (Bryan O'Sullivan) Date: Wed, 13 Feb 2013 10:55:14 -0800 Subject: [PATCH 6 of 6 V2] blackbox: tests for the blackbox extension In-Reply-To: <2B10A89294DA6740AC6155F56842F9CE0565A88A@PRN-MBX01-2.TheFacebook.com> References: <2B10A89294DA6740AC6155F56842F9CE0565A88A@PRN-MBX01-2.TheFacebook.com> Message-ID: On Wed, Feb 13, 2013 at 10:30 AM, Durham Goode wrote: > I started off with Nic's code (though only a few lines remain), so I think > it's good to put him in the copyright as well. > Done: http://hg.intevation.org/mercurial/crew/rev/1506eb487ddd -------------- next part -------------- An HTML attachment was scrubbed... URL: From bos at serpentine.com Wed Feb 13 13:04:29 2013 From: bos at serpentine.com (Bryan O'Sullivan) Date: Wed, 13 Feb 2013 11:04:29 -0800 Subject: [PATCH] util: make ensuredirs safer against races Message-ID: # HG changeset patch # User Bryan O'Sullivan # Date 1360782158 28800 # Node ID e6216ef880db51568b067ab4fc88c2bdf50beca2 # Parent 1506eb487dddbc377398096ce797fa5ccd712f10 util: make ensuredirs safer against races diff --git a/mercurial/scmutil.py b/mercurial/scmutil.py --- a/mercurial/scmutil.py +++ b/mercurial/scmutil.py @@ -306,8 +306,7 @@ class vfs(abstractvfs): # to a directory. Let the posixfile() call below raise IOError. if basename: if atomictemp: - if not os.path.isdir(dirname): - util.ensuredirs(dirname, self.createmode) + util.ensuredirs(dirname, self.createmode) return util.atomictempfile(f, mode, self.createmode) try: if 'w' in mode: @@ -325,8 +324,7 @@ class vfs(abstractvfs): if e.errno != errno.ENOENT: raise nlink = 0 - if not os.path.isdir(dirname): - util.ensuredirs(dirname, self.createmode) + util.ensuredirs(dirname, self.createmode) if nlink > 0: if self._trustnlink is None: self._trustnlink = nlink > 1 or util.checknlink(f) @@ -345,9 +343,7 @@ class vfs(abstractvfs): except OSError: pass - dirname = os.path.dirname(linkname) - if not os.path.exists(dirname): - util.ensuredirs(dirname, self.createmode) + util.ensuredirs(os.path.dirname(linkname), self.createmode) if self._cansymlink: try: diff --git a/mercurial/util.py b/mercurial/util.py --- a/mercurial/util.py +++ b/mercurial/util.py @@ -16,7 +16,7 @@ hide platform-specific details from the from i18n import _ import error, osutil, encoding, collections import errno, re, shutil, sys, tempfile, traceback -import os, time, datetime, calendar, textwrap, signal +import os, stat, time, datetime, calendar, textwrap, signal import imp, socket, urllib if os.name == 'nt': @@ -882,13 +882,20 @@ def makedirs(name, mode=None): def ensuredirs(name, mode=None): """race-safe recursive directory creation""" + if os.path.isdir(name): + return + parent = os.path.dirname(os.path.abspath(name)) + if parent != name: + ensuredirs(parent, mode) try: - makedirs(name, mode) + os.mkdir(name) except OSError, err: if err.errno == errno.EEXIST and os.path.isdir(name): # someone else seems to have won a directory creation race return raise + if mode is not None: + os.chmod(name, mode) def readfile(path): fp = open(path, 'rb') From durham at fb.com Wed Feb 13 13:23:20 2013 From: durham at fb.com (Durham Goode) Date: Wed, 13 Feb 2013 11:23:20 -0800 Subject: [PATCH] blackbox: only show new heads on incoming Message-ID: <20a00d8c36a1e4209454.1360783400@dev350.prn1.facebook.com> # HG changeset patch # User Durham Goode # Date 1360782421 28800 # Wed Feb 13 11:07:01 2013 -0800 # Node ID 20a00d8c36a1e4209454b42468205df439b1ea8c # Parent 111fef1dae2c3f5feecb3fd3fe075c093f4f993a blackbox: only show new heads on incoming The blackbox was logging every head after every incoming group. Now we only log the heads that have changed. Added a test. Moved the hooks test to the bottom of the file since the hooks interfer with the tests after it. diff --git a/mercurial/localrepo.py b/mercurial/localrepo.py --- a/mercurial/localrepo.py +++ b/mercurial/localrepo.py @@ -2400,11 +2400,11 @@ self.hook("incoming", node=hex(n), source=srctype, url=url) - heads = self.heads() + newheads = [h for h in self.heads() if h not in oldheads] self.ui.log("incoming", _("%s incoming changes - new heads: %s\n"), len(added), - ', '.join([hex(c[:6]) for c in heads])) + ', '.join([hex(c[:6]) for c in newheads])) self._afterlock(runhooks) finally: diff --git a/tests/test-blackbox.t b/tests/test-blackbox.t --- a/tests/test-blackbox.t +++ b/tests/test-blackbox.t @@ -28,6 +28,38 @@ 1970/01/01 00:00:00 bob> add a 1970/01/01 00:00:00 bob> add exited 0 after * seconds (glob) +incoming change tracking + +create two heads to verify that we only see one change in the log later + $ hg commit -ma + $ hg up null + 0 files updated, 0 files merged, 1 files removed, 0 files unresolved + $ echo b > b + $ hg commit -Amb + adding b + created new head + +clone, commit, pull + $ hg clone . ../blackboxtest2 + updating to branch default + 1 files updated, 0 files merged, 0 files removed, 0 files unresolved + $ echo c > c + $ hg commit -Amc + adding c + $ cd ../blackboxtest2 + $ hg pull + pulling from $TESTTMP/blackboxtest + searching for changes + adding changesets + adding manifests + adding file changes + added 1 changesets with 1 changes to 1 files + (run 'hg update' to get a working copy) + $ hg blackbox -l 3 + 1970/01/01 00:00:00 bob> pull + 1970/01/01 00:00:00 bob> 1 incoming changes - new heads: d02f48003e62 (glob) + 1970/01/01 00:00:00 bob> pull exited None after * seconds (glob) + extension and python hooks - use the eol extension for a pythonhook $ echo '[extensions]' >> .hg/hgrc @@ -36,32 +68,12 @@ $ echo 'update = echo hooked' >> .hg/hgrc $ hg update hooked - 0 files updated, 0 files merged, 0 files removed, 0 files unresolved + 1 files updated, 0 files merged, 0 files removed, 0 files unresolved $ hg blackbox -l 4 1970/01/01 00:00:00 bob> update 1970/01/01 00:00:00 bob> pythonhook-preupdate: hgext.eol.preupdate finished in * seconds (glob) 1970/01/01 00:00:00 bob> exthook-update: echo hooked finished in * seconds (glob) 1970/01/01 00:00:00 bob> update exited False after * seconds (glob) -incoming change tracking - - $ hg clone . ../blackboxtest2 - updating to branch default - 0 files updated, 0 files merged, 0 files removed, 0 files unresolved - $ hg commit -ma - $ cd ../blackboxtest2 - $ hg pull - pulling from $TESTTMP/blackboxtest - requesting all changes - adding changesets - adding manifests - adding file changes - added 1 changesets with 1 changes to 1 files - (run 'hg update' to get a working copy) - $ hg blackbox -l 3 - 1970/01/01 00:00:00 bob> pull - 1970/01/01 00:00:00 bob> 1 incoming changes - new heads: cb9a9f314b8b (glob) - 1970/01/01 00:00:00 bob> pull exited None after * seconds (glob) - cleanup $ cd .. From kbullock+mercurial at ringworld.org Wed Feb 13 13:32:06 2013 From: kbullock+mercurial at ringworld.org (Kevin Bullock) Date: Wed, 13 Feb 2013 13:32:06 -0600 Subject: [PATCH] util: make ensuredirs safer against races In-Reply-To: References: Message-ID: On Feb 13, 2013, at 1:04 PM, Bryan O'Sullivan wrote: > # HG changeset patch > # User Bryan O'Sullivan > # Date 1360782158 28800 > # Node ID e6216ef880db51568b067ab4fc88c2bdf50beca2 > # Parent 1506eb487dddbc377398096ce797fa5ccd712f10 > util: make ensuredirs safer against races > > [...] > diff --git a/mercurial/util.py b/mercurial/util.py > --- a/mercurial/util.py > +++ b/mercurial/util.py > @@ -16,7 +16,7 @@ hide platform-specific details from the > from i18n import _ > import error, osutil, encoding, collections > import errno, re, shutil, sys, tempfile, traceback > -import os, time, datetime, calendar, textwrap, signal > +import os, stat, time, datetime, calendar, textwrap, signal Is stat actually needed? I don't see it used below. pacem in terris / ??? / ?????? / ????????? / ?? Kevin R. Bullock From bos at serpentine.com Wed Feb 13 13:34:36 2013 From: bos at serpentine.com (Bryan O'Sullivan) Date: Wed, 13 Feb 2013 11:34:36 -0800 Subject: [PATCH] util: make ensuredirs safer against races In-Reply-To: References: Message-ID: On Wed, Feb 13, 2013 at 11:32 AM, Kevin Bullock < kbullock+mercurial at ringworld.org> wrote: > Is stat actually needed? I don't see it used below. > Good catch. -------------- next part -------------- An HTML attachment was scrubbed... URL: From bos at serpentine.com Wed Feb 13 13:34:49 2013 From: bos at serpentine.com (Bryan O'Sullivan) Date: Wed, 13 Feb 2013 11:34:49 -0800 Subject: [PATCH] blackbox: only show new heads on incoming In-Reply-To: <20a00d8c36a1e4209454.1360783400@dev350.prn1.facebook.com> References: <20a00d8c36a1e4209454.1360783400@dev350.prn1.facebook.com> Message-ID: On Wed, Feb 13, 2013 at 11:23 AM, Durham Goode wrote: > blackbox: only show new heads on incoming > Crewed, thanks. -------------- next part -------------- An HTML attachment was scrubbed... URL: From durham at fb.com Wed Feb 13 13:42:44 2013 From: durham at fb.com (Durham Goode) Date: Wed, 13 Feb 2013 19:42:44 +0000 Subject: [PATCH RFC] commit: add --reuse-message for keeping the old commit message during amend In-Reply-To: <1360731362.12295.24.camel@calx> Message-ID: <2B10A89294DA6740AC6155F56842F9CE0565A924@PRN-MBX01-2.TheFacebook.com> On 2/12/13 8:56 PM, "Matt Mackall" wrote: > >I'm now inclined to think that 'hg commit --amend' will eventually be >replaced by 'hg amend', which will have a different default. Then we'll >deprecate --amend on commit. > >So I think we should leave this alone. But I don't think we've got quite >enough experience here to add the new amend command yet. If anyone feels strongly about getting the extra commit flag in, speak up. For Facebook's purposes we will just add an amend alias for our users that does 'hg --config ui.editor=true commit --amend' while we wait for the real 'hg amend'. As for having amend experience, as I've started using evolve more I've found I use an amend flows in three ways: 1. (most common) Amending the code in the current commit 2. Amending the code in a commit further down. 3. (least common) Amending the commit description. So my ideal "hg amend" would do #1 by default, #2 with "hg amend --to 'tip~2'", and #3 with "hg amend -e". #2 is the only crazy one, but I've been using a script that does it in one step and it makes editing chains of commits much much easier. From kbullock+mercurial at ringworld.org Wed Feb 13 13:47:43 2013 From: kbullock+mercurial at ringworld.org (Kevin Bullock) Date: Wed, 13 Feb 2013 13:47:43 -0600 Subject: [PATCH 1 of 6] backout: use cmdutil.revert directly instead of commands.revert Message-ID: # HG changeset patch # User Kevin Bullock # Date 1360681637 0 # Node ID a6300d15b1e82121a9b646126ba35809068f340e # Parent 1506eb487dddbc377398096ce797fa5ccd712f10 backout: use cmdutil.revert directly instead of commands.revert Before this change, backout would explicitly set the options it passed to commands.revert in order to fall thru most of its logic and call cmdutil.revert. This change makes it clearer what backup is trying to accomplish and makes it robust against changes to the revert command. diff --git a/mercurial/commands.py b/mercurial/commands.py --- a/mercurial/commands.py +++ b/mercurial/commands.py @@ -458,12 +458,8 @@ def backout(ui, repo, node=None, rev=Non branch = repo.dirstate.branch() hg.clean(repo, node, show_stats=False) repo.dirstate.setbranch(branch) - revert_opts = opts.copy() - revert_opts['date'] = None - revert_opts['all'] = True - revert_opts['rev'] = hex(parent) - revert_opts['no_backup'] = None - revert(ui, repo, **revert_opts) + rctx = scmutil.revsingle(repo, hex(parent)) + cmdutil.revert(ui, repo, rctx, repo.dirstate.parents()) if not opts.get('merge') and op1 != node: try: ui.setconfig('ui', 'forcemerge', opts.get('tool', '')) From kbullock+mercurial at ringworld.org Wed Feb 13 13:47:44 2013 From: kbullock+mercurial at ringworld.org (Kevin Bullock) Date: Wed, 13 Feb 2013 13:47:44 -0600 Subject: [PATCH 2 of 6] backout: remove unnecessary frobbing of addremove option In-Reply-To: References: Message-ID: <67fff6f7f7bbe643f8cb.1360784864@x-128-101-230-141.uofm-secure.wireless.umn.edu> # HG changeset patch # User Kevin Bullock # Date 1360684050 0 # Node ID 67fff6f7f7bbe643f8cb21567d05d1533589c94d # Parent a6300d15b1e82121a9b646126ba35809068f340e backout: remove unnecessary frobbing of addremove option There's no way for addremove to show up in backout's opts dictionary. It was being set manually because cmdutil.commit expected it to be there (and would throw an exception if it wasn't). This was fixed waaaaaaay back in: changeset: 5829:784073457a0f user: Kirill Smelkov date: Thu Jan 10 12:07:18 2008 +0300 summary: cmdutil.commit: extract 'addremove' from opts carefully diff --git a/mercurial/commands.py b/mercurial/commands.py --- a/mercurial/commands.py +++ b/mercurial/commands.py @@ -468,7 +468,6 @@ def backout(ui, repo, node=None, rev=Non ui.setconfig('ui', 'forcemerge', '') commit_opts = opts.copy() - commit_opts['addremove'] = False if not commit_opts['message'] and not commit_opts['logfile']: # we don't translate commit messages commit_opts['message'] = "Backed out changeset %s" % short(node) From kbullock+mercurial at ringworld.org Wed Feb 13 13:47:45 2013 From: kbullock+mercurial at ringworld.org (Kevin Bullock) Date: Wed, 13 Feb 2013 13:47:45 -0600 Subject: [PATCH 3 of 6] backout: remove unnecessary dict copy In-Reply-To: References: Message-ID: <0bd924ff1d80ad014103.1360784865@x-128-101-230-141.uofm-secure.wireless.umn.edu> # HG changeset patch # User Kevin Bullock # Date 1360685100 0 # Node ID 0bd924ff1d80ad01410368fe25e278b6150a6ebf # Parent 67fff6f7f7bbe643f8cb21567d05d1533589c94d backout: remove unnecessary dict copy This is step 1 to remove backout's call to commands.commit. We don't use the options again anywhere below except for backout's own purposes, specifically choosing a merge tool, so we just write the commit options in directly. diff --git a/mercurial/commands.py b/mercurial/commands.py --- a/mercurial/commands.py +++ b/mercurial/commands.py @@ -467,12 +467,12 @@ def backout(ui, repo, node=None, rev=Non finally: ui.setconfig('ui', 'forcemerge', '') - commit_opts = opts.copy() - if not commit_opts['message'] and not commit_opts['logfile']: + if not opts['message'] and not opts['logfile']: # we don't translate commit messages - commit_opts['message'] = "Backed out changeset %s" % short(node) - commit_opts['force_editor'] = True - commit(ui, repo, **commit_opts) + opts['message'] = "Backed out changeset %s" % short(node) + opts['force_editor'] = True + commit(ui, repo, **opts) + def nice(node): return '%d:%s' % (repo.changelog.rev(node), short(node)) ui.status(_('changeset %s backs out changeset %s\n') % From kbullock+mercurial at ringworld.org Wed Feb 13 13:47:46 2013 From: kbullock+mercurial at ringworld.org (Kevin Bullock) Date: Wed, 13 Feb 2013 13:47:46 -0600 Subject: [PATCH 4 of 6] commit: factor out status printing into a helper function In-Reply-To: References: Message-ID: # HG changeset patch # User Kevin Bullock # Date 1360686734 0 # Node ID c5b0c803433947a51e1901f627e91d685457c0cb # Parent 0bd924ff1d80ad01410368fe25e278b6150a6ebf commit: factor out status printing into a helper function We create a new function commitstatus() in cmdutil that handles printing the status message(s) after a commit. This will allow other commit-like commands to use it, and in particular is step 2 towards removing backout's call to commands.commit. diff --git a/mercurial/cmdutil.py b/mercurial/cmdutil.py --- a/mercurial/cmdutil.py +++ b/mercurial/cmdutil.py @@ -1821,6 +1821,52 @@ def commitforceeditor(repo, ctx, subs): return text +def commitstatus(repo, node, branch, bheads=None, opts={}): + ctx = repo[node] + parents = ctx.parents() + + if (not opts.get('amend') and bheads and node not in bheads and not + [x for x in parents if x.node() in bheads and x.branch() == branch]): + repo.ui.status(_('created new head\n')) + # The message is not printed for initial roots. For the other + # changesets, it is printed in the following situations: + # + # Par column: for the 2 parents with ... + # N: null or no parent + # B: parent is on another named branch + # C: parent is a regular non head changeset + # H: parent was a branch head of the current branch + # Msg column: whether we print "created new head" message + # In the following, it is assumed that there already exists some + # initial branch heads of the current branch, otherwise nothing is + # printed anyway. + # + # Par Msg Comment + # N N y additional topo root + # + # B N y additional branch root + # C N y additional topo head + # H N n usual case + # + # B B y weird additional branch root + # C B y branch merge + # H B n merge with named branch + # + # C C y additional head from merge + # C H n merge with a head + # + # H H n head merge: head count decreases + + if not opts.get('close_branch'): + for r in parents: + if r.closesbranch() and r.branch() == branch: + repo.ui.status(_('reopening closed branch head %d\n') % r) + + if repo.ui.debugflag: + repo.ui.write(_('committed changeset %d:%s\n') % (int(ctx), ctx.hex())) + elif repo.ui.verbose: + repo.ui.write(_('committed changeset %d:%s\n') % (int(ctx), ctx)) + def revert(ui, repo, ctx, parents, *pats, **opts): parent, p2 = parents node = ctx.node() diff --git a/mercurial/commands.py b/mercurial/commands.py --- a/mercurial/commands.py +++ b/mercurial/commands.py @@ -1356,50 +1356,7 @@ def commit(ui, repo, *pats, **opts): ui.status(_("nothing changed\n")) return 1 - ctx = repo[node] - parents = ctx.parents() - - if (not opts.get('amend') and bheads and node not in bheads and not - [x for x in parents if x.node() in bheads and x.branch() == branch]): - ui.status(_('created new head\n')) - # The message is not printed for initial roots. For the other - # changesets, it is printed in the following situations: - # - # Par column: for the 2 parents with ... - # N: null or no parent - # B: parent is on another named branch - # C: parent is a regular non head changeset - # H: parent was a branch head of the current branch - # Msg column: whether we print "created new head" message - # In the following, it is assumed that there already exists some - # initial branch heads of the current branch, otherwise nothing is - # printed anyway. - # - # Par Msg Comment - # N N y additional topo root - # - # B N y additional branch root - # C N y additional topo head - # H N n usual case - # - # B B y weird additional branch root - # C B y branch merge - # H B n merge with named branch - # - # C C y additional head from merge - # C H n merge with a head - # - # H H n head merge: head count decreases - - if not opts.get('close_branch'): - for r in parents: - if r.closesbranch() and r.branch() == branch: - ui.status(_('reopening closed branch head %d\n') % r) - - if ui.debugflag: - ui.write(_('committed changeset %d:%s\n') % (int(ctx), ctx.hex())) - elif ui.verbose: - ui.write(_('committed changeset %d:%s\n') % (int(ctx), ctx)) + cmdutil.commitstatus(repo, node, branch, bheads, opts) @command('copy|cp', [('A', 'after', None, _('record a copy that has already occurred')), From kbullock+mercurial at ringworld.org Wed Feb 13 13:47:47 2013 From: kbullock+mercurial at ringworld.org (Kevin Bullock) Date: Wed, 13 Feb 2013 13:47:47 -0600 Subject: [PATCH 5 of 6] backout: call cmdutil.commit directly instead of commands.commit In-Reply-To: References: Message-ID: <2a7b18b83de419ff4e7a.1360784867@x-128-101-230-141.uofm-secure.wireless.umn.edu> # HG changeset patch # User Kevin Bullock # Date 1360687004 0 # Node ID 2a7b18b83de419ff4e7a942795ef7a32c8a3e9a7 # Parent c5b0c803433947a51e1901f627e91d685457c0cb backout: call cmdutil.commit directly instead of commands.commit This cleans up the messiness of having one command call another, and makes the backout command robust against changes to the commit command. diff --git a/mercurial/commands.py b/mercurial/commands.py --- a/mercurial/commands.py +++ b/mercurial/commands.py @@ -456,6 +456,7 @@ def backout(ui, repo, node=None, rev=Non wlock = repo.wlock() try: branch = repo.dirstate.branch() + bheads = repo.branchheads(branch) hg.clean(repo, node, show_stats=False) repo.dirstate.setbranch(branch) rctx = scmutil.revsingle(repo, hex(parent)) @@ -467,11 +468,17 @@ def backout(ui, repo, node=None, rev=Non finally: ui.setconfig('ui', 'forcemerge', '') + e = cmdutil.commiteditor if not opts['message'] and not opts['logfile']: # we don't translate commit messages opts['message'] = "Backed out changeset %s" % short(node) - opts['force_editor'] = True - commit(ui, repo, **opts) + e = cmdutil.commitforceeditor + + def commitfunc(ui, repo, message, match, opts): + return repo.commit(message, opts.get('user'), opts.get('date'), + match, editor=e) + newnode = cmdutil.commit(ui, repo, commitfunc, [], opts) + cmdutil.commitstatus(repo, newnode, branch, bheads) def nice(node): return '%d:%s' % (repo.changelog.rev(node), short(node)) From kbullock+mercurial at ringworld.org Wed Feb 13 13:47:48 2013 From: kbullock+mercurial at ringworld.org (Kevin Bullock) Date: Wed, 13 Feb 2013 13:47:48 -0600 Subject: [PATCH 6 of 6] scmutil: split platform-specific bits into their own modules In-Reply-To: References: Message-ID: # HG changeset patch # User Kevin Bullock # Date 1360690581 21600 # Node ID e0398ae149a834d19b718ec0c9869bbc16ba3086 # Parent 2a7b18b83de419ff4e7a942795ef7a32c8a3e9a7 scmutil: split platform-specific bits into their own modules This parallels what's done for the util module, which imports either mercurial.posix or mercurial.windows as 'platform' and then slurps the appropriate functions into its own namespace. diff --git a/mercurial/scmposix.py b/mercurial/scmposix.py new file mode 100644 --- /dev/null +++ b/mercurial/scmposix.py @@ -0,0 +1,32 @@ +import sys, os +import osutil + +def _rcfiles(path): + rcs = [os.path.join(path, 'hgrc')] + rcdir = os.path.join(path, 'hgrc.d') + try: + rcs.extend([os.path.join(rcdir, f) + for f, kind in osutil.listdir(rcdir) + if f.endswith(".rc")]) + except OSError: + pass + return rcs + +def systemrcpath(): + path = [] + if sys.platform == 'plan9': + root = 'lib/mercurial' + else: + root = 'etc/mercurial' + # old mod_python does not set sys.argv + if len(getattr(sys, 'argv', [])) > 0: + p = os.path.dirname(os.path.dirname(sys.argv[0])) + path.extend(_rcfiles(os.path.join(p, root))) + path.extend(_rcfiles('/' + root)) + return path + +def userrcpath(): + if sys.platform == 'plan9': + return [os.environ['home'] + '/lib/hgrc'] + else: + return [os.path.expanduser('~/.hgrc')] diff --git a/mercurial/scmutil.py b/mercurial/scmutil.py --- a/mercurial/scmutil.py +++ b/mercurial/scmutil.py @@ -11,6 +11,14 @@ import util, error, osutil, revset, simi import match as matchmod import os, errno, re, stat, sys, glob +if os.name == 'nt': + import scmwindows as scmplatform +else: + import scmposix as scmplatform + +systemrcpath = scmplatform.systemrcpath +userrcpath = scmplatform.userrcpath + def nochangesfound(ui, repo, excluded=None): '''Report no changes for push/pull, excluded is None or a list of nodes excluded from the push/pull. @@ -535,84 +543,6 @@ def rcpath(): _rcpath = osrcpath() return _rcpath -if os.name != 'nt': - - def rcfiles(path): - rcs = [os.path.join(path, 'hgrc')] - rcdir = os.path.join(path, 'hgrc.d') - try: - rcs.extend([os.path.join(rcdir, f) - for f, kind in osutil.listdir(rcdir) - if f.endswith(".rc")]) - except OSError: - pass - return rcs - - def systemrcpath(): - path = [] - if sys.platform == 'plan9': - root = 'lib/mercurial' - else: - root = 'etc/mercurial' - # old mod_python does not set sys.argv - if len(getattr(sys, 'argv', [])) > 0: - p = os.path.dirname(os.path.dirname(sys.argv[0])) - path.extend(rcfiles(os.path.join(p, root))) - path.extend(rcfiles('/' + root)) - return path - - def userrcpath(): - if sys.platform == 'plan9': - return [os.environ['home'] + '/lib/hgrc'] - else: - return [os.path.expanduser('~/.hgrc')] - -else: - - import _winreg - - def systemrcpath(): - '''return default os-specific hgrc search path''' - rcpath = [] - filename = util.executablepath() - # Use mercurial.ini found in directory with hg.exe - progrc = os.path.join(os.path.dirname(filename), 'mercurial.ini') - if os.path.isfile(progrc): - rcpath.append(progrc) - return rcpath - # Use hgrc.d found in directory with hg.exe - progrcd = os.path.join(os.path.dirname(filename), 'hgrc.d') - if os.path.isdir(progrcd): - for f, kind in osutil.listdir(progrcd): - if f.endswith('.rc'): - rcpath.append(os.path.join(progrcd, f)) - return rcpath - # else look for a system rcpath in the registry - value = util.lookupreg('SOFTWARE\\Mercurial', None, - _winreg.HKEY_LOCAL_MACHINE) - if not isinstance(value, str) or not value: - return rcpath - value = util.localpath(value) - for p in value.split(os.pathsep): - if p.lower().endswith('mercurial.ini'): - rcpath.append(p) - elif os.path.isdir(p): - for f, kind in osutil.listdir(p): - if f.endswith('.rc'): - rcpath.append(os.path.join(p, f)) - return rcpath - - def userrcpath(): - '''return os-specific hgrc search path to the user dir''' - home = os.path.expanduser('~') - path = [os.path.join(home, 'mercurial.ini'), - os.path.join(home, '.hgrc')] - userprofile = os.environ.get('USERPROFILE') - if userprofile: - path.append(os.path.join(userprofile, 'mercurial.ini')) - path.append(os.path.join(userprofile, '.hgrc')) - return path - def revsingle(repo, revspec, default='.'): if not revspec: return repo[default] diff --git a/mercurial/scmwindows.py b/mercurial/scmwindows.py new file mode 100644 --- /dev/null +++ b/mercurial/scmwindows.py @@ -0,0 +1,45 @@ +import sys, os +import osutil +import _winreg + +def systemrcpath(): + '''return default os-specific hgrc search path''' + rcpath = [] + filename = util.executablepath() + # Use mercurial.ini found in directory with hg.exe + progrc = os.path.join(os.path.dirname(filename), 'mercurial.ini') + if os.path.isfile(progrc): + rcpath.append(progrc) + return rcpath + # Use hgrc.d found in directory with hg.exe + progrcd = os.path.join(os.path.dirname(filename), 'hgrc.d') + if os.path.isdir(progrcd): + for f, kind in osutil.listdir(progrcd): + if f.endswith('.rc'): + rcpath.append(os.path.join(progrcd, f)) + return rcpath + # else look for a system rcpath in the registry + value = util.lookupreg('SOFTWARE\\Mercurial', None, + _winreg.HKEY_LOCAL_MACHINE) + if not isinstance(value, str) or not value: + return rcpath + value = util.localpath(value) + for p in value.split(os.pathsep): + if p.lower().endswith('mercurial.ini'): + rcpath.append(p) + elif os.path.isdir(p): + for f, kind in osutil.listdir(p): + if f.endswith('.rc'): + rcpath.append(os.path.join(p, f)) + return rcpath + +def userrcpath(): + '''return os-specific hgrc search path to the user dir''' + home = os.path.expanduser('~') + path = [os.path.join(home, 'mercurial.ini'), + os.path.join(home, '.hgrc')] + userprofile = os.environ.get('USERPROFILE') + if userprofile: + path.append(os.path.join(userprofile, 'mercurial.ini')) + path.append(os.path.join(userprofile, '.hgrc')) + return path From mpm at selenic.com Wed Feb 13 14:03:33 2013 From: mpm at selenic.com (Matt Mackall) Date: Wed, 13 Feb 2013 14:03:33 -0600 Subject: [PATCH] util: make ensuredirs safer against races In-Reply-To: References: Message-ID: <1360785813.12295.33.camel@calx> On Wed, 2013-02-13 at 11:34 -0800, Bryan O'Sullivan wrote: > On Wed, Feb 13, 2013 at 11:32 AM, Kevin Bullock < > kbullock+mercurial at ringworld.org> wrote: > > > Is stat actually needed? I don't see it used below. > > > > Good catch. The test suite will catch unused imports if you have pyflakes installed. -- Mathematics is the supreme nostalgia of our time. From bboissin at gmail.com Wed Feb 13 14:30:04 2013 From: bboissin at gmail.com (Benoit Boissinot) Date: Wed, 13 Feb 2013 21:30:04 +0100 Subject: [PATCH STABLE] Tests: fix test on windows by appending glob to lines returning "\" in the path In-Reply-To: <000001ce09df$4f4e1f80$edea5e80$@besonet.ch> References: <000001ce09df$4f4e1f80$edea5e80$@besonet.ch> Message-ID: Crewed, thanks. On Wed, Feb 13, 2013 at 12:43 PM, Simon Heimberg wrote: > # HG changeset patch > # User Simon Heimberg > # Date 1360755357 -3600 > # Node ID a9b334ae174bff56afe1c9fb060cf940d04295e7 > # Parent 013fcd112f13f31a35ea6a40d8cd1c6923cdaf20 > Tests: fix test on windows by appending glob to lines returning "\" in the > path > > This lines were introduced in cd403d6d96ef and made the test fail on > windows. > > diff -r 013fcd112f13 -r a9b334ae174b tests/test-obsolete.t > --- a/tests/test-obsolete.t Sat Feb 09 11:00:42 2013 +0100 > +++ b/tests/test-obsolete.t Wed Feb 13 12:35:57 2013 +0100 > @@ -816,7 +816,7 @@ > summary: A > > $ hg incoming > - comparing with $TESTTMP/tmpe/repo-issue3805 > + comparing with $TESTTMP/tmpe/repo-issue3805 (glob) > searching for changes > changeset: 2:3816541e5485 > tag: tip > @@ -826,7 +826,7 @@ > summary: A > > $ hg incoming --bundle ../issue3805.hg > - comparing with $TESTTMP/tmpe/repo-issue3805 > + comparing with $TESTTMP/tmpe/repo-issue3805 (glob) > searching for changes > changeset: 2:3816541e5485 > tag: tip > @@ -836,7 +836,7 @@ > summary: A > > $ hg outgoing > - comparing with $TESTTMP/tmpe/repo-issue3805 > + comparing with $TESTTMP/tmpe/repo-issue3805 (glob) > searching for changes > no changes found > [1] > > _______________________________________________ > Mercurial-devel mailing list > Mercurial-devel at selenic.com > http://selenic.com/mailman/listinfo/mercurial-devel > -------------- next part -------------- An HTML attachment was scrubbed... URL: From bboissin at gmail.com Wed Feb 13 14:34:34 2013 From: bboissin at gmail.com (Benoit Boissinot) Date: Wed, 13 Feb 2013 21:34:34 +0100 Subject: [PATCH STABLE] Tests: fix test on windows by appending glob to lines returning "\" in the path In-Reply-To: References: <000001ce09df$4f4e1f80$edea5e80$@besonet.ch> Message-ID: Side note: I fixed the patch description. You might find http://mercurial.selenic.com/wiki/ContributingChanges#Patch_descriptionshelpful to learn about our preferred formatting. Cheers, Benoit On Wed, Feb 13, 2013 at 9:30 PM, Benoit Boissinot wrote: > Crewed, thanks. > > > On Wed, Feb 13, 2013 at 12:43 PM, Simon Heimberg wrote: > >> # HG changeset patch >> # User Simon Heimberg >> # Date 1360755357 -3600 >> # Node ID a9b334ae174bff56afe1c9fb060cf940d04295e7 >> # Parent 013fcd112f13f31a35ea6a40d8cd1c6923cdaf20 >> Tests: fix test on windows by appending glob to lines returning "\" in the >> path >> >> This lines were introduced in cd403d6d96ef and made the test fail on >> windows. >> >> diff -r 013fcd112f13 -r a9b334ae174b tests/test-obsolete.t >> --- a/tests/test-obsolete.t Sat Feb 09 11:00:42 2013 +0100 >> +++ b/tests/test-obsolete.t Wed Feb 13 12:35:57 2013 +0100 >> @@ -816,7 +816,7 @@ >> summary: A >> >> $ hg incoming >> - comparing with $TESTTMP/tmpe/repo-issue3805 >> + comparing with $TESTTMP/tmpe/repo-issue3805 (glob) >> searching for changes >> changeset: 2:3816541e5485 >> tag: tip >> @@ -826,7 +826,7 @@ >> summary: A >> >> $ hg incoming --bundle ../issue3805.hg >> - comparing with $TESTTMP/tmpe/repo-issue3805 >> + comparing with $TESTTMP/tmpe/repo-issue3805 (glob) >> searching for changes >> changeset: 2:3816541e5485 >> tag: tip >> @@ -836,7 +836,7 @@ >> summary: A >> >> $ hg outgoing >> - comparing with $TESTTMP/tmpe/repo-issue3805 >> + comparing with $TESTTMP/tmpe/repo-issue3805 (glob) >> searching for changes >> no changes found >> [1] >> >> _______________________________________________ >> Mercurial-devel mailing list >> Mercurial-devel at selenic.com >> http://selenic.com/mailman/listinfo/mercurial-devel >> > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From bos at serpentine.com Wed Feb 13 14:49:20 2013 From: bos at serpentine.com (Bryan O'Sullivan) Date: Wed, 13 Feb 2013 12:49:20 -0800 Subject: [PATCH 6 of 6] scmutil: split platform-specific bits into their own modules In-Reply-To: References: Message-ID: On Wed, Feb 13, 2013 at 11:47 AM, Kevin Bullock < kbullock+mercurial at ringworld.org> wrote: > scmutil: split platform-specific bits into their own modules > I approve this patch series and/or detergent. -------------- next part -------------- An HTML attachment was scrubbed... URL: From kbullock+mercurial at ringworld.org Wed Feb 13 14:55:53 2013 From: kbullock+mercurial at ringworld.org (Kevin Bullock) Date: Wed, 13 Feb 2013 14:55:53 -0600 Subject: [PATCH 6 of 6] scmutil: split platform-specific bits into their own modules In-Reply-To: References: Message-ID: <1B6C70A4-094F-4AA2-AC41-140E1747FE62@ringworld.org> On Feb 13, 2013, at 2:49 PM, Bryan O'Sullivan wrote: > On Wed, Feb 13, 2013 at 11:47 AM, Kevin Bullock wrote: > scmutil: split platform-specific bits into their own modules > > I approve this patch series and/or detergent. Rolling a new version of this patch -- I had some excess imports of my own, which test-check-pyflakes.t caught. Will crew as soon as tests complete. pacem in terris / ??? / ?????? / ????????? / ?? Kevin R. Bullock From bboissin at gmail.com Wed Feb 13 15:07:17 2013 From: bboissin at gmail.com (Benoit Boissinot) Date: Wed, 13 Feb 2013 22:07:17 +0100 Subject: [PATCH 0 of 4] detect unnecessary glob lines In-Reply-To: References: <013201ce09c9$994e11f0$cbea35d0$@besonet.ch> Message-ID: Pushed it (with some minor changes in description, and remove the $HGPORT:* in changesets #3). Thanks, Benoit On Wed, Feb 13, 2013 at 10:37 AM, Benoit Boissinot wrote: > > > > On Wed, Feb 13, 2013 at 10:07 AM, Simon He. wrote: > >> No, I still do not know how to run tests on windows. The tests have passed >> on linux. (I should have written this, sorry.) >> I planned to check the output on the buildbot for messages about >> unnecessary >> glob lines. >> >> I will try to fix the typos and hope I will find all... >> > > I would have fixed them while applying the serie, no worry. I wonder if > Adrian or Patrick would be able to run it on windows for you. > > Benoit > -------------- next part -------------- An HTML attachment was scrubbed... URL: From durham at fb.com Wed Feb 13 15:38:47 2013 From: durham at fb.com (Durham Goode) Date: Wed, 13 Feb 2013 13:38:47 -0800 Subject: [PATCH RFC] blackbox: do not translate the log messages Message-ID: <9e42d1429fc278b83adb.1360791527@dev350.prn1.facebook.com> # HG changeset patch # User Durham Goode # Date 1360788690 28800 # Wed Feb 13 12:51:30 2013 -0800 # Node ID 9e42d1429fc278b83adb14e039f8fb4093048b0f # Parent dcef36a6f4e3f8dfd99987c8867209d40799277b blackbox: do not translate the log messages User 'timeless' in irc mentioned that having the blackbox be translated would result in logs that: - may be mixed language, if multiple users use the same repo - are not google searchable (since searching for english gives more results) - might not be readable by an admin if the employee is using hg in his native language And therefore we should log everything in english. It seems weird to me to produce a log in english when the user chose a different language. I don't know what mercurial's translation policy is, nor am I familiar with foreign language use of software in general, so I wanted to throw this out there for comment before I made the change. diff --git a/mercurial/dispatch.py b/mercurial/dispatch.py --- a/mercurial/dispatch.py +++ b/mercurial/dispatch.py @@ -747,7 +747,7 @@ return ret finally: duration = time.time() - starttime - ui.log("commandfinish", _("%s exited %s after %0.2f seconds\n"), + ui.log("commandfinish", "%s exited %s after %0.2f seconds\n", cmd, ret, duration) if repo and repo != req.repo: repo.close() diff --git a/mercurial/hook.py b/mercurial/hook.py --- a/mercurial/hook.py +++ b/mercurial/hook.py @@ -98,7 +98,7 @@ readablefunc = funcname if isinstance(funcname, types.FunctionType): readablefunc = funcname.__module__ + "." + funcname.__name__ - ui.log('pythonhook', _('pythonhook-%s: %s finished in %0.2f seconds\n'), + ui.log('pythonhook', 'pythonhook-%s: %s finished in %0.2f seconds\n', name, readablefunc, duration) if r: if throw: @@ -132,7 +132,7 @@ r = util.system(cmd, environ=env, cwd=cwd, out=ui.fout) duration = time.time() - starttime - ui.log('exthook', _('exthook-%s: %s finished in %0.2f seconds\n'), + ui.log('exthook', 'exthook-%s: %s finished in %0.2f seconds\n', name, cmd, duration) if r: desc, r = util.explainexit(r) diff --git a/mercurial/localrepo.py b/mercurial/localrepo.py --- a/mercurial/localrepo.py +++ b/mercurial/localrepo.py @@ -2402,7 +2402,7 @@ newheads = [h for h in self.heads() if h not in oldheads] self.ui.log("incoming", - _("%s incoming changes - new heads: %s\n"), + "%s incoming changes - new heads: %s\n", len(added), ', '.join([hex(c[:6]) for c in newheads])) self._afterlock(runhooks) From hgbuildbot at kublai.com Wed Feb 13 17:47:09 2013 From: hgbuildbot at kublai.com (hgbuildbot at kublai.com) Date: Wed, 13 Feb 2013 15:47:09 -0800 Subject: buildbot failure in Mercurial on hg tests Message-ID: <20130213234710.78CE424AEC@hgbuildbot.cs.ubc.ca> The Buildbot has detected a new failure on builder hg tests while building hg. Full details are available at: http://hgbuildbot.kublai.com/builders/hg%20tests/builds/501 Buildbot URL: http://hgbuildbot.kublai.com/ Buildslave for this Build: p64.osuosl.test Build Reason: scheduler Build Source Stamp: [branch default] 4c6f7f0dadaba9f7a0dce64ec0cd11c40373a98d Blamelist: Bryan O'Sullivan ,Kevin Bullock ,Simon Heimberg BUILD FAILED: failed pure sincerely, -The Buildbot From angel.ezquerra at gmail.com Wed Feb 13 18:06:18 2013 From: angel.ezquerra at gmail.com (Angel Ezquerra) Date: Thu, 14 Feb 2013 01:06:18 +0100 Subject: [PATCH] subrepo: do not push "clean" subrepos when the parent repo is pushed Message-ID: <26276460d54aecdeb107.1360800378@Angel-PC.localdomain> # HG changeset patch # User Angel Ezquerra # Date 1360795816 -3600 # Node ID 26276460d54aecdeb107c82c4e3f2ca7c0c6a8b3 # Parent 55b9b294b7544a6a144f627f71f4b770907d5a98 subrepo: do not push "clean" subrepos when the parent repo is pushed A clean subrepo is defined as one that has not had its dirstate, bookmarks or phases modified. This patch works by adding a "clean" method to subrepos. In the case of mercurial subrepos, this method calculates a "stamp" (i.e. a set of file hashes) of the repository state at the time of push with a similar "stamp" that was stored on a file when the subrepo was cloned or pushed to a given remote target. If the stamps match the subrepo has no changes that must be pushed to the target repository and thus the push can be skipped. Note that we calculate the stamp file by calculating hashes for several key repository files, such as the dirstate, the bookmarks file and the phaseroots file. This means that our "clean" detection is not perfect, in the sense that if the working directory has been updated to a different revision we will assume that the subrepo is not clean. However, if we update to another revision and back to the original revision the clean() method will correctly detec the subrepo as being clean. Also note that a subrepo being "clean" is not the opposite of it being "dirty". A subrepo is dirty if it updated to a different revision that the one that is pointed to by the subrepo parent or if its working directory is not clean. This is a different concept. diff --git a/mercurial/subrepo.py b/mercurial/subrepo.py --- a/mercurial/subrepo.py +++ b/mercurial/subrepo.py @@ -300,6 +300,16 @@ class abstractsubrepo(object): + def clean(self): + """ + returns true if the repository has not changed since it was last + cloned or pulled. + Note that this is very different and definitely not the opposite + of the repository being "dirty", which is related to having changes + on the working directory or the current revision. + """ + return False + def dirty(self, ignoreupdate=False): """returns true if the dirstate of the subrepo is dirty or does not match current stored state. If ignoreupdate is true, only check @@ -426,6 +436,73 @@ self._repo.ui.setconfig('ui', '_usedassubrepo', 'True') self._initrepo(r, state[0], create) + def clean(self, path): + """ + returns true if the repository has not changed since it was last + cloned or pulled. + Note that this is very different and definitely not the opposite + of the repository being "dirty", which is related to having changes + on the working directory or the current revision. + """ + return self._calcrepostamp(path) == self._readrepostamp(path) + + def _getfilestamp(self, filename): + data = '' + if os.path.exists(filename): + fd = open(filename) + data = fd.read() + fd.close() + return util.sha1(data).hexdigest() + + def _calcrepostamp(self, remotepath): + '''calculate a unique "stamp" for the current repository state + + This method is used to to detect when there are changes that may + require a push to a given remote path.''' + filelist = ('dirstate', 'bookmarks', 'store/phaseroots') + stamp = ['# %s\n' % remotepath] + lock = self._repo.lock() + try: + for relname in filelist: + absname = os.path.normpath(self._repo.join(relname)) + stamp.append('%s = %s\n' % (absname, self._getfilestamp(absname))) + finally: + lock.release() + return stamp + + def _getstampfilename(self, remotepath): + '''get a unique filename for the remote repo stamp''' + fname = util.sha1(remotepath).hexdigest() + return self._repo.join(os.path.join('stamps', fname)) + + def _readrepostamp(self, remotepath): + '''read an existing remote repository stamp''' + stampfile = self._getstampfilename(remotepath) + if not os.path.exists(stampfile): + return '' + fd = open(stampfile, 'r') + stamp = fd.readlines() + fd.close() + return stamp + + def _updaterepostamp(self, remotepath): + ''' + Calc the current repo stamp saving it into a remote repo stamp file + Each remote repo requires its own stamp file, because a subrepo may + be clean versus a given remote repo, but not versus another. + ''' + # save it to the clean file + # We should lock the repo + stampfile = self._getstampfilename(remotepath) + # [FIXME] should lock the repo? it is already locked by _calcrepostamp + stamp = self._calcrepostamp(remotepath) + stampdir = self._repo.join('stamps') + if not os.path.exists(stampdir): + util.makedir(stampdir, True) + fd = open(stampfile, 'w') + fd.writelines(stamp) + fd.close() + @annotatesubrepoerror def _initrepo(self, parentrepo, source, create): self._repo._subparent = parentrepo @@ -544,12 +621,17 @@ update=False) self._repo = cloned.local() self._initrepo(parentrepo, source, create=True) + self._updaterepostamp(srcurl) else: self._repo.ui.status(_('pulling subrepo %s from %s\n') % (subrelpath(self), srcurl)) + cleansub = self.clean(srcurl) self._repo.pull(other) bookmarks.updatefromremote(self._repo.ui, self._repo, other, srcurl) + if cleansub: + # keep the repo clean after pull + self._updaterepostamp(srcurl) @annotatesubrepoerror def get(self, state, overwrite=False): @@ -557,6 +639,9 @@ source, revision, kind = state self._repo.ui.debug("getting subrepo %s\n" % self._path) hg.updaterepo(self._repo, revision, overwrite) + srcurl = _abssource(self._repo) + if self.clean(srcurl): + self._updaterepostamp(srcurl) @annotatesubrepoerror def merge(self, state): @@ -599,10 +684,20 @@ return False dsturl = _abssource(self._repo, True) + if not force: + if self.clean(dsturl): + self._repo.ui.status( + _('no changes made to subrepo %s since last push to %s\n') + % (subrelpath(self), dsturl)) + return None self._repo.ui.status(_('pushing subrepo %s to %s\n') % (subrelpath(self), dsturl)) other = hg.peer(self._repo, {'ssh': ssh}, dsturl) - return self._repo.push(other, force, newbranch=newbranch) + res = self._repo.push(other, force, newbranch=newbranch) + + # the repo is now clean + self._updaterepostamp(dsturl) + return res @annotatesubrepoerror def outgoing(self, ui, dest, opts): -------------- next part -------------- A non-text attachment was scrubbed... Name: hg-2.4.patch Type: text/x-patch Size: 7200 bytes Desc: not available URL: From angel.ezquerra at gmail.com Wed Feb 13 18:13:44 2013 From: angel.ezquerra at gmail.com (Angel Ezquerra) Date: Thu, 14 Feb 2013 01:13:44 +0100 Subject: [PATCH] subrepo: do not push "clean" subrepos when the parent repo is pushed In-Reply-To: <26276460d54aecdeb107.1360800378@Angel-PC.localdomain> References: <26276460d54aecdeb107.1360800378@Angel-PC.localdomain> Message-ID: On Thu, Feb 14, 2013 at 1:06 AM, Angel Ezquerra wrote: > # HG changeset patch > # User Angel Ezquerra > # Date 1360795816 -3600 > # Node ID 26276460d54aecdeb107c82c4e3f2ca7c0c6a8b3 > # Parent 55b9b294b7544a6a144f627f71f4b770907d5a98 > subrepo: do not push "clean" subrepos when the parent repo is pushed > > A clean subrepo is defined as one that has not had its dirstate, bookmarks or > phases modified. > > This patch works by adding a "clean" method to subrepos. In the case of > mercurial subrepos, this method calculates a "stamp" (i.e. a set of file hashes) > of the repository state at the time of push with a similar "stamp" that was > stored on a file when the subrepo was cloned or pushed to a given remote target. > If the stamps match the subrepo has no changes that must be pushed to the target > repository and thus the push can be skipped. > > Note that we calculate the stamp file by calculating hashes for several key > repository files, such as the dirstate, the bookmarks file and the phaseroots > file. This means that our "clean" detection is not perfect, in the sense that > if the working directory has been updated to a different revision we will > assume that the subrepo is not clean. However, if we update to another revision > and back to the original revision the clean() method will correctly detec the > subrepo as being clean. > > Also note that a subrepo being "clean" is not the opposite of it being "dirty". > A subrepo is dirty if it updated to a different revision that the one that is > pointed to by the subrepo parent or if its working directory is not clean. This > is a different concept. > > diff --git a/mercurial/subrepo.py b/mercurial/subrepo.py > --- a/mercurial/subrepo.py > +++ b/mercurial/subrepo.py > @@ -300,6 +300,16 @@ > > class abstractsubrepo(object): > > + def clean(self): > + """ > + returns true if the repository has not changed since it was last > + cloned or pulled. > + Note that this is very different and definitely not the opposite > + of the repository being "dirty", which is related to having changes > + on the working directory or the current revision. > + """ > + return False > + > def dirty(self, ignoreupdate=False): > """returns true if the dirstate of the subrepo is dirty or does not > match current stored state. If ignoreupdate is true, only check > @@ -426,6 +436,73 @@ > self._repo.ui.setconfig('ui', '_usedassubrepo', 'True') > self._initrepo(r, state[0], create) > > + def clean(self, path): > + """ > + returns true if the repository has not changed since it was last > + cloned or pulled. > + Note that this is very different and definitely not the opposite > + of the repository being "dirty", which is related to having changes > + on the working directory or the current revision. > + """ > + return self._calcrepostamp(path) == self._readrepostamp(path) > + > + def _getfilestamp(self, filename): > + data = '' > + if os.path.exists(filename): > + fd = open(filename) > + data = fd.read() > + fd.close() > + return util.sha1(data).hexdigest() > + > + def _calcrepostamp(self, remotepath): > + '''calculate a unique "stamp" for the current repository state > + > + This method is used to to detect when there are changes that may > + require a push to a given remote path.''' > + filelist = ('dirstate', 'bookmarks', 'store/phaseroots') > + stamp = ['# %s\n' % remotepath] > + lock = self._repo.lock() > + try: > + for relname in filelist: > + absname = os.path.normpath(self._repo.join(relname)) > + stamp.append('%s = %s\n' % (absname, self._getfilestamp(absname))) > + finally: > + lock.release() > + return stamp > + > + def _getstampfilename(self, remotepath): > + '''get a unique filename for the remote repo stamp''' > + fname = util.sha1(remotepath).hexdigest() > + return self._repo.join(os.path.join('stamps', fname)) > + > + def _readrepostamp(self, remotepath): > + '''read an existing remote repository stamp''' > + stampfile = self._getstampfilename(remotepath) > + if not os.path.exists(stampfile): > + return '' > + fd = open(stampfile, 'r') > + stamp = fd.readlines() > + fd.close() > + return stamp > + > + def _updaterepostamp(self, remotepath): > + ''' > + Calc the current repo stamp saving it into a remote repo stamp file > + Each remote repo requires its own stamp file, because a subrepo may > + be clean versus a given remote repo, but not versus another. > + ''' > + # save it to the clean file > + # We should lock the repo > + stampfile = self._getstampfilename(remotepath) > + # [FIXME] should lock the repo? it is already locked by _calcrepostamp > + stamp = self._calcrepostamp(remotepath) > + stampdir = self._repo.join('stamps') > + if not os.path.exists(stampdir): > + util.makedir(stampdir, True) > + fd = open(stampfile, 'w') > + fd.writelines(stamp) > + fd.close() > + > @annotatesubrepoerror > def _initrepo(self, parentrepo, source, create): > self._repo._subparent = parentrepo > @@ -544,12 +621,17 @@ > update=False) > self._repo = cloned.local() > self._initrepo(parentrepo, source, create=True) > + self._updaterepostamp(srcurl) > else: > self._repo.ui.status(_('pulling subrepo %s from %s\n') > % (subrelpath(self), srcurl)) > + cleansub = self.clean(srcurl) > self._repo.pull(other) > bookmarks.updatefromremote(self._repo.ui, self._repo, other, > srcurl) > + if cleansub: > + # keep the repo clean after pull > + self._updaterepostamp(srcurl) > > @annotatesubrepoerror > def get(self, state, overwrite=False): > @@ -557,6 +639,9 @@ > source, revision, kind = state > self._repo.ui.debug("getting subrepo %s\n" % self._path) > hg.updaterepo(self._repo, revision, overwrite) > + srcurl = _abssource(self._repo) > + if self.clean(srcurl): > + self._updaterepostamp(srcurl) > > @annotatesubrepoerror > def merge(self, state): > @@ -599,10 +684,20 @@ > return False > > dsturl = _abssource(self._repo, True) > + if not force: > + if self.clean(dsturl): > + self._repo.ui.status( > + _('no changes made to subrepo %s since last push to %s\n') > + % (subrelpath(self), dsturl)) > + return None > self._repo.ui.status(_('pushing subrepo %s to %s\n') % > (subrelpath(self), dsturl)) > other = hg.peer(self._repo, {'ssh': ssh}, dsturl) > - return self._repo.push(other, force, newbranch=newbranch) > + res = self._repo.push(other, force, newbranch=newbranch) > + > + # the repo is now clean > + self._updaterepostamp(dsturl) > + return res > > @annotatesubrepoerror > def outgoing(self, ui, dest, opts): > > _______________________________________________ > Mercurial-devel mailing list > Mercurial-devel at selenic.com > http://selenic.com/mailman/listinfo/mercurial-devel > This is step one in the plan that Matt, Martin and I discussed to improve subrepos during the London sprint. The "subrepo clean" detection proposed by this patch is not perfect, but it should work in many cases and those should only be false negatives (i.e. there should not be any false positives). It fails to detect a clean subrepo if you update to a different revision than the one pointed to by the parent repository. However it will work fine if you update to a different revision and you update back to the original revision. One insight that I gained while making this patch is that we need a repo hash per remote path, because a subrepo may be clean with respect a remote repo but not with respect to another. Perhaps this was obvious to others but it was not to me at first. Now I'm thinking that perhaps I should have put this info on the commit message :-) I thought about splitting this patch a bit, but I did not find a very good way to do so. Perhaps I could first create a patch that adds the clean flag to the AbstractSubrepo and then one that adds the flag to the hg subrepo and another one that uses the flag. If you think that is what I should do I will resend of course. I also am working on step two of the plan, which was to add a "--subrepos" flag to hg push. Cheers, Angel From hgbuildbot at kublai.com Wed Feb 13 18:28:31 2013 From: hgbuildbot at kublai.com (hgbuildbot at kublai.com) Date: Wed, 13 Feb 2013 16:28:31 -0800 Subject: buildbot failure in Mercurial on hg tests (stable) Message-ID: <20130214002831.A78F7265F2@hgbuildbot.cs.ubc.ca> The Buildbot has detected a new failure on builder hg tests (stable) while building hg. Full details are available at: http://hgbuildbot.kublai.com/builders/hg%20tests%20%28stable%29/builds/303 Buildbot URL: http://hgbuildbot.kublai.com/ Buildslave for this Build: p64.osuosl.test Build Reason: scheduler Build Source Stamp: [branch stable] f6f35d646cb5919997d3a23b942594def5d9e243 Blamelist: Simon Heimberg BUILD FAILED: failed run-tests.py (python2.4) run-tests.py (python2.5) sincerely, -The Buildbot From hgbuildbot at kublai.com Wed Feb 13 19:19:56 2013 From: hgbuildbot at kublai.com (hgbuildbot at kublai.com) Date: Wed, 13 Feb 2013 17:19:56 -0800 Subject: buildbot success in Mercurial on OS X 10.7 hg tests Message-ID: <20130214011956.9B261266C0@hgbuildbot.cs.ubc.ca> The Buildbot has detected a restored build on builder OS X 10.7 hg tests while building hg. Full details are available at: http://hgbuildbot.kublai.com/builders/OS%20X%2010.7%20hg%20tests/builds/409 Buildbot URL: http://hgbuildbot.kublai.com/ Buildslave for this Build: lion Build Reason: scheduler Build Source Stamp: [branch default] 423eee0b0b14086173f3adf423e512b1f9f75053 Blamelist: Bryan O'Sullivan ,Durham Goode Build succeeded! sincerely, -The Buildbot From mpm at selenic.com Wed Feb 13 19:29:00 2013 From: mpm at selenic.com (Matt Mackall) Date: Wed, 13 Feb 2013 19:29:00 -0600 Subject: [PATCH RFC] blackbox: do not translate the log messages In-Reply-To: <9e42d1429fc278b83adb.1360791527@dev350.prn1.facebook.com> References: <9e42d1429fc278b83adb.1360791527@dev350.prn1.facebook.com> Message-ID: <1360805340.12295.51.camel@calx> On Wed, 2013-02-13 at 13:38 -0800, Durham Goode wrote: > # HG changeset patch > # User Durham Goode > # Date 1360788690 28800 > # Wed Feb 13 12:51:30 2013 -0800 > # Node ID 9e42d1429fc278b83adb14e039f8fb4093048b0f > # Parent dcef36a6f4e3f8dfd99987c8867209d40799277b > blackbox: do not translate the log messages > > User 'timeless' in irc mentioned that having the blackbox be translated > would result in logs that: > > - may be mixed language, if multiple users use the same repo > - are not google searchable (since searching for english gives more results) > - might not be readable by an admin if the employee is using hg in his native > language > > And therefore we should log everything in english. > > It seems weird to me to produce a log in english when the user chose a different > language. I don't know what mercurial's translation policy is, nor am I familiar > with foreign language use of software in general, so I wanted to throw this out > there for comment before I made the change. The blackbox is primarily intended for us by admins.. and us. So I think English is preferable. Check-code should complain about untranslated strings like this. The usual pattern is to wrap untranslated strings in ("parentheses") to shut it up. > diff --git a/mercurial/dispatch.py b/mercurial/dispatch.py > --- a/mercurial/dispatch.py > +++ b/mercurial/dispatch.py > @@ -747,7 +747,7 @@ > return ret > finally: > duration = time.time() - starttime > - ui.log("commandfinish", _("%s exited %s after %0.2f seconds\n"), > + ui.log("commandfinish", "%s exited %s after %0.2f seconds\n", > cmd, ret, duration) > if repo and repo != req.repo: > repo.close() > diff --git a/mercurial/hook.py b/mercurial/hook.py > --- a/mercurial/hook.py > +++ b/mercurial/hook.py > @@ -98,7 +98,7 @@ > readablefunc = funcname > if isinstance(funcname, types.FunctionType): > readablefunc = funcname.__module__ + "." + funcname.__name__ > - ui.log('pythonhook', _('pythonhook-%s: %s finished in %0.2f seconds\n'), > + ui.log('pythonhook', 'pythonhook-%s: %s finished in %0.2f seconds\n', > name, readablefunc, duration) > if r: > if throw: > @@ -132,7 +132,7 @@ > r = util.system(cmd, environ=env, cwd=cwd, out=ui.fout) > > duration = time.time() - starttime > - ui.log('exthook', _('exthook-%s: %s finished in %0.2f seconds\n'), > + ui.log('exthook', 'exthook-%s: %s finished in %0.2f seconds\n', > name, cmd, duration) > if r: > desc, r = util.explainexit(r) > diff --git a/mercurial/localrepo.py b/mercurial/localrepo.py > --- a/mercurial/localrepo.py > +++ b/mercurial/localrepo.py > @@ -2402,7 +2402,7 @@ > > newheads = [h for h in self.heads() if h not in oldheads] > self.ui.log("incoming", > - _("%s incoming changes - new heads: %s\n"), > + "%s incoming changes - new heads: %s\n", > len(added), > ', '.join([hex(c[:6]) for c in newheads])) > self._afterlock(runhooks) > _______________________________________________ > Mercurial-devel mailing list > Mercurial-devel at selenic.com > http://selenic.com/mailman/listinfo/mercurial-devel -- Mathematics is the supreme nostalgia of our time. From mads at kiilerich.com Wed Feb 13 19:30:16 2013 From: mads at kiilerich.com (Mads Kiilerich) Date: Thu, 14 Feb 2013 02:30:16 +0100 Subject: [PATCH 2 of 2 V4] hgweb: teach archive how to handle file patterns In-Reply-To: References: Message-ID: <511C3E28.8050205@kiilerich.com> Angel Ezquerra wrote, On 02/10/2013 11:56 AM: > # HG changeset patch > # User Angel Ezquerra > # Date 1360493525 -3600 > # Node ID fb655ad16f6675265da9d472ded7140a223fb283 > # Parent be3e96a41d0f4b7a1f1dd443f5261d6eeb66626a > hgweb: teach archive how to handle file patterns > > The archive web command now takes into account the "file" request entry, if one > is provided. > > The provided "file" is processed as a "path" pattern by default, which makes it > easy to only archive a certain file or directory. However, it is possible to > specify a different type of pattern, such as relglob by specifying it > explicitly on the query URL. Note that only "safe" patterns are allowed. Safe > patterns are 'path', 'relpath', 'glog' and 'relglob'. Other pattern types are > not allowed because they could be expensive to calculate. > > With this change hgweb can to process requests such as: > > 1. http://mercurial.selenic.com/hg/archive/tip.zip/mercurial/templates > > This will download all files on the mercurial/templates directory as a zip > file > > 2. http://mercurial.selenic.com/hg/archive/tip.tar.gz/relglob:*.py > > This will download all *.py files in the repository into a tar.gz file. > > An so forth. > > Note that this is a first step to add support for downloading directories from > the web interface. Currently the only way to use this feature is by manually > constructing the URL that you want to download. We will have to modify the > archiveentry map entry on the different templates so that it adds the current > folder path to the archive links. > > This revision also adds a two tests for this feature to test-archive.t. The > first tests the selective archive feature and the second tests that the server > rejects "unsafe" patterns. > > diff --git a/mercurial/hgweb/webcommands.py b/mercurial/hgweb/webcommands.py > --- a/mercurial/hgweb/webcommands.py > +++ b/mercurial/hgweb/webcommands.py > @@ -803,6 +803,17 @@ > if cnode == key or key == 'tip': > arch_version = short(cnode) > name = "%s-%s" % (reponame, arch_version) > + > + ctx = webutil.changectx(web.repo, req) > + pats = [] > + file = req.form.get('file', None) > + defaultpat = 'path' > + if file: > + pats = [req.form['file'][0]] > + if not scmutil.patsaresafe(pats, defaultpat): > + msg = 'Archive pattern not allowed: %s' % pats[0] > + raise ErrorResponse(HTTP_FORBIDDEN, msg) > + > mimetype, artype, extension, encoding = web.archive_specs[type_] > headers = [ > ('Content-Disposition', 'attachment; filename=%s%s' % (name, extension)) > @@ -812,9 +823,9 @@ > req.headers.extend(headers) > req.respond(HTTP_OK, mimetype) > > - ctx = webutil.changectx(web.repo, req) > + matchfn = scmutil.match(ctx, pats, default=defaultpat) > archival.archive(web.repo, req, cnode, artype, prefix=name, > - matchfn=scmutil.match(ctx, []), > + matchfn=matchfn, > subrepos=web.configbool("web", "archivesubrepos")) > return [] > > diff --git a/mercurial/scmutil.py b/mercurial/scmutil.py > --- a/mercurial/scmutil.py > +++ b/mercurial/scmutil.py > @@ -682,6 +682,15 @@ > > return l > > +def patsaresafe(pats, defaultpattype): > + for pat in pats: > + pattype = defaultpattype > + if ':' in pat: > + pattype = pat.split(':')[0] > + if pattype.lower() not in ('path', 'relpath', 'glog', 'relglob'): (btw: relpath and relglob are completely undocumented in the patterns help.) 'glog' seems to be a typo. That indicates that the feature doesn't have good test coverage and also haven't been fully tested manually. But both kinds of globs are in in my opinion not sufficiently safe. Consider for example the execution time for hg locate "glob:*********************x" and how something like that can be used to denial of service attacks in hgweb. I must say that I am no big fan of this feature as it is. * It is conceptually too complex compared to the value it adds. * Patterns can not be made explorable in hgweb and it is undocumented and there is no good place to document it. * URLs thus has to be constructed manually ... and it is not obvious how to encode for instance globs with '?' in a url. * It doesn't have the full power of specifying multiple patterns with -X and -I as we are used to when using patterns. * It is not obvious which subset of patterns that can be used. If something in this area is needed then I would suggest focusing on just making it possible to download a single directory as tar file. There is no need for a pattern - we only need a path after the archive, for instance .../archive/REV.tar.bz2/sub/dir . /Mads From mpm at selenic.com Wed Feb 13 19:31:55 2013 From: mpm at selenic.com (Matt Mackall) Date: Wed, 13 Feb 2013 19:31:55 -0600 Subject: [PATCH] subrepo: do not push "clean" subrepos when the parent repo is pushed In-Reply-To: <26276460d54aecdeb107.1360800378@Angel-PC.localdomain> References: <26276460d54aecdeb107.1360800378@Angel-PC.localdomain> Message-ID: <1360805515.12295.53.camel@calx> On Thu, 2013-02-14 at 01:06 +0100, Angel Ezquerra wrote: > # HG changeset patch > # User Angel Ezquerra > # Date 1360795816 -3600 > # Node ID 26276460d54aecdeb107c82c4e3f2ca7c0c6a8b3 > # Parent 55b9b294b7544a6a144f627f71f4b770907d5a98 > subrepo: do not push "clean" subrepos when the parent repo is pushed > > A clean subrepo is defined as one that has not had its dirstate, bookmarks or > phases modified. > > This patch works by adding a "clean" method to subrepos. In the case of > mercurial subrepos, this method calculates a "stamp" (i.e. a set of file hashes) > of the repository state at the time of push with a similar "stamp" that was > stored on a file when the subrepo was cloned or pushed to a given remote target. > If the stamps match the subrepo has no changes that must be pushed to the target > repository and thus the push can be skipped. > > Note that we calculate the stamp file by calculating hashes for several key > repository files, such as the dirstate, the bookmarks file and the phaseroots > file. This means that our "clean" detection is not perfect, in the sense that > if the working directory has been updated to a different revision we will > assume that the subrepo is not clean. However, if we update to another revision > and back to the original revision the clean() method will correctly detec the > subrepo as being clean. Why is the dirstate interesting? I would posit that we're only interested in things that we'd push or pull. Dirstate being modified should not force us to push. > Also note that a subrepo being "clean" is not the opposite of it being "dirty". > A subrepo is dirty if it updated to a different revision that the one that is > pointed to by the subrepo parent or if its working directory is not clean. This > is a different concept. Ok, let's give it a different name. How about storeclean() so it's explicit it's about the store? I think this needs to be (at least) a few different patches: 1) introduce the helper functions 2) record clean state on clone/pull 3) check clean state on push > diff --git a/mercurial/subrepo.py b/mercurial/subrepo.py > --- a/mercurial/subrepo.py > +++ b/mercurial/subrepo.py > @@ -300,6 +300,16 @@ > > class abstractsubrepo(object): > > + def clean(self): > + """ > + returns true if the repository has not changed since it was last > + cloned or pulled. > + Note that this is very different and definitely not the opposite > + of the repository being "dirty", which is related to having changes > + on the working directory or the current revision. > + """ > + return False > + > def dirty(self, ignoreupdate=False): > """returns true if the dirstate of the subrepo is dirty or does not > match current stored state. If ignoreupdate is true, only check > @@ -426,6 +436,73 @@ > self._repo.ui.setconfig('ui', '_usedassubrepo', 'True') > self._initrepo(r, state[0], create) > > + def clean(self, path): > + """ > + returns true if the repository has not changed since it was last > + cloned or pulled. > + Note that this is very different and definitely not the opposite > + of the repository being "dirty", which is related to having changes > + on the working directory or the current revision. > + """ Duplicate docs. > + return self._calcrepostamp(path) == self._readrepostamp(path) This is suboptimal, especially if any of the files are large. It'd be better to be able to break after we find the first changed file. > + def _getfilestamp(self, filename): > + data = '' > + if os.path.exists(filename): > + fd = open(filename) > + data = fd.read() > + fd.close() > + return util.sha1(data).hexdigest() Most of this doesn't want to be member functions. We'll need it for git. > + def _calcrepostamp(self, remotepath): > + '''calculate a unique "stamp" for the current repository state > + > + This method is used to to detect when there are changes that may > + require a push to a given remote path.''' > + filelist = ('dirstate', 'bookmarks', 'store/phaseroots') > + stamp = ['# %s\n' % remotepath] > + lock = self._repo.lock() > + try: > + for relname in filelist: > + absname = os.path.normpath(self._repo.join(relname)) > + stamp.append('%s = %s\n' % (absname, self._getfilestamp(absname))) > + finally: > + lock.release() > + return stamp > + > + def _getstampfilename(self, remotepath): > + '''get a unique filename for the remote repo stamp''' > + fname = util.sha1(remotepath).hexdigest() > + return self._repo.join(os.path.join('stamps', fname)) Probably don't want a 40-character name here. This should go in .hg/cache/ on hg repos and have a less generic name than stamp. > + def _readrepostamp(self, remotepath): > + '''read an existing remote repository stamp''' > + stampfile = self._getstampfilename(remotepath) > + if not os.path.exists(stampfile): > + return '' > + fd = open(stampfile, 'r') > + stamp = fd.readlines() > + fd.close() > + return stamp > + > + def _updaterepostamp(self, remotepath): > + ''' > + Calc the current repo stamp saving it into a remote repo stamp file > + Each remote repo requires its own stamp file, because a subrepo may > + be clean versus a given remote repo, but not versus another. > + ''' > + # save it to the clean file > + # We should lock the repo > + stampfile = self._getstampfilename(remotepath) > + # [FIXME] should lock the repo? it is already locked by _calcrepostamp No, the lock should be in the callers of _calcrepostamp. > + stamp = self._calcrepostamp(remotepath) > + stampdir = self._repo.join('stamps') > + if not os.path.exists(stampdir): > + util.makedir(stampdir, True) > + fd = open(stampfile, 'w') > + fd.writelines(stamp) > + fd.close() > + > @annotatesubrepoerror > def _initrepo(self, parentrepo, source, create): > self._repo._subparent = parentrepo > @@ -544,12 +621,17 @@ > update=False) > self._repo = cloned.local() > self._initrepo(parentrepo, source, create=True) > + self._updaterepostamp(srcurl) > else: > self._repo.ui.status(_('pulling subrepo %s from %s\n') > % (subrelpath(self), srcurl)) > + cleansub = self.clean(srcurl) > self._repo.pull(other) > bookmarks.updatefromremote(self._repo.ui, self._repo, other, > srcurl) > + if cleansub: > + # keep the repo clean after pull > + self._updaterepostamp(srcurl) > > @annotatesubrepoerror > def get(self, state, overwrite=False): > @@ -557,6 +639,9 @@ > source, revision, kind = state > self._repo.ui.debug("getting subrepo %s\n" % self._path) > hg.updaterepo(self._repo, revision, overwrite) > + srcurl = _abssource(self._repo) > + if self.clean(srcurl): > + self._updaterepostamp(srcurl) > > @annotatesubrepoerror > def merge(self, state): > @@ -599,10 +684,20 @@ > return False > > dsturl = _abssource(self._repo, True) > + if not force: > + if self.clean(dsturl): > + self._repo.ui.status( > + _('no changes made to subrepo %s since last push to %s\n') > + % (subrelpath(self), dsturl)) > + return None > self._repo.ui.status(_('pushing subrepo %s to %s\n') % > (subrelpath(self), dsturl)) > other = hg.peer(self._repo, {'ssh': ssh}, dsturl) > - return self._repo.push(other, force, newbranch=newbranch) > + res = self._repo.push(other, force, newbranch=newbranch) > + > + # the repo is now clean > + self._updaterepostamp(dsturl) > + return res > > @annotatesubrepoerror > def outgoing(self, ui, dest, opts): > _______________________________________________ > Mercurial-devel mailing list > Mercurial-devel at selenic.com > http://selenic.com/mailman/listinfo/mercurial-devel -- Mathematics is the supreme nostalgia of our time. From angel.ezquerra at gmail.com Thu Feb 14 02:22:02 2013 From: angel.ezquerra at gmail.com (Angel Ezquerra) Date: Thu, 14 Feb 2013 09:22:02 +0100 Subject: [PATCH 2 of 2 V4] hgweb: teach archive how to handle file patterns In-Reply-To: <511C3E28.8050205@kiilerich.com> References: <511C3E28.8050205@kiilerich.com> Message-ID: On Thu, Feb 14, 2013 at 2:30 AM, Mads Kiilerich wrote: > Angel Ezquerra wrote, On 02/10/2013 11:56 AM: > >> # HG changeset patch >> # User Angel Ezquerra >> # Date 1360493525 -3600 >> # Node ID fb655ad16f6675265da9d472ded7140a223fb283 >> # Parent be3e96a41d0f4b7a1f1dd443f5261d6eeb66626a >> hgweb: teach archive how to handle file patterns >> >> The archive web command now takes into account the "file" request entry, >> if one >> is provided. >> >> The provided "file" is processed as a "path" pattern by default, which >> makes it >> easy to only archive a certain file or directory. However, it is possible >> to >> specify a different type of pattern, such as relglob by specifying it >> explicitly on the query URL. Note that only "safe" patterns are allowed. >> Safe >> patterns are 'path', 'relpath', 'glog' and 'relglob'. Other pattern types >> are >> not allowed because they could be expensive to calculate. >> >> With this change hgweb can to process requests such as: >> >> 1. http://mercurial.selenic.com/hg/archive/tip.zip/mercurial/templates >> >> This will download all files on the mercurial/templates directory as >> a zip >> file >> >> 2. http://mercurial.selenic.com/hg/archive/tip.tar.gz/relglob:*.py >> >> This will download all *.py files in the repository into a tar.gz >> file. >> >> An so forth. >> >> Note that this is a first step to add support for downloading directories >> from >> the web interface. Currently the only way to use this feature is by >> manually >> constructing the URL that you want to download. We will have to modify the >> archiveentry map entry on the different templates so that it adds the >> current >> folder path to the archive links. >> >> This revision also adds a two tests for this feature to test-archive.t. >> The >> first tests the selective archive feature and the second tests that the >> server >> rejects "unsafe" patterns. >> >> diff --git a/mercurial/hgweb/webcommands.py >> b/mercurial/hgweb/webcommands.py >> --- a/mercurial/hgweb/webcommands.py >> +++ b/mercurial/hgweb/webcommands.py >> @@ -803,6 +803,17 @@ >> if cnode == key or key == 'tip': >> arch_version = short(cnode) >> name = "%s-%s" % (reponame, arch_version) >> + >> + ctx = webutil.changectx(web.repo, req) >> + pats = [] >> + file = req.form.get('file', None) >> + defaultpat = 'path' >> + if file: >> + pats = [req.form['file'][0]] >> + if not scmutil.patsaresafe(pats, defaultpat): >> + msg = 'Archive pattern not allowed: %s' % pats[0] >> + raise ErrorResponse(HTTP_FORBIDDEN, msg) >> + >> mimetype, artype, extension, encoding = web.archive_specs[type_] >> headers = [ >> ('Content-Disposition', 'attachment; filename=%s%s' % (name, >> extension)) >> @@ -812,9 +823,9 @@ >> req.headers.extend(headers) >> req.respond(HTTP_OK, mimetype) >> - ctx = webutil.changectx(web.repo, req) >> + matchfn = scmutil.match(ctx, pats, default=defaultpat) >> archival.archive(web.repo, req, cnode, artype, prefix=name, >> - matchfn=scmutil.match(ctx, []), >> + matchfn=matchfn, >> subrepos=web.configbool("web", "archivesubrepos")) >> return [] >> diff --git a/mercurial/scmutil.py b/mercurial/scmutil.py >> --- a/mercurial/scmutil.py >> +++ b/mercurial/scmutil.py >> @@ -682,6 +682,15 @@ >> return l >> +def patsaresafe(pats, defaultpattype): >> + for pat in pats: >> + pattype = defaultpattype >> + if ':' in pat: >> + pattype = pat.split(':')[0] >> + if pattype.lower() not in ('path', 'relpath', 'glog', 'relglob'): Mads, thanks for your review. You raise some very valid concerns. Please see my comments below. > (btw: relpath and relglob are completely undocumented in the patterns help.) > > 'glog' seems to be a typo. That indicates that the feature doesn't have good > test coverage and also haven't been fully tested manually. The error is harmless in the sense that it means that glob patterns would be rejected as well (i.e. the patsaresafe() method is actually safer than it should :-) I could add tests for all safe pattern types but I think that would be overkill? Anyway I'm thinking this may not be necessary if I reduce the scope of the pattern feature as I'll explain below. > But both kinds of globs are in in my opinion not sufficiently safe. Consider > for example the execution time for > hg locate "glob:*********************x" > and how something like that can be used to denial of service attacks in > hgweb. True. The primary use cases for this feature are: 1. Download a single folder (with its subfolders) 2. Download a subset of the files, particularly the files matching a set of filetypes, from "big" repositories. The feature as currently implemented covers both use cases, but it actually goes way beyond that. Maybe we can tight it up? That is, maybe we can make sure that only those two very specific scenarios are covered? > I must say that I am no big fan of this feature as it is. > * It is conceptually too complex compared to the value it adds. I think we can simplify it while taking it a bit beyond the "download a single folder" use case. > * Patterns can not be made explorable in hgweb and it is undocumented and > there is no good place to document it. The obvious place to document them would be on the 403 error message that we show when an "unsafe" pattern is shown. > * URLs thus has to be constructed manually ... True. I don't have a good solution for that. However hgweb already lets you access URLs that you can construct but to which that there is no way to get through the web interface (for example, explicit TAG links, explicit RSS links, etc). > and it is not obvious how to > encode for instance globs with '?' in a url. Also True. I guess that we could urldecode the selected file? In any case I think that this is another indication that we should limit the scope of what can be done further. > * It doesn't have the full power of specifying multiple patterns with -X and > -I as we are used to when using patterns. I don't think this is necessary. What I mean is that this is not an all or nothing proposition. The fact that we cannot do everything that can be done with a proper mercurial client through the mercurial command line does not mean that should not provide any of functionality at all through hgweb! > * It is not obvious which subset of patterns that can be used. If we make the valid patterns much more explicit I think we can make it quite obvious, and the 403 error can help educate the user. What I have in mind is to completely disallow explicitly specifying the pattern type. Instead we could just implicitly allow simple "relglob" patterns when , which basically would behave as command line shell globs. That means that we would only allow using a single "*" or "**". If one of these were found we would run a relglob. If more than one were found we would consider the pattern unsafe. These are valid concerns. When I started implement this feature my plan was just to add a way to download a single folder through the web interface (to do so I still need to do another patch that changes the templates to add the current path folder to archive links). However I realized that it would be just as easy and almost free to also allow to download specific types of files (what I had in mind was to download all *.py files from a repository, for example). Now you have convinced me that we must limit the scope of this much more. > If something in this area is needed then I would suggest focusing on just > making it possible to download a single directory as tar file. There is no > need for a pattern - we only need a path after the archive, for instance > .../archive/REV.tar.bz2/sub/dir . This will definitely be possible and even accessible through the web interface. I'd just like to also be able to do: .../archive/REV.tar.bz2/sub/dir/**.{c,h} Cheers, Angel From angel.ezquerra at gmail.com Thu Feb 14 02:39:55 2013 From: angel.ezquerra at gmail.com (Angel Ezquerra) Date: Thu, 14 Feb 2013 09:39:55 +0100 Subject: [PATCH] subrepo: do not push "clean" subrepos when the parent repo is pushed In-Reply-To: <1360805515.12295.53.camel@calx> References: <26276460d54aecdeb107.1360800378@Angel-PC.localdomain> <1360805515.12295.53.camel@calx> Message-ID: On Thu, Feb 14, 2013 at 2:31 AM, Matt Mackall wrote: > On Thu, 2013-02-14 at 01:06 +0100, Angel Ezquerra wrote: >> # HG changeset patch >> # User Angel Ezquerra >> # Date 1360795816 -3600 >> # Node ID 26276460d54aecdeb107c82c4e3f2ca7c0c6a8b3 >> # Parent 55b9b294b7544a6a144f627f71f4b770907d5a98 >> subrepo: do not push "clean" subrepos when the parent repo is pushed >> >> A clean subrepo is defined as one that has not had its dirstate, bookmarks or >> phases modified. >> >> This patch works by adding a "clean" method to subrepos. In the case of >> mercurial subrepos, this method calculates a "stamp" (i.e. a set of file hashes) >> of the repository state at the time of push with a similar "stamp" that was >> stored on a file when the subrepo was cloned or pushed to a given remote target. >> If the stamps match the subrepo has no changes that must be pushed to the target >> repository and thus the push can be skipped. >> >> Note that we calculate the stamp file by calculating hashes for several key >> repository files, such as the dirstate, the bookmarks file and the phaseroots >> file. This means that our "clean" detection is not perfect, in the sense that >> if the working directory has been updated to a different revision we will >> assume that the subrepo is not clean. However, if we update to another revision >> and back to the original revision the clean() method will correctly detec the >> subrepo as being clean. > Why is the dirstate interesting? I would posit that we're only > interested in things that we'd push or pull. Dirstate being modified > should not force us to push. I think I may have misunderstood you when we discussed this during the sprint. I thought you mentioned that we should check the direstate, the bookmarks and the phaseroots. I don't know the mercurial store format well enough to tell which files we need to hash. Would hashing "store/00changelog.i" and "store/00manifest.i" be enough? An alternative would be to hash the list of repository heads and consider the repo unclean if that changed? >> Also note that a subrepo being "clean" is not the opposite of it being "dirty". >> A subrepo is dirty if it updated to a different revision that the one that is >> pointed to by the subrepo parent or if its working directory is not clean. This >> is a different concept. > > Ok, let's give it a different name. How about storeclean() so it's > explicit it's about the store? OK, as long as bookmarks and phases can be considered part of the store? > I think this needs to be (at least) a few different patches: > > 1) introduce the helper functions > 2) record clean state on clone/pull > 3) check clean state on push Will do. >> diff --git a/mercurial/subrepo.py b/mercurial/subrepo.py >> --- a/mercurial/subrepo.py >> +++ b/mercurial/subrepo.py >> @@ -300,6 +300,16 @@ >> >> class abstractsubrepo(object): >> >> + def clean(self): >> + """ >> + returns true if the repository has not changed since it was last >> + cloned or pulled. >> + Note that this is very different and definitely not the opposite >> + of the repository being "dirty", which is related to having changes >> + on the working directory or the current revision. >> + """ >> + return False >> + >> def dirty(self, ignoreupdate=False): >> """returns true if the dirstate of the subrepo is dirty or does not >> match current stored state. If ignoreupdate is true, only check >> @@ -426,6 +436,73 @@ >> self._repo.ui.setconfig('ui', '_usedassubrepo', 'True') >> self._initrepo(r, state[0], create) >> >> + def clean(self, path): >> + """ >> + returns true if the repository has not changed since it was last >> + cloned or pulled. >> + Note that this is very different and definitely not the opposite >> + of the repository being "dirty", which is related to having changes >> + on the working directory or the current revision. >> + """ > > Duplicate docs. > >> + return self._calcrepostamp(path) == self._readrepostamp(path) > > This is suboptimal, especially if any of the files are large. It'd be > better to be able to break after we find the first changed file. Perhaps _calcrepostamp could be a generator. clean() (i.e. cleanstore) could then just check each individual line. >> + def _getfilestamp(self, filename): >> + data = '' >> + if os.path.exists(filename): >> + fd = open(filename) >> + data = fd.read() >> + fd.close() >> + return util.sha1(data).hexdigest() > > Most of this doesn't want to be member functions. We'll need it for git. Sure, although I know even less about git's internals than mercurial's to be able to know what should be hashed inside the .git folder. Should these be kept in subrepos.py or perhaps moved to mercurial.util? Also _calcrepostamp could be moved out as well by making the "file list" a parameter. >> + def _calcrepostamp(self, remotepath): >> + '''calculate a unique "stamp" for the current repository state >> + >> + This method is used to to detect when there are changes that may >> + require a push to a given remote path.''' >> + filelist = ('dirstate', 'bookmarks', 'store/phaseroots') >> + stamp = ['# %s\n' % remotepath] >> + lock = self._repo.lock() >> + try: >> + for relname in filelist: >> + absname = os.path.normpath(self._repo.join(relname)) >> + stamp.append('%s = %s\n' % (absname, self._getfilestamp(absname))) >> + finally: >> + lock.release() >> + return stamp >> + >> + def _getstampfilename(self, remotepath): >> + '''get a unique filename for the remote repo stamp''' >> + fname = util.sha1(remotepath).hexdigest() >> + return self._repo.join(os.path.join('stamps', fname)) > > Probably don't want a 40-character name here. This should go > in .hg/cache/ on hg repos and have a less generic name than stamp. OK, I'll just keep the first 12 hash characters. >> + def _readrepostamp(self, remotepath): >> + '''read an existing remote repository stamp''' >> + stampfile = self._getstampfilename(remotepath) >> + if not os.path.exists(stampfile): >> + return '' >> + fd = open(stampfile, 'r') >> + stamp = fd.readlines() >> + fd.close() >> + return stamp >> + >> + def _updaterepostamp(self, remotepath): >> + ''' >> + Calc the current repo stamp saving it into a remote repo stamp file >> + Each remote repo requires its own stamp file, because a subrepo may >> + be clean versus a given remote repo, but not versus another. >> + ''' >> + # save it to the clean file >> + # We should lock the repo >> + stampfile = self._getstampfilename(remotepath) >> + # [FIXME] should lock the repo? it is already locked by _calcrepostamp > > No, the lock should be in the callers of _calcrepostamp. OK. How would that work on the case of git repos? Is it possible to "lock" a git repo? Matt, thanks for the detailed review! Angel From diptongo at gmail.com Thu Feb 14 03:54:42 2013 From: diptongo at gmail.com (Isaac Jurado) Date: Thu, 14 Feb 2013 10:54:42 +0100 Subject: [PATCH] subrepo: do not push "clean" subrepos when the parent repo is pushed In-Reply-To: <26276460d54aecdeb107.1360800378@Angel-PC.localdomain> References: <26276460d54aecdeb107.1360800378@Angel-PC.localdomain> Message-ID: On Thu, Feb 14, 2013 at 1:06 AM, Angel Ezquerra wrote: > # HG changeset patch > # User Angel Ezquerra > # Date 1360795816 -3600 > # Node ID 26276460d54aecdeb107c82c4e3f2ca7c0c6a8b3 > # Parent 55b9b294b7544a6a144f627f71f4b770907d5a98 > subrepo: do not push "clean" subrepos when the parent repo is pushed > > A clean subrepo is defined as one that has not had its dirstate, bookmarks or > phases modified. > > This patch works by adding a "clean" method to subrepos. In the case of > mercurial subrepos, this method calculates a "stamp" (i.e. a set of file hashes) > of the repository state at the time of push with a similar "stamp" that was > stored on a file when the subrepo was cloned or pushed to a given remote target. > If the stamps match the subrepo has no changes that must be pushed to the target > repository and thus the push can be skipped. > > Note that we calculate the stamp file by calculating hashes for several key > repository files, such as the dirstate, the bookmarks file and the phaseroots > file. This means that our "clean" detection is not perfect, in the sense that > if the working directory has been updated to a different revision we will > assume that the subrepo is not clean. However, if we update to another revision > and back to the original revision the clean() method will correctly detec the > subrepo as being clean. > > Also note that a subrepo being "clean" is not the opposite of it being "dirty". > A subrepo is dirty if it updated to a different revision that the one that is > pointed to by the subrepo parent or if its working directory is not clean. This > is a different concept. Have you considered the following situations? 1. The .hgsub file changes 2. The [subpaths] section redirects pushes to a different location from last push. I couldn't deduce it from the code so I had to ask. Cheers. -- Isaac Jurado "The noblest pleasure is the joy of understanding" Leonardo da Vinci From pierre-yves.david at logilab.fr Thu Feb 14 04:23:01 2013 From: pierre-yves.david at logilab.fr (Pierre-Yves David) Date: Thu, 14 Feb 2013 11:23:01 +0100 Subject: [PATCH RFC] commit: add --reuse-message for keeping the old commit message during amend In-Reply-To: <2B10A89294DA6740AC6155F56842F9CE0565A924@PRN-MBX01-2.TheFacebook.com> References: <1360731362.12295.24.camel@calx> <2B10A89294DA6740AC6155F56842F9CE0565A924@PRN-MBX01-2.TheFacebook.com> Message-ID: <20130214102301.GB17607@crater2.logilab.fr> On Wed, Feb 13, 2013 at 07:42:44PM +0000, Durham Goode wrote: > On 2/12/13 8:56 PM, "Matt Mackall" wrote: > > > >I'm now inclined to think that 'hg commit --amend' will eventually be > >replaced by 'hg amend', which will have a different default. Then we'll > >deprecate --amend on commit. > > > >So I think we should leave this alone. But I don't think we've got quite > >enough experience here to add the new amend command yet. In evolve, I'll probably drop the internal "hg amend" code in favor of using "hg commit --amend" with an altered editor. > > > If anyone feels strongly about getting the extra commit flag in, speak up. > For Facebook's purposes we will just add an amend alias for our users > that does 'hg --config ui.editor=true commit --amend' while we wait for > the real 'hg amend'. Note that you have to fix --config in alias first :-) > As for having amend experience, as I've started using evolve more I've > found I use an amend flows in three ways: > > 1. (most common) Amending the code in the current commit > 2. Amending the code in a commit further down. > 3. (least common) Amending the commit description. My most common usage are #1 and #3. I usually the "." commit as a "staging area" slowly adding content and writing the commit message at the end. The #2 operation is multi step a) rebase your change on target commit (as hg update with dirty wc does) b) amend c) hg evolve --all descendant It's probably something that we'll want but that requires first class support for multi step operation. Otherwise user will get terribly confused. > So my ideal "hg amend" would do #1 by default, #2 with "hg amend --to > 'tip~2'", and #3 with "hg amend -e". #2 is the only crazy one, but I've > been using a script that does it in one step and it makes editing chains > of commits much much easier. -- Pierre-Yves David http://www.logilab.fr/ -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 198 bytes Desc: Digital signature URL: From pierre-yves.david at logilab.fr Thu Feb 14 04:27:23 2013 From: pierre-yves.david at logilab.fr (Pierre-Yves David) Date: Thu, 14 Feb 2013 11:27:23 +0100 Subject: [PATCH 04 of 19] commit: refactor mergestate management into workingctx In-Reply-To: References: <07bdd03d86dcce1558d7.1360538991@dev010.prn1.facebook.com> Message-ID: <20130214102723.GC17607@crater2.logilab.fr> On Sun, Feb 10, 2013 at 03:29:54PM -0800, David Schleimer wrote: > + def unresolved(self): > + assert self._unresolved is not None # must call status first > + return self._unresolved I would be happy If we could get ride of those assert statement by either - having the status automatically called if cache is empty - having a real exception raise It looks like there were alredy here before you started your refactoring, so it is not really related to your series -- Pierre-Yves David http://www.logilab.fr/ -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 198 bytes Desc: Digital signature URL: From hgbuildbot at kublai.com Thu Feb 14 04:41:56 2013 From: hgbuildbot at kublai.com (hgbuildbot at kublai.com) Date: Thu, 14 Feb 2013 02:41:56 -0800 Subject: buildbot failure in Mercurial on OS X 10.7 hg tests Message-ID: <20130214104156.AC63F266C0@hgbuildbot.cs.ubc.ca> The Buildbot has detected a new failure on builder OS X 10.7 hg tests while building hg. Full details are available at: http://hgbuildbot.kublai.com/builders/OS%20X%2010.7%20hg%20tests/builds/410 Buildbot URL: http://hgbuildbot.kublai.com/ Buildslave for this Build: lion Build Reason: scheduler Build Source Stamp: [branch default] 4c6f7f0dadaba9f7a0dce64ec0cd11c40373a98d Blamelist: Kevin Bullock ,Simon Heimberg BUILD FAILED: failed run-tests.py (python2.6) run-tests.py (python2.7) pure sincerely, -The Buildbot From hg at intevation.org Thu Feb 14 06:00:13 2013 From: hg at intevation.org (Mercurial Commits) Date: Thu, 14 Feb 2013 13:00:13 +0100 Subject: mercurial/crew@18690: 61 outgoing changesets (2 stable) Message-ID: <1360843213.963304.6537.nullmailer@hg.intevation.org> 61 outgoing changesets (2 stable) in mercurial/crew: http://hg.intevation.org/mercurial/crew/rev/4c6f7f0dadab changeset: 18690:4c6f7f0dadab bookmark: @ tag: tip user: Kevin Bullock date: Tue Feb 12 11:36:21 2013 -0600 summary: scmutil: split platform-specific bits into their own modules http://hg.intevation.org/mercurial/crew/rev/12721a20ed30 changeset: 18689:12721a20ed30 user: Kevin Bullock date: Tue Feb 12 16:36:44 2013 +0000 summary: backout: call cmdutil.commit directly instead of commands.commit http://hg.intevation.org/mercurial/crew/rev/79107fad06aa changeset: 18688:79107fad06aa user: Kevin Bullock date: Tue Feb 12 16:32:14 2013 +0000 summary: commit: factor out status printing into a helper function http://hg.intevation.org/mercurial/crew/rev/1d183b33f007 changeset: 18687:1d183b33f007 user: Kevin Bullock date: Tue Feb 12 16:05:00 2013 +0000 summary: backout: remove unnecessary dict copy http://hg.intevation.org/mercurial/crew/rev/0bca4d31f647 changeset: 18686:0bca4d31f647 user: Kevin Bullock date: Tue Feb 12 15:47:30 2013 +0000 summary: backout: remove unnecessary frobbing of addremove option http://hg.intevation.org/mercurial/crew/rev/fafdff7e9c43 changeset: 18685:fafdff7e9c43 user: Kevin Bullock date: Tue Feb 12 15:07:17 2013 +0000 summary: backout: use cmdutil.revert directly instead of commands.revert http://hg.intevation.org/mercurial/crew/rev/c161e4cf77d4 changeset: 18684:c161e4cf77d4 parent: 18683:a343eccd5ee2 parent: 18679:f6f35d646cb5 user: Kevin Bullock date: Wed Feb 13 15:09:43 2013 -0600 summary: merge with stable http://hg.intevation.org/mercurial/crew/rev/a343eccd5ee2 changeset: 18683:a343eccd5ee2 user: Simon Heimberg date: Wed Feb 13 21:51:47 2013 +0100 summary: check-code: warn about line glob match with no glob character (?*/) http://hg.intevation.org/mercurial/crew/rev/408f2202bd80 changeset: 18682:408f2202bd80 user: Simon Heimberg date: Wed Feb 13 22:05:30 2013 +0100 summary: tests: remove glob from output lines containing no glob character http://hg.intevation.org/mercurial/crew/rev/7591ed29e824 changeset: 18681:7591ed29e824 user: Simon Heimberg date: Mon Oct 15 23:28:45 2012 +0200 summary: tests: inform on Windows about unnecessary glob lines http://hg.intevation.org/mercurial/crew/rev/15711d9d8b2c changeset: 18680:15711d9d8b2c parent: 18678:423eee0b0b14 user: Simon Heimberg date: Wed Feb 13 21:58:52 2013 +0100 summary: tests: quickly check if the glob line already matches the output http://hg.intevation.org/mercurial/crew/rev/f6f35d646cb5 changeset: 18679:f6f35d646cb5 branch: stable parent: 18657:d4a79e075303 user: Simon Heimberg date: Wed Feb 13 12:35:57 2013 +0100 summary: tests: append glob to filename output when required (windows) http://hg.intevation.org/mercurial/crew/rev/423eee0b0b14 changeset: 18678:423eee0b0b14 user: Bryan O'Sullivan date: Wed Feb 13 12:20:10 2013 -0800 summary: util: make ensuredirs safer against races http://hg.intevation.org/mercurial/crew/rev/539210ed2069 changeset: 18677:539210ed2069 user: Durham Goode date: Wed Feb 13 11:07:01 2013 -0800 summary: blackbox: only show new heads on incoming http://hg.intevation.org/mercurial/crew/rev/1506eb487ddd changeset: 18676:1506eb487ddd user: Bryan O'Sullivan date: Wed Feb 13 10:54:52 2013 -0800 summary: blackbox: fix copyright http://hg.intevation.org/mercurial/crew/rev/f816aa377e0d changeset: 18675:f816aa377e0d user: Bryan O'Sullivan date: Tue Feb 12 16:02:35 2013 -0800 summary: blackbox: fix a failing pyflakes test http://hg.intevation.org/mercurial/crew/rev/c61b49d059eb changeset: 18674:c61b49d059eb user: Durham Goode date: Sat Feb 09 13:35:30 2013 -0800 summary: blackbox: tests for the blackbox extension http://hg.intevation.org/mercurial/crew/rev/f27598902007 changeset: 18673:f27598902007 user: Durham Goode date: Sat Feb 09 09:09:46 2013 -0800 summary: blackbox: adds a 'blackbox' command for viewing recent logs http://hg.intevation.org/mercurial/crew/rev/b2b4ddc55caa changeset: 18672:b2b4ddc55caa user: Durham Goode date: Sat Feb 09 09:04:48 2013 -0800 summary: blackbox: log incoming changes via ui.log() http://hg.intevation.org/mercurial/crew/rev/1c305128e5b9 changeset: 18671:1c305128e5b9 user: Durham Goode date: Sat Feb 09 09:04:32 2013 -0800 summary: blackbox: logs python and extension hooks via ui.log() http://hg.intevation.org/mercurial/crew/rev/ddc7268da176 changeset: 18670:ddc7268da176 user: Durham Goode date: Sat Feb 09 09:04:14 2013 -0800 summary: blackbox: log the commands that are run http://hg.intevation.org/mercurial/crew/rev/18242716a014 changeset: 18669:18242716a014 user: Durham Goode date: Tue Feb 12 14:08:33 2013 -0800 summary: blackbox: adds a blackbox extension http://hg.intevation.org/mercurial/crew/rev/4034b8d551b1 changeset: 18668:4034b8d551b1 user: Bryan O'Sullivan date: Mon Feb 11 16:15:12 2013 -0800 summary: scmutil: create directories in a race-safe way during update http://hg.intevation.org/mercurial/crew/rev/f12804d3ff80 changeset: 18667:f12804d3ff80 parent: 18666:fb9d1c2805ff parent: 18658:5e63a85299ba user: Bryan O'Sullivan date: Mon Feb 11 14:50:54 2013 -0800 summary: Merge http://hg.intevation.org/mercurial/crew/rev/fb9d1c2805ff changeset: 18666:fb9d1c2805ff user: Idan Kamara date: Sat Feb 09 19:02:45 2013 +0200 summary: test-atomictempfile: convert to unit test http://hg.intevation.org/mercurial/crew/rev/2cbfb8c497ee changeset: 18665:2cbfb8c497ee user: Idan Kamara date: Sat Feb 09 19:13:39 2013 +0200 summary: tests: add a test runner utility that prints nothing when all tests pass http://hg.intevation.org/mercurial/crew/rev/30d899febef8 changeset: 18664:30d899febef8 user: Dan Villiom Podlaski Christiansen date: Sun Feb 10 13:14:31 2013 +0100 summary: hgweb: consistent author name width http://hg.intevation.org/mercurial/crew/rev/05cf40f9b0ec changeset: 18663:05cf40f9b0ec user: Durham Goode date: Sun Feb 10 12:23:39 2013 -0800 summary: dirstate: fix generator/list error when using python 2.7 http://hg.intevation.org/mercurial/crew/rev/c5f7e83d47cd changeset: 18662:c5f7e83d47cd user: Pierre-Yves David date: Mon Feb 11 16:21:48 2013 +0100 summary: mq: comply with filtering when injecting fake tags (issue3812) http://hg.intevation.org/mercurial/crew/rev/4fb92f14a97a changeset: 18661:4fb92f14a97a user: David Schleimer date: Fri Feb 08 05:36:08 2013 -0800 summary: commit: factor out post-commit cleanup into workingctx http://hg.intevation.org/mercurial/crew/rev/7e6946ed5756 changeset: 18660:7e6946ed5756 user: David Schleimer date: Fri Feb 08 05:36:08 2013 -0800 summary: localrepo: use workingctx for validation in commit http://hg.intevation.org/mercurial/crew/rev/b946470efed9 changeset: 18659:b946470efed9 parent: 18656:8eb3408bf005 user: David Schleimer date: Fri Feb 08 05:36:07 2013 -0800 summary: localrepo: create context used for actual commit earlier http://hg.intevation.org/mercurial/crew/rev/5e63a85299ba changeset: 18658:5e63a85299ba parent: 18656:8eb3408bf005 parent: 18657:d4a79e075303 user: Thomas Arendsen Hein date: Mon Feb 11 16:57:46 2013 +0100 summary: merge with crew-stable http://hg.intevation.org/mercurial/crew/rev/d4a79e075303 changeset: 18657:d4a79e075303 branch: stable bookmark: crew-stable parent: 18617:227479f61db9 user: Pierre-Yves David date: Sat Feb 09 23:28:42 2013 +0000 summary: debugobsolete: improve command help http://hg.intevation.org/mercurial/crew/rev/8eb3408bf005 changeset: 18656:8eb3408bf005 user: Kevin Bullock date: Sun Feb 10 23:01:12 2013 +0000 summary: import: don't rollback on failed import --exact (issue3616) http://hg.intevation.org/mercurial/crew/rev/882681bc3166 changeset: 18655:882681bc3166 parent: 18653:170142161672 parent: 18654:d9ff580fcaa2 user: Bryan O'Sullivan date: Sun Feb 10 16:22:32 2013 -0800 summary: Merge http://hg.intevation.org/mercurial/crew/rev/d9ff580fcaa2 changeset: 18654:d9ff580fcaa2 parent: 18651:e556659340f0 parent: 18648:013fcd112f13 user: Bryan O'Sullivan date: Sun Feb 10 16:21:30 2013 -0800 summary: Merge http://hg.intevation.org/mercurial/crew/rev/170142161672 changeset: 18653:170142161672 parent: 18652:a5e94bee77ed parent: 18651:e556659340f0 user: Benoit Boissinot date: Mon Feb 11 01:21:24 2013 +0100 summary: merge crew and main http://hg.intevation.org/mercurial/crew/rev/a5e94bee77ed changeset: 18652:a5e94bee77ed parent: 18642:76b69cccb07a parent: 18648:013fcd112f13 user: Benoit Boissinot date: Mon Feb 11 01:17:50 2013 +0100 summary: merge crew and main http://hg.intevation.org/mercurial/crew/rev/e556659340f0 changeset: 18651:e556659340f0 user: Siddharth Agarwal date: Sun Feb 10 16:55:01 2013 +0000 summary: manifestmerge: fix order in which manifests are fetched http://hg.intevation.org/mercurial/crew/rev/de0bd4bfc6d7 changeset: 18650:de0bd4bfc6d7 user: Siddharth Agarwal date: Sun Feb 10 12:16:46 2013 +0000 summary: merge: run _forgetremoved after manifestmerge http://hg.intevation.org/mercurial/crew/rev/0969980308c7 changeset: 18649:0969980308c7 parent: 18642:76b69cccb07a user: Siddharth Agarwal date: Sun Feb 10 16:23:14 2013 +0000 summary: dirstate: disable gc while parsing the dirstate http://hg.intevation.org/mercurial/crew/rev/76b69cccb07a changeset: 18642:76b69cccb07a user: Mads Kiilerich date: Fri Feb 08 22:54:17 2013 +0100 summary: export: show 'Date' header in a format that also is readable for humans http://hg.intevation.org/mercurial/crew/rev/c1d23b4a66d5 changeset: 18641:c1d23b4a66d5 user: Mads Kiilerich date: Sun Feb 10 18:26:04 2013 +0100 summary: factotum: fix urllib2 import so it no longer relies on a demandimport bug http://hg.intevation.org/mercurial/crew/rev/c6a81e54c209 changeset: 18640:c6a81e54c209 user: Mads Kiilerich date: Sun Jan 27 03:32:09 2013 +0100 summary: hgweb: make the test suite use hgweb in a more WSGI compliant way http://hg.intevation.org/mercurial/crew/rev/76ff3a715cf2 changeset: 18639:76ff3a715cf2 user: Mads Kiilerich date: Sun Feb 10 18:24:29 2013 +0100 summary: hgweb: simplify internal staticfile return codes http://hg.intevation.org/mercurial/crew/rev/3e92772d5383 changeset: 18638:3e92772d5383 user: Mads Kiilerich date: Sun Feb 10 18:24:29 2013 +0100 summary: spelling: fix some minor issues found by spell checker http://hg.intevation.org/mercurial/crew/rev/cc28a84db8c9 changeset: 18637:cc28a84db8c9 user: Mads Kiilerich date: Fri Feb 08 23:26:00 2013 +0100 summary: bundlerepo: replace basemap with the base field in the index http://hg.intevation.org/mercurial/crew/rev/a40d608e2a7b changeset: 18636:a40d608e2a7b user: Mads Kiilerich date: Fri Feb 08 22:54:48 2013 +0100 summary: profiling: replace '+' markup of nested lines with indentation http://hg.intevation.org/mercurial/crew/rev/6204e4d4dd6d changeset: 18635:6204e4d4dd6d parent: 18634:0027a5cec9d0 parent: 18633:a8648f32b8ed user: Augie Fackler date: Sun Feb 10 04:04:22 2013 -0600 summary: Merge crew and main. http://hg.intevation.org/mercurial/crew/rev/a8648f32b8ed changeset: 18633:a8648f32b8ed user: Bryan O'Sullivan date: Sat Feb 09 15:51:32 2013 -0800 summary: merge: don't fiddle with name lookups or i18n in hot loops http://hg.intevation.org/mercurial/crew/rev/5774732bb5e5 changeset: 18632:5774732bb5e5 user: Bryan O'Sullivan date: Sat Feb 09 15:51:32 2013 -0800 summary: merge: apply non-interactive working dir updates in parallel http://hg.intevation.org/mercurial/crew/rev/047110c0e2a8 changeset: 18631:047110c0e2a8 user: Bryan O'Sullivan date: Sat Feb 09 15:51:32 2013 -0800 summary: worker: allow a function to be run in multiple worker processes http://hg.intevation.org/mercurial/crew/rev/ac4dbceeb14a changeset: 18630:ac4dbceeb14a user: Bryan O'Sullivan date: Sat Feb 09 15:51:32 2013 -0800 summary: worker: partition a list (of tasks) into equal-sized chunks http://hg.intevation.org/mercurial/crew/rev/dcb27c153a40 changeset: 18629:dcb27c153a40 user: Bryan O'Sullivan date: Sat Feb 09 15:51:26 2013 -0800 summary: worker: estimate whether it's worth running a task in parallel http://hg.intevation.org/mercurial/crew/rev/fed06dd07665 changeset: 18628:fed06dd07665 user: Bryan O'Sullivan date: Sat Feb 09 15:22:12 2013 -0800 summary: worker: count the number of CPUs http://hg.intevation.org/mercurial/crew/rev/4b5d37ca3c11 changeset: 18627:4b5d37ca3c11 user: Bryan O'Sullivan date: Sat Feb 09 15:22:10 2013 -0800 summary: tests: getremove test output changes (fold into previous patch) http://hg.intevation.org/mercurial/crew/rev/6390dd22b12f changeset: 18626:6390dd22b12f user: Bryan O'Sullivan date: Sat Feb 09 15:22:09 2013 -0800 summary: merge: report non-interactive progress in chunks http://hg.intevation.org/mercurial/crew/rev/3e20079117c5 changeset: 18625:3e20079117c5 user: Bryan O'Sullivan date: Sat Feb 09 15:22:08 2013 -0800 summary: merge: handle subrepo merges and .hgsubstate specially http://hg.intevation.org/mercurial/crew/rev/e2dc5397bc82 changeset: 18624:e2dc5397bc82 user: Bryan O'Sullivan date: Sat Feb 09 15:22:04 2013 -0800 summary: tests: update test output (will be folded into parent) http://hg.intevation.org/mercurial/crew/rev/9b9e2d9e83a1 changeset: 18623:9b9e2d9e83a1 user: Bryan O'Sullivan date: Sat Feb 09 15:21:58 2013 -0800 summary: merge: split out mostly-non-interactive working dir updates -- Repository URL: http://hg.intevation.org/mercurial/crew From angel.ezquerra at gmail.com Thu Feb 14 07:05:07 2013 From: angel.ezquerra at gmail.com (Angel Ezquerra) Date: Thu, 14 Feb 2013 14:05:07 +0100 Subject: [PATCH] subrepo: do not push "clean" subrepos when the parent repo is pushed In-Reply-To: References: <26276460d54aecdeb107.1360800378@Angel-PC.localdomain> Message-ID: On Thu, Feb 14, 2013 at 10:54 AM, Isaac Jurado wrote: > On Thu, Feb 14, 2013 at 1:06 AM, Angel Ezquerra > wrote: >> # HG changeset patch >> # User Angel Ezquerra >> # Date 1360795816 -3600 >> # Node ID 26276460d54aecdeb107c82c4e3f2ca7c0c6a8b3 >> # Parent 55b9b294b7544a6a144f627f71f4b770907d5a98 >> subrepo: do not push "clean" subrepos when the parent repo is pushed >> >> A clean subrepo is defined as one that has not had its dirstate, bookmarks or >> phases modified. >> >> This patch works by adding a "clean" method to subrepos. In the case of >> mercurial subrepos, this method calculates a "stamp" (i.e. a set of file hashes) >> of the repository state at the time of push with a similar "stamp" that was >> stored on a file when the subrepo was cloned or pushed to a given remote target. >> If the stamps match the subrepo has no changes that must be pushed to the target >> repository and thus the push can be skipped. >> >> Note that we calculate the stamp file by calculating hashes for several key >> repository files, such as the dirstate, the bookmarks file and the phaseroots >> file. This means that our "clean" detection is not perfect, in the sense that >> if the working directory has been updated to a different revision we will >> assume that the subrepo is not clean. However, if we update to another revision >> and back to the original revision the clean() method will correctly detec the >> subrepo as being clean. >> >> Also note that a subrepo being "clean" is not the opposite of it being "dirty". >> A subrepo is dirty if it updated to a different revision that the one that is >> pointed to by the subrepo parent or if its working directory is not clean. This >> is a different concept. > > Have you considered the following situations? > > 1. The .hgsub file changes > 2. The [subpaths] section redirects pushes to a different location > from last push. > > I couldn't deduce it from the code so I had to ask. > > Cheers. The patch certainly covers situation #1 because we keep track of the clean status for each remote path. Changing the .hgsub file will simply change the remote path (it could also remove a subrepo, in which case this does not apply; or add it in which case the repo will just be cloned). Regarding situation #2 I have not tried it. It is great that you bring this up. I believe it should probably work because the patch checks the current remote path, and I believe that is obtained after the subpath substitution has been done. That being said I'll have to check that is the case. Thanks for your comments, Angel From mercurial-bugs at selenic.com Thu Feb 14 05:01:49 2013 From: mercurial-bugs at selenic.com (mercurial-bugs at selenic.com) Date: Thu, 14 Feb 2013 11:01:49 +0000 Subject: [Bug 3823] New: Merge fails with KeyError: '.hgsubstate' Message-ID: http://bz.selenic.com/show_bug.cgi?id=3823 Priority: normal Bug ID: 3823 CC: mercurial-devel at selenic.com Assignee: bugzilla at selenic.com Summary: Merge fails with KeyError: '.hgsubstate' Severity: bug Classification: Unclassified OS: Mac OS Reporter: lwarxx at gmail.com Hardware: Macintosh Status: UNCONFIRMED Version: 2.5 Component: Mercurial Product: Mercurial Merge fails when right branch contains commit with updated subrepository and at least one additional changeset. So far it happens only with one repository. For example, this works (commits are merged to feature branch one by one): hg up default hg ci -m 'modify file' hg up feature hg merge default hg ci -m 'merge' hg up default hg up -R subrepo hg ci -m 'update subrepo' hg up feature hg merge default hg ci -m 'merge' And this fails (two commits merged to feature branch at once): hg up default hg ci -m 'modify file' hg up -R subrepo hg ci -m 'update subrepo' hg up feature hg merge default The exception is below: ** unknown exception encountered, please report by visiting ** http://mercurial.selenic.com/wiki/BugTracker ** Python 2.7.3 (default, Nov 19 2012, 00:46:55) [GCC 4.2.1 Compatible Apple Clang 4.1 ((tags/Apple/clang-421.11.66))] ** Mercurial Distributed SCM (version 2.5) ** Extensions loaded: pager, mq, color, rebase, graphlog, fetch, notify, patchbomb, convert, record, eol, purge, transplant Traceback (most recent call last): File "/opt/local/bin/hg", line 38, in mercurial.dispatch.run() File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/mercurial/dispatch.py", line 28, in run sys.exit((dispatch(request(sys.argv[1:])) or 0) & 255) File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/mercurial/dispatch.py", line 65, in dispatch return _runcatch(req) File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/mercurial/dispatch.py", line 88, in _runcatch return _dispatch(req) File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/mercurial/dispatch.py", line 743, in _dispatch cmdpats, cmdoptions) File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/mercurial/dispatch.py", line 514, in runcommand ret = _runcommand(ui, options, cmd, d) File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/mercurial/extensions.py", line 189, in wrap return wrapper(origfn, *args, **kwargs) File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/hgext/color.py", line 394, in colorcmd return orig(ui_, opts, cmd, cmdfunc) File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/mercurial/extensions.py", line 189, in wrap return wrapper(origfn, *args, **kwargs) File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/hgext/pager.py", line 130, in pagecmd return orig(ui, options, cmd, cmdfunc) File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/mercurial/dispatch.py", line 833, in _runcommand return checkargs() File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/mercurial/dispatch.py", line 804, in checkargs return cmdfunc() File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/mercurial/dispatch.py", line 740, in d = lambda: util.checksignature(func)(ui, *args, **cmdoptions) File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/mercurial/util.py", line 475, in check return func(*args, **kwargs) File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/mercurial/extensions.py", line 144, in wrap util.checksignature(origfn), *args, **kwargs) File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/mercurial/util.py", line 475, in check return func(*args, **kwargs) File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/hgext/mq.py", line 3508, in mqcommand return orig(ui, repo, *args, **kwargs) File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/mercurial/util.py", line 475, in check return func(*args, **kwargs) File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/mercurial/commands.py", line 4438, in merge return hg.merge(repo, node, force=opts.get('force')) File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/mercurial/hg.py", line 481, in merge stats = mergemod.update(repo, node, True, force, False) File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/mercurial/merge.py", line 630, in update stats = applyupdates(repo, actions, wc, p2, pa, overwrite) File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/mercurial/merge.py", line 391, in applyupdates r = ms.resolve(fd, wctx, mctx) File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/mercurial/merge.py", line 67, in resolve if self[dfile] == 'r': File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/mercurial/merge.py", line 57, in __getitem__ return self._state[dfile][0] KeyError: '.hgsubstate' -- You are receiving this mail because: You are on the CC list for the bug. From kbullock+mercurial at ringworld.org Thu Feb 14 10:12:36 2013 From: kbullock+mercurial at ringworld.org (Kevin Bullock) Date: Thu, 14 Feb 2013 10:12:36 -0600 Subject: [PATCH] subrepo: do not push "clean" subrepos when the parent repo is pushed In-Reply-To: References: <26276460d54aecdeb107.1360800378@Angel-PC.localdomain> <1360805515.12295.53.camel@calx> Message-ID: <55351C35-5DA0-4D7C-8E70-B30EFCA470C4@ringworld.org> On 14 Feb 2013, at 2:39 AM, Angel Ezquerra wrote: > On Thu, Feb 14, 2013 at 2:31 AM, Matt Mackall wrote: >> On Thu, 2013-02-14 at 01:06 +0100, Angel Ezquerra wrote: >>> # HG changeset patch >>> # User Angel Ezquerra >>> # Date 1360795816 -3600 >>> # Node ID 26276460d54aecdeb107c82c4e3f2ca7c0c6a8b3 >>> # Parent 55b9b294b7544a6a144f627f71f4b770907d5a98 >>> subrepo: do not push "clean" subrepos when the parent repo is pushed >>> >>> A clean subrepo is defined as one that has not had its dirstate, bookmarks or >>> phases modified. >>> >>> This patch works by adding a "clean" method to subrepos. In the case of >>> mercurial subrepos, this method calculates a "stamp" (i.e. a set of file hashes) >>> of the repository state at the time of push with a similar "stamp" that was >>> stored on a file when the subrepo was cloned or pushed to a given remote target. >>> If the stamps match the subrepo has no changes that must be pushed to the target >>> repository and thus the push can be skipped. >>> >>> Note that we calculate the stamp file by calculating hashes for several key >>> repository files, such as the dirstate, the bookmarks file and the phaseroots >>> file. This means that our "clean" detection is not perfect, in the sense that >>> if the working directory has been updated to a different revision we will >>> assume that the subrepo is not clean. However, if we update to another revision >>> and back to the original revision the clean() method will correctly detec the >>> subrepo as being clean. > >> Why is the dirstate interesting? I would posit that we're only >> interested in things that we'd push or pull. Dirstate being modified >> should not force us to push. > > I think I may have misunderstood you when we discussed this during the > sprint. I thought you mentioned that we should check the direstate, > the bookmarks and the phaseroots. I remember asking the same question during the sprint -- we'll need to check the dirstate later to figure out whether we can move a subrepo aside on -update-. It doesn't apply to clean-ness for the purposes of push and pull. > I don't know the mercurial store format well enough to tell which > files we need to hash. Would hashing "store/00changelog.i" and > "store/00manifest.i" be enough? An alternative would be to hash the > list of repository heads and consider the repo unclean if that > changed? I would think that the changelog, bookmarks, and phaseroots would be enough. pacem in terris / ??? / ?????? / ????????? / ?? Kevin R. Bullock From bos at serpentine.com Thu Feb 14 10:26:19 2013 From: bos at serpentine.com (Bryan O'Sullivan) Date: Thu, 14 Feb 2013 08:26:19 -0800 Subject: [PATCH RFC] blackbox: do not translate the log messages In-Reply-To: <1360805340.12295.51.camel@calx> References: <9e42d1429fc278b83adb.1360791527@dev350.prn1.facebook.com> <1360805340.12295.51.camel@calx> Message-ID: On Wed, Feb 13, 2013 at 5:29 PM, Matt Mackall wrote: > Check-code should complain about untranslated strings like this. > I've applied the patch as-is. check-code doesn't care because it knows nothing about ui.log. -------------- next part -------------- An HTML attachment was scrubbed... URL: From durham at fb.com Thu Feb 14 12:46:56 2013 From: durham at fb.com (Durham Goode) Date: Thu, 14 Feb 2013 18:46:56 +0000 Subject: [PATCH hglib] tests: fix tests that use integer bookmarks In-Reply-To: <02dd78c2b8d74dc8a97d.1360324568@dev350.prn1.facebook.com> Message-ID: <2B10A89294DA6740AC6155F56842F9CE0565B428@PRN-MBX01-2.TheFacebook.com> Pinging this since it's a week old and a test failure. Matt, the crew people I talked to said they couldn't apply this since it's the hglib repo, so you might have to be the one. On 2/8/13 11:56 AM, "Durham Goode" wrote: ># HG changeset patch ># User Durham Goode ># Date 1360324302 28800 ># Node ID 02dd78c2b8d74dc8a97d1aa17238cebf37ccd708 ># Parent 7ce1c3b93414e08a9be1d83f17e7d87d2a24ab3b >tests: fix tests that use integer bookmarks > >Integer bookmarks are now not allowed (since they alias with revision >numbers), >so a hglib test was failing. > >diff --git a/tests/test-bookmarks.py b/tests/test-bookmarks.py >--- a/tests/test-bookmarks.py >+++ b/tests/test-bookmarks.py >@@ -10,14 +10,14 @@ > self.append('a', 'a') > rev1, node1 = self.client.commit('second') > >- self.client.bookmark('0', rev0) >+ self.client.bookmark('zero', rev0) > self.assertEquals(self.client.bookmarks(), >- ([('0', rev0, node0[:12])], -1)) >+ ([('zero', rev0, node0[:12])], -1)) > >- self.client.bookmark('1', rev1) >+ self.client.bookmark('one', rev1) > self.assertEquals(self.client.bookmarks(), >- ([('0', rev0, node0[:12]), >- ('1', rev1, node1[:12])], 1)) >+ ([('one', rev1, node1[:12]), >+ ('zero', rev0, node0[:12])], 0)) > > #def test_spaces(self): > # self.client.bookmark('s pace', self.rev0) >_______________________________________________ >Mercurial-devel mailing list >Mercurial-devel at selenic.com >http://selenic.com/mailman/listinfo/mercurial-devel > From mpm at selenic.com Thu Feb 14 13:14:43 2013 From: mpm at selenic.com (Matt Mackall) Date: Thu, 14 Feb 2013 13:14:43 -0600 Subject: [PATCH hglib] tests: fix tests that use integer bookmarks In-Reply-To: <2B10A89294DA6740AC6155F56842F9CE0565B428@PRN-MBX01-2.TheFacebook.com> References: <2B10A89294DA6740AC6155F56842F9CE0565B428@PRN-MBX01-2.TheFacebook.com> Message-ID: <1360869283.12295.54.camel@calx> On Thu, 2013-02-14 at 18:46 +0000, Durham Goode wrote: > Pinging this since it's a week old and a test failure. Matt, the crew > people I talked to said they couldn't apply this since it's the hglib > repo, so you might have to be the one. Pushed, thanks for the reminder. -- Mathematics is the supreme nostalgia of our time. From mercurial-bugs at selenic.com Thu Feb 14 08:18:23 2013 From: mercurial-bugs at selenic.com (mercurial-bugs at selenic.com) Date: Thu, 14 Feb 2013 14:18:23 +0000 Subject: [Bug 3824] New: move the strip command to an extension of its own Message-ID: http://bz.selenic.com/show_bug.cgi?id=3824 Priority: normal Bug ID: 3824 CC: mercurial-devel at selenic.com Assignee: bugzilla at selenic.com Summary: move the strip command to an extension of its own Severity: feature Classification: Unclassified OS: All Reporter: bos at serpentine.com Hardware: All Status: UNCONFIRMED Version: unspecified Component: mq Product: Mercurial I'd like to be able to have people/tools use strip without being exposed to the rest of mq. We should create a strip extension that only supports this command, and modify mq to use it. -- You are receiving this mail because: You are on the CC list for the bug. From hgbuildbot at kublai.com Thu Feb 14 13:35:45 2013 From: hgbuildbot at kublai.com (hgbuildbot at kublai.com) Date: Thu, 14 Feb 2013 11:35:45 -0800 Subject: buildbot success in Mercurial on python-hglib Message-ID: <20130214193545.AF85F25ED9@hgbuildbot.cs.ubc.ca> The Buildbot has detected a restored build on builder python-hglib while building hg. Full details are available at: http://hgbuildbot.kublai.com/builders/python-hglib/builds/800 Buildbot URL: http://hgbuildbot.kublai.com/ Buildslave for this Build: l6 Build Reason: scheduler Build Source Stamp: [branch default] 4f485bd68f1debb88d5022a732d85c8c225e91fc Blamelist: Durham Goode Build succeeded! sincerely, -The Buildbot From cryo at cyanite.org Thu Feb 14 13:40:14 2013 From: cryo at cyanite.org (Sune Foldager) Date: Thu, 14 Feb 2013 20:40:14 +0100 Subject: [PATCH 4 of 9] bundle-ng: move gengroup into bundler In-Reply-To: References: Message-ID: <1107b6c3ba5652700eca.1360870814@firefly.edlund.dk> # HG changeset patch # User Sune Foldager # Date 1360455164 -3600 # Node ID 1107b6c3ba5652700ecaa0184d00490f81d2b063 # Parent ad5a6d13a57e28c75167facacc2811cefc014155 bundle-ng: move gengroup into bundler diff -r ad5a6d13a57e -r 1107b6c3ba56 mercurial/changegroup.py --- a/mercurial/changegroup.py Sat Feb 09 23:42:03 2013 +0100 +++ b/mercurial/changegroup.py Sun Feb 10 01:12:44 2013 +0100 @@ -6,7 +6,7 @@ # GNU General Public License version 2 or any later version. from i18n import _ -from node import nullrev +from node import nullrev, hex import mdiff, util, dagutil import struct, os, bz2, zlib, tempfile @@ -225,11 +225,24 @@ class bundle10(object): deltaheader = _BUNDLE10_DELTA_HEADER - def __init__(self, bundlecaps=None): + def __init__(self, bundlecaps=None, repo=None): # Set of capabilities we can use to build the bundle. if bundlecaps is None: bundlecaps = set() self._bundlecaps = bundlecaps + if repo is not None: + self._changelog = repo.changelog + self._manifest = repo.manifest + reorder = repo.ui.config('bundle', 'reorder', 'auto') + if reorder == 'auto': + reorder = None + else: + reorder = util.parsebool(reorder) + else: + reorder = False + self._repo = repo + self._reorder = reorder + self.count = [0, 0] def start(self, lookup): self._lookup = lookup def close(self): @@ -276,6 +289,43 @@ yield self.close() + def generate(self, clnodes, getmfnodes, getfiles, getfilenodes, source): + '''yield a sequence of changegroup chunks (strings)''' + repo = self._repo + cl = self._changelog + mf = self._manifest + reorder = self._reorder + progress = repo.ui.progress + count = self.count + _bundling = _('bundling') + + count[:] = [0, len(clnodes)] + for chunk in self.group(clnodes, cl, reorder=reorder): + yield chunk + progress(_bundling, None) + + for chunk in self.group(getmfnodes(), mf, reorder=reorder): + yield chunk + progress(_bundling, None) + + changedfiles = getfiles() + count[:] = [0, len(changedfiles)] + for fname in sorted(changedfiles): + filerevlog = repo.file(fname) + if not len(filerevlog): + raise util.Abort(_("empty or missing revlog for %s") + % fname) + nodelist = getfilenodes(fname, filerevlog) + if nodelist: + count[0] += 1 + yield self.fileheader(fname) + for chunk in self.group(nodelist, filerevlog, reorder): + yield chunk + yield self.close() + progress(_bundling, None) + + if clnodes: + repo.hook('outgoing', node=hex(clnodes[0]), source=source) def revchunk(self, revlog, rev, prev): node = revlog.node(rev) From cryo at cyanite.org Thu Feb 14 13:40:10 2013 From: cryo at cyanite.org (Sune Foldager) Date: Thu, 14 Feb 2013 20:40:10 +0100 Subject: [PATCH 0 of 9] Move and refactor bundling logic Message-ID: Benoit and I worked on this at the sprint, following the bundle format 2 discussion. It takes some first steps towards implementing the new format. It basically moves all bundle creation logic out of localrepo.py and into changegroup.py, into the bundler10 class. The patch queue is posted as-is for easier review, although it may need some work before push. Moving forwards from this, I think the plan is something like the following: I'd like to do a dev spike on creating a new bundle format, ignoring some details such as we haven't decided on some specifics about how to encode hunk types, lengths etc. I think (but Benoit and I don't entirely agree) it would be best to put that into a new bundler20 (or whatever) class, which derives from bundler10. A factory would then be needed to return the correct bundler. I think that keeping it in the same class, will cause a lot of clutter, a lot of if newbundleformat: in many places, and make the code harder to follow. I'm sure we can discuss this for hours to come :) Then there is the unbundling part, on which work hasn't begun (unless Benoit did something not yet pushed). -- Sune From cryo at cyanite.org Thu Feb 14 13:40:11 2013 From: cryo at cyanite.org (Sune Foldager) Date: Thu, 14 Feb 2013 20:40:11 +0100 Subject: [PATCH 1 of 9] bundle-ng: move bundler creation up in the stack In-Reply-To: References: Message-ID: # HG changeset patch # User Benoit Boissinot # Date 1360432342 -3600 # Node ID d78029a5c1f72e2eb75321409ad969462b7d372f # Parent 46edbc49a9f213dd9c78e4dbaa8809661058bb07 bundle-ng: move bundler creation up in the stack Create a simple start() method to pass the lookup function until bundler becomes smarter and gets a repo object. diff -r 46edbc49a9f2 -r d78029a5c1f7 contrib/shrink-revlog.py --- a/contrib/shrink-revlog.py Sat Feb 09 16:02:01 2013 +0000 +++ b/contrib/shrink-revlog.py Sat Feb 09 18:52:22 2013 +0100 @@ -117,7 +117,8 @@ unlookup = lambda x: int(x, 10) try: - bundler = changegroup.bundle10(lookup) + bundler = changegroup.bundle10() + bundler.start(lookup) group = util.chunkbuffer(r1.group(order, bundler)) group = changegroup.unbundle10(group, "UN") r2.addgroup(group, unlookup, tr) diff -r 46edbc49a9f2 -r d78029a5c1f7 mercurial/changegroup.py --- a/mercurial/changegroup.py Sat Feb 09 16:02:01 2013 +0000 +++ b/mercurial/changegroup.py Sat Feb 09 18:52:22 2013 +0100 @@ -225,7 +225,9 @@ class bundle10(object): deltaheader = _BUNDLE10_DELTA_HEADER - def __init__(self, lookup): + def __init__(self): + pass + def start(self, lookup): self._lookup = lookup def close(self): return closechunk() diff -r 46edbc49a9f2 -r d78029a5c1f7 mercurial/localrepo.py --- a/mercurial/localrepo.py Sat Feb 09 16:02:01 2013 +0000 +++ b/mercurial/localrepo.py Sat Feb 09 18:52:22 2013 +0100 @@ -1823,7 +1823,9 @@ if revs is None and not outgoing.excluded: # push everything, # use the fast path, no race possible on push - cg = self._changegroup(outgoing.missing, 'push') + bundler = changegroup.bundle10() + cg = self._changegroup(outgoing.missing, bundler, + 'push') else: cg = self.getlocalbundle('push', outgoing) @@ -1978,7 +1980,8 @@ csets, bases, heads = cl.nodesbetween(bases, heads) # We assume that all ancestors of bases are known common = cl.ancestors([cl.rev(n) for n in bases]) - return self._changegroupsubset(common, csets, heads, source) + bundler = changegroup.bundle10() + return self._changegroupsubset(common, csets, heads, bundler, source) def getlocalbundle(self, source, outgoing): """Like getbundle, but taking a discovery.outgoing as an argument. @@ -1987,9 +1990,11 @@ precomputed sets in outgoing.""" if not outgoing.missing: return None + bundler = changegroup.bundle10() return self._changegroupsubset(outgoing.common, outgoing.missing, outgoing.missingheads, + bundler, source) def getbundle(self, source, heads=None, common=None): @@ -2013,7 +2018,7 @@ discovery.outgoing(cl, common, heads)) @unfilteredmethod - def _changegroupsubset(self, commonrevs, csets, heads, source): + def _changegroupsubset(self, commonrevs, csets, heads, bundler, source): cl = self.changelog mf = self.manifest @@ -2026,7 +2031,7 @@ # can we go through the fast path ? heads.sort() if heads == sorted(self.heads()): - return self._changegroup(csets, source) + return self._changegroup(csets, bundler, source) # slow path self.hook('preoutgoing', throw=True, source=source) @@ -2068,7 +2073,7 @@ unit=_files, total=count[1]) return fstate[1][x] - bundler = changegroup.bundle10(lookup) + bundler.start(lookup) reorder = self.ui.config('bundle', 'reorder', 'auto') if reorder == 'auto': reorder = None @@ -2125,7 +2130,7 @@ return self.changegroupsubset(basenodes, self.heads(), source) @unfilteredmethod - def _changegroup(self, nodes, source): + def _changegroup(self, nodes, bundler, source): """Compute the changegroup of all nodes that we have that a recipient doesn't. Return a chunkbuffer object whose read() method will return successive changegroup chunks. @@ -2176,7 +2181,7 @@ total=count[1], unit=_files) return cl.node(revlog.linkrev(revlog.rev(x))) - bundler = changegroup.bundle10(lookup) + bundler.start(lookup) reorder = self.ui.config('bundle', 'reorder', 'auto') if reorder == 'auto': reorder = None From cryo at cyanite.org Thu Feb 14 13:40:13 2013 From: cryo at cyanite.org (Sune Foldager) Date: Thu, 14 Feb 2013 20:40:13 +0100 Subject: [PATCH 3 of 9] bundle-ng: add bundlecaps argument to getbundle() command In-Reply-To: References: Message-ID: # HG changeset patch # User Benoit Boissinot # Date 1360449723 -3600 # Node ID ad5a6d13a57e28c75167facacc2811cefc014155 # Parent 66e25980c10d10b00b658608472b251b2d3ee4fe bundle-ng: add bundlecaps argument to getbundle() command diff -r 66e25980c10d -r ad5a6d13a57e mercurial/changegroup.py --- a/mercurial/changegroup.py Sat Feb 09 18:48:34 2013 +0100 +++ b/mercurial/changegroup.py Sat Feb 09 23:42:03 2013 +0100 @@ -225,8 +225,11 @@ class bundle10(object): deltaheader = _BUNDLE10_DELTA_HEADER - def __init__(self): - pass + def __init__(self, bundlecaps=None): + # Set of capabilities we can use to build the bundle. + if bundlecaps is None: + bundlecaps = set() + self._bundlecaps = bundlecaps def start(self, lookup): self._lookup = lookup def close(self): diff -r 66e25980c10d -r ad5a6d13a57e mercurial/commands.py --- a/mercurial/commands.py Sat Feb 09 18:48:34 2013 +0100 +++ b/mercurial/commands.py Sat Feb 09 23:42:03 2013 +0100 @@ -1054,13 +1054,16 @@ base = ['null'] else: base = scmutil.revrange(repo, opts.get('base')) + # TODO: get desired bundlecaps from command line. + bundlecaps = None if base: if dest: raise util.Abort(_("--base is incompatible with specifying " "a destination")) common = [repo.lookup(rev) for rev in base] heads = revs and map(repo.lookup, revs) or revs - cg = repo.getbundle('bundle', heads=heads, common=common) + cg = repo.getbundle('bundle', heads=heads, common=common, + bundlecaps=bundlecaps) outgoing = None else: dest = ui.expandpath(dest or 'default-push', dest or 'default') @@ -1072,7 +1075,7 @@ onlyheads=heads, force=opts.get('force'), portable=True) - cg = repo.getlocalbundle('bundle', outgoing) + cg = repo.getlocalbundle('bundle', outgoing, bundlecaps) if not cg: scmutil.nochangesfound(ui, repo, outgoing and outgoing.excluded) return 1 @@ -1920,6 +1923,8 @@ args['common'] = [bin(s) for s in common] if head: args['heads'] = [bin(s) for s in head] + # TODO: get desired bundlecaps from command line. + args['bundlecaps'] = None bundle = repo.getbundle('debug', **args) bundletype = opts.get('type', 'bzip2').lower() diff -r 66e25980c10d -r ad5a6d13a57e mercurial/localrepo.py --- a/mercurial/localrepo.py Sat Feb 09 18:48:34 2013 +0100 +++ b/mercurial/localrepo.py Sat Feb 09 23:42:03 2013 +0100 @@ -99,8 +99,9 @@ def known(self, nodes): return self._repo.known(nodes) - def getbundle(self, source, heads=None, common=None): - return self._repo.getbundle(source, heads=heads, common=common) + def getbundle(self, source, heads=None, common=None, bundlecaps=None): + return self._repo.getbundle(source, heads=heads, common=common, + bundlecaps=None) # TODO We might want to move the next two calls into legacypeer and add # unbundle instead. @@ -1678,6 +1679,7 @@ heads = rheads if remote.capable('getbundle'): + # TODO: get bundlecaps from remote cg = remote.getbundle('pull', common=common, heads=heads or rheads) elif heads is None: @@ -1819,15 +1821,17 @@ remoteheads, newbranch, bool(inc)) + # TODO: get bundlecaps from remote + bundlecaps = None # create a changegroup from local if revs is None and not outgoing.excluded: # push everything, # use the fast path, no race possible on push - bundler = changegroup.bundle10() + bundler = changegroup.bundle10(bundlecaps) cg = self._changegroup(outgoing.missing, bundler, 'push') else: - cg = self.getlocalbundle('push', outgoing) + cg = self.getlocalbundle('push', outgoing, bundlecaps) # apply changegroup to remote if unbundle: @@ -1983,21 +1987,21 @@ bundler = changegroup.bundle10() return self._changegroupsubset(common, csets, heads, bundler, source) - def getlocalbundle(self, source, outgoing): + def getlocalbundle(self, source, outgoing, bundlecaps=None): """Like getbundle, but taking a discovery.outgoing as an argument. This is only implemented for local repos and reuses potentially precomputed sets in outgoing.""" if not outgoing.missing: return None - bundler = changegroup.bundle10() + bundler = changegroup.bundle10(bundlecaps) return self._changegroupsubset(outgoing.common, outgoing.missing, outgoing.missingheads, bundler, source) - def getbundle(self, source, heads=None, common=None): + def getbundle(self, source, heads=None, common=None, bundlecaps=None): """Like changegroupsubset, but returns the set difference between the ancestors of heads and the ancestors common. @@ -2015,7 +2019,8 @@ if not heads: heads = cl.heads() return self.getlocalbundle(source, - discovery.outgoing(cl, common, heads)) + discovery.outgoing(cl, common, heads), + bundlecaps=bundlecaps) @unfilteredmethod def _changegroupsubset(self, commonrevs, csets, heads, bundler, source): diff -r 66e25980c10d -r ad5a6d13a57e mercurial/wireproto.py --- a/mercurial/wireproto.py Sat Feb 09 18:48:34 2013 +0100 +++ b/mercurial/wireproto.py Sat Feb 09 23:42:03 2013 +0100 @@ -281,13 +281,15 @@ bases=bases, heads=heads) return changegroupmod.unbundle10(self._decompress(f), 'UN') - def getbundle(self, source, heads=None, common=None): + def getbundle(self, source, heads=None, common=None, bundlecaps=None): self.requirecap('getbundle', _('look up remote changes')) opts = {} if heads is not None: opts['heads'] = encodelist(heads) if common is not None: opts['common'] = encodelist(common) + if bundlecaps is not None: + opts['bundlecaps'] = ','.join(bundlecaps) f = self._callstream("getbundle", **opts) return changegroupmod.unbundle10(self._decompress(f), 'UN') @@ -449,9 +451,12 @@ return repo.debugwireargs(one, two, **opts) def getbundle(repo, proto, others): - opts = options('getbundle', ['heads', 'common'], others) + opts = options('getbundle', ['heads', 'common', 'bundlecaps'], others) for k, v in opts.iteritems(): - opts[k] = decodelist(v) + if k in ('heads', 'common'): + opts[k] = decodelist(v) + elif k == 'bundlecaps': + opts[k] = set(v.split(',')) cg = repo.getbundle('serve', **opts) return streamres(proto.groupchunks(cg)) From cryo at cyanite.org Thu Feb 14 13:40:15 2013 From: cryo at cyanite.org (Sune Foldager) Date: Thu, 14 Feb 2013 20:40:15 +0100 Subject: [PATCH 5 of 9] bundle-ng: unify _changegroup and _changegroupsubset In-Reply-To: References: Message-ID: <3821b9f543fbeabc29a2.1360870815@firefly.edlund.dk> # HG changeset patch # User Benoit Boissinot # Date 1360507643 -3600 # Node ID 3821b9f543fbeabc29a2c34b3f78272837364586 # Parent 1107b6c3ba5652700ecaa0184d00490f81d2b063 bundle-ng: unify _changegroup and _changegroupsubset diff -r 1107b6c3ba56 -r 3821b9f543fb mercurial/localrepo.py --- a/mercurial/localrepo.py Sun Feb 10 01:12:44 2013 +0100 +++ b/mercurial/localrepo.py Sun Feb 10 15:47:23 2013 +0100 @@ -1827,9 +1827,13 @@ if revs is None and not outgoing.excluded: # push everything, # use the fast path, no race possible on push - bundler = changegroup.bundle10(bundlecaps) - cg = self._changegroup(outgoing.missing, bundler, - 'push') + bundler = changegroup.bundle10(bundlecaps, self) + cg = self._changegroupsubset(outgoing.common, + outgoing.missing, + outgoing.missingheads, + bundler, + 'push', + fastpath=True) else: cg = self.getlocalbundle('push', outgoing, bundlecaps) @@ -2023,10 +2027,10 @@ bundlecaps=bundlecaps) @unfilteredmethod - def _changegroupsubset(self, commonrevs, csets, heads, bundler, source): - - cl = self.changelog - mf = self.manifest + def _changegroupsubset(self, commonrevs, csets, heads, bundler, source, + fastpath=False): + cl = bundler._changelog + mf = bundler._manifest mfs = {} # needed manifests fnodes = {} # needed file nodes changedfiles = set() @@ -2035,10 +2039,8 @@ # can we go through the fast path ? heads.sort() - if heads == sorted(self.heads()): - return self._changegroup(csets, bundler, source) + fastpathlinkrev = fastpath or heads == sorted(self.heads()) - # slow path self.hook('preoutgoing', throw=True, source=source) self.changegroupinfo(csets, source) @@ -2065,10 +2067,11 @@ return x elif revlog == mf: clnode = mfs[x] - mdata = mf.readfast(x) - for f, n in mdata.iteritems(): - if f in changedfiles: - fnodes[f].setdefault(n, clnode) + if not fastpathlinkrev: + mdata = mf.readfast(x) + for f, n in mdata.iteritems(): + if f in changedfiles: + fnodes[f].setdefault(n, clnode) count[0] += 1 progress(_bundling, count[0], unit=_manifests, total=count[1]) @@ -2103,6 +2106,19 @@ progress(_bundling, None) mfs.clear() + return changedfiles + def getfilenodes(fname, filerevlog): + if fastpathlinkrev: + ln, llr = filerevlog.node, filerevlog.linkrev + def genfilenodes(): + for r in filerevlog: + linkrev = llr(r) + if linkrev not in commonrevs: + yield filerevlog.node(r), cl.node(linkrev) + fnodes[fname] = dict(genfilenodes()) + fstate[0] = fname + fstate[1] = fnodes.pop(fname, {}) + return prune(filerevlog, fstate[1]) # Go through all our files in order sorted by name. count[:] = [0, len(changedfiles)] @@ -2135,100 +2151,6 @@ return self.changegroupsubset(basenodes, self.heads(), source) @unfilteredmethod - def _changegroup(self, nodes, bundler, source): - """Compute the changegroup of all nodes that we have that a recipient - doesn't. Return a chunkbuffer object whose read() method will return - successive changegroup chunks. - - This is much easier than the previous function as we can assume that - the recipient has any changenode we aren't sending them. - - nodes is the set of nodes to send""" - - cl = self.changelog - mf = self.manifest - mfs = {} - changedfiles = set() - fstate = [''] - count = [0, 0] - - self.hook('preoutgoing', throw=True, source=source) - self.changegroupinfo(nodes, source) - - revset = set([cl.rev(n) for n in nodes]) - - def gennodelst(log): - ln, llr = log.node, log.linkrev - return [ln(r) for r in log if llr(r) in revset] - - progress = self.ui.progress - _bundling = _('bundling') - _changesets = _('changesets') - _manifests = _('manifests') - _files = _('files') - - def lookup(revlog, x): - if revlog == cl: - c = cl.read(x) - changedfiles.update(c[3]) - mfs.setdefault(c[0], x) - count[0] += 1 - progress(_bundling, count[0], - unit=_changesets, total=count[1]) - return x - elif revlog == mf: - count[0] += 1 - progress(_bundling, count[0], - unit=_manifests, total=count[1]) - return cl.node(revlog.linkrev(revlog.rev(x))) - else: - progress(_bundling, count[0], item=fstate[0], - total=count[1], unit=_files) - return cl.node(revlog.linkrev(revlog.rev(x))) - - bundler.start(lookup) - reorder = self.ui.config('bundle', 'reorder', 'auto') - if reorder == 'auto': - reorder = None - else: - reorder = util.parsebool(reorder) - - def gengroup(): - '''yield a sequence of changegroup chunks (strings)''' - # construct a list of all changed files - - count[:] = [0, len(nodes)] - for chunk in bundler.group(nodes, cl, reorder=reorder): - yield chunk - progress(_bundling, None) - - count[:] = [0, len(mfs)] - for chunk in bundler.group(gennodelst(mf), mf, reorder=reorder): - yield chunk - progress(_bundling, None) - - count[:] = [0, len(changedfiles)] - for fname in sorted(changedfiles): - filerevlog = self.file(fname) - if not len(filerevlog): - raise util.Abort(_("empty or missing revlog for %s") - % fname) - fstate[0] = fname - nodelist = gennodelst(filerevlog) - if nodelist: - count[0] += 1 - yield bundler.fileheader(fname) - for chunk in bundler.group(nodelist, filerevlog, reorder): - yield chunk - yield bundler.close() - progress(_bundling, None) - - if nodes: - self.hook('outgoing', node=hex(nodes[0]), source=source) - - return changegroup.unbundle10(util.chunkbuffer(gengroup()), 'UN') - - @unfilteredmethod def addchangegroup(self, source, srctype, url, emptyok=False): """Add the changegroup returned by source.read() to this repo. srctype is a string like 'push', 'pull', or 'unbundle'. url is From cryo at cyanite.org Thu Feb 14 13:40:18 2013 From: cryo at cyanite.org (Sune Foldager) Date: Thu, 14 Feb 2013 20:40:18 +0100 Subject: [PATCH 8 of 9] bundle-ng: simplify lookup and state handling In-Reply-To: References: Message-ID: # HG changeset patch # User Benoit Boissinot # Date 1360511730 -3600 # Node ID b667e61d5bfba9ca82e92be3af855da55b856c7a # Parent d71c702c2b38307f63394cf9625ac530a7611112 bundle-ng: simplify lookup and state handling diff -r d71c702c2b38 -r b667e61d5bfb mercurial/changegroup.py --- a/mercurial/changegroup.py Sun Feb 10 16:23:10 2013 +0100 +++ b/mercurial/changegroup.py Sun Feb 10 16:55:30 2013 +0100 @@ -242,14 +242,13 @@ reorder = False self._repo = repo self._reorder = reorder - self.count = [0, 0] def close(self): return closechunk() def fileheader(self, fname): return chunkheader(len(fname)) + fname - def group(self, nodelist, revlog, reorder=None): + def group(self, nodelist, revlog, lookup, reorder=None): """Calculate a delta group, yielding a sequence of changegroup chunks (strings). @@ -282,7 +281,8 @@ # build deltas for r in xrange(len(revs) - 1): prev, curr = revs[r], revs[r + 1] - for c in self.revchunk(revlog, curr, prev): + linknode = lookup(revlog.node(curr)) + for c in self.revchunk(revlog, curr, prev, linknode): yield c yield self.close() @@ -294,7 +294,7 @@ mf = self._manifest reorder = self._reorder progress = repo.ui.progress - count = self.count + count = [0, 0] _bundling = _('bundling') _changesets = _('changesets') _manifests = _('manifests') @@ -303,7 +303,6 @@ mfs = {} # needed manifests fnodes = {} # needed file nodes changedfiles = set() - fstate = ['', {}] # filter any nodes that claim to be part of the known set def prune(revlog, missing): @@ -311,35 +310,29 @@ return [n for n in missing if rl(rr(n)) not in commonrevs] - def lookup(revlog, x): - if revlog == cl: - c = cl.read(x) - changedfiles.update(c[3]) - mfs.setdefault(c[0], x) - count[0] += 1 - progress(_bundling, count[0], - unit=_changesets, total=count[1]) - return x - elif revlog == mf: - clnode = mfs[x] - if not fastpathlinkrev: - mdata = mf.readfast(x) - for f, n in mdata.iteritems(): - if f in changedfiles: - fnodes[f].setdefault(n, clnode) - count[0] += 1 - progress(_bundling, count[0], - unit=_manifests, total=count[1]) - return clnode - else: - progress(_bundling, count[0], item=fstate[0], - unit=_files, total=count[1]) - return fstate[1][x] + def lookupcl(x): + c = cl.read(x) + changedfiles.update(c[3]) + mfs.setdefault(c[0], x) + count[0] += 1 + progress(_bundling, count[0], + unit=_changesets, total=count[1]) + return x - self._lookup = lookup + def lookupmf(x): + clnode = mfs[x] + if not fastpathlinkrev: + mdata = mf.readfast(x) + for f, n in mdata.iteritems(): + if f in changedfiles: + fnodes[f].setdefault(n, clnode) + count[0] += 1 + progress(_bundling, count[0], + unit=_manifests, total=count[1]) + return clnode count[:] = [0, len(clnodes)] - for chunk in self.group(clnodes, cl, reorder=reorder): + for chunk in self.group(clnodes, cl, lookupcl, reorder=reorder): yield chunk progress(_bundling, None) @@ -347,7 +340,7 @@ fnodes[f] = {} count[:] = [0, len(mfs)] mfnodes = prune(mf, mfs) - for chunk in self.group(mfnodes, mf, reorder=reorder): + for chunk in self.group(mfnodes, mf, lookupmf, reorder=reorder): yield chunk progress(_bundling, None) @@ -367,13 +360,20 @@ if linkrev not in commonrevs: yield filerevlog.node(r), cl.node(linkrev) fnodes[fname] = dict(genfilenodes()) - fstate[0] = fname - fstate[1] = fnodes.pop(fname, {}) - filenodes = prune(filerevlog, fstate[1]) + + linkrevnodes = fnodes.pop(fname, {}) + # Lookup for filenodes. + def lookupfilelog(x): + progress(_bundling, count[0], item=fname, + unit=_files, total=count[1]) + return linkrevnodes[x] + + filenodes = prune(filerevlog, linkrevnodes) if filenodes: count[0] += 1 yield self.fileheader(fname) - for chunk in self.group(filenodes, filerevlog, reorder): + for chunk in self.group(filenodes, filerevlog, lookupfilelog, + reorder): yield chunk yield self.close() progress(_bundling, None) @@ -381,7 +381,7 @@ if clnodes: repo.hook('outgoing', node=hex(clnodes[0]), source=source) - def revchunk(self, revlog, rev, prev): + def revchunk(self, revlog, rev, prev, linknode): node = revlog.node(rev) p1, p2 = revlog.parentrevs(rev) base = prev @@ -392,7 +392,6 @@ prefix = mdiff.trivialdiffheader(len(delta)) else: delta = revlog.revdiff(base, rev) - linknode = self._lookup(revlog, node) p1n, p2n = revlog.parents(node) basenode = revlog.node(base) meta = self.builddeltaheader(node, p1n, p2n, basenode, linknode) From cryo at cyanite.org Thu Feb 14 13:40:12 2013 From: cryo at cyanite.org (Sune Foldager) Date: Thu, 14 Feb 2013 20:40:12 +0100 Subject: [PATCH 2 of 9] bundle-ng: move group into the bundler In-Reply-To: References: Message-ID: <66e25980c10d10b00b65.1360870812@firefly.edlund.dk> # HG changeset patch # User Sune Foldager # Date 1360432114 -3600 # Node ID 66e25980c10d10b00b658608472b251b2d3ee4fe # Parent d78029a5c1f72e2eb75321409ad969462b7d372f bundle-ng: move group into the bundler diff -r d78029a5c1f7 -r 66e25980c10d contrib/shrink-revlog.py --- a/contrib/shrink-revlog.py Sat Feb 09 18:52:22 2013 +0100 +++ b/contrib/shrink-revlog.py Sat Feb 09 18:48:34 2013 +0100 @@ -119,7 +119,7 @@ try: bundler = changegroup.bundle10() bundler.start(lookup) - group = util.chunkbuffer(r1.group(order, bundler)) + group = util.chunkbuffer(bundler.group(order, r1)) group = changegroup.unbundle10(group, "UN") r2.addgroup(group, unlookup, tr) finally: diff -r d78029a5c1f7 -r 66e25980c10d mercurial/changegroup.py --- a/mercurial/changegroup.py Sat Feb 09 18:52:22 2013 +0100 +++ b/mercurial/changegroup.py Sat Feb 09 18:48:34 2013 +0100 @@ -7,7 +7,7 @@ from i18n import _ from node import nullrev -import mdiff, util +import mdiff, util, dagutil import struct, os, bz2, zlib, tempfile _BUNDLE10_DELTA_HEADER = "20s20s20s20s" @@ -231,8 +231,49 @@ self._lookup = lookup def close(self): return closechunk() + def fileheader(self, fname): return chunkheader(len(fname)) + fname + + def group(self, nodelist, revlog, reorder=None): + """Calculate a delta group, yielding a sequence of changegroup chunks + (strings). + + Given a list of changeset revs, return a set of deltas and + metadata corresponding to nodes. The first delta is + first parent(nodelist[0]) -> nodelist[0], the receiver is + guaranteed to have this parent as it has all history before + these changesets. In the case firstparent is nullrev the + changegroup starts with a full revision. + """ + + # if we don't have any revisions touched by these changesets, bail + if len(nodelist) == 0: + yield self.close() + return + + # for generaldelta revlogs, we linearize the revs; this will both be + # much quicker and generate a much smaller bundle + if (revlog._generaldelta and reorder is not False) or reorder: + dag = dagutil.revlogdag(revlog) + revs = set(revlog.rev(n) for n in nodelist) + revs = dag.linearize(revs) + else: + revs = sorted([revlog.rev(n) for n in nodelist]) + + # add the parent of the first rev + p = revlog.parentrevs(revs[0])[0] + revs.insert(0, p) + + # build deltas + for r in xrange(len(revs) - 1): + prev, curr = revs[r], revs[r + 1] + for c in self.revchunk(revlog, curr, prev): + yield c + + yield self.close() + + def revchunk(self, revlog, rev, prev): node = revlog.node(rev) p1, p2 = revlog.parentrevs(rev) diff -r d78029a5c1f7 -r 66e25980c10d mercurial/localrepo.py --- a/mercurial/localrepo.py Sat Feb 09 18:52:22 2013 +0100 +++ b/mercurial/localrepo.py Sat Feb 09 18:48:34 2013 +0100 @@ -2084,7 +2084,7 @@ # Create a changenode group generator that will call our functions # back to lookup the owning changenode and collect information. count[:] = [0, len(csets)] - for chunk in cl.group(csets, bundler, reorder=reorder): + for chunk in bundler.group(csets, cl, reorder=reorder): yield chunk progress(_bundling, None) @@ -2093,7 +2093,7 @@ for f in changedfiles: fnodes[f] = {} count[:] = [0, len(mfs)] - for chunk in mf.group(prune(mf, mfs), bundler, reorder=reorder): + for chunk in bundler.group(prune(mf, mfs), mf, reorder=reorder): yield chunk progress(_bundling, None) @@ -2113,7 +2113,7 @@ if nodelist: count[0] += 1 yield bundler.fileheader(fname) - for chunk in filerevlog.group(nodelist, bundler, reorder): + for chunk in bundler.group(nodelist, filerevlog, reorder): yield chunk # Signal that no more groups are left. @@ -2193,12 +2193,12 @@ # construct a list of all changed files count[:] = [0, len(nodes)] - for chunk in cl.group(nodes, bundler, reorder=reorder): + for chunk in bundler.group(nodes, cl, reorder=reorder): yield chunk progress(_bundling, None) count[:] = [0, len(mfs)] - for chunk in mf.group(gennodelst(mf), bundler, reorder=reorder): + for chunk in bundler.group(gennodelst(mf), mf, reorder=reorder): yield chunk progress(_bundling, None) @@ -2213,7 +2213,7 @@ if nodelist: count[0] += 1 yield bundler.fileheader(fname) - for chunk in filerevlog.group(nodelist, bundler, reorder): + for chunk in bundler.group(nodelist, filerevlog, reorder): yield chunk yield bundler.close() progress(_bundling, None) diff -r d78029a5c1f7 -r 66e25980c10d mercurial/revlog.py --- a/mercurial/revlog.py Sat Feb 09 18:52:22 2013 +0100 +++ b/mercurial/revlog.py Sat Feb 09 18:48:34 2013 +0100 @@ -14,7 +14,7 @@ # import stuff from node for others to import from revlog from node import bin, hex, nullid, nullrev from i18n import _ -import ancestor, mdiff, parsers, error, util, dagutil +import ancestor, mdiff, parsers, error, util import struct, zlib, errno _pack = struct.pack @@ -1148,44 +1148,6 @@ self._basecache = (curr, chainbase) return node - def group(self, nodelist, bundler, reorder=None): - """Calculate a delta group, yielding a sequence of changegroup chunks - (strings). - - Given a list of changeset revs, return a set of deltas and - metadata corresponding to nodes. The first delta is - first parent(nodelist[0]) -> nodelist[0], the receiver is - guaranteed to have this parent as it has all history before - these changesets. In the case firstparent is nullrev the - changegroup starts with a full revision. - """ - - # if we don't have any revisions touched by these changesets, bail - if len(nodelist) == 0: - yield bundler.close() - return - - # for generaldelta revlogs, we linearize the revs; this will both be - # much quicker and generate a much smaller bundle - if (self._generaldelta and reorder is not False) or reorder: - dag = dagutil.revlogdag(self) - revs = set(self.rev(n) for n in nodelist) - revs = dag.linearize(revs) - else: - revs = sorted([self.rev(n) for n in nodelist]) - - # add the parent of the first rev - p = self.parentrevs(revs[0])[0] - revs.insert(0, p) - - # build deltas - for r in xrange(len(revs) - 1): - prev, curr = revs[r], revs[r + 1] - for c in bundler.revchunk(self, curr, prev): - yield c - - yield bundler.close() - def addgroup(self, bundle, linkmapper, transaction): """ add a delta group From cryo at cyanite.org Thu Feb 14 13:40:17 2013 From: cryo at cyanite.org (Sune Foldager) Date: Thu, 14 Feb 2013 20:40:17 +0100 Subject: [PATCH 7 of 9] bundle-ng: simplify bundle10.generate a bit In-Reply-To: References: Message-ID: # HG changeset patch # User Sune Foldager # Date 1360509790 -3600 # Node ID d71c702c2b38307f63394cf9625ac530a7611112 # Parent 5a481bafae2d4e3ae66b161b509cc7bb51a0560f bundle-ng: simplify bundle10.generate a bit diff -r 5a481bafae2d -r d71c702c2b38 contrib/shrink-revlog.py --- a/contrib/shrink-revlog.py Sun Feb 10 16:03:20 2013 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,295 +0,0 @@ -"""reorder a revlog (the manifest by default) to save space - -Specifically, this topologically sorts the revisions in the revlog so that -revisions on the same branch are adjacent as much as possible. This is a -workaround for the fact that Mercurial computes deltas relative to the -previous revision rather than relative to a parent revision. - -This is *not* safe to run on a changelog. -""" - -# Originally written by Benoit Boissinot -# as a patch to rewrite-log. Cleaned up, refactored, documented, and -# renamed by Greg Ward . - -# XXX would be nice to have a way to verify the repository after shrinking, -# e.g. by comparing "before" and "after" states of random changesets -# (maybe: export before, shrink, export after, diff). - -import os, errno -from mercurial import revlog, transaction, node, util, scmutil -from mercurial import changegroup -from mercurial.i18n import _ - - -def postorder(start, edges): - result = [] - visit = list(start) - finished = set() - - while visit: - cur = visit[-1] - for p in edges[cur]: - # defend against node.nullrev because it's occasionally - # possible for a node to have parents (null, something) - # rather than (something, null) - if p not in finished and p != node.nullrev: - visit.append(p) - break - else: - result.append(cur) - finished.add(cur) - visit.pop() - - return result - -def toposort_reversepostorder(ui, rl): - # postorder of the reverse directed graph - - # map rev to list of parent revs (p2 first) - parents = {} - heads = set() - ui.status(_('reading revs\n')) - try: - for rev in rl: - ui.progress(_('reading'), rev, total=len(rl)) - (p1, p2) = rl.parentrevs(rev) - if p1 == p2 == node.nullrev: - parents[rev] = () # root node - elif p1 == p2 or p2 == node.nullrev: - parents[rev] = (p1,) # normal node - else: - parents[rev] = (p2, p1) # merge node - heads.add(rev) - for p in parents[rev]: - heads.discard(p) - finally: - ui.progress(_('reading'), None) - - heads = list(heads) - heads.sort(reverse=True) - - ui.status(_('sorting revs\n')) - return postorder(heads, parents) - -def toposort_postorderreverse(ui, rl): - # reverse-postorder of the reverse directed graph - - children = {} - roots = set() - ui.status(_('reading revs\n')) - try: - for rev in rl: - ui.progress(_('reading'), rev, total=len(rl)) - (p1, p2) = rl.parentrevs(rev) - if p1 == p2 == node.nullrev: - roots.add(rev) - children[rev] = [] - if p1 != node.nullrev: - children[p1].append(rev) - if p2 != node.nullrev: - children[p2].append(rev) - finally: - ui.progress(_('reading'), None) - - roots = list(roots) - roots.sort() - - ui.status(_('sorting revs\n')) - result = postorder(roots, children) - result.reverse() - return result - -def writerevs(ui, r1, r2, order, tr): - - ui.status(_('writing revs\n')) - - - order = [r1.node(r) for r in order] - - # this is a bit ugly, but it works - count = [0] - def lookup(revl, x): - count[0] += 1 - ui.progress(_('writing'), count[0], total=len(order)) - return "%020d" % revl.linkrev(revl.rev(x)) - - unlookup = lambda x: int(x, 10) - - try: - bundler = changegroup.bundle10() - bundler.start(lookup) - group = util.chunkbuffer(bundler.group(order, r1)) - group = changegroup.unbundle10(group, "UN") - r2.addgroup(group, unlookup, tr) - finally: - ui.progress(_('writing'), None) - -def report(ui, r1, r2): - def getsize(r): - s = 0 - for fn in (r.indexfile, r.datafile): - try: - s += os.stat(fn).st_size - except OSError, inst: - if inst.errno != errno.ENOENT: - raise - return s - - oldsize = float(getsize(r1)) - newsize = float(getsize(r2)) - - # argh: have to pass an int to %d, because a float >= 2^32 - # blows up under Python 2.5 or earlier - ui.write(_('old file size: %12d bytes (%6.1f MiB)\n') - % (int(oldsize), oldsize / 1024 / 1024)) - ui.write(_('new file size: %12d bytes (%6.1f MiB)\n') - % (int(newsize), newsize / 1024 / 1024)) - - shrink_percent = (oldsize - newsize) / oldsize * 100 - shrink_factor = oldsize / newsize - ui.write(_('shrinkage: %.1f%% (%.1fx)\n') - % (shrink_percent, shrink_factor)) - -def shrink(ui, repo, **opts): - """shrink a revlog by reordering revisions - - Rewrites all the entries in some revlog of the current repository - (by default, the manifest log) to save space. - - Different sort algorithms have different performance - characteristics. Use ``--sort`` to select a sort algorithm so you - can determine which works best for your data. - """ - - if not repo.local(): - raise util.Abort(_('not a local repository: %s') % repo.root) - - fn = opts.get('revlog') - if not fn: - indexfn = repo.sjoin('00manifest.i') - else: - if not fn.endswith('.i'): - raise util.Abort(_('--revlog option must specify the revlog index ' - 'file (*.i), not %s') % opts.get('revlog')) - - indexfn = os.path.realpath(fn) - store = repo.sjoin('') - if not indexfn.startswith(store): - raise util.Abort(_('--revlog option must specify a revlog in %s, ' - 'not %s') % (store, indexfn)) - - sortname = opts['sort'] - try: - toposort = globals()['toposort_' + sortname] - except KeyError: - raise util.Abort(_('no such toposort algorithm: %s') % sortname) - - if not os.path.exists(indexfn): - raise util.Abort(_('no such file: %s') % indexfn) - if '00changelog' in indexfn: - raise util.Abort(_('shrinking the changelog ' - 'will corrupt your repository')) - - ui.write(_('shrinking %s\n') % indexfn) - tmpindexfn = util.mktempcopy(indexfn, emptyok=True) - - r1 = revlog.revlog(scmutil.opener(os.getcwd(), audit=False), indexfn) - r2 = revlog.revlog(scmutil.opener(os.getcwd(), audit=False), tmpindexfn) - - datafn, tmpdatafn = r1.datafile, r2.datafile - - oldindexfn = indexfn + '.old' - olddatafn = datafn + '.old' - if os.path.exists(oldindexfn) or os.path.exists(olddatafn): - raise util.Abort(_('one or both of\n' - ' %s\n' - ' %s\n' - 'exists from a previous run; please clean up ' - 'before running again') % (oldindexfn, olddatafn)) - - # Don't use repo.transaction(), because then things get hairy with - # paths: some need to be relative to .hg, and some need to be - # absolute. Doing it this way keeps things simple: everything is an - # absolute path. - lock = repo.lock(wait=False) - tr = transaction.transaction(ui.warn, - open, - repo.sjoin('journal')) - - def ignoremissing(func): - def f(*args, **kw): - try: - return func(*args, **kw) - except OSError, inst: - if inst.errno != errno.ENOENT: - raise - return f - - try: - try: - order = toposort(ui, r1) - - suboptimal = 0 - for i in xrange(1, len(order)): - parents = [p for p in r1.parentrevs(order[i]) - if p != node.nullrev] - if parents and order[i - 1] not in parents: - suboptimal += 1 - ui.note(_('%d suboptimal nodes\n') % suboptimal) - - writerevs(ui, r1, r2, order, tr) - report(ui, r1, r2) - tr.close() - except: # re-raises - # Abort transaction first, so we truncate the files before - # deleting them. - tr.abort() - for fn in (tmpindexfn, tmpdatafn): - ignoremissing(os.unlink)(fn) - raise - if not opts.get('dry_run'): - # racy, both files cannot be renamed atomically - # copy files - util.oslink(indexfn, oldindexfn) - ignoremissing(util.oslink)(datafn, olddatafn) - - # rename - util.rename(tmpindexfn, indexfn) - try: - os.chmod(tmpdatafn, os.stat(datafn).st_mode) - util.rename(tmpdatafn, datafn) - except OSError, inst: - if inst.errno != errno.ENOENT: - raise - ignoremissing(os.unlink)(datafn) - else: - for fn in (tmpindexfn, tmpdatafn): - ignoremissing(os.unlink)(fn) - finally: - lock.release() - - if not opts.get('dry_run'): - ui.write( - _('note: old revlog saved in:\n' - ' %s\n' - ' %s\n' - '(You can delete those files when you are satisfied that your\n' - 'repository is still sane. ' - 'Running \'hg verify\' is strongly recommended.)\n') - % (oldindexfn, olddatafn)) - -cmdtable = { - 'shrink': (shrink, - [('', 'revlog', '', - _('the revlog to shrink (.i)')), - ('n', 'dry-run', None, - _('do not shrink, simulate only')), - ('', 'sort', 'reversepostorder', - _('name of sort algorithm to use')), - ], - _('hg shrink [--revlog PATH]')) -} - -if __name__ == "__main__": - print "shrink-revlog.py is now an extension (see hg help extensions)" diff -r 5a481bafae2d -r d71c702c2b38 mercurial/changegroup.py --- a/mercurial/changegroup.py Sun Feb 10 16:03:20 2013 +0100 +++ b/mercurial/changegroup.py Sun Feb 10 16:23:10 2013 +0100 @@ -243,8 +243,6 @@ self._repo = repo self._reorder = reorder self.count = [0, 0] - def start(self, lookup): - self._lookup = lookup def close(self): return closechunk() @@ -338,17 +336,29 @@ unit=_files, total=count[1]) return fstate[1][x] - self.start(lookup) + self._lookup = lookup - def getmfnodes(): - for f in changedfiles: - fnodes[f] = {} - count[:] = [0, len(mfs)] - return prune(mf, mfs) - def getfiles(): - mfs.clear() - return changedfiles - def getfilenodes(fname, filerevlog): + count[:] = [0, len(clnodes)] + for chunk in self.group(clnodes, cl, reorder=reorder): + yield chunk + progress(_bundling, None) + + for f in changedfiles: + fnodes[f] = {} + count[:] = [0, len(mfs)] + mfnodes = prune(mf, mfs) + for chunk in self.group(mfnodes, mf, reorder=reorder): + yield chunk + progress(_bundling, None) + + mfs.clear() + count[:] = [0, len(changedfiles)] + for fname in sorted(changedfiles): + filerevlog = repo.file(fname) + if not len(filerevlog): + raise util.Abort(_("empty or missing revlog for %s") + % fname) + if fastpathlinkrev: ln, llr = filerevlog.node, filerevlog.linkrev def genfilenodes(): @@ -359,30 +369,11 @@ fnodes[fname] = dict(genfilenodes()) fstate[0] = fname fstate[1] = fnodes.pop(fname, {}) - return prune(filerevlog, fstate[1]) - - - count[:] = [0, len(clnodes)] - for chunk in self.group(clnodes, cl, reorder=reorder): - yield chunk - progress(_bundling, None) - - for chunk in self.group(getmfnodes(), mf, reorder=reorder): - yield chunk - progress(_bundling, None) - - changedfiles = getfiles() - count[:] = [0, len(changedfiles)] - for fname in sorted(changedfiles): - filerevlog = repo.file(fname) - if not len(filerevlog): - raise util.Abort(_("empty or missing revlog for %s") - % fname) - nodelist = getfilenodes(fname, filerevlog) - if nodelist: + filenodes = prune(filerevlog, fstate[1]) + if filenodes: count[0] += 1 yield self.fileheader(fname) - for chunk in self.group(nodelist, filerevlog, reorder): + for chunk in self.group(filenodes, filerevlog, reorder): yield chunk yield self.close() progress(_bundling, None) diff -r 5a481bafae2d -r d71c702c2b38 tests/test-contrib.t --- a/tests/test-contrib.t Sun Feb 10 16:03:20 2013 +0100 +++ b/tests/test-contrib.t Sun Feb 10 16:23:10 2013 +0100 @@ -103,34 +103,6 @@ no changes found [1] - -#if hardlink - -Test shrink-revlog: - $ cd repo-a - $ hg --config extensions.shrink="$CONTRIBDIR/shrink-revlog.py" shrink - shrinking $TESTTMP/repo-a/.hg/store/00manifest.i (glob) - reading revs - sorting revs - writing revs - old file size: 324 bytes ( 0.0 MiB) - new file size: 324 bytes ( 0.0 MiB) - shrinkage: 0.0% (1.0x) - note: old revlog saved in: - $TESTTMP/repo-a/.hg/store/00manifest.i.old (glob) - $TESTTMP/repo-a/.hg/store/00manifest.d.old (glob) - (You can delete those files when you are satisfied that your - repository is still sane. Running 'hg verify' is strongly recommended.) - $ hg verify - checking changesets - checking manifests - crosschecking files in changesets and manifests - checking files - 1 files, 3 changesets, 3 total revisions - $ cd .. - -#endif - Test simplemerge command: $ cp "$CONTRIBDIR/simplemerge" . From cryo at cyanite.org Thu Feb 14 13:40:16 2013 From: cryo at cyanite.org (Sune Foldager) Date: Thu, 14 Feb 2013 20:40:16 +0100 Subject: [PATCH 6 of 9] bundle-ng: move bundle generation to changegroup.py In-Reply-To: References: Message-ID: <5a481bafae2d4e3ae66b.1360870816@firefly.edlund.dk> # HG changeset patch # User Benoit Boissinot # Date 1360508600 -3600 # Node ID 5a481bafae2d4e3ae66b161b509cc7bb51a0560f # Parent 3821b9f543fbeabc29a2c34b3f78272837364586 bundle-ng: move bundle generation to changegroup.py diff -r 3821b9f543fb -r 5a481bafae2d mercurial/changegroup.py --- a/mercurial/changegroup.py Sun Feb 10 15:47:23 2013 +0100 +++ b/mercurial/changegroup.py Sun Feb 10 16:03:20 2013 +0100 @@ -289,7 +289,7 @@ yield self.close() - def generate(self, clnodes, getmfnodes, getfiles, getfilenodes, source): + def generate(self, commonrevs, clnodes, fastpathlinkrev, source): '''yield a sequence of changegroup chunks (strings)''' repo = self._repo cl = self._changelog @@ -298,6 +298,69 @@ progress = repo.ui.progress count = self.count _bundling = _('bundling') + _changesets = _('changesets') + _manifests = _('manifests') + _files = _('files') + + mfs = {} # needed manifests + fnodes = {} # needed file nodes + changedfiles = set() + fstate = ['', {}] + + # filter any nodes that claim to be part of the known set + def prune(revlog, missing): + rr, rl = revlog.rev, revlog.linkrev + return [n for n in missing + if rl(rr(n)) not in commonrevs] + + def lookup(revlog, x): + if revlog == cl: + c = cl.read(x) + changedfiles.update(c[3]) + mfs.setdefault(c[0], x) + count[0] += 1 + progress(_bundling, count[0], + unit=_changesets, total=count[1]) + return x + elif revlog == mf: + clnode = mfs[x] + if not fastpathlinkrev: + mdata = mf.readfast(x) + for f, n in mdata.iteritems(): + if f in changedfiles: + fnodes[f].setdefault(n, clnode) + count[0] += 1 + progress(_bundling, count[0], + unit=_manifests, total=count[1]) + return clnode + else: + progress(_bundling, count[0], item=fstate[0], + unit=_files, total=count[1]) + return fstate[1][x] + + self.start(lookup) + + def getmfnodes(): + for f in changedfiles: + fnodes[f] = {} + count[:] = [0, len(mfs)] + return prune(mf, mfs) + def getfiles(): + mfs.clear() + return changedfiles + def getfilenodes(fname, filerevlog): + if fastpathlinkrev: + ln, llr = filerevlog.node, filerevlog.linkrev + def genfilenodes(): + for r in filerevlog: + linkrev = llr(r) + if linkrev not in commonrevs: + yield filerevlog.node(r), cl.node(linkrev) + fnodes[fname] = dict(genfilenodes()) + fstate[0] = fname + fstate[1] = fnodes.pop(fname, {}) + return prune(filerevlog, fstate[1]) + count[:] = [0, len(clnodes)] for chunk in self.group(clnodes, cl, reorder=reorder): diff -r 3821b9f543fb -r 5a481bafae2d mercurial/localrepo.py --- a/mercurial/localrepo.py Sun Feb 10 15:47:23 2013 +0100 +++ b/mercurial/localrepo.py Sun Feb 10 16:03:20 2013 +0100 @@ -2029,122 +2029,14 @@ @unfilteredmethod def _changegroupsubset(self, commonrevs, csets, heads, bundler, source, fastpath=False): - cl = bundler._changelog - mf = bundler._manifest - mfs = {} # needed manifests - fnodes = {} # needed file nodes - changedfiles = set() - fstate = ['', {}] - count = [0, 0] - # can we go through the fast path ? heads.sort() fastpathlinkrev = fastpath or heads == sorted(self.heads()) self.hook('preoutgoing', throw=True, source=source) self.changegroupinfo(csets, source) - - # filter any nodes that claim to be part of the known set - def prune(revlog, missing): - rr, rl = revlog.rev, revlog.linkrev - return [n for n in missing - if rl(rr(n)) not in commonrevs] - - progress = self.ui.progress - _bundling = _('bundling') - _changesets = _('changesets') - _manifests = _('manifests') - _files = _('files') - - def lookup(revlog, x): - if revlog == cl: - c = cl.read(x) - changedfiles.update(c[3]) - mfs.setdefault(c[0], x) - count[0] += 1 - progress(_bundling, count[0], - unit=_changesets, total=count[1]) - return x - elif revlog == mf: - clnode = mfs[x] - if not fastpathlinkrev: - mdata = mf.readfast(x) - for f, n in mdata.iteritems(): - if f in changedfiles: - fnodes[f].setdefault(n, clnode) - count[0] += 1 - progress(_bundling, count[0], - unit=_manifests, total=count[1]) - return clnode - else: - progress(_bundling, count[0], item=fstate[0], - unit=_files, total=count[1]) - return fstate[1][x] - - bundler.start(lookup) - reorder = self.ui.config('bundle', 'reorder', 'auto') - if reorder == 'auto': - reorder = None - else: - reorder = util.parsebool(reorder) - - def gengroup(): - # Create a changenode group generator that will call our functions - # back to lookup the owning changenode and collect information. - count[:] = [0, len(csets)] - for chunk in bundler.group(csets, cl, reorder=reorder): - yield chunk - progress(_bundling, None) - - # Create a generator for the manifestnodes that calls our lookup - # and data collection functions back. - for f in changedfiles: - fnodes[f] = {} - count[:] = [0, len(mfs)] - for chunk in bundler.group(prune(mf, mfs), mf, reorder=reorder): - yield chunk - progress(_bundling, None) - - mfs.clear() - return changedfiles - def getfilenodes(fname, filerevlog): - if fastpathlinkrev: - ln, llr = filerevlog.node, filerevlog.linkrev - def genfilenodes(): - for r in filerevlog: - linkrev = llr(r) - if linkrev not in commonrevs: - yield filerevlog.node(r), cl.node(linkrev) - fnodes[fname] = dict(genfilenodes()) - fstate[0] = fname - fstate[1] = fnodes.pop(fname, {}) - return prune(filerevlog, fstate[1]) - - # Go through all our files in order sorted by name. - count[:] = [0, len(changedfiles)] - for fname in sorted(changedfiles): - filerevlog = self.file(fname) - if not len(filerevlog): - raise util.Abort(_("empty or missing revlog for %s") - % fname) - fstate[0] = fname - fstate[1] = fnodes.pop(fname, {}) - - nodelist = prune(filerevlog, fstate[1]) - if nodelist: - count[0] += 1 - yield bundler.fileheader(fname) - for chunk in bundler.group(nodelist, filerevlog, reorder): - yield chunk - - # Signal that no more groups are left. - yield bundler.close() - progress(_bundling, None) - - if csets: - self.hook('outgoing', node=hex(csets[0]), source=source) - - return changegroup.unbundle10(util.chunkbuffer(gengroup()), 'UN') + gengroup = bundler.generate(commonrevs, csets, fastpathlinkrev, source) + return changegroup.unbundle10(util.chunkbuffer(gengroup), 'UN') def changegroup(self, basenodes, source): # to avoid a race we use changegroupsubset() (issue1320) From cryo at cyanite.org Thu Feb 14 13:40:19 2013 From: cryo at cyanite.org (Sune Foldager) Date: Thu, 14 Feb 2013 20:40:19 +0100 Subject: [PATCH 9 of 9] bundle-ng: move progress out of the linkrev callback In-Reply-To: References: Message-ID: # HG changeset patch # User Benoit Boissinot # Date 1360592532 -3600 # Node ID f91e6ea657eb37840f2fdd1414c89d963c7b20d4 # Parent b667e61d5bfba9ca82e92be3af855da55b856c7a bundle-ng: move progress out of the linkrev callback diff -r b667e61d5bfb -r f91e6ea657eb mercurial/changegroup.py --- a/mercurial/changegroup.py Sun Feb 10 16:55:30 2013 +0100 +++ b/mercurial/changegroup.py Mon Feb 11 15:22:12 2013 +0100 @@ -242,13 +242,14 @@ reorder = False self._repo = repo self._reorder = reorder + self._progress = repo.ui.progress def close(self): return closechunk() def fileheader(self, fname): return chunkheader(len(fname)) + fname - def group(self, nodelist, revlog, lookup, reorder=None): + def group(self, nodelist, revlog, lookup, units=None, reorder=None): """Calculate a delta group, yielding a sequence of changegroup chunks (strings). @@ -260,6 +261,7 @@ changegroup starts with a full revision. """ + _bundling = _('bundling') # if we don't have any revisions touched by these changesets, bail if len(nodelist) == 0: yield self.close() @@ -279,7 +281,10 @@ revs.insert(0, p) # build deltas + total = len(revs) - 1 for r in xrange(len(revs) - 1): + if units is not None: + self._progress(_bundling, r + 1, unit=units, total=total) prev, curr = revs[r], revs[r + 1] linknode = lookup(revlog.node(curr)) for c in self.revchunk(revlog, curr, prev, linknode): @@ -293,8 +298,7 @@ cl = self._changelog mf = self._manifest reorder = self._reorder - progress = repo.ui.progress - count = [0, 0] + progress = self._progress _bundling = _('bundling') _changesets = _('changesets') _manifests = _('manifests') @@ -314,9 +318,6 @@ c = cl.read(x) changedfiles.update(c[3]) mfs.setdefault(c[0], x) - count[0] += 1 - progress(_bundling, count[0], - unit=_changesets, total=count[1]) return x def lookupmf(x): @@ -326,27 +327,24 @@ for f, n in mdata.iteritems(): if f in changedfiles: fnodes[f].setdefault(n, clnode) - count[0] += 1 - progress(_bundling, count[0], - unit=_manifests, total=count[1]) return clnode - count[:] = [0, len(clnodes)] - for chunk in self.group(clnodes, cl, lookupcl, reorder=reorder): + for chunk in self.group(clnodes, cl, lookupcl, units=_changesets, + reorder=reorder): yield chunk progress(_bundling, None) for f in changedfiles: fnodes[f] = {} - count[:] = [0, len(mfs)] mfnodes = prune(mf, mfs) - for chunk in self.group(mfnodes, mf, lookupmf, reorder=reorder): + for chunk in self.group(mfnodes, mf, lookupmf, units=_manifests, + reorder=reorder): yield chunk progress(_bundling, None) mfs.clear() - count[:] = [0, len(changedfiles)] - for fname in sorted(changedfiles): + total = len(changedfiles) + for i, fname in enumerate(sorted(changedfiles)): filerevlog = repo.file(fname) if not len(filerevlog): raise util.Abort(_("empty or missing revlog for %s") @@ -364,16 +362,15 @@ linkrevnodes = fnodes.pop(fname, {}) # Lookup for filenodes. def lookupfilelog(x): - progress(_bundling, count[0], item=fname, - unit=_files, total=count[1]) return linkrevnodes[x] filenodes = prune(filerevlog, linkrevnodes) if filenodes: - count[0] += 1 + progress(_bundling, i + 1, item=fname, unit=_files, + total=total) yield self.fileheader(fname) for chunk in self.group(filenodes, filerevlog, lookupfilelog, - reorder): + reorder=reorder): yield chunk yield self.close() progress(_bundling, None) From cryo at cyanite.org Thu Feb 14 14:09:39 2013 From: cryo at cyanite.org (Sune Foldager) Date: Thu, 14 Feb 2013 21:09:39 +0100 Subject: [PATCH 0 of 9] Move and refactor bundling logic In-Reply-To: References: Message-ID: <20130214200939.GA17989@cyanite.org> Let me be the first to say that this queue is somewhat dysfunctional, I apologize. My skills with text-mode merging and evolve haven't been good enough, and I must now restore some older versions of some of the patches to make it work again. The problem starts in patch 2 or 3. Will repost later. -Sune From hgbuildbot at kublai.com Thu Feb 14 14:30:00 2013 From: hgbuildbot at kublai.com (hgbuildbot at kublai.com) Date: Thu, 14 Feb 2013 12:30:00 -0800 Subject: buildbot success in Mercurial on hg tests Message-ID: <20130214203001.8EBE3263D0@hgbuildbot.cs.ubc.ca> The Buildbot has detected a restored build on builder hg tests while building hg. Full details are available at: http://hgbuildbot.kublai.com/builders/hg%20tests/builds/502 Buildbot URL: http://hgbuildbot.kublai.com/ Buildslave for this Build: p64.osuosl.test Build Reason: scheduler Build Source Stamp: [branch default] af4387d8d1c79ed597bdba7e8e41433efd5255ed Blamelist: Durham Goode ,Kevin Bullock Build succeeded! sincerely, -The Buildbot From mpm at selenic.com Thu Feb 14 14:45:51 2013 From: mpm at selenic.com (Matt Mackall) Date: Thu, 14 Feb 2013 14:45:51 -0600 Subject: [PATCH 0 of 9] Move and refactor bundling logic In-Reply-To: References: Message-ID: <1360874751.12295.59.camel@calx> On Thu, 2013-02-14 at 20:40 +0100, Sune Foldager wrote: > Benoit and I worked on this at the sprint, following the bundle format 2 > discussion. It takes some first steps towards implementing the new format. > It basically moves all bundle creation logic out of localrepo.py and into > changegroup.py, into the bundler10 class. > > The patch queue is posted as-is for easier review, although it may need some > work before push. Moving forwards from this, I think the plan is something > like the following: > > I'd like to do a dev spike on creating a new bundle format, ignoring some > details such as we haven't decided on some specifics about how to encode hunk > types, lengths etc. I think (but Benoit and I don't entirely agree) it would > be best to put that into a new bundler20 (or whatever) class, which derives > from bundler10. A factory would then be needed to return the correct bundler. That more or less matches my vision. It's why there's a version number on the existing class. > I think that keeping it in the same class, will cause a lot of clutter, a lot > of if newbundleformat: in many places, and make the code harder to follow. In particular, it should be possible to unconditionally do stuff like: bundler.addbookmarkchunk(...) # or whatever new feature ..and if the bundle version being used doesn't support it, silently no-op. -- Mathematics is the supreme nostalgia of our time. From diptongo at gmail.com Thu Feb 14 16:44:57 2013 From: diptongo at gmail.com (Isaac Jurado) Date: Thu, 14 Feb 2013 23:44:57 +0100 Subject: Bugzilla server's system time Message-ID: <20130214224457.GA3634@findus> Hi, I think the bugzilla server's clock is not on time. I posted a comment ten minutes ago and it appears as 17:40:53 UTC when it should have been 22:40:53 UTC. Maybe it's just the timezone, locale or the Bugzilla configuration. Cheers. -- Isaac Jurado "The noblest pleasure is the joy of understanding." Leonardo da Vinci From cryo at cyanite.org Thu Feb 14 17:07:19 2013 From: cryo at cyanite.org (Sune Foldager) Date: Fri, 15 Feb 2013 00:07:19 +0100 Subject: [PATCH 1 of 9] bundle-ng: move bundler creation up in the stack In-Reply-To: References: Message-ID: # HG changeset patch # User Benoit Boissinot # Date 1360432342 -3600 # Node ID d78029a5c1f72e2eb75321409ad969462b7d372f # Parent 46edbc49a9f213dd9c78e4dbaa8809661058bb07 bundle-ng: move bundler creation up in the stack Create a simple start() method to pass the lookup function until bundler becomes smarter and gets a repo object. diff -r 46edbc49a9f2 -r d78029a5c1f7 contrib/shrink-revlog.py --- a/contrib/shrink-revlog.py Sat Feb 09 16:02:01 2013 +0000 +++ b/contrib/shrink-revlog.py Sat Feb 09 18:52:22 2013 +0100 @@ -117,7 +117,8 @@ unlookup = lambda x: int(x, 10) try: - bundler = changegroup.bundle10(lookup) + bundler = changegroup.bundle10() + bundler.start(lookup) group = util.chunkbuffer(r1.group(order, bundler)) group = changegroup.unbundle10(group, "UN") r2.addgroup(group, unlookup, tr) diff -r 46edbc49a9f2 -r d78029a5c1f7 mercurial/changegroup.py --- a/mercurial/changegroup.py Sat Feb 09 16:02:01 2013 +0000 +++ b/mercurial/changegroup.py Sat Feb 09 18:52:22 2013 +0100 @@ -225,7 +225,9 @@ class bundle10(object): deltaheader = _BUNDLE10_DELTA_HEADER - def __init__(self, lookup): + def __init__(self): + pass + def start(self, lookup): self._lookup = lookup def close(self): return closechunk() diff -r 46edbc49a9f2 -r d78029a5c1f7 mercurial/localrepo.py --- a/mercurial/localrepo.py Sat Feb 09 16:02:01 2013 +0000 +++ b/mercurial/localrepo.py Sat Feb 09 18:52:22 2013 +0100 @@ -1823,7 +1823,9 @@ if revs is None and not outgoing.excluded: # push everything, # use the fast path, no race possible on push - cg = self._changegroup(outgoing.missing, 'push') + bundler = changegroup.bundle10() + cg = self._changegroup(outgoing.missing, bundler, + 'push') else: cg = self.getlocalbundle('push', outgoing) @@ -1978,7 +1980,8 @@ csets, bases, heads = cl.nodesbetween(bases, heads) # We assume that all ancestors of bases are known common = cl.ancestors([cl.rev(n) for n in bases]) - return self._changegroupsubset(common, csets, heads, source) + bundler = changegroup.bundle10() + return self._changegroupsubset(common, csets, heads, bundler, source) def getlocalbundle(self, source, outgoing): """Like getbundle, but taking a discovery.outgoing as an argument. @@ -1987,9 +1990,11 @@ precomputed sets in outgoing.""" if not outgoing.missing: return None + bundler = changegroup.bundle10() return self._changegroupsubset(outgoing.common, outgoing.missing, outgoing.missingheads, + bundler, source) def getbundle(self, source, heads=None, common=None): @@ -2013,7 +2018,7 @@ discovery.outgoing(cl, common, heads)) @unfilteredmethod - def _changegroupsubset(self, commonrevs, csets, heads, source): + def _changegroupsubset(self, commonrevs, csets, heads, bundler, source): cl = self.changelog mf = self.manifest @@ -2026,7 +2031,7 @@ # can we go through the fast path ? heads.sort() if heads == sorted(self.heads()): - return self._changegroup(csets, source) + return self._changegroup(csets, bundler, source) # slow path self.hook('preoutgoing', throw=True, source=source) @@ -2068,7 +2073,7 @@ unit=_files, total=count[1]) return fstate[1][x] - bundler = changegroup.bundle10(lookup) + bundler.start(lookup) reorder = self.ui.config('bundle', 'reorder', 'auto') if reorder == 'auto': reorder = None @@ -2125,7 +2130,7 @@ return self.changegroupsubset(basenodes, self.heads(), source) @unfilteredmethod - def _changegroup(self, nodes, source): + def _changegroup(self, nodes, bundler, source): """Compute the changegroup of all nodes that we have that a recipient doesn't. Return a chunkbuffer object whose read() method will return successive changegroup chunks. @@ -2176,7 +2181,7 @@ total=count[1], unit=_files) return cl.node(revlog.linkrev(revlog.rev(x))) - bundler = changegroup.bundle10(lookup) + bundler.start(lookup) reorder = self.ui.config('bundle', 'reorder', 'auto') if reorder == 'auto': reorder = None From cryo at cyanite.org Thu Feb 14 17:07:18 2013 From: cryo at cyanite.org (Sune Foldager) Date: Fri, 15 Feb 2013 00:07:18 +0100 Subject: [PATCH 0 of 9] WORKING move and refactor of bundle code Message-ID: See earlier post for more information, but let me add that the patches apply against 46edbc49a9f2 currently. Apologies for list spam.. this time the tests run correctly for all patches. -Sune From cryo at cyanite.org Thu Feb 14 17:07:21 2013 From: cryo at cyanite.org (Sune Foldager) Date: Fri, 15 Feb 2013 00:07:21 +0100 Subject: [PATCH 3 of 9] bundle-ng: add bundlecaps argument to getbundle() command In-Reply-To: References: Message-ID: # HG changeset patch # User Benoit Boissinot # Date 1360449723 -3600 # Node ID ad5a6d13a57e28c75167facacc2811cefc014155 # Parent 66e25980c10d10b00b658608472b251b2d3ee4fe bundle-ng: add bundlecaps argument to getbundle() command diff -r 66e25980c10d -r ad5a6d13a57e mercurial/changegroup.py --- a/mercurial/changegroup.py Sat Feb 09 18:48:34 2013 +0100 +++ b/mercurial/changegroup.py Sat Feb 09 23:42:03 2013 +0100 @@ -225,8 +225,11 @@ class bundle10(object): deltaheader = _BUNDLE10_DELTA_HEADER - def __init__(self): - pass + def __init__(self, bundlecaps=None): + # Set of capabilities we can use to build the bundle. + if bundlecaps is None: + bundlecaps = set() + self._bundlecaps = bundlecaps def start(self, lookup): self._lookup = lookup def close(self): diff -r 66e25980c10d -r ad5a6d13a57e mercurial/commands.py --- a/mercurial/commands.py Sat Feb 09 18:48:34 2013 +0100 +++ b/mercurial/commands.py Sat Feb 09 23:42:03 2013 +0100 @@ -1054,13 +1054,16 @@ base = ['null'] else: base = scmutil.revrange(repo, opts.get('base')) + # TODO: get desired bundlecaps from command line. + bundlecaps = None if base: if dest: raise util.Abort(_("--base is incompatible with specifying " "a destination")) common = [repo.lookup(rev) for rev in base] heads = revs and map(repo.lookup, revs) or revs - cg = repo.getbundle('bundle', heads=heads, common=common) + cg = repo.getbundle('bundle', heads=heads, common=common, + bundlecaps=bundlecaps) outgoing = None else: dest = ui.expandpath(dest or 'default-push', dest or 'default') @@ -1072,7 +1075,7 @@ onlyheads=heads, force=opts.get('force'), portable=True) - cg = repo.getlocalbundle('bundle', outgoing) + cg = repo.getlocalbundle('bundle', outgoing, bundlecaps) if not cg: scmutil.nochangesfound(ui, repo, outgoing and outgoing.excluded) return 1 @@ -1920,6 +1923,8 @@ args['common'] = [bin(s) for s in common] if head: args['heads'] = [bin(s) for s in head] + # TODO: get desired bundlecaps from command line. + args['bundlecaps'] = None bundle = repo.getbundle('debug', **args) bundletype = opts.get('type', 'bzip2').lower() diff -r 66e25980c10d -r ad5a6d13a57e mercurial/localrepo.py --- a/mercurial/localrepo.py Sat Feb 09 18:48:34 2013 +0100 +++ b/mercurial/localrepo.py Sat Feb 09 23:42:03 2013 +0100 @@ -99,8 +99,9 @@ def known(self, nodes): return self._repo.known(nodes) - def getbundle(self, source, heads=None, common=None): - return self._repo.getbundle(source, heads=heads, common=common) + def getbundle(self, source, heads=None, common=None, bundlecaps=None): + return self._repo.getbundle(source, heads=heads, common=common, + bundlecaps=None) # TODO We might want to move the next two calls into legacypeer and add # unbundle instead. @@ -1678,6 +1679,7 @@ heads = rheads if remote.capable('getbundle'): + # TODO: get bundlecaps from remote cg = remote.getbundle('pull', common=common, heads=heads or rheads) elif heads is None: @@ -1819,15 +1821,17 @@ remoteheads, newbranch, bool(inc)) + # TODO: get bundlecaps from remote + bundlecaps = None # create a changegroup from local if revs is None and not outgoing.excluded: # push everything, # use the fast path, no race possible on push - bundler = changegroup.bundle10() + bundler = changegroup.bundle10(bundlecaps) cg = self._changegroup(outgoing.missing, bundler, 'push') else: - cg = self.getlocalbundle('push', outgoing) + cg = self.getlocalbundle('push', outgoing, bundlecaps) # apply changegroup to remote if unbundle: @@ -1983,21 +1987,21 @@ bundler = changegroup.bundle10() return self._changegroupsubset(common, csets, heads, bundler, source) - def getlocalbundle(self, source, outgoing): + def getlocalbundle(self, source, outgoing, bundlecaps=None): """Like getbundle, but taking a discovery.outgoing as an argument. This is only implemented for local repos and reuses potentially precomputed sets in outgoing.""" if not outgoing.missing: return None - bundler = changegroup.bundle10() + bundler = changegroup.bundle10(bundlecaps) return self._changegroupsubset(outgoing.common, outgoing.missing, outgoing.missingheads, bundler, source) - def getbundle(self, source, heads=None, common=None): + def getbundle(self, source, heads=None, common=None, bundlecaps=None): """Like changegroupsubset, but returns the set difference between the ancestors of heads and the ancestors common. @@ -2015,7 +2019,8 @@ if not heads: heads = cl.heads() return self.getlocalbundle(source, - discovery.outgoing(cl, common, heads)) + discovery.outgoing(cl, common, heads), + bundlecaps=bundlecaps) @unfilteredmethod def _changegroupsubset(self, commonrevs, csets, heads, bundler, source): diff -r 66e25980c10d -r ad5a6d13a57e mercurial/wireproto.py --- a/mercurial/wireproto.py Sat Feb 09 18:48:34 2013 +0100 +++ b/mercurial/wireproto.py Sat Feb 09 23:42:03 2013 +0100 @@ -281,13 +281,15 @@ bases=bases, heads=heads) return changegroupmod.unbundle10(self._decompress(f), 'UN') - def getbundle(self, source, heads=None, common=None): + def getbundle(self, source, heads=None, common=None, bundlecaps=None): self.requirecap('getbundle', _('look up remote changes')) opts = {} if heads is not None: opts['heads'] = encodelist(heads) if common is not None: opts['common'] = encodelist(common) + if bundlecaps is not None: + opts['bundlecaps'] = ','.join(bundlecaps) f = self._callstream("getbundle", **opts) return changegroupmod.unbundle10(self._decompress(f), 'UN') @@ -449,9 +451,12 @@ return repo.debugwireargs(one, two, **opts) def getbundle(repo, proto, others): - opts = options('getbundle', ['heads', 'common'], others) + opts = options('getbundle', ['heads', 'common', 'bundlecaps'], others) for k, v in opts.iteritems(): - opts[k] = decodelist(v) + if k in ('heads', 'common'): + opts[k] = decodelist(v) + elif k == 'bundlecaps': + opts[k] = set(v.split(',')) cg = repo.getbundle('serve', **opts) return streamres(proto.groupchunks(cg)) From cryo at cyanite.org Thu Feb 14 17:07:20 2013 From: cryo at cyanite.org (Sune Foldager) Date: Fri, 15 Feb 2013 00:07:20 +0100 Subject: [PATCH 2 of 9] bundle-ng: move group into the bundler In-Reply-To: References: Message-ID: <66e25980c10d10b00b65.1360883240@firefly.edlund.dk> # HG changeset patch # User Sune Foldager # Date 1360432114 -3600 # Node ID 66e25980c10d10b00b658608472b251b2d3ee4fe # Parent d78029a5c1f72e2eb75321409ad969462b7d372f bundle-ng: move group into the bundler diff -r d78029a5c1f7 -r 66e25980c10d contrib/shrink-revlog.py --- a/contrib/shrink-revlog.py Sat Feb 09 18:52:22 2013 +0100 +++ b/contrib/shrink-revlog.py Sat Feb 09 18:48:34 2013 +0100 @@ -119,7 +119,7 @@ try: bundler = changegroup.bundle10() bundler.start(lookup) - group = util.chunkbuffer(r1.group(order, bundler)) + group = util.chunkbuffer(bundler.group(order, r1)) group = changegroup.unbundle10(group, "UN") r2.addgroup(group, unlookup, tr) finally: diff -r d78029a5c1f7 -r 66e25980c10d mercurial/changegroup.py --- a/mercurial/changegroup.py Sat Feb 09 18:52:22 2013 +0100 +++ b/mercurial/changegroup.py Sat Feb 09 18:48:34 2013 +0100 @@ -7,7 +7,7 @@ from i18n import _ from node import nullrev -import mdiff, util +import mdiff, util, dagutil import struct, os, bz2, zlib, tempfile _BUNDLE10_DELTA_HEADER = "20s20s20s20s" @@ -231,8 +231,49 @@ self._lookup = lookup def close(self): return closechunk() + def fileheader(self, fname): return chunkheader(len(fname)) + fname + + def group(self, nodelist, revlog, reorder=None): + """Calculate a delta group, yielding a sequence of changegroup chunks + (strings). + + Given a list of changeset revs, return a set of deltas and + metadata corresponding to nodes. The first delta is + first parent(nodelist[0]) -> nodelist[0], the receiver is + guaranteed to have this parent as it has all history before + these changesets. In the case firstparent is nullrev the + changegroup starts with a full revision. + """ + + # if we don't have any revisions touched by these changesets, bail + if len(nodelist) == 0: + yield self.close() + return + + # for generaldelta revlogs, we linearize the revs; this will both be + # much quicker and generate a much smaller bundle + if (revlog._generaldelta and reorder is not False) or reorder: + dag = dagutil.revlogdag(revlog) + revs = set(revlog.rev(n) for n in nodelist) + revs = dag.linearize(revs) + else: + revs = sorted([revlog.rev(n) for n in nodelist]) + + # add the parent of the first rev + p = revlog.parentrevs(revs[0])[0] + revs.insert(0, p) + + # build deltas + for r in xrange(len(revs) - 1): + prev, curr = revs[r], revs[r + 1] + for c in self.revchunk(revlog, curr, prev): + yield c + + yield self.close() + + def revchunk(self, revlog, rev, prev): node = revlog.node(rev) p1, p2 = revlog.parentrevs(rev) diff -r d78029a5c1f7 -r 66e25980c10d mercurial/localrepo.py --- a/mercurial/localrepo.py Sat Feb 09 18:52:22 2013 +0100 +++ b/mercurial/localrepo.py Sat Feb 09 18:48:34 2013 +0100 @@ -2084,7 +2084,7 @@ # Create a changenode group generator that will call our functions # back to lookup the owning changenode and collect information. count[:] = [0, len(csets)] - for chunk in cl.group(csets, bundler, reorder=reorder): + for chunk in bundler.group(csets, cl, reorder=reorder): yield chunk progress(_bundling, None) @@ -2093,7 +2093,7 @@ for f in changedfiles: fnodes[f] = {} count[:] = [0, len(mfs)] - for chunk in mf.group(prune(mf, mfs), bundler, reorder=reorder): + for chunk in bundler.group(prune(mf, mfs), mf, reorder=reorder): yield chunk progress(_bundling, None) @@ -2113,7 +2113,7 @@ if nodelist: count[0] += 1 yield bundler.fileheader(fname) - for chunk in filerevlog.group(nodelist, bundler, reorder): + for chunk in bundler.group(nodelist, filerevlog, reorder): yield chunk # Signal that no more groups are left. @@ -2193,12 +2193,12 @@ # construct a list of all changed files count[:] = [0, len(nodes)] - for chunk in cl.group(nodes, bundler, reorder=reorder): + for chunk in bundler.group(nodes, cl, reorder=reorder): yield chunk progress(_bundling, None) count[:] = [0, len(mfs)] - for chunk in mf.group(gennodelst(mf), bundler, reorder=reorder): + for chunk in bundler.group(gennodelst(mf), mf, reorder=reorder): yield chunk progress(_bundling, None) @@ -2213,7 +2213,7 @@ if nodelist: count[0] += 1 yield bundler.fileheader(fname) - for chunk in filerevlog.group(nodelist, bundler, reorder): + for chunk in bundler.group(nodelist, filerevlog, reorder): yield chunk yield bundler.close() progress(_bundling, None) diff -r d78029a5c1f7 -r 66e25980c10d mercurial/revlog.py --- a/mercurial/revlog.py Sat Feb 09 18:52:22 2013 +0100 +++ b/mercurial/revlog.py Sat Feb 09 18:48:34 2013 +0100 @@ -14,7 +14,7 @@ # import stuff from node for others to import from revlog from node import bin, hex, nullid, nullrev from i18n import _ -import ancestor, mdiff, parsers, error, util, dagutil +import ancestor, mdiff, parsers, error, util import struct, zlib, errno _pack = struct.pack @@ -1148,44 +1148,6 @@ self._basecache = (curr, chainbase) return node - def group(self, nodelist, bundler, reorder=None): - """Calculate a delta group, yielding a sequence of changegroup chunks - (strings). - - Given a list of changeset revs, return a set of deltas and - metadata corresponding to nodes. The first delta is - first parent(nodelist[0]) -> nodelist[0], the receiver is - guaranteed to have this parent as it has all history before - these changesets. In the case firstparent is nullrev the - changegroup starts with a full revision. - """ - - # if we don't have any revisions touched by these changesets, bail - if len(nodelist) == 0: - yield bundler.close() - return - - # for generaldelta revlogs, we linearize the revs; this will both be - # much quicker and generate a much smaller bundle - if (self._generaldelta and reorder is not False) or reorder: - dag = dagutil.revlogdag(self) - revs = set(self.rev(n) for n in nodelist) - revs = dag.linearize(revs) - else: - revs = sorted([self.rev(n) for n in nodelist]) - - # add the parent of the first rev - p = self.parentrevs(revs[0])[0] - revs.insert(0, p) - - # build deltas - for r in xrange(len(revs) - 1): - prev, curr = revs[r], revs[r + 1] - for c in bundler.revchunk(self, curr, prev): - yield c - - yield bundler.close() - def addgroup(self, bundle, linkmapper, transaction): """ add a delta group From cryo at cyanite.org Thu Feb 14 17:07:26 2013 From: cryo at cyanite.org (Sune Foldager) Date: Fri, 15 Feb 2013 00:07:26 +0100 Subject: [PATCH 8 of 9] bundle-ng: simplify lookup and state handling In-Reply-To: References: Message-ID: <67f558991d99dca49cd5.1360883246@firefly.edlund.dk> # HG changeset patch # User Benoit Boissinot # Date 1360511730 -3600 # Node ID 67f558991d99dca49cd51485b0e9f96b70dc7301 # Parent 45c57eaf3b41b1493169ffe474926b793bb12db9 bundle-ng: simplify lookup and state handling diff -r 45c57eaf3b41 -r 67f558991d99 mercurial/changegroup.py --- a/mercurial/changegroup.py Sun Feb 10 16:23:10 2013 +0100 +++ b/mercurial/changegroup.py Sun Feb 10 16:55:30 2013 +0100 @@ -242,14 +242,13 @@ reorder = False self._repo = repo self._reorder = reorder - self.count = [0, 0] def close(self): return closechunk() def fileheader(self, fname): return chunkheader(len(fname)) + fname - def group(self, nodelist, revlog, reorder=None): + def group(self, nodelist, revlog, lookup, reorder=None): """Calculate a delta group, yielding a sequence of changegroup chunks (strings). @@ -282,7 +281,8 @@ # build deltas for r in xrange(len(revs) - 1): prev, curr = revs[r], revs[r + 1] - for c in self.revchunk(revlog, curr, prev): + linknode = lookup(revlog.node(curr)) + for c in self.revchunk(revlog, curr, prev, linknode): yield c yield self.close() @@ -294,7 +294,7 @@ mf = self._manifest reorder = self._reorder progress = repo.ui.progress - count = self.count + count = [0, 0] _bundling = _('bundling') _changesets = _('changesets') _manifests = _('manifests') @@ -303,7 +303,6 @@ mfs = {} # needed manifests fnodes = {} # needed file nodes changedfiles = set() - fstate = ['', {}] # filter any nodes that claim to be part of the known set def prune(revlog, missing): @@ -311,35 +310,29 @@ return [n for n in missing if rl(rr(n)) not in commonrevs] - def lookup(revlog, x): - if revlog == cl: - c = cl.read(x) - changedfiles.update(c[3]) - mfs.setdefault(c[0], x) - count[0] += 1 - progress(_bundling, count[0], - unit=_changesets, total=count[1]) - return x - elif revlog == mf: - clnode = mfs[x] - if not fastpathlinkrev: - mdata = mf.readfast(x) - for f, n in mdata.iteritems(): - if f in changedfiles: - fnodes[f].setdefault(n, clnode) - count[0] += 1 - progress(_bundling, count[0], - unit=_manifests, total=count[1]) - return clnode - else: - progress(_bundling, count[0], item=fstate[0], - unit=_files, total=count[1]) - return fstate[1][x] + def lookupcl(x): + c = cl.read(x) + changedfiles.update(c[3]) + mfs.setdefault(c[0], x) + count[0] += 1 + progress(_bundling, count[0], + unit=_changesets, total=count[1]) + return x - self._lookup = lookup + def lookupmf(x): + clnode = mfs[x] + if not fastpathlinkrev: + mdata = mf.readfast(x) + for f, n in mdata.iteritems(): + if f in changedfiles: + fnodes[f].setdefault(n, clnode) + count[0] += 1 + progress(_bundling, count[0], + unit=_manifests, total=count[1]) + return clnode count[:] = [0, len(clnodes)] - for chunk in self.group(clnodes, cl, reorder=reorder): + for chunk in self.group(clnodes, cl, lookupcl, reorder=reorder): yield chunk progress(_bundling, None) @@ -347,7 +340,7 @@ fnodes[f] = {} count[:] = [0, len(mfs)] mfnodes = prune(mf, mfs) - for chunk in self.group(mfnodes, mf, reorder=reorder): + for chunk in self.group(mfnodes, mf, lookupmf, reorder=reorder): yield chunk progress(_bundling, None) @@ -367,13 +360,20 @@ if linkrev not in commonrevs: yield filerevlog.node(r), cl.node(linkrev) fnodes[fname] = dict(genfilenodes()) - fstate[0] = fname - fstate[1] = fnodes.pop(fname, {}) - filenodes = prune(filerevlog, fstate[1]) + + linkrevnodes = fnodes.pop(fname, {}) + # Lookup for filenodes. + def lookupfilelog(x): + progress(_bundling, count[0], item=fname, + unit=_files, total=count[1]) + return linkrevnodes[x] + + filenodes = prune(filerevlog, linkrevnodes) if filenodes: count[0] += 1 yield self.fileheader(fname) - for chunk in self.group(filenodes, filerevlog, reorder): + for chunk in self.group(filenodes, filerevlog, lookupfilelog, + reorder): yield chunk yield self.close() progress(_bundling, None) @@ -381,7 +381,7 @@ if clnodes: repo.hook('outgoing', node=hex(clnodes[0]), source=source) - def revchunk(self, revlog, rev, prev): + def revchunk(self, revlog, rev, prev, linknode): node = revlog.node(rev) p1, p2 = revlog.parentrevs(rev) base = prev @@ -392,7 +392,6 @@ prefix = mdiff.trivialdiffheader(len(delta)) else: delta = revlog.revdiff(base, rev) - linknode = self._lookup(revlog, node) p1n, p2n = revlog.parents(node) basenode = revlog.node(base) meta = self.builddeltaheader(node, p1n, p2n, basenode, linknode) From cryo at cyanite.org Thu Feb 14 17:07:22 2013 From: cryo at cyanite.org (Sune Foldager) Date: Fri, 15 Feb 2013 00:07:22 +0100 Subject: [PATCH 4 of 9] bundle-ng: move gengroup into bundler In-Reply-To: References: Message-ID: <6dd1df40c7389a645b5b.1360883242@firefly.edlund.dk> # HG changeset patch # User Sune Foldager # Date 1360455164 -3600 # Node ID 6dd1df40c7389a645b5bb81aca15feb366653cca # Parent ad5a6d13a57e28c75167facacc2811cefc014155 bundle-ng: move gengroup into bundler diff -r ad5a6d13a57e -r 6dd1df40c738 mercurial/changegroup.py --- a/mercurial/changegroup.py Sat Feb 09 23:42:03 2013 +0100 +++ b/mercurial/changegroup.py Sun Feb 10 01:12:44 2013 +0100 @@ -6,7 +6,7 @@ # GNU General Public License version 2 or any later version. from i18n import _ -from node import nullrev +from node import nullrev, hex import mdiff, util, dagutil import struct, os, bz2, zlib, tempfile @@ -225,11 +225,24 @@ class bundle10(object): deltaheader = _BUNDLE10_DELTA_HEADER - def __init__(self, bundlecaps=None): + def __init__(self, bundlecaps=None, repo=None): # Set of capabilities we can use to build the bundle. if bundlecaps is None: bundlecaps = set() self._bundlecaps = bundlecaps + if repo is not None: + self._changelog = repo.changelog + self._manifest = repo.manifest + reorder = repo.ui.config('bundle', 'reorder', 'auto') + if reorder == 'auto': + reorder = None + else: + reorder = util.parsebool(reorder) + else: + reorder = False + self._repo = repo + self._reorder = reorder + self.count = [0, 0] def start(self, lookup): self._lookup = lookup def close(self): @@ -276,6 +289,43 @@ yield self.close() + def generate(self, clnodes, getmfnodes, getfiles, getfilenodes, source): + '''yield a sequence of changegroup chunks (strings)''' + repo = self._repo + cl = self._changelog + mf = self._manifest + reorder = self._reorder + progress = repo.ui.progress + count = self.count + _bundling = _('bundling') + + count[:] = [0, len(clnodes)] + for chunk in self.group(clnodes, cl, reorder=reorder): + yield chunk + progress(_bundling, None) + + for chunk in self.group(getmfnodes(), mf, reorder=reorder): + yield chunk + progress(_bundling, None) + + changedfiles = getfiles() + count[:] = [0, len(changedfiles)] + for fname in sorted(changedfiles): + filerevlog = repo.file(fname) + if not len(filerevlog): + raise util.Abort(_("empty or missing revlog for %s") + % fname) + nodelist = getfilenodes(fname, filerevlog) + if nodelist: + count[0] += 1 + yield self.fileheader(fname) + for chunk in self.group(nodelist, filerevlog, reorder): + yield chunk + yield self.close() + progress(_bundling, None) + + if clnodes: + repo.hook('outgoing', node=hex(clnodes[0]), source=source) def revchunk(self, revlog, rev, prev): node = revlog.node(rev) diff -r ad5a6d13a57e -r 6dd1df40c738 mercurial/localrepo.py --- a/mercurial/localrepo.py Sat Feb 09 23:42:03 2013 +0100 +++ b/mercurial/localrepo.py Sun Feb 10 01:12:44 2013 +0100 @@ -1827,7 +1827,7 @@ if revs is None and not outgoing.excluded: # push everything, # use the fast path, no race possible on push - bundler = changegroup.bundle10(bundlecaps) + bundler = changegroup.bundle10(bundlecaps, self) cg = self._changegroup(outgoing.missing, bundler, 'push') else: @@ -1984,7 +1984,7 @@ csets, bases, heads = cl.nodesbetween(bases, heads) # We assume that all ancestors of bases are known common = cl.ancestors([cl.rev(n) for n in bases]) - bundler = changegroup.bundle10() + bundler = changegroup.bundle10(repo=self) return self._changegroupsubset(common, csets, heads, bundler, source) def getlocalbundle(self, source, outgoing, bundlecaps=None): @@ -1994,7 +1994,7 @@ precomputed sets in outgoing.""" if not outgoing.missing: return None - bundler = changegroup.bundle10(bundlecaps) + bundler = changegroup.bundle10(bundlecaps, self) return self._changegroupsubset(outgoing.common, outgoing.missing, outgoing.missingheads, @@ -2025,13 +2025,12 @@ @unfilteredmethod def _changegroupsubset(self, commonrevs, csets, heads, bundler, source): - cl = self.changelog - mf = self.manifest + cl = bundler._changelog + mf = bundler._manifest mfs = {} # needed manifests fnodes = {} # needed file nodes changedfiles = set() fstate = ['', {}] - count = [0, 0] # can we go through the fast path ? heads.sort() @@ -2055,6 +2054,7 @@ _files = _('files') def lookup(revlog, x): + count = bundler.count if revlog == cl: c = cl.read(x) changedfiles.update(c[3]) @@ -2079,56 +2079,23 @@ return fstate[1][x] bundler.start(lookup) - reorder = self.ui.config('bundle', 'reorder', 'auto') - if reorder == 'auto': - reorder = None - else: - reorder = util.parsebool(reorder) - def gengroup(): - # Create a changenode group generator that will call our functions - # back to lookup the owning changenode and collect information. - count[:] = [0, len(csets)] - for chunk in bundler.group(csets, cl, reorder=reorder): - yield chunk - progress(_bundling, None) - - # Create a generator for the manifestnodes that calls our lookup - # and data collection functions back. + def getmfnodes(): for f in changedfiles: fnodes[f] = {} - count[:] = [0, len(mfs)] - for chunk in bundler.group(prune(mf, mfs), mf, reorder=reorder): - yield chunk - progress(_bundling, None) + bundler.count[:] = [0, len(mfs)] + return prune(mf, mfs) + def getfiles(): + mfs.clear() + return changedfiles + def getfilenodes(fname, filerevlog): + fstate[0] = fname + fstate[1] = fnodes.pop(fname, {}) + return prune(filerevlog, fstate[1]) - mfs.clear() - - # Go through all our files in order sorted by name. - count[:] = [0, len(changedfiles)] - for fname in sorted(changedfiles): - filerevlog = self.file(fname) - if not len(filerevlog): - raise util.Abort(_("empty or missing revlog for %s") - % fname) - fstate[0] = fname - fstate[1] = fnodes.pop(fname, {}) - - nodelist = prune(filerevlog, fstate[1]) - if nodelist: - count[0] += 1 - yield bundler.fileheader(fname) - for chunk in bundler.group(nodelist, filerevlog, reorder): - yield chunk - - # Signal that no more groups are left. - yield bundler.close() - progress(_bundling, None) - - if csets: - self.hook('outgoing', node=hex(csets[0]), source=source) - - return changegroup.unbundle10(util.chunkbuffer(gengroup()), 'UN') + gengroup = bundler.generate(csets, getmfnodes, getfiles, getfilenodes, + source) + return changegroup.unbundle10(util.chunkbuffer(gengroup), 'UN') def changegroup(self, basenodes, source): # to avoid a race we use changegroupsubset() (issue1320) @@ -2145,12 +2112,11 @@ nodes is the set of nodes to send""" - cl = self.changelog - mf = self.manifest + cl = bundler._changelog + mf = bundler._manifest mfs = {} changedfiles = set() fstate = [''] - count = [0, 0] self.hook('preoutgoing', throw=True, source=source) self.changegroupinfo(nodes, source) @@ -2168,6 +2134,7 @@ _files = _('files') def lookup(revlog, x): + count = bundler.count if revlog == cl: c = cl.read(x) changedfiles.update(c[3]) @@ -2187,46 +2154,19 @@ return cl.node(revlog.linkrev(revlog.rev(x))) bundler.start(lookup) - reorder = self.ui.config('bundle', 'reorder', 'auto') - if reorder == 'auto': - reorder = None - else: - reorder = util.parsebool(reorder) - def gengroup(): - '''yield a sequence of changegroup chunks (strings)''' - # construct a list of all changed files + def getmfnodes(): + bundler.count[:] = [0, len(mfs)] + return gennodelst(mf) + def getfiles(): + return changedfiles + def getfilenodes(fname, filerevlog): + fstate[0] = fname + return gennodelst(filerevlog) - count[:] = [0, len(nodes)] - for chunk in bundler.group(nodes, cl, reorder=reorder): - yield chunk - progress(_bundling, None) - - count[:] = [0, len(mfs)] - for chunk in bundler.group(gennodelst(mf), mf, reorder=reorder): - yield chunk - progress(_bundling, None) - - count[:] = [0, len(changedfiles)] - for fname in sorted(changedfiles): - filerevlog = self.file(fname) - if not len(filerevlog): - raise util.Abort(_("empty or missing revlog for %s") - % fname) - fstate[0] = fname - nodelist = gennodelst(filerevlog) - if nodelist: - count[0] += 1 - yield bundler.fileheader(fname) - for chunk in bundler.group(nodelist, filerevlog, reorder): - yield chunk - yield bundler.close() - progress(_bundling, None) - - if nodes: - self.hook('outgoing', node=hex(nodes[0]), source=source) - - return changegroup.unbundle10(util.chunkbuffer(gengroup()), 'UN') + gengroup = bundler.generate(nodes, getmfnodes, getfiles, getfilenodes, + source) + return changegroup.unbundle10(util.chunkbuffer(gengroup), 'UN') @unfilteredmethod def addchangegroup(self, source, srctype, url, emptyok=False): From cryo at cyanite.org Thu Feb 14 17:07:24 2013 From: cryo at cyanite.org (Sune Foldager) Date: Fri, 15 Feb 2013 00:07:24 +0100 Subject: [PATCH 6 of 9] bundle-ng: move bundle generation to changegroup.py In-Reply-To: References: Message-ID: # HG changeset patch # User Benoit Boissinot # Date 1360508600 -3600 # Node ID da249fd44d65728ccc8d1fe926e951a771cec558 # Parent 6599871bf18242484de2a8245bde12769ee8c7db bundle-ng: move bundle generation to changegroup.py diff -r 6599871bf182 -r da249fd44d65 mercurial/changegroup.py --- a/mercurial/changegroup.py Sun Feb 10 15:47:23 2013 +0100 +++ b/mercurial/changegroup.py Sun Feb 10 16:03:20 2013 +0100 @@ -289,7 +289,7 @@ yield self.close() - def generate(self, clnodes, getmfnodes, getfiles, getfilenodes, source): + def generate(self, commonrevs, clnodes, fastpathlinkrev, source): '''yield a sequence of changegroup chunks (strings)''' repo = self._repo cl = self._changelog @@ -298,6 +298,69 @@ progress = repo.ui.progress count = self.count _bundling = _('bundling') + _changesets = _('changesets') + _manifests = _('manifests') + _files = _('files') + + mfs = {} # needed manifests + fnodes = {} # needed file nodes + changedfiles = set() + fstate = ['', {}] + + # filter any nodes that claim to be part of the known set + def prune(revlog, missing): + rr, rl = revlog.rev, revlog.linkrev + return [n for n in missing + if rl(rr(n)) not in commonrevs] + + def lookup(revlog, x): + if revlog == cl: + c = cl.read(x) + changedfiles.update(c[3]) + mfs.setdefault(c[0], x) + count[0] += 1 + progress(_bundling, count[0], + unit=_changesets, total=count[1]) + return x + elif revlog == mf: + clnode = mfs[x] + if not fastpathlinkrev: + mdata = mf.readfast(x) + for f, n in mdata.iteritems(): + if f in changedfiles: + fnodes[f].setdefault(n, clnode) + count[0] += 1 + progress(_bundling, count[0], + unit=_manifests, total=count[1]) + return clnode + else: + progress(_bundling, count[0], item=fstate[0], + unit=_files, total=count[1]) + return fstate[1][x] + + self.start(lookup) + + def getmfnodes(): + for f in changedfiles: + fnodes[f] = {} + count[:] = [0, len(mfs)] + return prune(mf, mfs) + def getfiles(): + mfs.clear() + return changedfiles + def getfilenodes(fname, filerevlog): + if fastpathlinkrev: + ln, llr = filerevlog.node, filerevlog.linkrev + def genfilenodes(): + for r in filerevlog: + linkrev = llr(r) + if linkrev not in commonrevs: + yield filerevlog.node(r), cl.node(linkrev) + fnodes[fname] = dict(genfilenodes()) + fstate[0] = fname + fstate[1] = fnodes.pop(fname, {}) + return prune(filerevlog, fstate[1]) + count[:] = [0, len(clnodes)] for chunk in self.group(clnodes, cl, reorder=reorder): diff -r 6599871bf182 -r da249fd44d65 mercurial/localrepo.py --- a/mercurial/localrepo.py Sun Feb 10 15:47:23 2013 +0100 +++ b/mercurial/localrepo.py Sun Feb 10 16:03:20 2013 +0100 @@ -2029,83 +2029,13 @@ @unfilteredmethod def _changegroupsubset(self, commonrevs, csets, heads, bundler, source, fastpath=False): - cl = bundler._changelog - mf = bundler._manifest - mfs = {} # needed manifests - fnodes = {} # needed file nodes - changedfiles = set() - fstate = ['', {}] - # can we go through the fast path ? heads.sort() fastpathlinkrev = fastpath or heads == sorted(self.heads()) self.hook('preoutgoing', throw=True, source=source) self.changegroupinfo(csets, source) - - # filter any nodes that claim to be part of the known set - def prune(revlog, missing): - rr, rl = revlog.rev, revlog.linkrev - return [n for n in missing - if rl(rr(n)) not in commonrevs] - - progress = self.ui.progress - _bundling = _('bundling') - _changesets = _('changesets') - _manifests = _('manifests') - _files = _('files') - - def lookup(revlog, x): - count = bundler.count - if revlog == cl: - c = cl.read(x) - changedfiles.update(c[3]) - mfs.setdefault(c[0], x) - count[0] += 1 - progress(_bundling, count[0], - unit=_changesets, total=count[1]) - return x - elif revlog == mf: - clnode = mfs[x] - if not fastpathlinkrev: - mdata = mf.readfast(x) - for f, n in mdata.iteritems(): - if f in changedfiles: - fnodes[f].setdefault(n, clnode) - count[0] += 1 - progress(_bundling, count[0], - unit=_manifests, total=count[1]) - return clnode - else: - progress(_bundling, count[0], item=fstate[0], - unit=_files, total=count[1]) - return fstate[1][x] - - bundler.start(lookup) - - def getmfnodes(): - for f in changedfiles: - fnodes[f] = {} - bundler.count[:] = [0, len(mfs)] - return prune(mf, mfs) - def getfiles(): - mfs.clear() - return changedfiles - def getfilenodes(fname, filerevlog): - if fastpathlinkrev: - ln, llr = filerevlog.node, filerevlog.linkrev - def genfilenodes(): - for r in filerevlog: - linkrev = llr(r) - if linkrev not in commonrevs: - yield filerevlog.node(r), cl.node(linkrev) - fnodes[fname] = dict(genfilenodes()) - fstate[0] = fname - fstate[1] = fnodes.pop(fname, {}) - return prune(filerevlog, fstate[1]) - - gengroup = bundler.generate(csets, getmfnodes, getfiles, getfilenodes, - source) + gengroup = bundler.generate(commonrevs, csets, fastpathlinkrev, source) return changegroup.unbundle10(util.chunkbuffer(gengroup), 'UN') def changegroup(self, basenodes, source): From cryo at cyanite.org Thu Feb 14 17:07:23 2013 From: cryo at cyanite.org (Sune Foldager) Date: Fri, 15 Feb 2013 00:07:23 +0100 Subject: [PATCH 5 of 9] bundle-ng: unify _changegroup and _changegroupsubset In-Reply-To: References: Message-ID: <6599871bf18242484de2.1360883243@firefly.edlund.dk> # HG changeset patch # User Benoit Boissinot # Date 1360507643 -3600 # Node ID 6599871bf18242484de2a8245bde12769ee8c7db # Parent 6dd1df40c7389a645b5bb81aca15feb366653cca bundle-ng: unify _changegroup and _changegroupsubset diff -r 6dd1df40c738 -r 6599871bf182 mercurial/localrepo.py --- a/mercurial/localrepo.py Sun Feb 10 01:12:44 2013 +0100 +++ b/mercurial/localrepo.py Sun Feb 10 15:47:23 2013 +0100 @@ -1828,8 +1828,12 @@ # push everything, # use the fast path, no race possible on push bundler = changegroup.bundle10(bundlecaps, self) - cg = self._changegroup(outgoing.missing, bundler, - 'push') + cg = self._changegroupsubset(outgoing.common, + outgoing.missing, + outgoing.missingheads, + bundler, + 'push', + fastpath=True) else: cg = self.getlocalbundle('push', outgoing, bundlecaps) @@ -2023,8 +2027,8 @@ bundlecaps=bundlecaps) @unfilteredmethod - def _changegroupsubset(self, commonrevs, csets, heads, bundler, source): - + def _changegroupsubset(self, commonrevs, csets, heads, bundler, source, + fastpath=False): cl = bundler._changelog mf = bundler._manifest mfs = {} # needed manifests @@ -2034,10 +2038,8 @@ # can we go through the fast path ? heads.sort() - if heads == sorted(self.heads()): - return self._changegroup(csets, bundler, source) + fastpathlinkrev = fastpath or heads == sorted(self.heads()) - # slow path self.hook('preoutgoing', throw=True, source=source) self.changegroupinfo(csets, source) @@ -2065,10 +2067,11 @@ return x elif revlog == mf: clnode = mfs[x] - mdata = mf.readfast(x) - for f, n in mdata.iteritems(): - if f in changedfiles: - fnodes[f].setdefault(n, clnode) + if not fastpathlinkrev: + mdata = mf.readfast(x) + for f, n in mdata.iteritems(): + if f in changedfiles: + fnodes[f].setdefault(n, clnode) count[0] += 1 progress(_bundling, count[0], unit=_manifests, total=count[1]) @@ -2089,6 +2092,14 @@ mfs.clear() return changedfiles def getfilenodes(fname, filerevlog): + if fastpathlinkrev: + ln, llr = filerevlog.node, filerevlog.linkrev + def genfilenodes(): + for r in filerevlog: + linkrev = llr(r) + if linkrev not in commonrevs: + yield filerevlog.node(r), cl.node(linkrev) + fnodes[fname] = dict(genfilenodes()) fstate[0] = fname fstate[1] = fnodes.pop(fname, {}) return prune(filerevlog, fstate[1]) @@ -2102,73 +2113,6 @@ return self.changegroupsubset(basenodes, self.heads(), source) @unfilteredmethod - def _changegroup(self, nodes, bundler, source): - """Compute the changegroup of all nodes that we have that a recipient - doesn't. Return a chunkbuffer object whose read() method will return - successive changegroup chunks. - - This is much easier than the previous function as we can assume that - the recipient has any changenode we aren't sending them. - - nodes is the set of nodes to send""" - - cl = bundler._changelog - mf = bundler._manifest - mfs = {} - changedfiles = set() - fstate = [''] - - self.hook('preoutgoing', throw=True, source=source) - self.changegroupinfo(nodes, source) - - revset = set([cl.rev(n) for n in nodes]) - - def gennodelst(log): - ln, llr = log.node, log.linkrev - return [ln(r) for r in log if llr(r) in revset] - - progress = self.ui.progress - _bundling = _('bundling') - _changesets = _('changesets') - _manifests = _('manifests') - _files = _('files') - - def lookup(revlog, x): - count = bundler.count - if revlog == cl: - c = cl.read(x) - changedfiles.update(c[3]) - mfs.setdefault(c[0], x) - count[0] += 1 - progress(_bundling, count[0], - unit=_changesets, total=count[1]) - return x - elif revlog == mf: - count[0] += 1 - progress(_bundling, count[0], - unit=_manifests, total=count[1]) - return cl.node(revlog.linkrev(revlog.rev(x))) - else: - progress(_bundling, count[0], item=fstate[0], - total=count[1], unit=_files) - return cl.node(revlog.linkrev(revlog.rev(x))) - - bundler.start(lookup) - - def getmfnodes(): - bundler.count[:] = [0, len(mfs)] - return gennodelst(mf) - def getfiles(): - return changedfiles - def getfilenodes(fname, filerevlog): - fstate[0] = fname - return gennodelst(filerevlog) - - gengroup = bundler.generate(nodes, getmfnodes, getfiles, getfilenodes, - source) - return changegroup.unbundle10(util.chunkbuffer(gengroup), 'UN') - - @unfilteredmethod def addchangegroup(self, source, srctype, url, emptyok=False): """Add the changegroup returned by source.read() to this repo. srctype is a string like 'push', 'pull', or 'unbundle'. url is From cryo at cyanite.org Thu Feb 14 17:07:25 2013 From: cryo at cyanite.org (Sune Foldager) Date: Fri, 15 Feb 2013 00:07:25 +0100 Subject: [PATCH 7 of 9] bundle-ng: simplify bundle10.generate a bit In-Reply-To: References: Message-ID: <45c57eaf3b41b1493169.1360883245@firefly.edlund.dk> # HG changeset patch # User Sune Foldager # Date 1360509790 -3600 # Node ID 45c57eaf3b41b1493169ffe474926b793bb12db9 # Parent da249fd44d65728ccc8d1fe926e951a771cec558 bundle-ng: simplify bundle10.generate a bit diff -r da249fd44d65 -r 45c57eaf3b41 contrib/shrink-revlog.py --- a/contrib/shrink-revlog.py Sun Feb 10 16:03:20 2013 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,295 +0,0 @@ -"""reorder a revlog (the manifest by default) to save space - -Specifically, this topologically sorts the revisions in the revlog so that -revisions on the same branch are adjacent as much as possible. This is a -workaround for the fact that Mercurial computes deltas relative to the -previous revision rather than relative to a parent revision. - -This is *not* safe to run on a changelog. -""" - -# Originally written by Benoit Boissinot -# as a patch to rewrite-log. Cleaned up, refactored, documented, and -# renamed by Greg Ward . - -# XXX would be nice to have a way to verify the repository after shrinking, -# e.g. by comparing "before" and "after" states of random changesets -# (maybe: export before, shrink, export after, diff). - -import os, errno -from mercurial import revlog, transaction, node, util, scmutil -from mercurial import changegroup -from mercurial.i18n import _ - - -def postorder(start, edges): - result = [] - visit = list(start) - finished = set() - - while visit: - cur = visit[-1] - for p in edges[cur]: - # defend against node.nullrev because it's occasionally - # possible for a node to have parents (null, something) - # rather than (something, null) - if p not in finished and p != node.nullrev: - visit.append(p) - break - else: - result.append(cur) - finished.add(cur) - visit.pop() - - return result - -def toposort_reversepostorder(ui, rl): - # postorder of the reverse directed graph - - # map rev to list of parent revs (p2 first) - parents = {} - heads = set() - ui.status(_('reading revs\n')) - try: - for rev in rl: - ui.progress(_('reading'), rev, total=len(rl)) - (p1, p2) = rl.parentrevs(rev) - if p1 == p2 == node.nullrev: - parents[rev] = () # root node - elif p1 == p2 or p2 == node.nullrev: - parents[rev] = (p1,) # normal node - else: - parents[rev] = (p2, p1) # merge node - heads.add(rev) - for p in parents[rev]: - heads.discard(p) - finally: - ui.progress(_('reading'), None) - - heads = list(heads) - heads.sort(reverse=True) - - ui.status(_('sorting revs\n')) - return postorder(heads, parents) - -def toposort_postorderreverse(ui, rl): - # reverse-postorder of the reverse directed graph - - children = {} - roots = set() - ui.status(_('reading revs\n')) - try: - for rev in rl: - ui.progress(_('reading'), rev, total=len(rl)) - (p1, p2) = rl.parentrevs(rev) - if p1 == p2 == node.nullrev: - roots.add(rev) - children[rev] = [] - if p1 != node.nullrev: - children[p1].append(rev) - if p2 != node.nullrev: - children[p2].append(rev) - finally: - ui.progress(_('reading'), None) - - roots = list(roots) - roots.sort() - - ui.status(_('sorting revs\n')) - result = postorder(roots, children) - result.reverse() - return result - -def writerevs(ui, r1, r2, order, tr): - - ui.status(_('writing revs\n')) - - - order = [r1.node(r) for r in order] - - # this is a bit ugly, but it works - count = [0] - def lookup(revl, x): - count[0] += 1 - ui.progress(_('writing'), count[0], total=len(order)) - return "%020d" % revl.linkrev(revl.rev(x)) - - unlookup = lambda x: int(x, 10) - - try: - bundler = changegroup.bundle10() - bundler.start(lookup) - group = util.chunkbuffer(bundler.group(order, r1)) - group = changegroup.unbundle10(group, "UN") - r2.addgroup(group, unlookup, tr) - finally: - ui.progress(_('writing'), None) - -def report(ui, r1, r2): - def getsize(r): - s = 0 - for fn in (r.indexfile, r.datafile): - try: - s += os.stat(fn).st_size - except OSError, inst: - if inst.errno != errno.ENOENT: - raise - return s - - oldsize = float(getsize(r1)) - newsize = float(getsize(r2)) - - # argh: have to pass an int to %d, because a float >= 2^32 - # blows up under Python 2.5 or earlier - ui.write(_('old file size: %12d bytes (%6.1f MiB)\n') - % (int(oldsize), oldsize / 1024 / 1024)) - ui.write(_('new file size: %12d bytes (%6.1f MiB)\n') - % (int(newsize), newsize / 1024 / 1024)) - - shrink_percent = (oldsize - newsize) / oldsize * 100 - shrink_factor = oldsize / newsize - ui.write(_('shrinkage: %.1f%% (%.1fx)\n') - % (shrink_percent, shrink_factor)) - -def shrink(ui, repo, **opts): - """shrink a revlog by reordering revisions - - Rewrites all the entries in some revlog of the current repository - (by default, the manifest log) to save space. - - Different sort algorithms have different performance - characteristics. Use ``--sort`` to select a sort algorithm so you - can determine which works best for your data. - """ - - if not repo.local(): - raise util.Abort(_('not a local repository: %s') % repo.root) - - fn = opts.get('revlog') - if not fn: - indexfn = repo.sjoin('00manifest.i') - else: - if not fn.endswith('.i'): - raise util.Abort(_('--revlog option must specify the revlog index ' - 'file (*.i), not %s') % opts.get('revlog')) - - indexfn = os.path.realpath(fn) - store = repo.sjoin('') - if not indexfn.startswith(store): - raise util.Abort(_('--revlog option must specify a revlog in %s, ' - 'not %s') % (store, indexfn)) - - sortname = opts['sort'] - try: - toposort = globals()['toposort_' + sortname] - except KeyError: - raise util.Abort(_('no such toposort algorithm: %s') % sortname) - - if not os.path.exists(indexfn): - raise util.Abort(_('no such file: %s') % indexfn) - if '00changelog' in indexfn: - raise util.Abort(_('shrinking the changelog ' - 'will corrupt your repository')) - - ui.write(_('shrinking %s\n') % indexfn) - tmpindexfn = util.mktempcopy(indexfn, emptyok=True) - - r1 = revlog.revlog(scmutil.opener(os.getcwd(), audit=False), indexfn) - r2 = revlog.revlog(scmutil.opener(os.getcwd(), audit=False), tmpindexfn) - - datafn, tmpdatafn = r1.datafile, r2.datafile - - oldindexfn = indexfn + '.old' - olddatafn = datafn + '.old' - if os.path.exists(oldindexfn) or os.path.exists(olddatafn): - raise util.Abort(_('one or both of\n' - ' %s\n' - ' %s\n' - 'exists from a previous run; please clean up ' - 'before running again') % (oldindexfn, olddatafn)) - - # Don't use repo.transaction(), because then things get hairy with - # paths: some need to be relative to .hg, and some need to be - # absolute. Doing it this way keeps things simple: everything is an - # absolute path. - lock = repo.lock(wait=False) - tr = transaction.transaction(ui.warn, - open, - repo.sjoin('journal')) - - def ignoremissing(func): - def f(*args, **kw): - try: - return func(*args, **kw) - except OSError, inst: - if inst.errno != errno.ENOENT: - raise - return f - - try: - try: - order = toposort(ui, r1) - - suboptimal = 0 - for i in xrange(1, len(order)): - parents = [p for p in r1.parentrevs(order[i]) - if p != node.nullrev] - if parents and order[i - 1] not in parents: - suboptimal += 1 - ui.note(_('%d suboptimal nodes\n') % suboptimal) - - writerevs(ui, r1, r2, order, tr) - report(ui, r1, r2) - tr.close() - except: # re-raises - # Abort transaction first, so we truncate the files before - # deleting them. - tr.abort() - for fn in (tmpindexfn, tmpdatafn): - ignoremissing(os.unlink)(fn) - raise - if not opts.get('dry_run'): - # racy, both files cannot be renamed atomically - # copy files - util.oslink(indexfn, oldindexfn) - ignoremissing(util.oslink)(datafn, olddatafn) - - # rename - util.rename(tmpindexfn, indexfn) - try: - os.chmod(tmpdatafn, os.stat(datafn).st_mode) - util.rename(tmpdatafn, datafn) - except OSError, inst: - if inst.errno != errno.ENOENT: - raise - ignoremissing(os.unlink)(datafn) - else: - for fn in (tmpindexfn, tmpdatafn): - ignoremissing(os.unlink)(fn) - finally: - lock.release() - - if not opts.get('dry_run'): - ui.write( - _('note: old revlog saved in:\n' - ' %s\n' - ' %s\n' - '(You can delete those files when you are satisfied that your\n' - 'repository is still sane. ' - 'Running \'hg verify\' is strongly recommended.)\n') - % (oldindexfn, olddatafn)) - -cmdtable = { - 'shrink': (shrink, - [('', 'revlog', '', - _('the revlog to shrink (.i)')), - ('n', 'dry-run', None, - _('do not shrink, simulate only')), - ('', 'sort', 'reversepostorder', - _('name of sort algorithm to use')), - ], - _('hg shrink [--revlog PATH]')) -} - -if __name__ == "__main__": - print "shrink-revlog.py is now an extension (see hg help extensions)" diff -r da249fd44d65 -r 45c57eaf3b41 mercurial/changegroup.py --- a/mercurial/changegroup.py Sun Feb 10 16:03:20 2013 +0100 +++ b/mercurial/changegroup.py Sun Feb 10 16:23:10 2013 +0100 @@ -243,8 +243,6 @@ self._repo = repo self._reorder = reorder self.count = [0, 0] - def start(self, lookup): - self._lookup = lookup def close(self): return closechunk() @@ -338,17 +336,29 @@ unit=_files, total=count[1]) return fstate[1][x] - self.start(lookup) + self._lookup = lookup - def getmfnodes(): - for f in changedfiles: - fnodes[f] = {} - count[:] = [0, len(mfs)] - return prune(mf, mfs) - def getfiles(): - mfs.clear() - return changedfiles - def getfilenodes(fname, filerevlog): + count[:] = [0, len(clnodes)] + for chunk in self.group(clnodes, cl, reorder=reorder): + yield chunk + progress(_bundling, None) + + for f in changedfiles: + fnodes[f] = {} + count[:] = [0, len(mfs)] + mfnodes = prune(mf, mfs) + for chunk in self.group(mfnodes, mf, reorder=reorder): + yield chunk + progress(_bundling, None) + + mfs.clear() + count[:] = [0, len(changedfiles)] + for fname in sorted(changedfiles): + filerevlog = repo.file(fname) + if not len(filerevlog): + raise util.Abort(_("empty or missing revlog for %s") + % fname) + if fastpathlinkrev: ln, llr = filerevlog.node, filerevlog.linkrev def genfilenodes(): @@ -359,30 +369,11 @@ fnodes[fname] = dict(genfilenodes()) fstate[0] = fname fstate[1] = fnodes.pop(fname, {}) - return prune(filerevlog, fstate[1]) - - - count[:] = [0, len(clnodes)] - for chunk in self.group(clnodes, cl, reorder=reorder): - yield chunk - progress(_bundling, None) - - for chunk in self.group(getmfnodes(), mf, reorder=reorder): - yield chunk - progress(_bundling, None) - - changedfiles = getfiles() - count[:] = [0, len(changedfiles)] - for fname in sorted(changedfiles): - filerevlog = repo.file(fname) - if not len(filerevlog): - raise util.Abort(_("empty or missing revlog for %s") - % fname) - nodelist = getfilenodes(fname, filerevlog) - if nodelist: + filenodes = prune(filerevlog, fstate[1]) + if filenodes: count[0] += 1 yield self.fileheader(fname) - for chunk in self.group(nodelist, filerevlog, reorder): + for chunk in self.group(filenodes, filerevlog, reorder): yield chunk yield self.close() progress(_bundling, None) diff -r da249fd44d65 -r 45c57eaf3b41 tests/test-contrib.t --- a/tests/test-contrib.t Sun Feb 10 16:03:20 2013 +0100 +++ b/tests/test-contrib.t Sun Feb 10 16:23:10 2013 +0100 @@ -103,34 +103,6 @@ no changes found [1] - -#if hardlink - -Test shrink-revlog: - $ cd repo-a - $ hg --config extensions.shrink="$CONTRIBDIR/shrink-revlog.py" shrink - shrinking $TESTTMP/repo-a/.hg/store/00manifest.i (glob) - reading revs - sorting revs - writing revs - old file size: 324 bytes ( 0.0 MiB) - new file size: 324 bytes ( 0.0 MiB) - shrinkage: 0.0% (1.0x) - note: old revlog saved in: - $TESTTMP/repo-a/.hg/store/00manifest.i.old (glob) - $TESTTMP/repo-a/.hg/store/00manifest.d.old (glob) - (You can delete those files when you are satisfied that your - repository is still sane. Running 'hg verify' is strongly recommended.) - $ hg verify - checking changesets - checking manifests - crosschecking files in changesets and manifests - checking files - 1 files, 3 changesets, 3 total revisions - $ cd .. - -#endif - Test simplemerge command: $ cp "$CONTRIBDIR/simplemerge" . From cryo at cyanite.org Thu Feb 14 17:07:27 2013 From: cryo at cyanite.org (Sune Foldager) Date: Fri, 15 Feb 2013 00:07:27 +0100 Subject: [PATCH 9 of 9] bundle-ng: move progress out of the linkrev callback In-Reply-To: References: Message-ID: # HG changeset patch # User Benoit Boissinot # Date 1360592532 -3600 # Node ID d9674d2d2ea1e775c408d562ee9aafd361d16f6a # Parent 67f558991d99dca49cd51485b0e9f96b70dc7301 bundle-ng: move progress out of the linkrev callback diff -r 67f558991d99 -r d9674d2d2ea1 mercurial/changegroup.py --- a/mercurial/changegroup.py Sun Feb 10 16:55:30 2013 +0100 +++ b/mercurial/changegroup.py Mon Feb 11 15:22:12 2013 +0100 @@ -242,13 +242,14 @@ reorder = False self._repo = repo self._reorder = reorder + self._progress = repo.ui.progress def close(self): return closechunk() def fileheader(self, fname): return chunkheader(len(fname)) + fname - def group(self, nodelist, revlog, lookup, reorder=None): + def group(self, nodelist, revlog, lookup, units=None, reorder=None): """Calculate a delta group, yielding a sequence of changegroup chunks (strings). @@ -260,6 +261,7 @@ changegroup starts with a full revision. """ + _bundling = _('bundling') # if we don't have any revisions touched by these changesets, bail if len(nodelist) == 0: yield self.close() @@ -279,7 +281,10 @@ revs.insert(0, p) # build deltas + total = len(revs) - 1 for r in xrange(len(revs) - 1): + if units is not None: + self._progress(_bundling, r + 1, unit=units, total=total) prev, curr = revs[r], revs[r + 1] linknode = lookup(revlog.node(curr)) for c in self.revchunk(revlog, curr, prev, linknode): @@ -293,8 +298,7 @@ cl = self._changelog mf = self._manifest reorder = self._reorder - progress = repo.ui.progress - count = [0, 0] + progress = self._progress _bundling = _('bundling') _changesets = _('changesets') _manifests = _('manifests') @@ -314,9 +318,6 @@ c = cl.read(x) changedfiles.update(c[3]) mfs.setdefault(c[0], x) - count[0] += 1 - progress(_bundling, count[0], - unit=_changesets, total=count[1]) return x def lookupmf(x): @@ -326,27 +327,24 @@ for f, n in mdata.iteritems(): if f in changedfiles: fnodes[f].setdefault(n, clnode) - count[0] += 1 - progress(_bundling, count[0], - unit=_manifests, total=count[1]) return clnode - count[:] = [0, len(clnodes)] - for chunk in self.group(clnodes, cl, lookupcl, reorder=reorder): + for chunk in self.group(clnodes, cl, lookupcl, units=_changesets, + reorder=reorder): yield chunk progress(_bundling, None) for f in changedfiles: fnodes[f] = {} - count[:] = [0, len(mfs)] mfnodes = prune(mf, mfs) - for chunk in self.group(mfnodes, mf, lookupmf, reorder=reorder): + for chunk in self.group(mfnodes, mf, lookupmf, units=_manifests, + reorder=reorder): yield chunk progress(_bundling, None) mfs.clear() - count[:] = [0, len(changedfiles)] - for fname in sorted(changedfiles): + total = len(changedfiles) + for i, fname in enumerate(sorted(changedfiles)): filerevlog = repo.file(fname) if not len(filerevlog): raise util.Abort(_("empty or missing revlog for %s") @@ -364,16 +362,15 @@ linkrevnodes = fnodes.pop(fname, {}) # Lookup for filenodes. def lookupfilelog(x): - progress(_bundling, count[0], item=fname, - unit=_files, total=count[1]) return linkrevnodes[x] filenodes = prune(filerevlog, linkrevnodes) if filenodes: - count[0] += 1 + progress(_bundling, i + 1, item=fname, unit=_files, + total=total) yield self.fileheader(fname) for chunk in self.group(filenodes, filerevlog, lookupfilelog, - reorder): + reorder=reorder): yield chunk yield self.close() progress(_bundling, None) From idankk86 at gmail.com Thu Feb 14 18:15:22 2013 From: idankk86 at gmail.com (Idan Kamara) Date: Fri, 15 Feb 2013 02:15:22 +0200 Subject: [PATCH 1 of 2 RFCv2] repoview: hide bookmarks that are prefixed with '.hg/' Message-ID: # HG changeset patch # User Idan Kamara # Date 1360886120 -7200 # Node ID d4c029076cf2213ad680a53dfd32b0886b2b7be0 # Parent af4387d8d1c79ed597bdba7e8e41433efd5255ed repoview: hide bookmarks that are prefixed with '.hg/' These bookmarks are used internally by things like stashed commits and should be hidden. diff --git a/mercurial/repoview.py b/mercurial/repoview.py --- a/mercurial/repoview.py +++ b/mercurial/repoview.py @@ -16,7 +16,11 @@ """Revisions candidates to be hidden This is a standalone function to help extensions to wrap it.""" - return obsolete.getrevs(repo, 'obsolete') + revs = list(obsolete.getrevs(repo, 'obsolete')) + for name, node in repo._bookmarks.items(): + if name.startswith('.hg/'): + revs.append(repo[node].rev()) + return revs def computehidden(repo): """compute the set of hidden revision to filter @@ -32,7 +36,10 @@ if r not in hideable] for par in repo[None].parents(): blockers.append(par.rev()) - for bm in repo._bookmarks.values(): + for name, bm in repo._bookmarks.items(): + # internal bookmarks should remain hidden + if name.startswith('.hg/'): + continue blockers.append(repo[bm].rev()) blocked = cl.ancestors(blockers, inclusive=True) return frozenset(r for r in hideable if r not in blocked) From idankk86 at gmail.com Thu Feb 14 18:15:23 2013 From: idankk86 at gmail.com (Idan Kamara) Date: Fri, 15 Feb 2013 02:15:23 +0200 Subject: [PATCH 2 of 2 RFCv2] commands: introduce stash command In-Reply-To: References: Message-ID: <06dd5eda17402c1e89a1.1360887323@idan> # HG changeset patch # User Idan Kamara # Date 1360886982 -7200 # Node ID 06dd5eda17402c1e89a1aa212e340b146394fad8 # Parent d4c029076cf2213ad680a53dfd32b0886b2b7be0 commands: introduce stash command Stashes are unnamed (by default) and can be listed using --list and inspected with -s/--show. Referring to stashes is done either by index (as shown in --list) or name (if one was given). If neither is specified, the most recent stash is chosen. A stash is saved as a regular secret commit in the repository and is identified by a bookmark under a special namespace '.hg/stash/'. It is hidden from the user and isn't exchanged with other repositories. When a stash is popped or deleted, it is stripped from the repository or marked obsolete if obsolete is enabled. It's currently not possible to stash when an mq patch is applied. Unless mq sometime in the future stops the use of strip (unlikely, mainly due to lack of interest in touching it), this won't change. Notes: - --list output could be more friendly - short option of --list is taken by -l of --log-message, slightly annoying and could perhaps be better off with a different name (or drop --log-message from options?) - command option validation is pretty nasty, can it be improved somehow? - there's a bug in the added test that I haven't been able to solve yet, any help will be appreciated Other feedback is also welcome! diff --git a/hgext/mq.py b/hgext/mq.py --- a/hgext/mq.py +++ b/hgext/mq.py @@ -3536,6 +3536,11 @@ ui.note(_("mq: (empty queue)\n")) return r +def stash(orig, ui, repo, *args, **kwargs): + if repo.mq.applied: + raise util.Abort(_('cannot stash with applied patches')) + return orig(ui, repo, *args, **kwargs) + def revsetmq(repo, subset, x): """``mq()`` Changesets managed by MQ. @@ -3554,6 +3559,7 @@ extensions.wrapcommand(commands.table, 'import', mqimport) extensions.wrapcommand(commands.table, 'summary', summary) + extensions.wrapcommand(commands.table, 'stash', stash) entry = extensions.wrapcommand(commands.table, 'init', mqinit) entry[1].extend(mqopt) diff --git a/mercurial/commands.py b/mercurial/commands.py --- a/mercurial/commands.py +++ b/mercurial/commands.py @@ -17,7 +17,7 @@ import minirst, revset, fileset import dagparser, context, simplemerge, graphmod import random, setdiscovery, treediscovery, dagutil, pvec, localrepo -import phases, obsolete +import phases, obsolete, stash as stashmod table = {} @@ -5366,6 +5366,135 @@ ui.configsource(section, name, untrusted)) ui.write('%s=%s\n' % (sectname, value)) + at command("stash", + [('', 'list', False, _('list all stashes')), # -l taken by logfile + ('f', 'force', False, _('unstash with dirty working dir')), + ('a', 'apply', False, _('apply the named or most recent stash')), + ('p', 'pop', False, + _('apply and pop the named or most recent stash')), + ('s', 'show', False, + _('show patch of the named or most recent stash')), + ('d', 'delete', False, _('delete the named or most recent stash')), + ('A', 'addremove', None, + _('mark new/missing files as added/removed before stashing')), + ('m', 'message', '', _('use text as stash message'), _('TEXT'))] + + commitopts + walkopts + mergetoolopts, + _('hg stash [--list|-a|-p|-d] [-f] [NAME]')) +def stash(ui, repo, name=None, pop=False, apply=False, delete=False, + show=False, **opts): + """stash all changes in the working directory + + Saves the state of the working directory so it can be restored at a later + time. + + Stashes are unnamed (by default) and can be listed using --list and + inspected with -s/--show. + + Referring to stashes is done either by index (as shown in --list) or name + (if one was given). If neither is specified, the most recent stash is + chosen. + + A stash is saved as a regular secret commit in the repository and is + identified by a bookmark under a special namespace ``.hg/stash/``. It is + hidden from the user and isn't exchanged with other repositories. When + a stash is popped or deleted, it is removed from the repository. + + .. container:: verbose + + Examples: + + - stash changes in a named stash:: + + hg stash wip + + - unstash (but don't delete) a named stash:: + + hg stash -a wip + + - unstash and remove previous stash:: + + hg stash --pop + + - show previous stash:: + + hg stash -p + + - list all stashes + + hg stash --list + """ + + # check command line options + l = [] + if opts.get('list'): + l.append('-l/--list') + if pop: + l.append('-p/--pop') + if delete: + l.append('-d/--delete') + + if len(l) > 1: + raise util.Abort(_('can specify one of: -l/--list, -p/--pop or' + '-d/--delete')) + + if opts.get('force') and not (pop or apply): + raise util.Abort(_('-f is only valid with -p/--pop or -a/--apply')) + + if l: + if opts.get('addremove'): + raise util.Abort(_('cannot specify -A/--addremove with %s') % l[0]) + for opt in commitopts + walkopts: + if opts.get(opt[1]): + raise util.Abort(_('cannot specify %s with %s') % (opt[1], + l[0])) + if opts.get('delete') or opts.get('list'): + for opt in mergetoolopts: + if opts.get(opt[1]): + raise util.Abort(_('cannot specify %s with %s') % (opt[1], + l[0])) + + repo = repo.unfiltered() + + if opts.get('list'): + for i, (name, ctx) in enumerate(sorted(stashmod.list_(repo).iteritems(), + key=lambda k: k[1].rev())): + name = name[len(stashmod.stashprefix):] + if name.startswith('.'): + name = '' + ui.write("%d %s@%d:%s - %s\n" % (i, name, ctx.p1().rev(), + short(ctx.p1().node()), ctx.description())) + return + + if name: + try: + name = int(name) + except ValueError: + name = stashmod.stashprefix + name + + if pop or apply: + name, ctx = stashmod.get(repo, name) + stats = stashmod.apply(repo, ctx, **opts) + if stats and stats[3] > 0: + if pop: + raise util.Abort(_('unresolved conflicts, not popping'), + hint=_('use hg resolve and ' + 'hg stash --delete')) + else: + raise util.Abort(_('unresolved conflicts'), + hint=_('use hg resolve')) + if pop: + stashmod.delete(ui, repo, name) + elif delete: + name, ctx = stashmod.get(repo, name) + stashmod.delete(ui, repo, name) + elif show: + name, ctx = stashmod.get(repo, name) + diff(ui, repo, change=ctx.rev()) + else: + ret = stashmod.create(ui, repo, name, **opts) + if ret: + ui.write(_("stashed working dir (hg stash --pop to unstash)\n")) + @command('^status|st', [('A', 'all', None, _('show status of all files')), ('m', 'modified', None, _('show only modified files')), diff --git a/mercurial/hg.py b/mercurial/hg.py --- a/mercurial/hg.py +++ b/mercurial/hg.py @@ -457,12 +457,13 @@ returns stats (see pydoc mercurial.merge.applyupdates)""" return mergemod.update(repo, node, False, overwrite, None) -def update(repo, node): +def update(repo, node, show_stats=True): """update the working directory to node, merging linear changes""" stats = updaterepo(repo, node, False) - _showstats(repo, stats) - if stats[3]: - repo.ui.status(_("use 'hg resolve' to retry unresolved file merges\n")) + if show_stats: + _showstats(repo, stats) + if stats[3]: + repo.ui.status(_("use 'hg resolve' to retry unresolved file merges\n")) return stats[3] > 0 # naming conflict in clone() diff --git a/mercurial/stash.py b/mercurial/stash.py new file mode 100644 --- /dev/null +++ b/mercurial/stash.py @@ -0,0 +1,129 @@ +from node import nullid, short +from i18n import _ +import hg, bookmarks, cmdutil, util, repair, phases, obsolete +import merge as mergemod + +stashprefix = '.hg/stash/' + +def create(ui, repo, name=None, **opts): + curr = repo[None] + if len(curr.parents()) > 1: + raise util.Abort(_('cannot stash when merging')) + # stashes are marked using a bookmark with a special prefix + stashes = list_(repo) + if name in stashes: + raise util.Abort(_('stash %s already exists') % name) + + e = cmdutil.commiteditor + if not opts['message'] and not opts['logfile']: + # we don't translate commit messages + opts['message'] = "Stashed working directory at %s" % str(curr.p1()) + + def commitfunc(ui, repo, message, match, opts): + return repo.commit(message, opts.get('user'), opts.get('date'), + match, editor=e) + ph = repo.ui.config('phases', 'new-commit', phases.draft) + try: + repo.ui.setconfig('phases', 'new-commit', 'secret') + node = cmdutil.commit(ui, repo, commitfunc, [], opts) + finally: + repo.ui.setconfig('phases', 'new-commit', ph) + if not node: + ui.status(_("nothing to stash\n")) + return + + ctx = repo[node] + ret = hg.update(repo, ctx.p1().node(), False) + assert not ret + + if ctx in set(stashes.values()): + sortedstash = sorted(stashes.iteritems(), key=lambda kv: kv[1].rev()) + for i, (name, sctx) in enumerate(sortedstash): + if ctx == sctx: + index = stashprefix + str(i) + break + ui.status(_("same changes already stashed at %s\n") % index) + return + + marks = repo._bookmarks + # if no name was given, use '.' + if not name: + name = stashprefix + '.' + str(ctx) + marks[name] = ctx.node() + marks.write() + + return name, ctx + +def list_(repo): + '''return a dict of stash name -> stash ctx''' + d = {} + for mark, n in repo._bookmarks.iteritems(): + if mark.startswith(stashprefix): + d[mark] = repo[n] + return d + +def get(repo, id_=None): + """ + if id_ = None, get the most recent stash (the one whose revision is + maximal. when it's an int, sort the stashes by revision and use it as an + index. otherwise, find a named stash with that name. + """ + stashes = list_(repo) + if id_ is None: + if stashes: + return max(stashes.iteritems(), key=lambda kv: kv[1].rev()) + else: + raise util.Abort(_('there are no stashes')) + else: + if isinstance(id_, int): + if id_ >= len(stashes): + raise util.Abort(_("stash index out of range")) + return sorted(stashes.iteritems(), + key=lambda kv: kv[1].rev())[id_] + else: + try: + return id_, stashes[id_] + except KeyError: + raise util.Abort(_("stash %s doesn't exist") % + id_[len(stashprefix):]) + +def apply(repo, ctx, force=False, **opts): + wctx = repo[None] + if not force and wctx.dirty(branch=False): + raise util.Abort(_('cannot apply with a dirty working directory'), + hint=_('use -f to force')) + + wlock = repo.wlock() + try: + # ui.forcemerge is an internal variable, do not document + repo.ui.setconfig('ui', 'forcemerge', opts.get('tool', '')) + try: + stats = mergemod.update(repo, ctx.node(), True, True, + False, ctx.p1().node(), True) + finally: + repo.ui.setconfig('ui', 'forcemerge', '') + + # drop the second merge parent + repo.setparents(wctx.p1().node(), nullid) + repo.dirstate.write() + # fix up dirstate for copies and renames + cmdutil.duplicatecopies(repo, ctx.rev(), ctx.p1().rev()) + + return stats + finally: + wlock.release() + +def delete(ui, repo, name): + ctx = repo[name] + if ctx.children(): + raise util.Abort(_('stash has children changesets, cannot delete')) + lock = repo.lock() + try: + del repo._bookmarks[name] + repo._bookmarks.write() + if obsolete._enabled: + obsolete.createmarkers(repo, [(ctx, ())]) + else: + repair.strip(ui, repo, [ctx.node()], topic='stash-backup') + finally: + lock.release() diff --git a/tests/test-stash.t b/tests/test-stash.t new file mode 100644 --- /dev/null +++ b/tests/test-stash.t @@ -0,0 +1,235 @@ + $ cat <> $HGRCPATH + > [extensions] + > graphlog= + > [defaults] + > glog = --template "{rev}:{node|short} {bookmarks} {desc}\\n" + > [alias] + > slog = log --template "{rev}:{node|short} {bookmarks} {desc}\\n" + > EOF + $ hg init + +basic setup and testing: + + $ touch a + $ hg ci -qAm. + $ hg stash + nothing to stash + $ hg stash --list + $ hg stash -d + abort: there are no stashes + [255] + $ hg stash -a + abort: there are no stashes + [255] + $ hg stash -s + abort: there are no stashes + [255] + $ hg stash -d foo + abort: stash foo doesn't exist + [255] + $ hg stash -a foo + abort: stash foo doesn't exist + [255] + $ hg stash -s foo + abort: stash foo doesn't exist + [255] + +stash a modification: + + $ echo a >> a + $ hg slog + 0:7f6b67e0497a . + $ hg stash + stashed working dir (hg stash --pop to unstash) + $ hg slog + 0:7f6b67e0497a . + $ hg stash --list + 0 @0:7f6b67e0497a - Stashed working directory at 7f6b67e0497a + $ hg stash -s + diff -r 7f6b67e0497a -r * a (glob) + --- a/a Thu Jan 01 00:00:00 1970 +0000 + +++ b/a * (glob) + @@ -0,0 +1,1 @@ + +a + +already stashed: (disabled for now since internal stash commit uses current date) + +$ echo a >> a +$ hg stash +same changes already stashed at .hg/stash/0 + +apply it: + + $ hg stash -a + $ hg parents + changeset: 0:7f6b67e0497a + tag: tip + user: test + date: Thu Jan 01 00:00:00 1970 +0000 + summary: . + + $ hg diff --nodates + diff -r 7f6b67e0497a a + --- a/a + +++ b/a + @@ -0,0 +1,1 @@ + +a + $ hg up -C . + 1 files updated, 0 files merged, 0 files removed, 0 files unresolved + $ echo b >> b + $ hg ci -qAm. + +pop it (different parents): + + $ hg stash --pop + saved backup bundle to $TESTTMP/.hg/strip-backup/*-stash-backup.hg (glob) + $ hg stash --list + $ hg diff --nodates + diff -r 901c2d3ce0fb a + --- a/a + +++ b/a + @@ -0,0 +1,1 @@ + +a + +named stash: + + $ echo c > c + $ echo a >> a + $ hg stash -A foo + adding c + stashed working dir (hg stash --pop to unstash) + $ hg stash --list + 0 foo at 1:901c2d3ce0fb - Stashed working directory at 901c2d3ce0fb + $ hg stash -s foo + diff -r 901c2d3ce0fb -r * a (glob) + --- a/a Thu Jan 01 00:00:00 1970 +0000 + +++ b/a * (glob) + @@ -0,0 +1,2 @@ + +a + +a + diff -r 901c2d3ce0fb -r * c (glob) + --- /dev/null Thu Jan 01 00:00:00 1970 +0000 + +++ b/c * (glob) + @@ -0,0 +1,1 @@ + +c + $ hg stash -a + $ hg stash -d foo + saved backup bundle to $TESTTMP/.hg/strip-backup/*-stash-backup.hg (glob) + +create several unnamed stashes: + + $ echo a >> a + $ hg stash + stashed working dir (hg stash --pop to unstash) + $ echo aa >> a + $ hg stash -m wip + stashed working dir (hg stash --pop to unstash) + $ echo aaa >> a + $ hg stash + stashed working dir (hg stash --pop to unstash) + $ hg stash --list + 0 @1:901c2d3ce0fb - Stashed working directory at 901c2d3ce0fb + 1 @1:901c2d3ce0fb - wip + 2 @1:901c2d3ce0fb - Stashed working directory at 901c2d3ce0fb + +apply them with a conflict: + + $ hg stash --pop 1 + saved backup bundle to $TESTTMP/.hg/strip-backup/*-stash-backup.hg (glob) + $ hg stash --list + 0 @1:901c2d3ce0fb - Stashed working directory at 901c2d3ce0fb + 1 @1:901c2d3ce0fb - Stashed working directory at 901c2d3ce0fb + $ hg stash -f -a + merging a + warning: conflicts during merge. + merging a incomplete! (edit conflicts, then use 'hg resolve --mark') + abort: unresolved conflicts + (use hg resolve) + [255] + $ hg update --clean . && rm a.orig + 1 files updated, 0 files merged, 0 files removed, 0 files unresolved + $ hg res -l + +use mergetool when applying: + + $ hg stash -f --pop --tool "internal:other" + saved backup bundle to $TESTTMP/.hg/strip-backup/*-stash-backup.hg (glob) + $ hg res -l + $ hg diff --nodates + diff -r 901c2d3ce0fb a + --- a/a + +++ b/a + @@ -0,0 +1,1 @@ + +aaa + $ hg stash -d + saved backup bundle to $TESTTMP/.hg/strip-backup/*-stash-backup.hg (glob) + +test that renames are preserved: + + $ hg up -qC . + $ hg mv b c + $ hg st --copies + A c + b + R b + $ hg stash + stashed working dir (hg stash --pop to unstash) + $ hg stash --pop + saved backup bundle to $TESTTMP/.hg/strip-backup/*-stash-backup.hg (glob) + $ hg st --copies + A c + b + R b + $ hg revert -q -a --no-backup + +stashed commits shouldn't be exchanged on push/pull: + + $ echo a >> a + $ hg stash + stashed working dir (hg stash --pop to unstash) + $ hg clone . clone + requesting all changes + adding changesets + adding manifests + adding file changes + added 2 changesets with 2 changes to 2 files + updating to branch default + 2 files updated, 0 files merged, 0 files removed, 0 files unresolved + $ cd clone + $ hg slog + 1:901c2d3ce0fb . + 0:7f6b67e0497a . + $ hg stash --list + $ cd .. && rm -r clone + +obsolete the parent of a stashed commit: + + $ hg up 0 -q + $ cat > obs.py << EOF + > import mercurial.obsolete + > mercurial.obsolete._enabled = True + > EOF + $ echo '[extensions]' >> $HGRCPATH + $ echo "obs=${TESTTMP}/obs.py" >> $HGRCPATH + + $ hg debugobsolete $(hg log --template '{node}' -r 1) + $ hg stash --list + 0 @1:901c2d3ce0fb - Stashed working directory at 901c2d3ce0fb + +obsolete enabled, pop won't strip: + + $ hg stash --pop + +no stashing with mq: + + $ printf '[extensions]\nmq=\n' >> $HGRCPATH + $ hg qnew foo + $ echo a >> a + $ hg stash + abort: cannot stash with applied patches + [255] + $ hg revert -a --no-backup -q + $ hg qpop + popping foo + patch queue now empty + $ hg qrm foo From idankk86 at gmail.com Thu Feb 14 18:22:30 2013 From: idankk86 at gmail.com (Idan Kamara) Date: Fri, 15 Feb 2013 02:22:30 +0200 Subject: [PATCH 2 of 2 RFCv2] commands: introduce stash command In-Reply-To: <06dd5eda17402c1e89a1.1360887323@idan> References: <06dd5eda17402c1e89a1.1360887323@idan> Message-ID: On Fri, Feb 15, 2013 at 2:15 AM, Idan Kamara wrote: > > # HG changeset patch > # User Idan Kamara > # Date 1360886982 -7200 > # Node ID 06dd5eda17402c1e89a1aa212e340b146394fad8 > # Parent d4c029076cf2213ad680a53dfd32b0886b2b7be0 > commands: introduce stash command I forgot to mention that the main change from v1 is the fact that stashed commits can now enjoy Pierre-Yves's work on changelog filtering (thanks:). -------------- next part -------------- An HTML attachment was scrubbed... URL: From mads at kiilerich.com Thu Feb 14 19:00:58 2013 From: mads at kiilerich.com (Mads Kiilerich) Date: Fri, 15 Feb 2013 02:00:58 +0100 Subject: [PATCH 2 of 2 V4] hgweb: teach archive how to handle file patterns In-Reply-To: References: <511C3E28.8050205@kiilerich.com> Message-ID: <511D88CA.1040505@kiilerich.com> Angel Ezquerra wrote, On 02/14/2013 09:22 AM: > On Thu, Feb 14, 2013 at 2:30 AM, Mads Kiilerich wrote: >> Angel Ezquerra wrote, On 02/10/2013 11:56 AM: >> If something in this area is needed then I would suggest focusing on just >> making it possible to download a single directory as tar file. There is no >> need for a pattern - we only need a path after the archive, for instance >> .../archive/REV.tar.bz2/sub/dir . > This will definitely be possible and even accessible through the web > interface. I'd just like to also be able to do: > > .../archive/REV.tar.bz2/sub/dir/**.{c,h} I don't know what Matt has suggested, but I would suggest targeting the "download a single folder" use case first. Support for ".../archive/REV.tar.bz2/sub/dir/" could be exposed in the UI and it would be simple and it would be obvious what it did and it would be somewhat useful. Patterns could perhaps be added later. It would be an extension of the existing functionality and the syntax would be (sufficiently) backwards compatible. /Mads From angel.ezquerra at gmail.com Thu Feb 14 19:23:25 2013 From: angel.ezquerra at gmail.com (Angel Ezquerra) Date: Fri, 15 Feb 2013 02:23:25 +0100 Subject: [PATCH 2 of 2 V4] hgweb: teach archive how to handle file patterns In-Reply-To: <511D88CA.1040505@kiilerich.com> References: <511C3E28.8050205@kiilerich.com> <511D88CA.1040505@kiilerich.com> Message-ID: On Fri, Feb 15, 2013 at 2:00 AM, Mads Kiilerich wrote: > Angel Ezquerra wrote, On 02/14/2013 09:22 AM: >> >> On Thu, Feb 14, 2013 at 2:30 AM, Mads Kiilerich >> wrote: >>> >>> Angel Ezquerra wrote, On 02/10/2013 11:56 AM: >>> If something in this area is needed then I would suggest focusing on just >>> making it possible to download a single directory as tar file. There is >>> no >>> need for a pattern - we only need a path after the archive, for instance >>> .../archive/REV.tar.bz2/sub/dir . >> >> This will definitely be possible and even accessible through the web >> interface. I'd just like to also be able to do: >> >> .../archive/REV.tar.bz2/sub/dir/**.{c,h} > > > I don't know what Matt has suggested, but I would suggest targeting the > "download a single folder" use case first. Support for > ".../archive/REV.tar.bz2/sub/dir/" could be exposed in the UI and it would > be simple and it would be obvious what it did and it would be somewhat > useful. > > Patterns could perhaps be added later. It would be an extension of the > existing functionality and the syntax would be (sufficiently) backwards > compatible. > > /Mads OK, I will reduce the scope of the patch for now, and expose it through the web interface as I planned. I'll propose the extension to use some limited sort of patterns on a separate patch. Cheers, Angel From matt_harbison at yahoo.com Thu Feb 14 21:49:29 2013 From: matt_harbison at yahoo.com (Matt Harbison) Date: Fri, 15 Feb 2013 03:49:29 +0000 (UTC) Subject: [PATCH] subrepo: do not push "clean" subrepos when the parent repo is pushed References: <26276460d54aecdeb107.1360800378@Angel-PC.localdomain> Message-ID: On Thu, 14 Feb 2013 01:13:44 +0100, Angel Ezquerra wrote: > On Thu, Feb 14, 2013 at 1:06 AM, Angel Ezquerra > wrote: ... > This is step one in the plan that Matt, Martin and I discussed to > improve subrepos during the London sprint. Is there a brief overview of the plan somewhere? > I also am working on step two of the plan, which was to add a > "--subrepos" flag to hg push. Is this your idea about passing (some?) parameters to subrepos [1]? If so, does 'outgoing' need the same method of filtering the option dict [2] for consistency? (I was a bit surprised that outgoing -S passes along the --rev option, which causes it to abort in the subrepo with a (parent) hash, or lie or abort if given a rev.) There's also a couple bugs written about --addremove not being passed along, so what to pass or not seems like a wider (general?) problem. FWIW, I've got code that seems to be able to honor the -r flag for 'outgoing' and 'push' (issue2314) [3], including the case where the parent commits an older version of the subrepo after a newer version. I wasn't happy with how I had to hack the option dict after translating --rev, but it sounds like you are working in this area anyway. So I'll try to submit this as a (rough) RFC this weekend, and assuming the concept is OK, we will probably need to coordinate how options are handed off to subrepos for 'push' and 'outgoing'. --Matt [1] http://www.selenic.com/pipermail/mercurial-devel/2011- September/034435.html [2] http://www.selenic.com/pipermail/mercurial-devel/2011- September/034453.html [3] http://bz.selenic.com/show_bug.cgi?id=2314 From matt_harbison at yahoo.com Thu Feb 14 21:57:50 2013 From: matt_harbison at yahoo.com (Matt Harbison) Date: Thu, 14 Feb 2013 22:57:50 -0500 Subject: [PATCH 0 of 4 STABLE V3] print chained subrepo exceptions Message-ID: This addresses Mads' suggestions from V2. The first patch is unchanged, the second makes the test more stable by not printing the full traceback, and the third became 3 and 4 here without the ui.tracebackflag hack. From matt_harbison at yahoo.com Thu Feb 14 21:57:52 2013 From: matt_harbison at yahoo.com (Matt Harbison) Date: Thu, 14 Feb 2013 22:57:52 -0500 Subject: [PATCH 2 of 4 STABLE V3] ui: add support for fully printing chained exception stacks in ui.traceback() In-Reply-To: References: Message-ID: <18b83d035077297b4da6.1360900672@Envy> # HG changeset patch # User Matt Harbison # Date 1360437334 18000 # Branch stable # Node ID 18b83d035077297b4da66bbd177743533870b061 # Parent 620ec1695340dc622212356dee673807d6a853f0 ui: add support for fully printing chained exception stacks in ui.traceback() Currently, only SubrepoAbort has a cause chained to it. diff --git a/mercurial/ui.py b/mercurial/ui.py --- a/mercurial/ui.py +++ b/mercurial/ui.py @@ -686,11 +686,23 @@ only to call in exception handler. returns true if traceback printed.''' if self.tracebackflag: - if exc: + if exc is None: + exc = sys.exc_info() + cause = getattr(exc[1], 'cause', None) + + if cause is not None: + causetb = traceback.format_tb(cause[2]) + exctb = traceback.format_tb(exc[2]) + exconly = traceback.format_exception_only(cause[0], cause[1]) + + # exclude frame where 'exc' was chained and rethrown from exctb + self.write_err('Traceback (most recent call last):\n', + ''.join(exctb[:-1]), + ''.join(causetb), + ''.join(exconly)) + else: traceback.print_exception(exc[0], exc[1], exc[2], file=self.ferr) - else: - traceback.print_exc(file=self.ferr) return self.tracebackflag def geteditor(self): diff --git a/tests/test-subrepo.t b/tests/test-subrepo.t --- a/tests/test-subrepo.t +++ b/tests/test-subrepo.t @@ -648,6 +648,11 @@ abort: default path for subrepository not found (in subrepo sub/repo) (glob) [255] +Ensure a full traceback, not just the SubrepoAbort part + + $ hg -R issue1852b update --traceback 2>&1 | grep 'raise util\.Abort' + raise util.Abort(_("default path for subrepository not found")) + Pull -u now doesn't help $ hg -R issue1852b pull -u issue1852a From matt_harbison at yahoo.com Thu Feb 14 21:57:51 2013 From: matt_harbison at yahoo.com (Matt Harbison) Date: Thu, 14 Feb 2013 22:57:51 -0500 Subject: [PATCH 1 of 4 STABLE V3] subrepo: chain the original exception to SubrepoAbort In-Reply-To: References: Message-ID: <620ec1695340dc622212.1360900671@Envy> # HG changeset patch # User Matt Harbison # Date 1360209249 18000 # Branch stable # Node ID 620ec1695340dc622212356dee673807d6a853f0 # Parent 227479f61db9d169c1afea6fa0a9dce7288d4932 subrepo: chain the original exception to SubrepoAbort The tracebacks in subrepos are truncated at the point where the original exception is caught and SubrepoAbort is raised in its place since 9e3910db4e78. That hides the most relevant subrepo methods when an error occurs. Python 2.x doesn't support chaining exceptions, so it is manually done here for manual printing later. diff --git a/mercurial/subrepo.py b/mercurial/subrepo.py --- a/mercurial/subrepo.py +++ b/mercurial/subrepo.py @@ -5,7 +5,7 @@ # This software may be used and distributed according to the terms of the # GNU General Public License version 2 or any later version. -import errno, os, re, xml.dom.minidom, shutil, posixpath +import errno, os, re, xml.dom.minidom, shutil, posixpath, sys import stat, subprocess, tarfile from i18n import _ import config, scmutil, util, node, error, cmdutil, bookmarks, match as matchmod @@ -19,6 +19,7 @@ def __init__(self, *args, **kw): error.Abort.__init__(self, *args, **kw) self.subrepo = kw.get('subrepo') + self.cause = kw.get('cause') def annotatesubrepoerror(func): def decoratedmethod(self, *args, **kargs): @@ -31,7 +32,8 @@ subrepo = subrelpath(self) errormsg = str(ex) + ' ' + _('(in subrepo %s)') % subrepo # avoid handling this exception by raising a SubrepoAbort exception - raise SubrepoAbort(errormsg, hint=ex.hint, subrepo=subrepo) + raise SubrepoAbort(errormsg, hint=ex.hint, subrepo=subrepo, + cause=sys.exc_info()) return res return decoratedmethod From matt_harbison at yahoo.com Thu Feb 14 21:57:53 2013 From: matt_harbison at yahoo.com (Matt Harbison) Date: Thu, 14 Feb 2013 22:57:53 -0500 Subject: [PATCH 3 of 4 STABLE V3] ui: add 'force' parameter to traceback() to override the current print setting In-Reply-To: References: Message-ID: <531876e328ce07dd3a93.1360900673@Envy> # HG changeset patch # User Matt Harbison # Date 1360437772 18000 # Branch stable # Node ID 531876e328ce07dd3a93ea00e63b00afdfd0b806 # Parent 18b83d035077297b4da66bbd177743533870b061 ui: add 'force' parameter to traceback() to override the current print setting This will allow a current traceback.print_exc() call in dispatch to be replaced with ui.traceback() even if --traceback was not given on the command line. diff --git a/mercurial/ui.py b/mercurial/ui.py --- a/mercurial/ui.py +++ b/mercurial/ui.py @@ -681,11 +681,11 @@ return t - def traceback(self, exc=None): - '''print exception traceback if traceback printing enabled. + def traceback(self, exc=None, force=False): + '''print exception traceback if traceback printing enabled or forced. only to call in exception handler. returns true if traceback printed.''' - if self.tracebackflag: + if self.tracebackflag or force: if exc is None: exc = sys.exc_info() cause = getattr(exc[1], 'cause', None) @@ -703,7 +703,7 @@ else: traceback.print_exception(exc[0], exc[1], exc[2], file=self.ferr) - return self.tracebackflag + return self.tracebackflag or force def geteditor(self): '''return editor to use''' From matt_harbison at yahoo.com Thu Feb 14 21:57:54 2013 From: matt_harbison at yahoo.com (Matt Harbison) Date: Thu, 14 Feb 2013 22:57:54 -0500 Subject: [PATCH 4 of 4 STABLE V3] dispatch: drop the traceback module import in favor of using ui.traceback() In-Reply-To: References: Message-ID: <6e1745620172f71a9ec7.1360900674@Envy> # HG changeset patch # User Matt Harbison # Date 1360439790 18000 # Branch stable # Node ID 6e1745620172f71a9ec702939227d509b13c756e # Parent 531876e328ce07dd3a93ea00e63b00afdfd0b806 dispatch: drop the traceback module import in favor of using ui.traceback() This ensures chained exception tracebacks are printed when using the --debugger option. diff --git a/mercurial/dispatch.py b/mercurial/dispatch.py --- a/mercurial/dispatch.py +++ b/mercurial/dispatch.py @@ -6,7 +6,7 @@ # GNU General Public License version 2 or any later version. from i18n import _ -import os, sys, atexit, signal, pdb, socket, errno, shlex, time, traceback, re +import os, sys, atexit, signal, pdb, socket, errno, shlex, time, re import util, commands, hg, fancyopts, extensions, hook, error import cmdutil, encoding import ui as uimod @@ -91,7 +91,7 @@ except: # re-raises # enter the debugger when we hit an exception if '--debugger' in req.args: - traceback.print_exc() + ui.traceback(sys.exc_info(), True) pdb.post_mortem(sys.exc_info()[2]) ui.traceback() raise From matt_harbison at yahoo.com Thu Feb 14 22:18:54 2013 From: matt_harbison at yahoo.com (Matt Harbison) Date: Fri, 15 Feb 2013 04:18:54 +0000 (UTC) Subject: [PATCH 4 of 4 STABLE V3] dispatch: drop the traceback module import in favor of using ui.traceback() References: <6e1745620172f71a9ec7.1360900674@Envy> Message-ID: On Thu, 14 Feb 2013 22:57:54 -0500, Matt Harbison wrote: > # HG changeset patch # User Matt Harbison > # Date 1360439790 18000 # Branch stable # Node ID > 6e1745620172f71a9ec702939227d509b13c756e # Parent > 531876e328ce07dd3a93ea00e63b00afdfd0b806 dispatch: drop the traceback > module import in favor of using ui.traceback() > > This ensures chained exception tracebacks are printed when using the > --debugger option. > For some reason, I got really strange output when I tried to write a test for this (almost looks like stdout and stderr output is interwoven). Worse, if the changes were accepted and the test run again, the entire test would fail and exit with code 258. Is this a known problem with using --debugger in the test suite (which probably isn't useful anyway), a silly configuration issue on my end, or something else? Below is a patch that can be applied on top of #4 to see the issue. A rerun will cause the test to fail with: + c:\temp\tmp6yk028hg-tst: line 447: syntax error near unexpected token `87' + c:\temp\tmp6yk028hg-tst: line 447: `c:\users\matt\projects\hg\mercurial\dispatch.py(87)_runcatch()' One of the odd things is dispatch.py line 87 corresponds to a line with nothing but 'try:'. I ran it with: python run-tests.py --local -i test-subrepo.t -t 600 diff --git a/tests/test-subrepo.t b/tests/test-subrepo.t --- a/tests/test-subrepo.t +++ b/tests/test-subrepo.t @@ -650,8 +650,47 @@ Ensure a full traceback, not just the SubrepoAbort part - $ hg -R issue1852b update --traceback 2>&1 | grep 'raise util\.Abort' - raise util.Abort(_("default path for subrepository not found")) + $ hg -R issue1852b update --debugger + entering debugger - type c to continue starting hg or h for help + > c:\users\matt\projects\hg\mercurial\dispatch.py(87)_runcatch() + -> try: + (Pdb) + > c:\python27_x86\lib\bdb.py(67)dispatch_line() + -> if self.quitting: raise BdbQuit + (Pdb) + Traceback (most recent call last): + File "c:\Users\Matt\Projects\hg\mercurial\dispatch.py", line 87, in _runcatch + try: + File "c:\Users\Matt\Projects\hg\mercurial\dispatch.py", line 87, in _runcatch + try: + File "c:\Python27_x86\lib\bdb.py", line 48, in trace_dispatch + return self.dispatch_line(frame) + File "c:\Python27_x86\lib\bdb.py", line 67, in dispatch_line + if self.quitting: raise BdbQuit + BdbQuit + ** unknown exception encountered, please report by visiting + ** http://mercurial.selenic.com/wiki/BugTracker + ** Python 2.7.2 (default, Jun 12 2011, 15:08:59) [MSC v.1500 32 bit (Intel)] + ** Mercurial Distributed SCM (version 2.5.1+6-2ca4aad59a18+20130215) + ** Extensions loaded: + Traceback (most recent call last): + File "c:/Users/Matt/Projects/hg/hg", line 38, in + mercurial.dispatch.run() + File "c:\Users\Matt\Projects\hg\mercurial\dispatch.py", line 28, in run + sys.exit((dispatch(request(sys.argv[1:])) or 0) & 255) + File "c:\Users\Matt\Projects\hg\mercurial\dispatch.py", line 65, in dispatch + return _runcatch(req) + File "c:\Users\Matt\Projects\hg\mercurial\dispatch.py", line 87, in _runcatch + try: + File "c:\Users\Matt\Projects\hg\mercurial\dispatch.py", line 87, in _runcatch + try: + File "c:\Python27_x86\lib\bdb.py", line 48, in trace_dispatch + return self.dispatch_line(frame) + File "c:\Python27_x86\lib\bdb.py", line 67, in dispatch_line + if self.quitting: raise BdbQuit + bdb.BdbQuit + [1] +# 2>&1 | grep 'raise util\.Abort' Pull -u now doesn't help From angel.ezquerra at gmail.com Fri Feb 15 05:18:07 2013 From: angel.ezquerra at gmail.com (Angel Ezquerra) Date: Fri, 15 Feb 2013 12:18:07 +0100 Subject: [PATCH] subrepo: do not push "clean" subrepos when the parent repo is pushed In-Reply-To: References: <26276460d54aecdeb107.1360800378@Angel-PC.localdomain> Message-ID: On Fri, Feb 15, 2013 at 4:49 AM, Matt Harbison wrote: > On Thu, 14 Feb 2013 01:13:44 +0100, Angel Ezquerra wrote: > >> On Thu, Feb 14, 2013 at 1:06 AM, Angel Ezquerra >> wrote: > > ... > >> This is step one in the plan that Matt, Martin and I discussed to >> improve subrepos during the London sprint. > > Is there a brief overview of the plan somewhere? I wrote a summary on the titanpad that we used during the sprint: http://titanpad.com/mercurial26 I've taken that and updated it a little with what has been discussed in this thread and my own thinking since them: * Discuss ways to improve some of the subrepo pain points - angel, mg - add way to pull subrepos with hg pull - just push changed subrepos - subrepos are eternal - We had a discussion with mpm on this and we believe we have a good plan: - Add -S/--subrepos flag to hg pull - Add cleanstore() method to subrepos which can tell pull/push if a subrepo store has changes. If not we can ignore it during push - The cleanstore method would check a timestamp or sha1 of the bookmarks, phaseroots and the changelog, but not the dirstatedirstate dirstate - Updated on clone and push; but also on pull if the store is already clean - Only push not cleanstore() subrepos - subrepo.deletable(): if self.clean() and dirstate working dir is clean() - fix Merge bug which makes subrepos stay on the working directory on update even if there are files on the parent that should go on the folder occupied by the subrepo - using deletable() we could remove subrepos from the working dir... - however this could cause data loss on update on a "central" repository containing relative subrepos. On non central subrepos it would require recloning the subrepo when updating back to a revision referring to that subrepo. - Introduce subrepo caching (this would fix the problem above and improve pull time considerably when subrepos are deleted) - Cloning would need to be smart enough to look on the subrepo cache. Otherwise it would not be possible to pull from central repositories that were are at revision -1 (since all subrepos would be on the cache, and none on the workind directory). - Document subpaths patterns that can make relative subrepos work with bitbucket and google code Perhaps it would be worth adding this to the wiki? >> I also am working on step two of the plan, which was to add a >> "--subrepos" flag to hg push. > > Is this your idea about passing (some?) parameters to subrepos [1]? If > so, does 'outgoing' need the same method of filtering the option dict [2] > for consistency? (I was a bit surprised that outgoing -S passes along the > --rev option, which causes it to abort in the subrepo with a (parent) > hash, or lie or abort if given a rev.) There's also a couple bugs written > about --addremove not being passed along, so what to pass or not seems > like a wider (general?) problem. The way I've implemented it is very similar to how the current subrepo.get() works. Basically I want hg pull --subrepos to behave as if you first did "hg pull" and then you did "hg update -r" for every new revision that "hg pull" brought into the repository. The idea is to make sure that you are able to update to any new revision without needing to have any network access (i.e. that the repository is self contained after doing hg pull --subrepos, as long as it already was self contained before). Martin Gesiler helped me with this patch during the sprint and he has been helping me since then. I'll send a patch soon. That being said, out of the options that pull takes there are a lot that do not make sense when pulling from subrepos, particularly --rev, --bookmark, --branch and specially --rebase. I think that if you need to do something special while pulling a subrepo perhaps it would be best to get into the subrepo and do a regular pull, or perhaps use the onsub extension (which I wish we integrated into mercurial). One thing that would help there would be to have a way to refer to the parent paths when pulling from within a subrepo. This would be particularly handy when using relative subrepo definitions, as you should. > FWIW, I've got code that seems to be able to honor the -r flag for > 'outgoing' and 'push' (issue2314) [3], including the case where the parent > commits an older version of the subrepo after a newer version. I wasn't > happy with how I had to hack the option dict after translating --rev, but > it sounds like you are working in this area anyway. So I'll try to submit > this as a (rough) RFC this weekend, and assuming the concept is OK, we > will probably need to coordinate how options are handed off to subrepos > for 'push' and 'outgoing'. I'll try to have a look at your patches when I get some time. Angel > [2] http://www.selenic.com/pipermail/mercurial-devel/2011- > September/034453.html > > [3] http://bz.selenic.com/show_bug.cgi?id=2314 > > _______________________________________________ > Mercurial-devel mailing list > Mercurial-devel at selenic.com > http://selenic.com/mailman/listinfo/mercurial-devel From pierre-yves.david at logilab.fr Fri Feb 15 05:31:29 2013 From: pierre-yves.david at logilab.fr (pierre-yves.david at logilab.fr) Date: Fri, 15 Feb 2013 12:31:29 +0100 Subject: [PATCH STABLE] mergetools: vimdiff issue a warning explaining how to abort Message-ID: # HG changeset patch # User Pierre-Yves David # Date 1360924084 -3600 # Branch stable # Node ID cabb74a6dc7a98b63f7ea51b5b87fb613a8be940 # Parent f6f35d646cb5919997d3a23b942594def5d9e243 mergetools: vimdiff issue a warning explaining how to abort Adds a message displayed at each vimdiff invocation: merge conflict detected, type ":cq" to abort Vimdiff is very confusing for non-vim user (not to speak about vim user confused anyway. However it is very likely that vimdiff is picked as the mergetool of choice when using the default config: - vim is available on all UNIX system. - Its one of the rare non graphical merge tools. diff --git a/contrib/mergetools.hgrc b/contrib/mergetools.hgrc --- a/contrib/mergetools.hgrc +++ b/contrib/mergetools.hgrc @@ -13,11 +13,11 @@ gvimdiff.args=--nofork -d -g -O $local $ gvimdiff.regkey=Software\Vim\GVim gvimdiff.regkeyalt=Software\Wow6432Node\Vim\GVim gvimdiff.regname=path gvimdiff.priority=-9 -vimdiff.args=$local $other $base +vimdiff.args=$local $other $base -c 'echohl WarningMsg | echo "merge conflict detected, type \":cq\" to abort" | echohl' vimdiff.check=changed vimdiff.priority=-10 merge.check=conflicts merge.priority=-100 From mercurial-bugs at selenic.com Fri Feb 15 00:49:00 2013 From: mercurial-bugs at selenic.com (mercurial-bugs at selenic.com) Date: Fri, 15 Feb 2013 06:49:00 +0000 Subject: [Bug 3826] New: hg convert with a filemap loses branches Message-ID: http://bz.selenic.com/show_bug.cgi?id=3826 Priority: normal Bug ID: 3826 CC: mercurial-devel at selenic.com Assignee: bugzilla at selenic.com Summary: hg convert with a filemap loses branches Severity: bug Classification: Unclassified OS: All Reporter: dijkstra.arjen at gmail.com Hardware: PC Status: UNCONFIRMED Version: unspecified Component: convert Product: Mercurial If I do a hg convert without a --filemap option from one hg repo to another hg repo, everything is fine. If I do a hg convert with a --filemap option from one hg repo to another hg repo, I keep losing branches. eg: filemap: rename . client2 # convert from client to ique $ hg convert --filemap filemap client ique I do lose some branches (some very important, frequently updated branches) It happened also with a ignore option in my filemap file, but I haven't got that example anymore, sorry. -- You are receiving this mail because: You are on the CC list for the bug. From hg at intevation.org Fri Feb 15 06:00:13 2013 From: hg at intevation.org (Mercurial Commits) Date: Fri, 15 Feb 2013 13:00:13 +0100 Subject: mercurial/crew@18692: 63 outgoing changesets (2 stable) Message-ID: <1360929613.569803.19277.nullmailer@hg.intevation.org> 63 outgoing changesets (2 stable) in mercurial/crew: http://hg.intevation.org/mercurial/crew/rev/af4387d8d1c7 changeset: 18692:af4387d8d1c7 bookmark: @ tag: tip user: Kevin Bullock date: Thu Feb 14 13:56:02 2013 -0600 summary: extensions: remove erroneous comment http://hg.intevation.org/mercurial/crew/rev/4f485bd68f1d changeset: 18691:4f485bd68f1d user: Durham Goode date: Wed Feb 13 12:51:30 2013 -0800 summary: blackbox: do not translate the log messages http://hg.intevation.org/mercurial/crew/rev/4c6f7f0dadab changeset: 18690:4c6f7f0dadab user: Kevin Bullock date: Tue Feb 12 11:36:21 2013 -0600 summary: scmutil: split platform-specific bits into their own modules http://hg.intevation.org/mercurial/crew/rev/12721a20ed30 changeset: 18689:12721a20ed30 user: Kevin Bullock date: Tue Feb 12 16:36:44 2013 +0000 summary: backout: call cmdutil.commit directly instead of commands.commit http://hg.intevation.org/mercurial/crew/rev/79107fad06aa changeset: 18688:79107fad06aa user: Kevin Bullock date: Tue Feb 12 16:32:14 2013 +0000 summary: commit: factor out status printing into a helper function http://hg.intevation.org/mercurial/crew/rev/1d183b33f007 changeset: 18687:1d183b33f007 user: Kevin Bullock date: Tue Feb 12 16:05:00 2013 +0000 summary: backout: remove unnecessary dict copy http://hg.intevation.org/mercurial/crew/rev/0bca4d31f647 changeset: 18686:0bca4d31f647 user: Kevin Bullock date: Tue Feb 12 15:47:30 2013 +0000 summary: backout: remove unnecessary frobbing of addremove option http://hg.intevation.org/mercurial/crew/rev/fafdff7e9c43 changeset: 18685:fafdff7e9c43 user: Kevin Bullock date: Tue Feb 12 15:07:17 2013 +0000 summary: backout: use cmdutil.revert directly instead of commands.revert http://hg.intevation.org/mercurial/crew/rev/c161e4cf77d4 changeset: 18684:c161e4cf77d4 parent: 18683:a343eccd5ee2 parent: 18679:f6f35d646cb5 user: Kevin Bullock date: Wed Feb 13 15:09:43 2013 -0600 summary: merge with stable http://hg.intevation.org/mercurial/crew/rev/a343eccd5ee2 changeset: 18683:a343eccd5ee2 user: Simon Heimberg date: Wed Feb 13 21:51:47 2013 +0100 summary: check-code: warn about line glob match with no glob character (?*/) http://hg.intevation.org/mercurial/crew/rev/408f2202bd80 changeset: 18682:408f2202bd80 user: Simon Heimberg date: Wed Feb 13 22:05:30 2013 +0100 summary: tests: remove glob from output lines containing no glob character http://hg.intevation.org/mercurial/crew/rev/7591ed29e824 changeset: 18681:7591ed29e824 user: Simon Heimberg date: Mon Oct 15 23:28:45 2012 +0200 summary: tests: inform on Windows about unnecessary glob lines http://hg.intevation.org/mercurial/crew/rev/15711d9d8b2c changeset: 18680:15711d9d8b2c parent: 18678:423eee0b0b14 user: Simon Heimberg date: Wed Feb 13 21:58:52 2013 +0100 summary: tests: quickly check if the glob line already matches the output http://hg.intevation.org/mercurial/crew/rev/f6f35d646cb5 changeset: 18679:f6f35d646cb5 branch: stable parent: 18657:d4a79e075303 user: Simon Heimberg date: Wed Feb 13 12:35:57 2013 +0100 summary: tests: append glob to filename output when required (windows) http://hg.intevation.org/mercurial/crew/rev/423eee0b0b14 changeset: 18678:423eee0b0b14 user: Bryan O'Sullivan date: Wed Feb 13 12:20:10 2013 -0800 summary: util: make ensuredirs safer against races http://hg.intevation.org/mercurial/crew/rev/539210ed2069 changeset: 18677:539210ed2069 user: Durham Goode date: Wed Feb 13 11:07:01 2013 -0800 summary: blackbox: only show new heads on incoming http://hg.intevation.org/mercurial/crew/rev/1506eb487ddd changeset: 18676:1506eb487ddd user: Bryan O'Sullivan date: Wed Feb 13 10:54:52 2013 -0800 summary: blackbox: fix copyright http://hg.intevation.org/mercurial/crew/rev/f816aa377e0d changeset: 18675:f816aa377e0d user: Bryan O'Sullivan date: Tue Feb 12 16:02:35 2013 -0800 summary: blackbox: fix a failing pyflakes test http://hg.intevation.org/mercurial/crew/rev/c61b49d059eb changeset: 18674:c61b49d059eb user: Durham Goode date: Sat Feb 09 13:35:30 2013 -0800 summary: blackbox: tests for the blackbox extension http://hg.intevation.org/mercurial/crew/rev/f27598902007 changeset: 18673:f27598902007 user: Durham Goode date: Sat Feb 09 09:09:46 2013 -0800 summary: blackbox: adds a 'blackbox' command for viewing recent logs http://hg.intevation.org/mercurial/crew/rev/b2b4ddc55caa changeset: 18672:b2b4ddc55caa user: Durham Goode date: Sat Feb 09 09:04:48 2013 -0800 summary: blackbox: log incoming changes via ui.log() http://hg.intevation.org/mercurial/crew/rev/1c305128e5b9 changeset: 18671:1c305128e5b9 user: Durham Goode date: Sat Feb 09 09:04:32 2013 -0800 summary: blackbox: logs python and extension hooks via ui.log() http://hg.intevation.org/mercurial/crew/rev/ddc7268da176 changeset: 18670:ddc7268da176 user: Durham Goode date: Sat Feb 09 09:04:14 2013 -0800 summary: blackbox: log the commands that are run http://hg.intevation.org/mercurial/crew/rev/18242716a014 changeset: 18669:18242716a014 user: Durham Goode date: Tue Feb 12 14:08:33 2013 -0800 summary: blackbox: adds a blackbox extension http://hg.intevation.org/mercurial/crew/rev/4034b8d551b1 changeset: 18668:4034b8d551b1 user: Bryan O'Sullivan date: Mon Feb 11 16:15:12 2013 -0800 summary: scmutil: create directories in a race-safe way during update http://hg.intevation.org/mercurial/crew/rev/f12804d3ff80 changeset: 18667:f12804d3ff80 parent: 18666:fb9d1c2805ff parent: 18658:5e63a85299ba user: Bryan O'Sullivan date: Mon Feb 11 14:50:54 2013 -0800 summary: Merge http://hg.intevation.org/mercurial/crew/rev/fb9d1c2805ff changeset: 18666:fb9d1c2805ff user: Idan Kamara date: Sat Feb 09 19:02:45 2013 +0200 summary: test-atomictempfile: convert to unit test http://hg.intevation.org/mercurial/crew/rev/2cbfb8c497ee changeset: 18665:2cbfb8c497ee user: Idan Kamara date: Sat Feb 09 19:13:39 2013 +0200 summary: tests: add a test runner utility that prints nothing when all tests pass http://hg.intevation.org/mercurial/crew/rev/30d899febef8 changeset: 18664:30d899febef8 user: Dan Villiom Podlaski Christiansen date: Sun Feb 10 13:14:31 2013 +0100 summary: hgweb: consistent author name width http://hg.intevation.org/mercurial/crew/rev/05cf40f9b0ec changeset: 18663:05cf40f9b0ec user: Durham Goode date: Sun Feb 10 12:23:39 2013 -0800 summary: dirstate: fix generator/list error when using python 2.7 http://hg.intevation.org/mercurial/crew/rev/c5f7e83d47cd changeset: 18662:c5f7e83d47cd user: Pierre-Yves David date: Mon Feb 11 16:21:48 2013 +0100 summary: mq: comply with filtering when injecting fake tags (issue3812) http://hg.intevation.org/mercurial/crew/rev/4fb92f14a97a changeset: 18661:4fb92f14a97a user: David Schleimer date: Fri Feb 08 05:36:08 2013 -0800 summary: commit: factor out post-commit cleanup into workingctx http://hg.intevation.org/mercurial/crew/rev/7e6946ed5756 changeset: 18660:7e6946ed5756 user: David Schleimer date: Fri Feb 08 05:36:08 2013 -0800 summary: localrepo: use workingctx for validation in commit http://hg.intevation.org/mercurial/crew/rev/b946470efed9 changeset: 18659:b946470efed9 parent: 18656:8eb3408bf005 user: David Schleimer date: Fri Feb 08 05:36:07 2013 -0800 summary: localrepo: create context used for actual commit earlier http://hg.intevation.org/mercurial/crew/rev/5e63a85299ba changeset: 18658:5e63a85299ba parent: 18656:8eb3408bf005 parent: 18657:d4a79e075303 user: Thomas Arendsen Hein date: Mon Feb 11 16:57:46 2013 +0100 summary: merge with crew-stable http://hg.intevation.org/mercurial/crew/rev/d4a79e075303 changeset: 18657:d4a79e075303 branch: stable bookmark: crew-stable parent: 18617:227479f61db9 user: Pierre-Yves David date: Sat Feb 09 23:28:42 2013 +0000 summary: debugobsolete: improve command help http://hg.intevation.org/mercurial/crew/rev/8eb3408bf005 changeset: 18656:8eb3408bf005 user: Kevin Bullock date: Sun Feb 10 23:01:12 2013 +0000 summary: import: don't rollback on failed import --exact (issue3616) http://hg.intevation.org/mercurial/crew/rev/882681bc3166 changeset: 18655:882681bc3166 parent: 18653:170142161672 parent: 18654:d9ff580fcaa2 user: Bryan O'Sullivan date: Sun Feb 10 16:22:32 2013 -0800 summary: Merge http://hg.intevation.org/mercurial/crew/rev/d9ff580fcaa2 changeset: 18654:d9ff580fcaa2 parent: 18651:e556659340f0 parent: 18648:013fcd112f13 user: Bryan O'Sullivan date: Sun Feb 10 16:21:30 2013 -0800 summary: Merge http://hg.intevation.org/mercurial/crew/rev/170142161672 changeset: 18653:170142161672 parent: 18652:a5e94bee77ed parent: 18651:e556659340f0 user: Benoit Boissinot date: Mon Feb 11 01:21:24 2013 +0100 summary: merge crew and main http://hg.intevation.org/mercurial/crew/rev/a5e94bee77ed changeset: 18652:a5e94bee77ed parent: 18642:76b69cccb07a parent: 18648:013fcd112f13 user: Benoit Boissinot date: Mon Feb 11 01:17:50 2013 +0100 summary: merge crew and main http://hg.intevation.org/mercurial/crew/rev/e556659340f0 changeset: 18651:e556659340f0 user: Siddharth Agarwal date: Sun Feb 10 16:55:01 2013 +0000 summary: manifestmerge: fix order in which manifests are fetched http://hg.intevation.org/mercurial/crew/rev/de0bd4bfc6d7 changeset: 18650:de0bd4bfc6d7 user: Siddharth Agarwal date: Sun Feb 10 12:16:46 2013 +0000 summary: merge: run _forgetremoved after manifestmerge http://hg.intevation.org/mercurial/crew/rev/0969980308c7 changeset: 18649:0969980308c7 parent: 18642:76b69cccb07a user: Siddharth Agarwal date: Sun Feb 10 16:23:14 2013 +0000 summary: dirstate: disable gc while parsing the dirstate http://hg.intevation.org/mercurial/crew/rev/76b69cccb07a changeset: 18642:76b69cccb07a user: Mads Kiilerich date: Fri Feb 08 22:54:17 2013 +0100 summary: export: show 'Date' header in a format that also is readable for humans http://hg.intevation.org/mercurial/crew/rev/c1d23b4a66d5 changeset: 18641:c1d23b4a66d5 user: Mads Kiilerich date: Sun Feb 10 18:26:04 2013 +0100 summary: factotum: fix urllib2 import so it no longer relies on a demandimport bug http://hg.intevation.org/mercurial/crew/rev/c6a81e54c209 changeset: 18640:c6a81e54c209 user: Mads Kiilerich date: Sun Jan 27 03:32:09 2013 +0100 summary: hgweb: make the test suite use hgweb in a more WSGI compliant way http://hg.intevation.org/mercurial/crew/rev/76ff3a715cf2 changeset: 18639:76ff3a715cf2 user: Mads Kiilerich date: Sun Feb 10 18:24:29 2013 +0100 summary: hgweb: simplify internal staticfile return codes http://hg.intevation.org/mercurial/crew/rev/3e92772d5383 changeset: 18638:3e92772d5383 user: Mads Kiilerich date: Sun Feb 10 18:24:29 2013 +0100 summary: spelling: fix some minor issues found by spell checker http://hg.intevation.org/mercurial/crew/rev/cc28a84db8c9 changeset: 18637:cc28a84db8c9 user: Mads Kiilerich date: Fri Feb 08 23:26:00 2013 +0100 summary: bundlerepo: replace basemap with the base field in the index http://hg.intevation.org/mercurial/crew/rev/a40d608e2a7b changeset: 18636:a40d608e2a7b user: Mads Kiilerich date: Fri Feb 08 22:54:48 2013 +0100 summary: profiling: replace '+' markup of nested lines with indentation http://hg.intevation.org/mercurial/crew/rev/6204e4d4dd6d changeset: 18635:6204e4d4dd6d parent: 18634:0027a5cec9d0 parent: 18633:a8648f32b8ed user: Augie Fackler date: Sun Feb 10 04:04:22 2013 -0600 summary: Merge crew and main. http://hg.intevation.org/mercurial/crew/rev/a8648f32b8ed changeset: 18633:a8648f32b8ed user: Bryan O'Sullivan date: Sat Feb 09 15:51:32 2013 -0800 summary: merge: don't fiddle with name lookups or i18n in hot loops http://hg.intevation.org/mercurial/crew/rev/5774732bb5e5 changeset: 18632:5774732bb5e5 user: Bryan O'Sullivan date: Sat Feb 09 15:51:32 2013 -0800 summary: merge: apply non-interactive working dir updates in parallel http://hg.intevation.org/mercurial/crew/rev/047110c0e2a8 changeset: 18631:047110c0e2a8 user: Bryan O'Sullivan date: Sat Feb 09 15:51:32 2013 -0800 summary: worker: allow a function to be run in multiple worker processes http://hg.intevation.org/mercurial/crew/rev/ac4dbceeb14a changeset: 18630:ac4dbceeb14a user: Bryan O'Sullivan date: Sat Feb 09 15:51:32 2013 -0800 summary: worker: partition a list (of tasks) into equal-sized chunks http://hg.intevation.org/mercurial/crew/rev/dcb27c153a40 changeset: 18629:dcb27c153a40 user: Bryan O'Sullivan date: Sat Feb 09 15:51:26 2013 -0800 summary: worker: estimate whether it's worth running a task in parallel http://hg.intevation.org/mercurial/crew/rev/fed06dd07665 changeset: 18628:fed06dd07665 user: Bryan O'Sullivan date: Sat Feb 09 15:22:12 2013 -0800 summary: worker: count the number of CPUs http://hg.intevation.org/mercurial/crew/rev/4b5d37ca3c11 changeset: 18627:4b5d37ca3c11 user: Bryan O'Sullivan date: Sat Feb 09 15:22:10 2013 -0800 summary: tests: getremove test output changes (fold into previous patch) http://hg.intevation.org/mercurial/crew/rev/6390dd22b12f changeset: 18626:6390dd22b12f user: Bryan O'Sullivan date: Sat Feb 09 15:22:09 2013 -0800 summary: merge: report non-interactive progress in chunks http://hg.intevation.org/mercurial/crew/rev/3e20079117c5 changeset: 18625:3e20079117c5 user: Bryan O'Sullivan date: Sat Feb 09 15:22:08 2013 -0800 summary: merge: handle subrepo merges and .hgsubstate specially http://hg.intevation.org/mercurial/crew/rev/e2dc5397bc82 changeset: 18624:e2dc5397bc82 user: Bryan O'Sullivan date: Sat Feb 09 15:22:04 2013 -0800 summary: tests: update test output (will be folded into parent) http://hg.intevation.org/mercurial/crew/rev/9b9e2d9e83a1 changeset: 18623:9b9e2d9e83a1 user: Bryan O'Sullivan date: Sat Feb 09 15:21:58 2013 -0800 summary: merge: split out mostly-non-interactive working dir updates -- Repository URL: http://hg.intevation.org/mercurial/crew From bboissin at gmail.com Fri Feb 15 06:21:44 2013 From: bboissin at gmail.com (Benoit Boissinot) Date: Fri, 15 Feb 2013 13:21:44 +0100 Subject: [PATCH STABLE] mergetools: vimdiff issue a warning explaining how to abort In-Reply-To: References: Message-ID: Looks good. On Fri, Feb 15, 2013 at 12:31 PM, wrote: > # HG changeset patch > # User Pierre-Yves David > # Date 1360924084 -3600 > # Branch stable > # Node ID cabb74a6dc7a98b63f7ea51b5b87fb613a8be940 > # Parent f6f35d646cb5919997d3a23b942594def5d9e243 > mergetools: vimdiff issue a warning explaining how to abort > > Adds a message displayed at each vimdiff invocation: > > merge conflict detected, type ":cq" to abort > > Vimdiff is very confusing for non-vim user (not to speak about vim user > confused > anyway. However it is very likely that vimdiff is picked as the mergetool > of > choice when using the default config: > - vim is available on all UNIX system. > - Its one of the rare non graphical merge tools. > > diff --git a/contrib/mergetools.hgrc b/contrib/mergetools.hgrc > --- a/contrib/mergetools.hgrc > +++ b/contrib/mergetools.hgrc > @@ -13,11 +13,11 @@ gvimdiff.args=--nofork -d -g -O $local $ > gvimdiff.regkey=Software\Vim\GVim > gvimdiff.regkeyalt=Software\Wow6432Node\Vim\GVim > gvimdiff.regname=path > gvimdiff.priority=-9 > > -vimdiff.args=$local $other $base > +vimdiff.args=$local $other $base -c 'echohl WarningMsg | echo "merge > conflict detected, type \":cq\" to abort" | echohl' > vimdiff.check=changed > vimdiff.priority=-10 > > merge.check=conflicts > merge.priority=-100 > _______________________________________________ > Mercurial-devel mailing list > Mercurial-devel at selenic.com > http://selenic.com/mailman/listinfo/mercurial-devel > -------------- next part -------------- An HTML attachment was scrubbed... URL: From matt_harbison at yahoo.com Fri Feb 15 10:49:33 2013 From: matt_harbison at yahoo.com (Matt Harbison) Date: Fri, 15 Feb 2013 08:49:33 -0800 (PST) Subject: [PATCH 4 of 4 STABLE V3] dispatch: drop the traceback module import in favor of using ui.traceback() In-Reply-To: <50D0A6F5-B69B-4AF2-8AC1-651FA2BB8E66@ringworld.org> Message-ID: <1360946973.88652.YahooMailClassic@web121003.mail.ne1.yahoo.com> --- On Fri, 2/15/13, Kevin Bullock wrote: > From: Kevin Bullock > Subject: Re: [PATCH 4 of 4 STABLE V3] dispatch: drop the traceback module import in favor of using ui.traceback() > To: "Matt Harbison" > Date: Friday, February 15, 2013, 11:04 AM > On 14 Feb 2013, at 10:18 PM, Matt > Harbison wrote: > > > On Thu, 14 Feb 2013 22:57:54 -0500, Matt Harbison > wrote: > > > >> # HG changeset patch # User Matt Harbison > >> # Date 1360439790 18000 # Branch stable # Node ID > >> 6e1745620172f71a9ec702939227d509b13c756e # Parent > >> 531876e328ce07dd3a93ea00e63b00afdfd0b806 dispatch: > drop the traceback > >> module import in favor of using ui.traceback() > >> > >> This ensures chained exception tracebacks are > printed when using the > >> --debugger option. > >> > > > > For some reason, I got really strange output when I > tried to write a test > > for this (almost looks like stdout and stderr output is > interwoven). > > Are you perchance on a Mac? > > pacem in terris / ??? / ?????? / > ????????? / ?? > Kevin R. Bullock Windows 7 From hgbuildbot at kublai.com Fri Feb 15 11:40:51 2013 From: hgbuildbot at kublai.com (hgbuildbot at kublai.com) Date: Fri, 15 Feb 2013 09:40:51 -0800 Subject: buildbot failure in Mercurial on hg tests Message-ID: <20130215174051.C817D26445@hgbuildbot.cs.ubc.ca> The Buildbot has detected a new failure on builder hg tests while building hg. Full details are available at: http://hgbuildbot.kublai.com/builders/hg%20tests/builds/503 Buildbot URL: http://hgbuildbot.kublai.com/ Buildslave for this Build: p64.osuosl.test Build Reason: scheduler Build Source Stamp: [branch default] 6a012704c841db7d6c018b916465fab961610544 Blamelist: Pierre-Yves David ,Simon Heimberg BUILD FAILED: failed run-tests.py (python2.4) run-tests.py (python2.6) http2 sincerely, -The Buildbot From bos at serpentine.com Fri Feb 15 13:45:14 2013 From: bos at serpentine.com (Bryan O'Sullivan) Date: Fri, 15 Feb 2013 11:45:14 -0800 Subject: [PATCH 2 of 2 RFCv2] commands: introduce stash command In-Reply-To: <06dd5eda17402c1e89a1.1360887323@idan> References: <06dd5eda17402c1e89a1.1360887323@idan> Message-ID: On Thu, Feb 14, 2013 at 4:15 PM, Idan Kamara wrote: > commands: introduce stash command > Love the idea, strongly unlove the dependency on mq :-( -------------- next part -------------- An HTML attachment was scrubbed... URL: From mpm at selenic.com Fri Feb 15 14:08:53 2013 From: mpm at selenic.com (Matt Mackall) Date: Fri, 15 Feb 2013 14:08:53 -0600 Subject: [PATCH STABLE] mergetools: vimdiff issue a warning explaining how to abort In-Reply-To: References: Message-ID: <1360958933.12295.80.camel@calx> On Fri, 2013-02-15 at 13:21 +0100, Benoit Boissinot wrote: > Looks good. > > -vimdiff.args=$local $other $base > > +vimdiff.args=$local $other $base -c 'echohl WarningMsg | echo "merge > > conflict detected, type \":cq\" to abort" | echohl' Actually, it's not so good. I get an otherwise blank screen that says: "smem" 676L, 20653C merge conflict detected, type ":cg" to abort Press ENTER or type command to continue If I were an everyday vimdiff user[1], I would be pissed off by this change in very short order. Especially if I were resolving 10 conflicts in a row. And if I were a NON-vimdiff user, I'd still have just about no idea what just happened or how to avoid it in the future. Whatever we do in this area, it MUST have negligible impact on people who rely on vimdiff today. What's needed here is a way to display something in the last line of the display (command area?), like how Emacs prints For information about the GNU Project and its goals, type M-x describe-project. before the first keystroke. That message should include the following information: - how to exit - 'vimdiff' so people can Google - 'merge conflict' so people can Google Hopefully that Googling can take them to a page in our wiki that explains how merge tools are configured and selected. Also, I actually went down this path yesterday and discovered your version is equivalent to: -c ':echo "merge conflict..."' I gave up after deciding this called for a vim expert. [1] And thank god I'm not, because I seriously hate vi. -- Mathematics is the supreme nostalgia of our time. From mpm at selenic.com Fri Feb 15 14:31:55 2013 From: mpm at selenic.com (Matt Mackall) Date: Fri, 15 Feb 2013 14:31:55 -0600 Subject: [PATCH 2 of 2 RFCv2] commands: introduce stash command In-Reply-To: References: <06dd5eda17402c1e89a1.1360887323@idan> Message-ID: <1360960315.12295.81.camel@calx> On Fri, 2013-02-15 at 11:45 -0800, Bryan O'Sullivan wrote: > On Thu, Feb 14, 2013 at 4:15 PM, Idan Kamara wrote: > > > commands: introduce stash command > > > > Love the idea, strongly unlove the dependency on mq :-( s/dependency on/incompatibility with/? -- Mathematics is the supreme nostalgia of our time. From mpm at selenic.com Fri Feb 15 14:40:31 2013 From: mpm at selenic.com (Matt Mackall) Date: Fri, 15 Feb 2013 14:40:31 -0600 Subject: [PATCH] subrepo: do not push "clean" subrepos when the parent repo is pushed In-Reply-To: References: <26276460d54aecdeb107.1360800378@Angel-PC.localdomain> <1360805515.12295.53.camel@calx> Message-ID: <1360960831.12295.87.camel@calx> On Thu, 2013-02-14 at 09:39 +0100, Angel Ezquerra wrote: > On Thu, Feb 14, 2013 at 2:31 AM, Matt Mackall wrote: > > On Thu, 2013-02-14 at 01:06 +0100, Angel Ezquerra wrote: > >> # HG changeset patch > >> # User Angel Ezquerra > >> # Date 1360795816 -3600 > >> # Node ID 26276460d54aecdeb107c82c4e3f2ca7c0c6a8b3 > >> # Parent 55b9b294b7544a6a144f627f71f4b770907d5a98 > >> subrepo: do not push "clean" subrepos when the parent repo is pushed > >> > >> A clean subrepo is defined as one that has not had its dirstate, bookmarks or > >> phases modified. > >> > >> This patch works by adding a "clean" method to subrepos. In the case of > >> mercurial subrepos, this method calculates a "stamp" (i.e. a set of file hashes) > >> of the repository state at the time of push with a similar "stamp" that was > >> stored on a file when the subrepo was cloned or pushed to a given remote target. > >> If the stamps match the subrepo has no changes that must be pushed to the target > >> repository and thus the push can be skipped. > >> > >> Note that we calculate the stamp file by calculating hashes for several key > >> repository files, such as the dirstate, the bookmarks file and the phaseroots > >> file. This means that our "clean" detection is not perfect, in the sense that > >> if the working directory has been updated to a different revision we will > >> assume that the subrepo is not clean. However, if we update to another revision > >> and back to the original revision the clean() method will correctly detec the > >> subrepo as being clean. > > > Why is the dirstate interesting? I would posit that we're only > > interested in things that we'd push or pull. Dirstate being modified > > should not force us to push. > > I think I may have misunderstood you when we discussed this during the > sprint. I thought you mentioned that we should check the direstate, > the bookmarks and the phaseroots. I may have misspoke. Pretty sure I talked primarily about the changelog. > I don't know the mercurial store format well enough to tell which > files we need to hash. Would hashing "store/00changelog.i" and > "store/00manifest.i" be enough? Hashing 00changelog.i is sufficient. > >> Also note that a subrepo being "clean" is not the opposite of it being "dirty". > >> A subrepo is dirty if it updated to a different revision that the one that is > >> pointed to by the subrepo parent or if its working directory is not clean. This > >> is a different concept. > > > > Ok, let's give it a different name. How about storeclean() so it's > > explicit it's about the store? > > OK, as long as bookmarks and phases can be considered part of the store? Phases definitely are. Bookmarks are a bit on the edge. > > I think this needs to be (at least) a few different patches: > > > > 1) introduce the helper functions > > 2) record clean state on clone/pull > > 3) check clean state on push > > Will do. > > >> diff --git a/mercurial/subrepo.py b/mercurial/subrepo.py > >> --- a/mercurial/subrepo.py > >> +++ b/mercurial/subrepo.py > >> @@ -300,6 +300,16 @@ > >> > >> class abstractsubrepo(object): > >> > >> + def clean(self): > >> + """ > >> + returns true if the repository has not changed since it was last > >> + cloned or pulled. > >> + Note that this is very different and definitely not the opposite > >> + of the repository being "dirty", which is related to having changes > >> + on the working directory or the current revision. > >> + """ > >> + return False > >> + > >> def dirty(self, ignoreupdate=False): > >> """returns true if the dirstate of the subrepo is dirty or does not > >> match current stored state. If ignoreupdate is true, only check > >> @@ -426,6 +436,73 @@ > >> self._repo.ui.setconfig('ui', '_usedassubrepo', 'True') > >> self._initrepo(r, state[0], create) > >> > >> + def clean(self, path): > >> + """ > >> + returns true if the repository has not changed since it was last > >> + cloned or pulled. > >> + Note that this is very different and definitely not the opposite > >> + of the repository being "dirty", which is related to having changes > >> + on the working directory or the current revision. > >> + """ > > > > Duplicate docs. > > > >> + return self._calcrepostamp(path) == self._readrepostamp(path) > > > > This is suboptimal, especially if any of the files are large. It'd be > > better to be able to break after we find the first changed file. > > Perhaps _calcrepostamp could be a generator. clean() (i.e. cleanstore) > could then just check each individual line. Sure. > >> + def _getfilestamp(self, filename): > >> + data = '' > >> + if os.path.exists(filename): > >> + fd = open(filename) > >> + data = fd.read() > >> + fd.close() > >> + return util.sha1(data).hexdigest() > > > > Most of this doesn't want to be member functions. We'll need it for git. > > Sure, although I know even less about git's internals than mercurial's > to be able to know what should be hashed inside the .git folder. The point is that we know today we're going to eventually want to handle git and that's probably going to involve a similar approach. Ergo, these should not be methods on the hg subrepo class. > Should these be kept in subrepos.py or perhaps moved to > mercurial.util? Also _calcrepostamp could be moved out as well by > making the "file list" a parameter. Save that for later, I think. > >> + def _calcrepostamp(self, remotepath): > >> + '''calculate a unique "stamp" for the current repository state > >> + > >> + This method is used to to detect when there are changes that may > >> + require a push to a given remote path.''' > >> + filelist = ('dirstate', 'bookmarks', 'store/phaseroots') > >> + stamp = ['# %s\n' % remotepath] > >> + lock = self._repo.lock() > >> + try: > >> + for relname in filelist: > >> + absname = os.path.normpath(self._repo.join(relname)) > >> + stamp.append('%s = %s\n' % (absname, self._getfilestamp(absname))) > >> + finally: > >> + lock.release() > >> + return stamp > >> + > >> + def _getstampfilename(self, remotepath): > >> + '''get a unique filename for the remote repo stamp''' > >> + fname = util.sha1(remotepath).hexdigest() > >> + return self._repo.join(os.path.join('stamps', fname)) > > > > Probably don't want a 40-character name here. This should go > > in .hg/cache/ on hg repos and have a less generic name than stamp. > > OK, I'll just keep the first 12 hash characters. > > >> + def _readrepostamp(self, remotepath): > >> + '''read an existing remote repository stamp''' > >> + stampfile = self._getstampfilename(remotepath) > >> + if not os.path.exists(stampfile): > >> + return '' > >> + fd = open(stampfile, 'r') > >> + stamp = fd.readlines() > >> + fd.close() > >> + return stamp > >> + > >> + def _updaterepostamp(self, remotepath): > >> + ''' > >> + Calc the current repo stamp saving it into a remote repo stamp file > >> + Each remote repo requires its own stamp file, because a subrepo may > >> + be clean versus a given remote repo, but not versus another. > >> + ''' > >> + # save it to the clean file > >> + # We should lock the repo > >> + stampfile = self._getstampfilename(remotepath) > >> + # [FIXME] should lock the repo? it is already locked by _calcrepostamp > > > > No, the lock should be in the callers of _calcrepostamp. > > OK. How would that work on the case of git repos? Is it possible to > "lock" a git repo? Defer that question. -- Mathematics is the supreme nostalgia of our time. From kbullock+mercurial at ringworld.org Fri Feb 15 15:12:12 2013 From: kbullock+mercurial at ringworld.org (Kevin Bullock) Date: Fri, 15 Feb 2013 15:12:12 -0600 Subject: [PATCH STABLE] mergetools: vimdiff issue a warning explaining how to abort In-Reply-To: <1360958933.12295.80.camel@calx> References: <1360958933.12295.80.camel@calx> Message-ID: <6677AE59-247C-47A6-82E1-D2AAEB8CC69D@ringworld.org> On 15 Feb 2013, at 2:08 PM, Matt Mackall wrote: > On Fri, 2013-02-15 at 13:21 +0100, Benoit Boissinot wrote: >> Looks good. > >>> -vimdiff.args=$local $other $base >>> +vimdiff.args=$local $other $base -c 'echohl WarningMsg | echo "merge >>> conflict detected, type \":cq\" to abort" | echohl' > > Actually, it's not so good. I get an otherwise blank screen that says: > > "smem" 676L, 20653C > merge conflict detected, type ":cg" to abort > Press ENTER or type command to continue > > If I were an everyday vimdiff user[1], I would be pissed off by this > change in very short order. Especially if I were resolving 10 conflicts > in a row. > > And if I were a NON-vimdiff user, I'd still have just about no idea what > just happened or how to avoid it in the future. Just crewed this (after having queued the patch before seeing Matt's response): changeset: 18877:ec9b9968b7f8 bookmark: @ tag: tip parent: 18874:6a012704c841 user: Kevin Bullock date: Fri Feb 15 15:06:43 2013 -0600 files: contrib/mergetools.hgrc description: mergetools: refine vimdiff warning message We explicitly redraw before echoing the message so that it simply displays at the bottom of the window. Also simplifies the message printing by using 'echomsg' (which uses 'echohl' internally) and adds the names of the software involved for improved Googleability. diff --git a/contrib/mergetools.hgrc b/contrib/mergetools.hgrc --- a/contrib/mergetools.hgrc +++ b/contrib/mergetools.hgrc @@ -15,7 +15,7 @@ gvimdiff.regkeyalt=Software\Wow6432Node\ gvimdiff.regname=path gvimdiff.priority=-9 -vimdiff.args=$local $other $base -c 'echohl WarningMsg | echo "merge conflict detected, type \":cq\" to abort" | echohl' +vimdiff.args=$local $other $base -c 'redraw | echomsg "hg merge conflict, type \":cq\" to abort vimdiff"' vimdiff.check=changed vimdiff.priority=-10 pacem in terris / ??? / ?????? / ????????? / ?? Kevin R. Bullock > Whatever we do in this area, it MUST have negligible impact on people > who rely on vimdiff today. > > What's needed here is a way to display something in the last line of the > display (command area?), like how Emacs prints > > For information about the GNU Project and its goals, type M-x describe-project. > > before the first keystroke. That message should include the following > information: > > - how to exit > - 'vimdiff' so people can Google > - 'merge conflict' so people can Google > > Hopefully that Googling can take them to a page in our wiki that > explains how merge tools are configured and selected. > > Also, I actually went down this path yesterday and discovered your > version is equivalent to: > > -c ':echo "merge conflict..."' > > I gave up after deciding this called for a vim expert. > > [1] And thank god I'm not, because I seriously hate vi. > > -- > Mathematics is the supreme nostalgia of our time. > > > _______________________________________________ > Mercurial-devel mailing list > Mercurial-devel at selenic.com > http://selenic.com/mailman/listinfo/mercurial-devel From kbullock+mercurial at ringworld.org Fri Feb 15 15:13:12 2013 From: kbullock+mercurial at ringworld.org (Kevin Bullock) Date: Fri, 15 Feb 2013 15:13:12 -0600 Subject: [PATCH STABLE] mergetools: vimdiff issue a warning explaining how to abort In-Reply-To: <6677AE59-247C-47A6-82E1-D2AAEB8CC69D@ringworld.org> References: <1360958933.12295.80.camel@calx> <6677AE59-247C-47A6-82E1-D2AAEB8CC69D@ringworld.org> Message-ID: On 15 Feb 2013, at 3:12 PM, Kevin Bullock wrote: > On 15 Feb 2013, at 2:08 PM, Matt Mackall wrote: > >> On Fri, 2013-02-15 at 13:21 +0100, Benoit Boissinot wrote: >>> Looks good. >> >>>> -vimdiff.args=$local $other $base >>>> +vimdiff.args=$local $other $base -c 'echohl WarningMsg | echo "merge >>>> conflict detected, type \":cq\" to abort" | echohl' >> >> Actually, it's not so good. I get an otherwise blank screen that says: >> >> "smem" 676L, 20653C >> merge conflict detected, type ":cg" to abort >> Press ENTER or type command to continue >> >> If I were an everyday vimdiff user[1], I would be pissed off by this >> change in very short order. Especially if I were resolving 10 conflicts >> in a row. >> >> And if I were a NON-vimdiff user, I'd still have just about no idea what >> just happened or how to avoid it in the future. > > Just crewed this (after having queued the patch before seeing Matt's response): Oh, and I crewed them on default -- this isn't stable-appropriate. pacem in terris / ??? / ?????? / ????????? / ?? Kevin R. Bullock From mpm at selenic.com Fri Feb 15 15:32:25 2013 From: mpm at selenic.com (Matt Mackall) Date: Fri, 15 Feb 2013 15:32:25 -0600 Subject: [PATCH STABLE] mergetools: vimdiff issue a warning explaining how to abort In-Reply-To: <6677AE59-247C-47A6-82E1-D2AAEB8CC69D@ringworld.org> References: <1360958933.12295.80.camel@calx> <6677AE59-247C-47A6-82E1-D2AAEB8CC69D@ringworld.org> Message-ID: <1360963945.12295.113.camel@calx> On Fri, 2013-02-15 at 15:12 -0600, Kevin Bullock wrote: > On 15 Feb 2013, at 2:08 PM, Matt Mackall wrote: > > > On Fri, 2013-02-15 at 13:21 +0100, Benoit Boissinot wrote: > >> Looks good. > > > >>> -vimdiff.args=$local $other $base > >>> +vimdiff.args=$local $other $base -c 'echohl WarningMsg | echo "merge > >>> conflict detected, type \":cq\" to abort" | echohl' > > > > Actually, it's not so good. I get an otherwise blank screen that says: > > > > "smem" 676L, 20653C > > merge conflict detected, type ":cg" to abort > > Press ENTER or type command to continue > > > > If I were an everyday vimdiff user[1], I would be pissed off by this > > change in very short order. Especially if I were resolving 10 conflicts > > in a row. > > > > And if I were a NON-vimdiff user, I'd still have just about no idea what > > just happened or how to avoid it in the future. > > Just crewed this (after having queued the patch before seeing Matt's response): Thanks for making this happen, guys. This version looks good in my test here. -- Mathematics is the supreme nostalgia of our time. From pierre-yves.david at ens-lyon.org Fri Feb 15 16:51:34 2013 From: pierre-yves.david at ens-lyon.org (Pierre-Yves David) Date: Fri, 15 Feb 2013 23:51:34 +0100 Subject: [PATCH STABLE] mergetools: vimdiff issue a warning explaining how to abort In-Reply-To: References: <1360958933.12295.80.camel@calx> <6677AE59-247C-47A6-82E1-D2AAEB8CC69D@ringworld.org> Message-ID: On 15 f?vr. 2013, at 22:13, Kevin Bullock wrote: > On 15 Feb 2013, at 3:12 PM, Kevin Bullock wrote: > >> On 15 Feb 2013, at 2:08 PM, Matt Mackall wrote: >> >>> On Fri, 2013-02-15 at 13:21 +0100, Benoit Boissinot wrote: >>>> Looks good. >>> >>>>> -vimdiff.args=$local $other $base >>>>> +vimdiff.args=$local $other $base -c 'echohl WarningMsg | echo "merge >>>>> conflict detected, type \":cq\" to abort" | echohl' >>> >>> Actually, it's not so good. I get an otherwise blank screen that says: >>> >>> "smem" 676L, 20653C >>> merge conflict detected, type ":cg" to abort >>> Press ENTER or type command to continue >>> >>> If I were an everyday vimdiff user[1], I would be pissed off by this >>> change in very short order. Especially if I were resolving 10 conflicts >>> in a row. >>> >>> And if I were a NON-vimdiff user, I'd still have just about no idea what >>> just happened or how to avoid it in the future. >> >> Just crewed this (after having queued the patch before seeing Matt's response): > > Oh, and I crewed them on default -- this isn't stable-appropriate. I've seen multiple data lose from editor misusage. We should probably reconsider that for stable. (on a related topic, having the patch on stable will help me to harass the Debian maintainer until the config is patched for wheezy) -- Pierre-Yves David From hgbuildbot at kublai.com Fri Feb 15 17:07:35 2013 From: hgbuildbot at kublai.com (hgbuildbot at kublai.com) Date: Fri, 15 Feb 2013 15:07:35 -0800 Subject: buildbot success in Mercurial on hg tests Message-ID: <20130215230735.84F2826445@hgbuildbot.cs.ubc.ca> The Buildbot has detected a restored build on builder hg tests while building hg. Full details are available at: http://hgbuildbot.kublai.com/builders/hg%20tests/builds/504 Buildbot URL: http://hgbuildbot.kublai.com/ Buildslave for this Build: p64.osuosl.test Build Reason: scheduler Build Source Stamp: [branch default] ec9b9968b7f84ac2de4722ed22a313868f84f6bc Blamelist: Kevin Bullock Build succeeded! sincerely, -The Buildbot From mpm at selenic.com Fri Feb 15 17:22:39 2013 From: mpm at selenic.com (Matt Mackall) Date: Fri, 15 Feb 2013 17:22:39 -0600 Subject: [PATCH STABLE] mergetools: vimdiff issue a warning explaining how to abort In-Reply-To: References: <1360958933.12295.80.camel@calx> <6677AE59-247C-47A6-82E1-D2AAEB8CC69D@ringworld.org> Message-ID: <1360970559.12295.125.camel@calx> On Fri, 2013-02-15 at 23:51 +0100, Pierre-Yves David wrote: > On 15 f?vr. 2013, at 22:13, Kevin Bullock wrote: > > > On 15 Feb 2013, at 3:12 PM, Kevin Bullock wrote: > > > >> On 15 Feb 2013, at 2:08 PM, Matt Mackall wrote: > >> > >>> On Fri, 2013-02-15 at 13:21 +0100, Benoit Boissinot wrote: > >>>> Looks good. > >>> > >>>>> -vimdiff.args=$local $other $base > >>>>> +vimdiff.args=$local $other $base -c 'echohl WarningMsg | echo "merge > >>>>> conflict detected, type \":cq\" to abort" | echohl' > >>> > >>> Actually, it's not so good. I get an otherwise blank screen that says: > >>> > >>> "smem" 676L, 20653C > >>> merge conflict detected, type ":cg" to abort > >>> Press ENTER or type command to continue > >>> > >>> If I were an everyday vimdiff user[1], I would be pissed off by this > >>> change in very short order. Especially if I were resolving 10 conflicts > >>> in a row. > >>> > >>> And if I were a NON-vimdiff user, I'd still have just about no idea what > >>> just happened or how to avoid it in the future. > >> > >> Just crewed this (after having queued the patch before seeing Matt's response): > > > > Oh, and I crewed them on default -- this isn't stable-appropriate. > > I've seen multiple data lose from editor misusage. > > We should probably reconsider that for stable. I have no doubt there are users who've done themselves considerable harm while trying to escape from vim's clutches. Sune apparently did this just yesterday. I have no objections to putting this on stable. > (on a related topic, having the patch on stable will help me to harass the Debian maintainer until the config is patched for wheezy) You might want to remind them of their own sensible-editor policy and how it applies here and to commit. -- Mathematics is the supreme nostalgia of our time. From mpm at selenic.com Fri Feb 15 17:24:41 2013 From: mpm at selenic.com (Matt Mackall) Date: Fri, 15 Feb 2013 17:24:41 -0600 Subject: Bugzilla server's system time In-Reply-To: <20130214224457.GA3634@findus> References: <20130214224457.GA3634@findus> Message-ID: <1360970681.12295.127.camel@calx> On Thu, 2013-02-14 at 23:44 +0100, Isaac Jurado wrote: > Hi, > > I think the bugzilla server's clock is not on time. I posted a comment > ten minutes ago and it appears as 17:40:53 UTC when it should have been > 22:40:53 UTC. Maybe it's just the timezone, locale or the Bugzilla > configuration. The server's time was correct, however it's in the EST timezone and Bugzilla defaults users to the server's timezone. I've changed the default to UTC. -- Mathematics is the supreme nostalgia of our time. From kbullock+mercurial at ringworld.org Fri Feb 15 21:24:33 2013 From: kbullock+mercurial at ringworld.org (Kevin Bullock) Date: Fri, 15 Feb 2013 21:24:33 -0600 Subject: [PATCH STABLE] mergetools: vimdiff issue a warning explaining how to abort In-Reply-To: <1360970559.12295.125.camel@calx> References: <1360958933.12295.80.camel@calx> <6677AE59-247C-47A6-82E1-D2AAEB8CC69D@ringworld.org> <1360970559.12295.125.camel@calx> Message-ID: <2DB4C614-A28A-4774-8725-D7899E85A960@ringworld.org> On 15 Feb 2013, at 5:22 PM, Matt Mackall wrote: > On Fri, 2013-02-15 at 23:51 +0100, Pierre-Yves David wrote: >> On 15 f?vr. 2013, at 22:13, Kevin Bullock wrote: >> >>> On 15 Feb 2013, at 3:12 PM, Kevin Bullock wrote: >>> >>>> On 15 Feb 2013, at 2:08 PM, Matt Mackall wrote: >>>> >>>>> On Fri, 2013-02-15 at 13:21 +0100, Benoit Boissinot wrote: >>>>>> Looks good. >>>>> >>>>>>> -vimdiff.args=$local $other $base >>>>>>> +vimdiff.args=$local $other $base -c 'echohl WarningMsg | echo "merge >>>>>>> conflict detected, type \":cq\" to abort" | echohl' >>>>> >>>>> Actually, it's not so good. I get an otherwise blank screen that says: >>>>> >>>>> "smem" 676L, 20653C >>>>> merge conflict detected, type ":cg" to abort >>>>> Press ENTER or type command to continue >>>>> >>>>> If I were an everyday vimdiff user[1], I would be pissed off by this >>>>> change in very short order. Especially if I were resolving 10 conflicts >>>>> in a row. >>>>> >>>>> And if I were a NON-vimdiff user, I'd still have just about no idea what >>>>> just happened or how to avoid it in the future. >>>> >>>> Just crewed this (after having queued the patch before seeing Matt's response): >>> >>> Oh, and I crewed them on default -- this isn't stable-appropriate. >> >> I've seen multiple data lose from editor misusage. >> >> We should probably reconsider that for stable. > > I have no doubt there are users who've done themselves considerable harm > while trying to escape from vim's clutches. Sune apparently did this > just yesterday. I have no objections to putting this on stable. Huh, okay. Grafted to stable, merged and pushed to crew. pacem in terris / ??? / ?????? / ????????? / ?? Kevin R. Bullock From hgbuildbot at kublai.com Fri Feb 15 21:48:55 2013 From: hgbuildbot at kublai.com (hgbuildbot at kublai.com) Date: Fri, 15 Feb 2013 19:48:55 -0800 Subject: buildbot success in Mercurial on hg tests (stable) Message-ID: <20130216034857.1A00C26038@hgbuildbot.cs.ubc.ca> The Buildbot has detected a restored build on builder hg tests (stable) while building hg. Full details are available at: http://hgbuildbot.kublai.com/builders/hg%20tests%20%28stable%29/builds/304 Buildbot URL: http://hgbuildbot.kublai.com/ Buildslave for this Build: p64.osuosl.test Build Reason: scheduler Build Source Stamp: [branch stable] 7d66a44e87ede62a076000fb1099498155a64d71 Blamelist: Kevin Bullock ,Pierre-Yves David Build succeeded! sincerely, -The Buildbot From matt_harbison at yahoo.com Fri Feb 15 23:03:15 2013 From: matt_harbison at yahoo.com (Matt Harbison) Date: Sat, 16 Feb 2013 00:03:15 -0500 Subject: [PATCH] subrepo: do not push "clean" subrepos when the parent repo is pushed In-Reply-To: References: <26276460d54aecdeb107.1360800378@Angel-PC.localdomain> Message-ID: <511F1313.6060403@yahoo.com> Angel Ezquerra wrote: > On Fri, Feb 15, 2013 at 4:49 AM, Matt Harbison wrote: >> On Thu, 14 Feb 2013 01:13:44 +0100, Angel Ezquerra wrote: >> >>> On Thu, Feb 14, 2013 at 1:06 AM, Angel Ezquerra >>> wrote: >> ... >> >>> This is step one in the plan that Matt, Martin and I discussed to >>> improve subrepos during the London sprint. >> Is there a brief overview of the plan somewhere? > > I wrote a summary on the titanpad that we used during the sprint: > > http://titanpad.com/mercurial26 > > I've taken that and updated it a little with what has been discussed > in this thread and my own thinking since them: Thanks for the writeup. I think I understand most of this, up to the caching and deletable parts. But that seems a bit further into the future, and maybe it will become more clear as this evolves. I'm not sure if deletable helps this, and I haven't looked into it yet, but any plans on being able to update between revs where a file exists but in the other rev, a subrepo exists instead in the same directory? (I think this is what issue3131 is about.) > * Discuss ways to improve some of the subrepo pain points - angel, mg > - add way to pull subrepos with hg pull > - just push changed subrepos > - subrepos are eternal > - We had a discussion with mpm on this and we believe we have a good plan: > - Add -S/--subrepos flag to hg pull > - Add cleanstore() method to subrepos which can tell pull/push > if a subrepo store has changes. If not we can ignore it during push > - The cleanstore method would check a timestamp or sha1 of > the bookmarks, phaseroots and the changelog, but not the > dirstatedirstate > dirstate > - Updated on clone and push; but also on pull if the store is > already clean > - Only push not cleanstore() subrepos > - subrepo.deletable(): if self.clean() and dirstate working dir is clean() > - fix Merge bug which makes subrepos stay on the working > directory on update even if there are files on the parent that should > go on the folder occupied by the subrepo > - using deletable() we could remove subrepos from the working dir... > - however this could cause data loss on update on a > "central" repository containing relative subrepos. On non central > subrepos it would require recloning the subrepo when updating back to > a revision referring to that subrepo. > - Introduce subrepo caching (this would fix the problem above > and improve pull time considerably when subrepos are deleted) > - Cloning would need to be smart enough to look on the > subrepo cache. Otherwise it would not be possible to pull from central > repositories that were are at revision -1 (since all subrepos would be > on the cache, and none on the workind directory). > > - Document subpaths patterns that can make relative subrepos work > with bitbucket and google code > > Perhaps it would be worth adding this to the wiki? > >>> I also am working on step two of the plan, which was to add a >>> "--subrepos" flag to hg push. >> Is this your idea about passing (some?) parameters to subrepos [1]? If >> so, does 'outgoing' need the same method of filtering the option dict [2] >> for consistency? (I was a bit surprised that outgoing -S passes along the >> --rev option, which causes it to abort in the subrepo with a (parent) >> hash, or lie or abort if given a rev.) There's also a couple bugs written >> about --addremove not being passed along, so what to pass or not seems >> like a wider (general?) problem. > > The way I've implemented it is very similar to how the current > subrepo.get() works. Basically I want hg pull --subrepos to behave as > if you first did "hg pull" and then you did "hg update -r" for every > new revision that "hg pull" brought into the repository. The idea is > to make sure that you are able to update to any new revision without > needing to have any network access (i.e. that the repository is self > contained after doing hg pull --subrepos, as long as it already was > self contained before). I really like this capability. > Martin Gesiler helped me with this patch during the sprint and he has > been helping me since then. I'll send a patch soon. > > That being said, out of the options that pull takes there are a lot > that do not make sense when pulling from subrepos, particularly --rev, > --bookmark, --branch and specially --rebase. Aren't --bookmark and --branch simply opts that predate the bookmark() and branch() revsets, without any special semantics? (I'm wondering specifically about bookmarks because I don't use them much, and IDK if --bookmark + --update does anything special that --rev + --update doesn't.) One of the things that seemed like it would be useful when trying to fix push -r is to have the methods in commands.py translate these options to a list of revs there, and pass that along. That way, every repo (even without subrepos) gets a list of revs instead of these various opts. The subrepo layer would have to translate to child revs before passing them on, but that doesn't seem terribly difficult. I don't use --rebase, but I can see how that would be bad. > I think that if you need > to do something special while pulling a subrepo perhaps it would be > best to get into the subrepo and do a regular pull, or perhaps use the > onsub extension (which I wish we integrated into mercurial). One thing > that would help there would be to have a way to refer to the parent > paths when pulling from within a subrepo. This would be particularly > handy when using relative subrepo definitions, as you should. I'm not sure what you mean about refering to parent paths. Do you have a use case in mind? >> FWIW, I've got code that seems to be able to honor the -r flag for >> 'outgoing' and 'push' (issue2314) [3], including the case where the parent >> commits an older version of the subrepo after a newer version. I wasn't >> happy with how I had to hack the option dict after translating --rev, but >> it sounds like you are working in this area anyway. So I'll try to submit >> this as a (rough) RFC this weekend, and assuming the concept is OK, we >> will probably need to coordinate how options are handed off to subrepos >> for 'push' and 'outgoing'. > > I'll try to have a look at your patches when I get some time. > > Angel > > >> [2] http://www.selenic.com/pipermail/mercurial-devel/2011- >> September/034453.html >> >> [3] http://bz.selenic.com/show_bug.cgi?id=2314 >> >> _______________________________________________ >> Mercurial-devel mailing list >> Mercurial-devel at selenic.com >> http://selenic.com/mailman/listinfo/mercurial-devel > From hgbuildbot at kublai.com Fri Feb 15 23:52:29 2013 From: hgbuildbot at kublai.com (hgbuildbot at kublai.com) Date: Fri, 15 Feb 2013 21:52:29 -0800 Subject: buildbot success in Mercurial on OS X 10.7 hg tests Message-ID: <20130216055229.C75B526D0F@hgbuildbot.cs.ubc.ca> The Buildbot has detected a restored build on builder OS X 10.7 hg tests while building hg. Full details are available at: http://hgbuildbot.kublai.com/builders/OS%20X%2010.7%20hg%20tests/builds/415 Buildbot URL: http://hgbuildbot.kublai.com/ Buildslave for this Build: lion Build Reason: scheduler Build Source Stamp: [branch default] ec9b9968b7f84ac2de4722ed22a313868f84f6bc Blamelist: Kevin Bullock Build succeeded! sincerely, -The Buildbot From idankk86 at gmail.com Sat Feb 16 02:43:41 2013 From: idankk86 at gmail.com (Idan Kamara) Date: Sat, 16 Feb 2013 10:43:41 +0200 Subject: [PATCH 2 of 2 RFCv2] commands: introduce stash command In-Reply-To: <1360960315.12295.81.camel@calx> References: <06dd5eda17402c1e89a1.1360887323@idan> <1360960315.12295.81.camel@calx> Message-ID: On Fri, Feb 15, 2013 at 10:31 PM, Matt Mackall wrote: > > On Fri, 2013-02-15 at 11:45 -0800, Bryan O'Sullivan wrote: > > On Thu, Feb 14, 2013 at 4:15 PM, Idan Kamara wrote: > > > > > commands: introduce stash command > > > > > > > Love the idea, strongly unlove the dependency on mq :-( > > s/dependency on/incompatibility with/? I guess that's what Bryan meant, and this was also raised in v1 [1]. I agree it's highly inconvenient that we can't support this, and I'd gladly welcome any suggestions (that maintain the approach of saving stashes as regular commits as opposed to patch files) to remedy the situation, or at least make it slightly better. But considering evolve is shaping up to be a viable alternative to mq in a few major versions, we would at least have something to give to these abandoned users. [1] http://markmail.org/message/p2fkoj5welx6nmkb -------------- next part -------------- An HTML attachment was scrubbed... URL: From angel.ezquerra at gmail.com Sat Feb 16 03:36:59 2013 From: angel.ezquerra at gmail.com (Angel Ezquerra) Date: Sat, 16 Feb 2013 10:36:59 +0100 Subject: util.makedirs is missing a "notindexed" parameters Message-ID: Hi, I just noticed that there is a util.makedirs but that it does not have a "notindexed" parameter. Internally it calls os.mkdir directly, rather than util.makedir. Wouldn't it make sense to be able to disable indexing on windows when creating a directory recursively? Cheers, Angel From angel.ezquerra at gmail.com Sat Feb 16 04:34:09 2013 From: angel.ezquerra at gmail.com (Angel Ezquerra) Date: Sat, 16 Feb 2013 11:34:09 +0100 Subject: [PATCH] subrepo: do not push "clean" subrepos when the parent repo is pushed In-Reply-To: <511F1313.6060403@yahoo.com> References: <26276460d54aecdeb107.1360800378@Angel-PC.localdomain> <511F1313.6060403@yahoo.com> Message-ID: On Sat, Feb 16, 2013 at 6:03 AM, Matt Harbison wrote: > Angel Ezquerra wrote: >> >> On Fri, Feb 15, 2013 at 4:49 AM, Matt Harbison >> wrote: >>> >>> On Thu, 14 Feb 2013 01:13:44 +0100, Angel Ezquerra wrote: >>> >>>> On Thu, Feb 14, 2013 at 1:06 AM, Angel Ezquerra >>>> wrote: >>> >>> ... >>> >>>> This is step one in the plan that Matt, Martin and I discussed to >>>> improve subrepos during the London sprint. >>> >>> Is there a brief overview of the plan somewhere? >> >> >> I wrote a summary on the titanpad that we used during the sprint: >> >> http://titanpad.com/mercurial26 >> >> I've taken that and updated it a little with what has been discussed >> in this thread and my own thinking since them: > > > Thanks for the writeup. I think I understand most of this, up to the > caching and deletable parts. But that seems a bit further into the future, > and maybe it will become more clear as this evolves. > > I'm not sure if deletable helps this, and I haven't looked into it yet, but > any plans on being able to update between revs where a file exists but in > the other rev, a subrepo exists instead in the same directory? (I think this > is what issue3131 is about.) Yes, that is one of the issues that this is trying to address. Let me try to explain the "caching and deletable" part a little better: The idea is that updating to a revision that does not refer to a subrepo should remove the subrepo form the working directory. That would resolve issue3131 among other things. This requires fixing several issues: 1. Mercurial should not delete a subrepo that has untracked changes. 2. Mercurial should not delete a subrepo that has "unsynchronized" changes 3. Mercurial should not really delete a subrepo, but "cache it". Otherwise running hg update 000 on your central repo would delete all your subrepos as well! 4. Mercurial should be able to pull from a cached subrepo when the actual subrepo is not found on the remote working directory. This is what the "deletable" and "caching" will try to fix. >> * Discuss ways to improve some of the subrepo pain points - angel, mg >> - add way to pull subrepos with hg pull >> - just push changed subrepos >> - subrepos are eternal >> - We had a discussion with mpm on this and we believe we have a good >> plan: >> - Add -S/--subrepos flag to hg pull >> - Add cleanstore() method to subrepos which can tell pull/push >> if a subrepo store has changes. If not we can ignore it during push >> - The cleanstore method would check a timestamp or sha1 of >> the bookmarks, phaseroots and the changelog, but not the >> dirstatedirstate >> dirstate >> - Updated on clone and push; but also on pull if the store is >> already clean >> - Only push not cleanstore() subrepos >> - subrepo.deletable(): if self.clean() and dirstate working dir is >> clean() >> - fix Merge bug which makes subrepos stay on the working >> directory on update even if there are files on the parent that should >> go on the folder occupied by the subrepo >> - using deletable() we could remove subrepos from the working >> dir... >> - however this could cause data loss on update on a >> "central" repository containing relative subrepos. On non central >> subrepos it would require recloning the subrepo when updating back to >> a revision referring to that subrepo. >> - Introduce subrepo caching (this would fix the problem above >> and improve pull time considerably when subrepos are deleted) >> - Cloning would need to be smart enough to look on the >> subrepo cache. Otherwise it would not be possible to pull from central >> repositories that were are at revision -1 (since all subrepos would be >> on the cache, and none on the workind directory). >> >> - Document subpaths patterns that can make relative subrepos work >> with bitbucket and google code >> >> Perhaps it would be worth adding this to the wiki? >> >>>> I also am working on step two of the plan, which was to add a >>>> "--subrepos" flag to hg push. >>> >>> Is this your idea about passing (some?) parameters to subrepos [1]? If >>> so, does 'outgoing' need the same method of filtering the option dict [2] >>> for consistency? (I was a bit surprised that outgoing -S passes along >>> the >>> --rev option, which causes it to abort in the subrepo with a (parent) >>> hash, or lie or abort if given a rev.) There's also a couple bugs >>> written >>> about --addremove not being passed along, so what to pass or not seems >>> like a wider (general?) problem. >> >> >> The way I've implemented it is very similar to how the current >> subrepo.get() works. Basically I want hg pull --subrepos to behave as >> if you first did "hg pull" and then you did "hg update -r" for every >> new revision that "hg pull" brought into the repository. The idea is >> to make sure that you are able to update to any new revision without >> needing to have any network access (i.e. that the repository is self >> contained after doing hg pull --subrepos, as long as it already was >> self contained before). > > > I really like this capability. Glad you like it. I think it will be very handy for heavy subrepo users. >> Martin Gesiler helped me with this patch during the sprint and he has >> been helping me since then. I'll send a patch soon. >> >> That being said, out of the options that pull takes there are a lot >> that do not make sense when pulling from subrepos, particularly --rev, >> --bookmark, --branch and specially --rebase. > > > Aren't --bookmark and --branch simply opts that predate the bookmark() and > branch() revsets, without any special semantics? (I'm wondering > specifically about bookmarks because I don't use them much, and IDK if > --bookmark + --update does anything special that --rev + --update doesn't.) > > One of the things that seemed like it would be useful when trying to fix > push -r is to have the methods in commands.py translate these options to a > list of revs there, and pass that along. That way, every repo (even without > subrepos) gets a list of revs instead of these various opts. The subrepo > layer would have to translate to child revs before passing them on, but that > doesn't seem terribly difficult. I think that the subrepo update should be linked to the revisions that are pointed to on the parent repository revision). If you want to update your subrepos independently of the parent repo the best solution IMHO is to use the onsub extension. Then you can pass a revset as you suggest, which will be interpreted by every individual command that is executed on each subrepo. > I don't use --rebase, but I can see how that would be bad. > > >> I think that if you need >> to do something special while pulling a subrepo perhaps it would be >> best to get into the subrepo and do a regular pull, or perhaps use the >> onsub extension (which I wish we integrated into mercurial). One thing >> that would help there would be to have a way to refer to the parent >> paths when pulling from within a subrepo. This would be particularly >> handy when using relative subrepo definitions, as you should. > > I'm not sure what you mean about refering to parent paths. Do you have a > use case in mind? This is a bit unrelated to the rest of the thread. I guess you need to know how the onsub extension works to understand what I meant. The onsub extension simply executes a command on every subrepo. For example: hg onsub "hg pull" This will run hg pull on every subrepo, using the default path of every subrepo. When a subrepo is first created, its hgrc file is created automatically, and a default path (and possibly a default-push path) is added to it. This default path is the one the subrepo was cloned from, as specified on the parent repository .hgsub file. The example command above would use that default path when running hg pull on a given subrepo. The problem is that if the subrepo is defined with a relative sync URL (as it should be), and then you change the default path on the parent repo, the pull source when you pull a subrepo from its parent repo, and the pull source when you pull from within the subrepo itself (as the onsub extension does) are no longer the same. That is why I would like the onsub extension to get a way to "access" the parent repository sync paths. The extension already provides a $HG_SUBURL environment variable, but it does not provide a way to get the parent repo default (or other) path. Cheers, Angel From diptongo at gmail.com Sat Feb 16 05:06:27 2013 From: diptongo at gmail.com (Isaac Jurado) Date: Sat, 16 Feb 2013 12:06:27 +0100 Subject: Bugzilla server's system time In-Reply-To: <1360970681.12295.127.camel@calx> References: <20130214224457.GA3634@findus> <1360970681.12295.127.camel@calx> Message-ID: <20130216110627.GA3609@findus> Replying Matt Mackall: > On Thu, 2013-02-14 at 23:44 +0100, Isaac Jurado wrote: > > Hi, > > > > I think the bugzilla server's clock is not on time. I posted a comment > > ten minutes ago and it appears as 17:40:53 UTC when it should have been > > 22:40:53 UTC. Maybe it's just the timezone, locale or the Bugzilla > > configuration. > > The server's time was correct, however it's in the EST timezone and > Bugzilla defaults users to the server's timezone. I've changed the > default to UTC. Great, thanks :-) -- Isaac Jurado "The noblest pleasure is the joy of understanding." Leonardo da Vinci From hg at intevation.org Sat Feb 16 06:00:15 2013 From: hg at intevation.org (Mercurial Commits) Date: Sat, 16 Feb 2013 13:00:15 +0100 Subject: mercurial/crew@18698: 69 outgoing changesets (4 stable) Message-ID: <1361016015.867696.2343.nullmailer@hg.intevation.org> 69 outgoing changesets (4 stable) in mercurial/crew: http://hg.intevation.org/mercurial/crew/rev/4a85ebb5c807 changeset: 18698:4a85ebb5c807 bookmark: @ tag: tip parent: 18695:ec9b9968b7f8 parent: 18697:7d66a44e87ed user: Kevin Bullock date: Fri Feb 15 21:20:24 2013 -0600 summary: merge with stable http://hg.intevation.org/mercurial/crew/rev/7d66a44e87ed changeset: 18697:7d66a44e87ed branch: stable user: Kevin Bullock date: Fri Feb 15 15:06:43 2013 -0600 summary: mergetools: refine vimdiff warning message http://hg.intevation.org/mercurial/crew/rev/f2b1f78cf202 changeset: 18696:f2b1f78cf202 branch: stable parent: 18679:f6f35d646cb5 user: Pierre-Yves David date: Fri Feb 15 11:28:04 2013 +0100 summary: mergetools: vimdiff issue a warning explaining how to abort http://hg.intevation.org/mercurial/crew/rev/ec9b9968b7f8 changeset: 18695:ec9b9968b7f8 user: Kevin Bullock date: Fri Feb 15 15:06:43 2013 -0600 summary: mergetools: refine vimdiff warning message http://hg.intevation.org/mercurial/crew/rev/6a012704c841 changeset: 18694:6a012704c841 user: Pierre-Yves David date: Fri Feb 15 11:28:04 2013 +0100 summary: mergetools: vimdiff issue a warning explaining how to abort http://hg.intevation.org/mercurial/crew/rev/633cd0c46e6a changeset: 18693:633cd0c46e6a user: Simon Heimberg date: Tue Feb 12 22:15:31 2013 +0100 summary: dispatch: also a separate warning message on aliases with --config http://hg.intevation.org/mercurial/crew/rev/af4387d8d1c7 changeset: 18692:af4387d8d1c7 user: Kevin Bullock date: Thu Feb 14 13:56:02 2013 -0600 summary: extensions: remove erroneous comment http://hg.intevation.org/mercurial/crew/rev/4f485bd68f1d changeset: 18691:4f485bd68f1d user: Durham Goode date: Wed Feb 13 12:51:30 2013 -0800 summary: blackbox: do not translate the log messages http://hg.intevation.org/mercurial/crew/rev/4c6f7f0dadab changeset: 18690:4c6f7f0dadab user: Kevin Bullock date: Tue Feb 12 11:36:21 2013 -0600 summary: scmutil: split platform-specific bits into their own modules http://hg.intevation.org/mercurial/crew/rev/12721a20ed30 changeset: 18689:12721a20ed30 user: Kevin Bullock date: Tue Feb 12 16:36:44 2013 +0000 summary: backout: call cmdutil.commit directly instead of commands.commit http://hg.intevation.org/mercurial/crew/rev/79107fad06aa changeset: 18688:79107fad06aa user: Kevin Bullock date: Tue Feb 12 16:32:14 2013 +0000 summary: commit: factor out status printing into a helper function http://hg.intevation.org/mercurial/crew/rev/1d183b33f007 changeset: 18687:1d183b33f007 user: Kevin Bullock date: Tue Feb 12 16:05:00 2013 +0000 summary: backout: remove unnecessary dict copy http://hg.intevation.org/mercurial/crew/rev/0bca4d31f647 changeset: 18686:0bca4d31f647 user: Kevin Bullock date: Tue Feb 12 15:47:30 2013 +0000 summary: backout: remove unnecessary frobbing of addremove option http://hg.intevation.org/mercurial/crew/rev/fafdff7e9c43 changeset: 18685:fafdff7e9c43 user: Kevin Bullock date: Tue Feb 12 15:07:17 2013 +0000 summary: backout: use cmdutil.revert directly instead of commands.revert http://hg.intevation.org/mercurial/crew/rev/c161e4cf77d4 changeset: 18684:c161e4cf77d4 parent: 18683:a343eccd5ee2 parent: 18679:f6f35d646cb5 user: Kevin Bullock date: Wed Feb 13 15:09:43 2013 -0600 summary: merge with stable http://hg.intevation.org/mercurial/crew/rev/a343eccd5ee2 changeset: 18683:a343eccd5ee2 user: Simon Heimberg date: Wed Feb 13 21:51:47 2013 +0100 summary: check-code: warn about line glob match with no glob character (?*/) http://hg.intevation.org/mercurial/crew/rev/408f2202bd80 changeset: 18682:408f2202bd80 user: Simon Heimberg date: Wed Feb 13 22:05:30 2013 +0100 summary: tests: remove glob from output lines containing no glob character http://hg.intevation.org/mercurial/crew/rev/7591ed29e824 changeset: 18681:7591ed29e824 user: Simon Heimberg date: Mon Oct 15 23:28:45 2012 +0200 summary: tests: inform on Windows about unnecessary glob lines http://hg.intevation.org/mercurial/crew/rev/15711d9d8b2c changeset: 18680:15711d9d8b2c parent: 18678:423eee0b0b14 user: Simon Heimberg date: Wed Feb 13 21:58:52 2013 +0100 summary: tests: quickly check if the glob line already matches the output http://hg.intevation.org/mercurial/crew/rev/f6f35d646cb5 changeset: 18679:f6f35d646cb5 branch: stable parent: 18657:d4a79e075303 user: Simon Heimberg date: Wed Feb 13 12:35:57 2013 +0100 summary: tests: append glob to filename output when required (windows) http://hg.intevation.org/mercurial/crew/rev/423eee0b0b14 changeset: 18678:423eee0b0b14 user: Bryan O'Sullivan date: Wed Feb 13 12:20:10 2013 -0800 summary: util: make ensuredirs safer against races http://hg.intevation.org/mercurial/crew/rev/539210ed2069 changeset: 18677:539210ed2069 user: Durham Goode date: Wed Feb 13 11:07:01 2013 -0800 summary: blackbox: only show new heads on incoming http://hg.intevation.org/mercurial/crew/rev/1506eb487ddd changeset: 18676:1506eb487ddd user: Bryan O'Sullivan date: Wed Feb 13 10:54:52 2013 -0800 summary: blackbox: fix copyright http://hg.intevation.org/mercurial/crew/rev/f816aa377e0d changeset: 18675:f816aa377e0d user: Bryan O'Sullivan date: Tue Feb 12 16:02:35 2013 -0800 summary: blackbox: fix a failing pyflakes test http://hg.intevation.org/mercurial/crew/rev/c61b49d059eb changeset: 18674:c61b49d059eb user: Durham Goode date: Sat Feb 09 13:35:30 2013 -0800 summary: blackbox: tests for the blackbox extension http://hg.intevation.org/mercurial/crew/rev/f27598902007 changeset: 18673:f27598902007 user: Durham Goode date: Sat Feb 09 09:09:46 2013 -0800 summary: blackbox: adds a 'blackbox' command for viewing recent logs http://hg.intevation.org/mercurial/crew/rev/b2b4ddc55caa changeset: 18672:b2b4ddc55caa user: Durham Goode date: Sat Feb 09 09:04:48 2013 -0800 summary: blackbox: log incoming changes via ui.log() http://hg.intevation.org/mercurial/crew/rev/1c305128e5b9 changeset: 18671:1c305128e5b9 user: Durham Goode date: Sat Feb 09 09:04:32 2013 -0800 summary: blackbox: logs python and extension hooks via ui.log() http://hg.intevation.org/mercurial/crew/rev/ddc7268da176 changeset: 18670:ddc7268da176 user: Durham Goode date: Sat Feb 09 09:04:14 2013 -0800 summary: blackbox: log the commands that are run http://hg.intevation.org/mercurial/crew/rev/18242716a014 changeset: 18669:18242716a014 user: Durham Goode date: Tue Feb 12 14:08:33 2013 -0800 summary: blackbox: adds a blackbox extension http://hg.intevation.org/mercurial/crew/rev/4034b8d551b1 changeset: 18668:4034b8d551b1 user: Bryan O'Sullivan date: Mon Feb 11 16:15:12 2013 -0800 summary: scmutil: create directories in a race-safe way during update http://hg.intevation.org/mercurial/crew/rev/f12804d3ff80 changeset: 18667:f12804d3ff80 parent: 18666:fb9d1c2805ff parent: 18658:5e63a85299ba user: Bryan O'Sullivan date: Mon Feb 11 14:50:54 2013 -0800 summary: Merge http://hg.intevation.org/mercurial/crew/rev/fb9d1c2805ff changeset: 18666:fb9d1c2805ff user: Idan Kamara date: Sat Feb 09 19:02:45 2013 +0200 summary: test-atomictempfile: convert to unit test http://hg.intevation.org/mercurial/crew/rev/2cbfb8c497ee changeset: 18665:2cbfb8c497ee user: Idan Kamara date: Sat Feb 09 19:13:39 2013 +0200 summary: tests: add a test runner utility that prints nothing when all tests pass http://hg.intevation.org/mercurial/crew/rev/30d899febef8 changeset: 18664:30d899febef8 user: Dan Villiom Podlaski Christiansen date: Sun Feb 10 13:14:31 2013 +0100 summary: hgweb: consistent author name width http://hg.intevation.org/mercurial/crew/rev/05cf40f9b0ec changeset: 18663:05cf40f9b0ec user: Durham Goode date: Sun Feb 10 12:23:39 2013 -0800 summary: dirstate: fix generator/list error when using python 2.7 http://hg.intevation.org/mercurial/crew/rev/c5f7e83d47cd changeset: 18662:c5f7e83d47cd user: Pierre-Yves David date: Mon Feb 11 16:21:48 2013 +0100 summary: mq: comply with filtering when injecting fake tags (issue3812) http://hg.intevation.org/mercurial/crew/rev/4fb92f14a97a changeset: 18661:4fb92f14a97a user: David Schleimer date: Fri Feb 08 05:36:08 2013 -0800 summary: commit: factor out post-commit cleanup into workingctx http://hg.intevation.org/mercurial/crew/rev/7e6946ed5756 changeset: 18660:7e6946ed5756 user: David Schleimer date: Fri Feb 08 05:36:08 2013 -0800 summary: localrepo: use workingctx for validation in commit http://hg.intevation.org/mercurial/crew/rev/b946470efed9 changeset: 18659:b946470efed9 parent: 18656:8eb3408bf005 user: David Schleimer date: Fri Feb 08 05:36:07 2013 -0800 summary: localrepo: create context used for actual commit earlier http://hg.intevation.org/mercurial/crew/rev/5e63a85299ba changeset: 18658:5e63a85299ba parent: 18656:8eb3408bf005 parent: 18657:d4a79e075303 user: Thomas Arendsen Hein date: Mon Feb 11 16:57:46 2013 +0100 summary: merge with crew-stable http://hg.intevation.org/mercurial/crew/rev/d4a79e075303 changeset: 18657:d4a79e075303 branch: stable bookmark: crew-stable parent: 18617:227479f61db9 user: Pierre-Yves David date: Sat Feb 09 23:28:42 2013 +0000 summary: debugobsolete: improve command help http://hg.intevation.org/mercurial/crew/rev/8eb3408bf005 changeset: 18656:8eb3408bf005 user: Kevin Bullock date: Sun Feb 10 23:01:12 2013 +0000 summary: import: don't rollback on failed import --exact (issue3616) http://hg.intevation.org/mercurial/crew/rev/882681bc3166 changeset: 18655:882681bc3166 parent: 18653:170142161672 parent: 18654:d9ff580fcaa2 user: Bryan O'Sullivan date: Sun Feb 10 16:22:32 2013 -0800 summary: Merge http://hg.intevation.org/mercurial/crew/rev/d9ff580fcaa2 changeset: 18654:d9ff580fcaa2 parent: 18651:e556659340f0 parent: 18648:013fcd112f13 user: Bryan O'Sullivan date: Sun Feb 10 16:21:30 2013 -0800 summary: Merge http://hg.intevation.org/mercurial/crew/rev/170142161672 changeset: 18653:170142161672 parent: 18652:a5e94bee77ed parent: 18651:e556659340f0 user: Benoit Boissinot date: Mon Feb 11 01:21:24 2013 +0100 summary: merge crew and main http://hg.intevation.org/mercurial/crew/rev/a5e94bee77ed changeset: 18652:a5e94bee77ed parent: 18642:76b69cccb07a parent: 18648:013fcd112f13 user: Benoit Boissinot date: Mon Feb 11 01:17:50 2013 +0100 summary: merge crew and main http://hg.intevation.org/mercurial/crew/rev/e556659340f0 changeset: 18651:e556659340f0 user: Siddharth Agarwal date: Sun Feb 10 16:55:01 2013 +0000 summary: manifestmerge: fix order in which manifests are fetched http://hg.intevation.org/mercurial/crew/rev/de0bd4bfc6d7 changeset: 18650:de0bd4bfc6d7 user: Siddharth Agarwal date: Sun Feb 10 12:16:46 2013 +0000 summary: merge: run _forgetremoved after manifestmerge http://hg.intevation.org/mercurial/crew/rev/0969980308c7 changeset: 18649:0969980308c7 parent: 18642:76b69cccb07a user: Siddharth Agarwal date: Sun Feb 10 16:23:14 2013 +0000 summary: dirstate: disable gc while parsing the dirstate http://hg.intevation.org/mercurial/crew/rev/76b69cccb07a changeset: 18642:76b69cccb07a user: Mads Kiilerich date: Fri Feb 08 22:54:17 2013 +0100 summary: export: show 'Date' header in a format that also is readable for humans http://hg.intevation.org/mercurial/crew/rev/c1d23b4a66d5 changeset: 18641:c1d23b4a66d5 user: Mads Kiilerich date: Sun Feb 10 18:26:04 2013 +0100 summary: factotum: fix urllib2 import so it no longer relies on a demandimport bug http://hg.intevation.org/mercurial/crew/rev/c6a81e54c209 changeset: 18640:c6a81e54c209 user: Mads Kiilerich date: Sun Jan 27 03:32:09 2013 +0100 summary: hgweb: make the test suite use hgweb in a more WSGI compliant way http://hg.intevation.org/mercurial/crew/rev/76ff3a715cf2 changeset: 18639:76ff3a715cf2 user: Mads Kiilerich date: Sun Feb 10 18:24:29 2013 +0100 summary: hgweb: simplify internal staticfile return codes http://hg.intevation.org/mercurial/crew/rev/3e92772d5383 changeset: 18638:3e92772d5383 user: Mads Kiilerich date: Sun Feb 10 18:24:29 2013 +0100 summary: spelling: fix some minor issues found by spell checker http://hg.intevation.org/mercurial/crew/rev/cc28a84db8c9 changeset: 18637:cc28a84db8c9 user: Mads Kiilerich date: Fri Feb 08 23:26:00 2013 +0100 summary: bundlerepo: replace basemap with the base field in the index http://hg.intevation.org/mercurial/crew/rev/a40d608e2a7b changeset: 18636:a40d608e2a7b user: Mads Kiilerich date: Fri Feb 08 22:54:48 2013 +0100 summary: profiling: replace '+' markup of nested lines with indentation http://hg.intevation.org/mercurial/crew/rev/6204e4d4dd6d changeset: 18635:6204e4d4dd6d parent: 18634:0027a5cec9d0 parent: 18633:a8648f32b8ed user: Augie Fackler date: Sun Feb 10 04:04:22 2013 -0600 summary: Merge crew and main. http://hg.intevation.org/mercurial/crew/rev/a8648f32b8ed changeset: 18633:a8648f32b8ed user: Bryan O'Sullivan date: Sat Feb 09 15:51:32 2013 -0800 summary: merge: don't fiddle with name lookups or i18n in hot loops http://hg.intevation.org/mercurial/crew/rev/5774732bb5e5 changeset: 18632:5774732bb5e5 user: Bryan O'Sullivan date: Sat Feb 09 15:51:32 2013 -0800 summary: merge: apply non-interactive working dir updates in parallel http://hg.intevation.org/mercurial/crew/rev/047110c0e2a8 changeset: 18631:047110c0e2a8 user: Bryan O'Sullivan date: Sat Feb 09 15:51:32 2013 -0800 summary: worker: allow a function to be run in multiple worker processes http://hg.intevation.org/mercurial/crew/rev/ac4dbceeb14a changeset: 18630:ac4dbceeb14a user: Bryan O'Sullivan date: Sat Feb 09 15:51:32 2013 -0800 summary: worker: partition a list (of tasks) into equal-sized chunks http://hg.intevation.org/mercurial/crew/rev/dcb27c153a40 changeset: 18629:dcb27c153a40 user: Bryan O'Sullivan date: Sat Feb 09 15:51:26 2013 -0800 summary: worker: estimate whether it's worth running a task in parallel http://hg.intevation.org/mercurial/crew/rev/fed06dd07665 changeset: 18628:fed06dd07665 user: Bryan O'Sullivan date: Sat Feb 09 15:22:12 2013 -0800 summary: worker: count the number of CPUs http://hg.intevation.org/mercurial/crew/rev/4b5d37ca3c11 changeset: 18627:4b5d37ca3c11 user: Bryan O'Sullivan date: Sat Feb 09 15:22:10 2013 -0800 summary: tests: getremove test output changes (fold into previous patch) http://hg.intevation.org/mercurial/crew/rev/6390dd22b12f changeset: 18626:6390dd22b12f user: Bryan O'Sullivan date: Sat Feb 09 15:22:09 2013 -0800 summary: merge: report non-interactive progress in chunks http://hg.intevation.org/mercurial/crew/rev/3e20079117c5 changeset: 18625:3e20079117c5 user: Bryan O'Sullivan date: Sat Feb 09 15:22:08 2013 -0800 summary: merge: handle subrepo merges and .hgsubstate specially http://hg.intevation.org/mercurial/crew/rev/e2dc5397bc82 changeset: 18624:e2dc5397bc82 user: Bryan O'Sullivan date: Sat Feb 09 15:22:04 2013 -0800 summary: tests: update test output (will be folded into parent) http://hg.intevation.org/mercurial/crew/rev/9b9e2d9e83a1 changeset: 18623:9b9e2d9e83a1 user: Bryan O'Sullivan date: Sat Feb 09 15:21:58 2013 -0800 summary: merge: split out mostly-non-interactive working dir updates -- Repository URL: http://hg.intevation.org/mercurial/crew From angel.ezquerra at gmail.com Sat Feb 16 06:27:24 2013 From: angel.ezquerra at gmail.com (Angel Ezquerra) Date: Sat, 16 Feb 2013 13:27:24 +0100 Subject: [PATCH 0 of 5 ] subrepo: do not push mercurial subreos whose store is clean Message-ID: This is a resend of a recent patch I sent to the list. It has been split into multiple patches as suggested by Matt. I've also tried to address the other comments that have been made. This lacks tests. I'd like to get some feedback on the message that we display when a subrepo is not pushed before tackling that. That being said, I've run all subrepo, push and pull tests and they all pass. From angel.ezquerra at gmail.com Sat Feb 16 06:27:25 2013 From: angel.ezquerra at gmail.com (Angel Ezquerra) Date: Sat, 16 Feb 2013 13:27:25 +0100 Subject: [PATCH 1 of 5] subrepo: introduce cleanstore helper functions In-Reply-To: References: Message-ID: # HG changeset patch # User Angel Ezquerra # Date 1360969620 -3600 # Node ID b56117a1b968211a464c4ba674539052328d3336 # Parent 013fcd112f13f31a35ea6a40d8cd1c6923cdaf20 subrepo: introduce cleanstore helper functions These helper functions are currently unused but will be used to implement the cleanstore method that will be introduced later. diff --git a/mercurial/subrepo.py b/mercurial/subrepo.py --- a/mercurial/subrepo.py +++ b/mercurial/subrepo.py @@ -14,6 +14,19 @@ nullstate = ('', '', 'empty') + +def _getstorehashcachename(remotepath): + '''get a unique filename for the store hash cache of a remote repository''' + return util.sha1(remotepath).hexdigest()[0:12] + +def _calcfilehash(filename): + data = '' + if os.path.exists(filename): + fd = open(filename) + data = fd.read() + fd.close() + return util.sha1(data).hexdigest() + class SubrepoAbort(error.Abort): """Exception class used to avoid handling a subrepo error more than once""" def __init__(self, *args, **kw): From angel.ezquerra at gmail.com Sat Feb 16 06:27:26 2013 From: angel.ezquerra at gmail.com (Angel Ezquerra) Date: Sat, 16 Feb 2013 13:27:26 +0100 Subject: [PATCH 2 of 5] subrepo: introduce storeclean method In-Reply-To: References: Message-ID: <108c3058f48613aaaeb9.1361017646@Angel-PC.localdomain> # HG changeset patch # User Angel Ezquerra # Date 1360973480 -3600 # Node ID 108c3058f48613aaaeb9c090c7e98d3c0ec15f1c # Parent b56117a1b968211a464c4ba674539052328d3336 subrepo: introduce storeclean method Currently this method is unused and it is not implemented for any specific subrepo type (it always returns False). It receives a remote repository path because a repository may have a clean store versus a given repository but not versus another. diff --git a/mercurial/subrepo.py b/mercurial/subrepo.py --- a/mercurial/subrepo.py +++ b/mercurial/subrepo.py @@ -313,6 +313,13 @@ class abstractsubrepo(object): + def storeclean(self, path): + """ + returns true if the repository has not changed since it was last + cloned from or pushed to a given repository. + """ + return False + def dirty(self, ignoreupdate=False): """returns true if the dirstate of the subrepo is dirty or does not match current stored state. If ignoreupdate is true, only check From angel.ezquerra at gmail.com Sat Feb 16 06:27:27 2013 From: angel.ezquerra at gmail.com (Angel Ezquerra) Date: Sat, 16 Feb 2013 13:27:27 +0100 Subject: [PATCH 3 of 5] util: add notindexed optional parameter to makedirs function In-Reply-To: References: Message-ID: <2c631f46e2fe2014c402.1361017647@Angel-PC.localdomain> # HG changeset patch # User Angel Ezquerra # Date 1361011453 -3600 # Node ID 2c631f46e2fe2014c4021249e61b471a5d92b7e4 # Parent 108c3058f48613aaaeb9c090c7e98d3c0ec15f1c util: add notindexed optional parameter to makedirs function diff --git a/mercurial/util.py b/mercurial/util.py --- a/mercurial/util.py +++ b/mercurial/util.py @@ -863,10 +863,10 @@ if safehasattr(self, '_fp'): # constructor actually did something self.discard() -def makedirs(name, mode=None): +def makedirs(name, mode=None, notindexed=False): """recursive directory creation with parent mode inheritance""" try: - os.mkdir(name) + makedir(name, notindexed) except OSError, err: if err.errno == errno.EEXIST: return @@ -875,8 +875,8 @@ parent = os.path.dirname(os.path.abspath(name)) if parent == name: raise - makedirs(parent, mode) - os.mkdir(name) + makedirs(parent, mode, notindexed) + makedir(name, notindexed) if mode is not None: os.chmod(name, mode) From angel.ezquerra at gmail.com Sat Feb 16 06:27:28 2013 From: angel.ezquerra at gmail.com (Angel Ezquerra) Date: Sat, 16 Feb 2013 13:27:28 +0100 Subject: [PATCH 4 of 5] subrepo: implement "cleanstore" method for mercurial subrepos In-Reply-To: References: Message-ID: <0f2ca0430dc9d6380a58.1361017648@Angel-PC.localdomain> # HG changeset patch # User Angel Ezquerra # Date 1360973933 -3600 # Node ID 0f2ca0430dc9d6380a58c31ddd83e59dbf6c4cf8 # Parent 2c631f46e2fe2014c4021249e61b471a5d92b7e4 subrepo: implement "cleanstore" method for mercurial subrepos The mercurial subrepo "cleanstore" method works by calculating a "store hash" of the repository state and comparing it to a cached store hash. The store hash is always cached when the repository is cloned from or pushed to a remote repository, but also on pull as long as the repository already had a clean store. If the hashes match the store is "clean" versus the selected repository. Note that this method is currenty unused, but it will be used by a later patch. The store hash is calculated by hashing several key repository files, such as the bookmarks file the phaseroots file and the changelog. Note that the hash comparison is done file by file so that we can exit early if a pair of hashes do not match. Also the hashes are calculated starting with the file that is most likely to be smaller upto the file that is more likely to be larger. diff --git a/mercurial/subrepo.py b/mercurial/subrepo.py --- a/mercurial/subrepo.py +++ b/mercurial/subrepo.py @@ -446,6 +446,72 @@ self._repo.ui.setconfig('ui', '_usedassubrepo', 'True') self._initrepo(r, state[0], create) + def storeclean(self, path): + clean = True + lock = self._repo.lock() + itercache = self._calcstorehash(path) + try: + for filehash in self._readstorehashcache(path): + if filehash != itercache.next(): + clean = False + break + except StopIteration: + # the cached and current pull states have a different size + clean = False + if clean: + try: + itercache.next() + # the cached and current pull states have a different size + clean = False + except StopIteration: + pass + lock.release() + return clean + + def _calcstorehash(self, remotepath): + '''calculate a unique "store hash" + + This method is used to to detect when there are changes that may + require a push to a given remote path.''' + # sort the files that will be hashed in increasing (likely) file size + filelist = ('bookmarks', 'store/phaseroots', 'store/00changelog.i') + yield '# %s\n' % remotepath + for relname in filelist: + absname = os.path.normpath(self._repo.join(relname)) + yield '%s = %s\n' % (absname, _calcfilehash(absname)) + + def _getstorehashcachepath(self, remotepath): + '''get a unique path for the store hash cache''' + return self._repo.join(os.path.join( + 'cache', 'storehash', _getstorehashcachename(remotepath))) + + def _readstorehashcache(self, remotepath): + '''read the store hash cache for a given remote repository''' + cachefile = self._getstorehashcachepath(remotepath) + if not os.path.exists(cachefile): + return '' + fd = open(cachefile, 'r') + pullstate = fd.readlines() + fd.close() + return pullstate + + def _cachestorehash(self, remotepath): + '''cache the current store hash + + Each remote repo requires its own store hash cache, because a subrepo + store may be "clean" versus a given remote repo, but not versus another + ''' + cachefile = self._getstorehashcachepath(remotepath) + lock = self._repo.lock() + storehash = list(self._calcstorehash(remotepath)) + cachedir = os.path.dirname(cachefile) + if not os.path.exists(cachedir): + util.makedirs(cachedir, notindexed=True) + fd = open(cachefile, 'w') + fd.writelines(storehash) + fd.close() + lock.release() + @annotatesubrepoerror def _initrepo(self, parentrepo, source, create): self._repo._subparent = parentrepo @@ -564,12 +630,17 @@ update=False) self._repo = cloned.local() self._initrepo(parentrepo, source, create=True) + self._cachestorehash(srcurl) else: self._repo.ui.status(_('pulling subrepo %s from %s\n') % (subrelpath(self), srcurl)) + cleansub = self.storeclean(srcurl) self._repo.pull(other) bookmarks.updatefromremote(self._repo.ui, self._repo, other, srcurl) + if cleansub: + # keep the repo clean after pull + self._cachestorehash(srcurl) @annotatesubrepoerror def get(self, state, overwrite=False): @@ -622,7 +693,11 @@ self._repo.ui.status(_('pushing subrepo %s to %s\n') % (subrelpath(self), dsturl)) other = hg.peer(self._repo, {'ssh': ssh}, dsturl) - return self._repo.push(other, force, newbranch=newbranch) + res = self._repo.push(other, force, newbranch=newbranch) + + # the repo is now clean + self._cachestorehash(dsturl) + return res @annotatesubrepoerror def outgoing(self, ui, dest, opts): From angel.ezquerra at gmail.com Sat Feb 16 06:27:29 2013 From: angel.ezquerra at gmail.com (Angel Ezquerra) Date: Sat, 16 Feb 2013 13:27:29 +0100 Subject: [PATCH 5 of 5] subrepo: do not push mercurial subrepos whose store is clean In-Reply-To: References: Message-ID: # HG changeset patch # User Angel Ezquerra # Date 1360974100 -3600 # Node ID f1ad0ece11a8936080b8594a69dc362a1d250499 # Parent 0f2ca0430dc9d6380a58c31ddd83e59dbf6c4cf8 subrepo: do not push mercurial subrepos whose store is clean This patch stops mercurial from pushing unmodified subrepos. An unmodified subrepo is one whose store is "clean". I have not added tests yet because I'd like to get feedback first, particularly on the message that is shown when a subrepo is not pushed because its store is clean. diff --git a/mercurial/subrepo.py b/mercurial/subrepo.py --- a/mercurial/subrepo.py +++ b/mercurial/subrepo.py @@ -690,6 +690,12 @@ return False dsturl = _abssource(self._repo, True) + if not force: + if self.storeclean(dsturl): + self._repo.ui.status( + _('no changes made to subrepo %s since last push to %s\n') + % (subrelpath(self), dsturl)) + return None self._repo.ui.status(_('pushing subrepo %s to %s\n') % (subrelpath(self), dsturl)) other = hg.peer(self._repo, {'ssh': ssh}, dsturl) From hgbuildbot at kublai.com Sat Feb 16 09:13:54 2013 From: hgbuildbot at kublai.com (hgbuildbot at kublai.com) Date: Sat, 16 Feb 2013 07:13:54 -0800 Subject: buildbot failure in Mercurial on OS X 10.7 hg tests Message-ID: <20130216151354.41F5E26706@hgbuildbot.cs.ubc.ca> The Buildbot has detected a new failure on builder OS X 10.7 hg tests while building hg. Full details are available at: http://hgbuildbot.kublai.com/builders/OS%20X%2010.7%20hg%20tests/builds/416 Buildbot URL: http://hgbuildbot.kublai.com/ Buildslave for this Build: lion Build Reason: scheduler Build Source Stamp: [branch default] 4a85ebb5c807b985f2d2107715c6e69ca747cac4 Blamelist: Kevin Bullock BUILD FAILED: failed run-tests.py (python2.7) sincerely, -The Buildbot From natosha at unity3d.com Sat Feb 16 17:14:58 2013 From: natosha at unity3d.com (Na'Tosha Bard) Date: Sun, 17 Feb 2013 00:14:58 +0100 Subject: [PATCH] largefiles: don't cache largefiles for pulled heads by default In-Reply-To: References: Message-ID: 2013/2/9 > # HG changeset patch > # User Na'Tosha Bard > # Date 1360444062 0 > # Node ID ec59cb6ffec44f330b52f4a0a41b117de38a0987 > # Parent 7f26c8bcbd74c0248acea8247f7b12b4aafe5a53 > largefiles: don't cache largefiles for pulled heads by default > I just wanted to bump this becuase I am concerned it got lost in all the re-sending of large patch series during/after the sprint. -- *Na'Tosha Bard* Software Developer | Unity Technologies - Copenhagen *E-Mail:* natosha at unity3d.com *Skype:* natosha.bard -------------- next part -------------- An HTML attachment was scrubbed... URL: From hg at intevation.org Sat Feb 16 18:35:13 2013 From: hg at intevation.org (Mercurial Commits) Date: Sun, 17 Feb 2013 01:35:13 +0100 Subject: mercurial@18667: 38 new changesets (1 stable) Message-ID: <1361061313.173148.25770.nullmailer@hg.intevation.org> 38 new changesets (1 stable) in mercurial: http://selenic.com/repo/hg//rev/9b9e2d9e83a1 changeset: 18630:9b9e2d9e83a1 parent: 18622:f9eebf5629fa user: Bryan O'Sullivan date: Sat Feb 09 15:21:58 2013 -0800 summary: merge: split out mostly-non-interactive working dir updates http://selenic.com/repo/hg//rev/e2dc5397bc82 changeset: 18631:e2dc5397bc82 user: Bryan O'Sullivan date: Sat Feb 09 15:22:04 2013 -0800 summary: tests: update test output (will be folded into parent) http://selenic.com/repo/hg//rev/3e20079117c5 changeset: 18632:3e20079117c5 user: Bryan O'Sullivan date: Sat Feb 09 15:22:08 2013 -0800 summary: merge: handle subrepo merges and .hgsubstate specially http://selenic.com/repo/hg//rev/6390dd22b12f changeset: 18633:6390dd22b12f user: Bryan O'Sullivan date: Sat Feb 09 15:22:09 2013 -0800 summary: merge: report non-interactive progress in chunks http://selenic.com/repo/hg//rev/4b5d37ca3c11 changeset: 18634:4b5d37ca3c11 user: Bryan O'Sullivan date: Sat Feb 09 15:22:10 2013 -0800 summary: tests: getremove test output changes (fold into previous patch) http://selenic.com/repo/hg//rev/fed06dd07665 changeset: 18635:fed06dd07665 user: Bryan O'Sullivan date: Sat Feb 09 15:22:12 2013 -0800 summary: worker: count the number of CPUs http://selenic.com/repo/hg//rev/dcb27c153a40 changeset: 18636:dcb27c153a40 user: Bryan O'Sullivan date: Sat Feb 09 15:51:26 2013 -0800 summary: worker: estimate whether it's worth running a task in parallel http://selenic.com/repo/hg//rev/ac4dbceeb14a changeset: 18637:ac4dbceeb14a user: Bryan O'Sullivan date: Sat Feb 09 15:51:32 2013 -0800 summary: worker: partition a list (of tasks) into equal-sized chunks http://selenic.com/repo/hg//rev/047110c0e2a8 changeset: 18638:047110c0e2a8 user: Bryan O'Sullivan date: Sat Feb 09 15:51:32 2013 -0800 summary: worker: allow a function to be run in multiple worker processes http://selenic.com/repo/hg//rev/5774732bb5e5 changeset: 18639:5774732bb5e5 user: Bryan O'Sullivan date: Sat Feb 09 15:51:32 2013 -0800 summary: merge: apply non-interactive working dir updates in parallel http://selenic.com/repo/hg//rev/a8648f32b8ed changeset: 18640:a8648f32b8ed user: Bryan O'Sullivan date: Sat Feb 09 15:51:32 2013 -0800 summary: merge: don't fiddle with name lookups or i18n in hot loops http://selenic.com/repo/hg//rev/6204e4d4dd6d changeset: 18641:6204e4d4dd6d parent: 18623:0027a5cec9d0 parent: 18640:a8648f32b8ed user: Augie Fackler date: Sun Feb 10 04:04:22 2013 -0600 summary: Merge crew and main. http://selenic.com/repo/hg//rev/a40d608e2a7b changeset: 18642:a40d608e2a7b user: Mads Kiilerich date: Fri Feb 08 22:54:48 2013 +0100 summary: profiling: replace '+' markup of nested lines with indentation http://selenic.com/repo/hg//rev/cc28a84db8c9 changeset: 18643:cc28a84db8c9 user: Mads Kiilerich date: Fri Feb 08 23:26:00 2013 +0100 summary: bundlerepo: replace basemap with the base field in the index http://selenic.com/repo/hg//rev/3e92772d5383 changeset: 18644:3e92772d5383 user: Mads Kiilerich date: Sun Feb 10 18:24:29 2013 +0100 summary: spelling: fix some minor issues found by spell checker http://selenic.com/repo/hg//rev/76ff3a715cf2 changeset: 18645:76ff3a715cf2 user: Mads Kiilerich date: Sun Feb 10 18:24:29 2013 +0100 summary: hgweb: simplify internal staticfile return codes http://selenic.com/repo/hg//rev/c6a81e54c209 changeset: 18646:c6a81e54c209 user: Mads Kiilerich date: Sun Jan 27 03:32:09 2013 +0100 summary: hgweb: make the test suite use hgweb in a more WSGI compliant way http://selenic.com/repo/hg//rev/c1d23b4a66d5 changeset: 18647:c1d23b4a66d5 user: Mads Kiilerich date: Sun Feb 10 18:26:04 2013 +0100 summary: factotum: fix urllib2 import so it no longer relies on a demandimport bug http://selenic.com/repo/hg//rev/76b69cccb07a changeset: 18648:76b69cccb07a user: Mads Kiilerich date: Fri Feb 08 22:54:17 2013 +0100 summary: export: show 'Date' header in a format that also is readable for humans http://selenic.com/repo/hg//rev/0969980308c7 changeset: 18649:0969980308c7 user: Siddharth Agarwal date: Sun Feb 10 16:23:14 2013 +0000 summary: dirstate: disable gc while parsing the dirstate http://selenic.com/repo/hg//rev/de0bd4bfc6d7 changeset: 18650:de0bd4bfc6d7 user: Siddharth Agarwal date: Sun Feb 10 12:16:46 2013 +0000 summary: merge: run _forgetremoved after manifestmerge http://selenic.com/repo/hg//rev/e556659340f0 changeset: 18651:e556659340f0 user: Siddharth Agarwal date: Sun Feb 10 16:55:01 2013 +0000 summary: manifestmerge: fix order in which manifests are fetched http://selenic.com/repo/hg//rev/a5e94bee77ed changeset: 18652:a5e94bee77ed parent: 18648:76b69cccb07a parent: 18629:013fcd112f13 user: Benoit Boissinot date: Mon Feb 11 01:17:50 2013 +0100 summary: merge crew and main http://selenic.com/repo/hg//rev/170142161672 changeset: 18653:170142161672 parent: 18652:a5e94bee77ed parent: 18651:e556659340f0 user: Benoit Boissinot date: Mon Feb 11 01:21:24 2013 +0100 summary: merge crew and main http://selenic.com/repo/hg//rev/d9ff580fcaa2 changeset: 18654:d9ff580fcaa2 parent: 18651:e556659340f0 parent: 18629:013fcd112f13 user: Bryan O'Sullivan date: Sun Feb 10 16:21:30 2013 -0800 summary: Merge http://selenic.com/repo/hg//rev/882681bc3166 changeset: 18655:882681bc3166 parent: 18653:170142161672 parent: 18654:d9ff580fcaa2 user: Bryan O'Sullivan date: Sun Feb 10 16:22:32 2013 -0800 summary: Merge http://selenic.com/repo/hg//rev/8eb3408bf005 changeset: 18656:8eb3408bf005 user: Kevin Bullock date: Sun Feb 10 23:01:12 2013 +0000 summary: import: don't rollback on failed import --exact (issue3616) http://selenic.com/repo/hg//rev/d4a79e075303 changeset: 18657:d4a79e075303 branch: stable parent: 18617:227479f61db9 user: Pierre-Yves David date: Sat Feb 09 23:28:42 2013 +0000 summary: debugobsolete: improve command help http://selenic.com/repo/hg//rev/5e63a85299ba changeset: 18658:5e63a85299ba parent: 18656:8eb3408bf005 parent: 18657:d4a79e075303 user: Thomas Arendsen Hein date: Mon Feb 11 16:57:46 2013 +0100 summary: merge with crew-stable http://selenic.com/repo/hg//rev/b946470efed9 changeset: 18659:b946470efed9 parent: 18656:8eb3408bf005 user: David Schleimer date: Fri Feb 08 05:36:07 2013 -0800 summary: localrepo: create context used for actual commit earlier http://selenic.com/repo/hg//rev/7e6946ed5756 changeset: 18660:7e6946ed5756 user: David Schleimer date: Fri Feb 08 05:36:08 2013 -0800 summary: localrepo: use workingctx for validation in commit http://selenic.com/repo/hg//rev/4fb92f14a97a changeset: 18661:4fb92f14a97a user: David Schleimer date: Fri Feb 08 05:36:08 2013 -0800 summary: commit: factor out post-commit cleanup into workingctx http://selenic.com/repo/hg//rev/c5f7e83d47cd changeset: 18662:c5f7e83d47cd user: Pierre-Yves David date: Mon Feb 11 16:21:48 2013 +0100 summary: mq: comply with filtering when injecting fake tags (issue3812) http://selenic.com/repo/hg//rev/05cf40f9b0ec changeset: 18663:05cf40f9b0ec user: Durham Goode date: Sun Feb 10 12:23:39 2013 -0800 summary: dirstate: fix generator/list error when using python 2.7 http://selenic.com/repo/hg//rev/30d899febef8 changeset: 18664:30d899febef8 user: Dan Villiom Podlaski Christiansen date: Sun Feb 10 13:14:31 2013 +0100 summary: hgweb: consistent author name width http://selenic.com/repo/hg//rev/2cbfb8c497ee changeset: 18665:2cbfb8c497ee user: Idan Kamara date: Sat Feb 09 19:13:39 2013 +0200 summary: tests: add a test runner utility that prints nothing when all tests pass http://selenic.com/repo/hg//rev/fb9d1c2805ff changeset: 18666:fb9d1c2805ff user: Idan Kamara date: Sat Feb 09 19:02:45 2013 +0200 summary: test-atomictempfile: convert to unit test http://selenic.com/repo/hg//rev/f12804d3ff80 changeset: 18667:f12804d3ff80 tag: tip parent: 18666:fb9d1c2805ff parent: 18658:5e63a85299ba user: Bryan O'Sullivan date: Mon Feb 11 14:50:54 2013 -0800 summary: Merge -- Repository URL: http://selenic.com/repo/hg/ From mercurial-bugs at selenic.com Sat Feb 16 20:47:57 2013 From: mercurial-bugs at selenic.com (mercurial-bugs at selenic.com) Date: Sun, 17 Feb 2013 02:47:57 +0000 Subject: [Bug 3827] New: stale phasecache causes LookupError on branchmap.updatecache() after strip Message-ID: http://bz.selenic.com/show_bug.cgi?id=3827 Priority: normal Bug ID: 3827 CC: mercurial-devel at selenic.com Assignee: bugzilla at selenic.com Summary: stale phasecache causes LookupError on branchmap.updatecache() after strip Severity: bug Classification: Unclassified OS: Linux Reporter: yuya at tcha.org Hardware: PC Status: UNCONFIRMED Version: 2.5.1 Component: Mercurial Product: Mercurial Since Mercurial 2.5, the following steps result in LookupError: no node. 1. Process-A loads phaseroots 2. Process-B strips the node pointed by phaseroots 3. Process-A updates branchcache after repo.invalidate() repo.invalidate() clears out most of cache data, but _phasecache isn't cleared. This is the same for Mercurial 2.4, but 2.4 works well maybe because it doesn't look up nodes by stale phasecache. Script to reproduce ---- LANG=C HGUSER=test export HGUSER #hg version -q hg init issue2428 cd issue2428 cat < .hg/hgrc [defaults] commit = -d "0 0" [extensions] mq = EOF touch toto hg add toto hg commit -m"add toto" touch tata hg add tata hg commit -m"add tata" hg up 0 touch titi hg add titi hg commit -m"add titi" hg phase -p tip { # load _phasecache.phaseroots printf 'runcommand\n\0\0\0\011phase\0-r1' sleep 1 # flush hg strip -r1 >&2 # by another process or thread # calls repo.invalidate() but _phasecache not cleared printf 'runcommand\n\0\0\0\010branches' } | hg serve --cmdserver pipe --trace ---- Stack trace ---- Traceback (most recent call last): File "/home/yuya/work/hghacks/mercurial-stable/mercurial/dispatch.py", line 88, in _runcatch return _dispatch(req) File "/home/yuya/work/hghacks/mercurial-stable/mercurial/dispatch.py", line 743, in _dispatch cmdpats, cmdoptions) File "/home/yuya/work/hghacks/mercurial-stable/mercurial/extensions.py", line 189, in wrap return wrapper(origfn, *args, **kwargs) File "/home/yuya/.hgext/textful/__init__.py", line 152, in textfulcmd cmdoptions) File "/home/yuya/work/hghacks/mercurial-stable/mercurial/dispatch.py", line 514, in runcommand ret = _runcommand(ui, options, cmd, d) File "/home/yuya/work/hghacks/mercurial-stable/mercurial/extensions.py", line 189, in wrap return wrapper(origfn, *args, **kwargs) File "/home/yuya/work/hghacks/mercurial-stable/hgext/color.py", line 394, in colorcmd return orig(ui_, opts, cmd, cmdfunc) File "/home/yuya/work/hghacks/mercurial-stable/mercurial/dispatch.py", line 833, in _runcommand return checkargs() File "/home/yuya/work/hghacks/mercurial-stable/mercurial/dispatch.py", line 804, in checkargs return cmdfunc() File "/home/yuya/work/hghacks/mercurial-stable/mercurial/dispatch.py", line 740, in d = lambda: util.checksignature(func)(ui, *args, **cmdoptions) File "/home/yuya/work/hghacks/mercurial-stable/mercurial/util.py", line 475, in check return func(*args, **kwargs) File "/home/yuya/work/hghacks/mercurial-stable/mercurial/extensions.py", line 144, in wrap util.checksignature(origfn), *args, **kwargs) File "/home/yuya/work/hghacks/mercurial-stable/mercurial/util.py", line 475, in check return func(*args, **kwargs) File "/home/yuya/work/hghacks/mercurial-stable/hgext/mq.py", line 3508, in mqcommand return orig(ui, repo, *args, **kwargs) File "/home/yuya/work/hghacks/mercurial-stable/mercurial/util.py", line 475, in check return func(*args, **kwargs) File "/home/yuya/work/hghacks/mercurial-stable/mercurial/commands.py", line 967, in branches for tag, heads in repo.branchmap().iteritems(): File "/home/yuya/work/hghacks/mercurial-stable/mercurial/localrepo.py", line 634, in branchmap branchmap.updatecache(self) File "/home/yuya/work/hghacks/mercurial-stable/mercurial/branchmap.py", line 75, in updatecache partial = subset.branchmap().copy() File "/home/yuya/work/hghacks/mercurial-stable/mercurial/localrepo.py", line 634, in branchmap branchmap.updatecache(self) File "/home/yuya/work/hghacks/mercurial-stable/mercurial/branchmap.py", line 75, in updatecache partial = subset.branchmap().copy() File "/home/yuya/work/hghacks/mercurial-stable/mercurial/localrepo.py", line 634, in branchmap branchmap.updatecache(self) File "/home/yuya/work/hghacks/mercurial-stable/mercurial/branchmap.py", line 62, in updatecache cl = repo.changelog File "/home/yuya/work/hghacks/mercurial-stable/mercurial/repoview.py", line 170, in changelog revs = filterrevs(unfi, self.filtername) File "/home/yuya/work/hghacks/mercurial-stable/mercurial/repoview.py", line 117, in filterrevs repo.filteredrevcache[filtername] = func(repo.unfiltered()) File "/home/yuya/work/hghacks/mercurial-stable/mercurial/repoview.py", line 68, in computemutable maymutable = filterrevs(repo, 'base') File "/home/yuya/work/hghacks/mercurial-stable/mercurial/repoview.py", line 117, in filterrevs repo.filteredrevcache[filtername] = func(repo.unfiltered()) File "/home/yuya/work/hghacks/mercurial-stable/mercurial/repoview.py", line 92, in computeimpactable firstmutable = min(firstmutable, min(cl.rev(r) for r in roots)) File "/home/yuya/work/hghacks/mercurial-stable/mercurial/repoview.py", line 92, in firstmutable = min(firstmutable, min(cl.rev(r) for r in roots)) File "/home/yuya/work/hghacks/mercurial-stable/mercurial/changelog.py", line 184, in rev r = super(changelog, self).rev(node) File "/home/yuya/work/hghacks/mercurial-stable/mercurial/revlog.py", line 293, in rev raise LookupError(node, self.indexfile, _('no node')) LookupError: 00changelog.i at 92a86c53f65b: no node ---- This issue was originally reported to TortoiseHg: https://bitbucket.org/tortoisehg/thg/issue/2428/strip-revisions-with-some-specific-phase -- You are receiving this mail because: You are on the CC list for the bug. From mercurial-bugs at selenic.com Sat Feb 16 23:31:59 2013 From: mercurial-bugs at selenic.com (mercurial-bugs at selenic.com) Date: Sun, 17 Feb 2013 05:31:59 +0000 Subject: [Bug 3828] New: "hg bundle --branch" fails for branches newly created on local repository Message-ID: http://bz.selenic.com/show_bug.cgi?id=3828 Priority: normal Bug ID: 3828 CC: mercurial-devel at selenic.com Assignee: bugzilla at selenic.com Summary: "hg bundle --branch" fails for branches newly created on local repository Severity: bug Classification: Unclassified OS: All Reporter: foozy at lares.dti.ne.jp Hardware: All Status: UNCONFIRMED Version: 2.5.1 Component: Mercurial Product: Mercurial "hg bundle --branch foo other-repo" fails, if "foo" is created newly on local repository. this can be reproduced by script below: hg init src echo a > src/a hg -R src commit -Am '#0' echo b > src/b hg -R src commit -Am '#1' hg clone src dst hg -R src update 0 hg -R src branch foo hg -R src commit -m '#2' hg -R src bundle --branch foo foo.hg dst -- You are receiving this mail because: You are on the CC list for the bug. From mercurial-bugs at selenic.com Sat Feb 16 23:51:23 2013 From: mercurial-bugs at selenic.com (mercurial-bugs at selenic.com) Date: Sun, 17 Feb 2013 05:51:23 +0000 Subject: [Bug 3829] New: some outgoing-like commands are not sensitive to branch specified in URL Message-ID: http://bz.selenic.com/show_bug.cgi?id=3829 Priority: normal Bug ID: 3829 CC: mercurial-devel at selenic.com Assignee: bugzilla at selenic.com Summary: some outgoing-like commands are not sensitive to branch specified in URL Severity: bug Classification: Unclassified OS: All Reporter: foozy at lares.dti.ne.jp Hardware: All Status: UNCONFIRMED Version: 2.5.1 Component: Mercurial Product: Mercurial "hg summary --remote" is not sensitive to the branch specified in destination URL, even though "hg push"/"hg outgoing" are so. this can be reproduced by script below: hg init src echo a > src/a hg -R src commit -Am '#0' hg clone src dst echo b > src/b hg -R src commit -Am '#1' hg -R src branch foo hg -R src commit -m '#2' echo "==== 2 outgoings should be in whole history ====" hg -R src outgoing dst hg -R src summary --remote --config paths.default=dst echo "==== 1 outgoing should be in default branch ====" hg -R src outgoing "dst#default" hg -R src summary --remote --config paths.default="dst#default" In above script, "hg sumary --remote" for "dst#default" will show "remote: 2 outgoing", even though there is only one outgoing revision on "default" branch. "hg histedit --outgoing" is not sensitive, too. -- You are receiving this mail because: You are on the CC list for the bug. From mercurial-bugs at selenic.com Sun Feb 17 05:06:59 2013 From: mercurial-bugs at selenic.com (mercurial-bugs at selenic.com) Date: Sun, 17 Feb 2013 11:06:59 +0000 Subject: [Bug 3830] New: "incoming" informatioin of "hg summary" is not sensitive to branch in URL Message-ID: http://bz.selenic.com/show_bug.cgi?id=3830 Priority: normal Bug ID: 3830 CC: mercurial-devel at selenic.com Assignee: bugzilla at selenic.com Summary: "incoming" informatioin of "hg summary" is not sensitive to branch in URL Severity: bug Classification: Unclassified OS: All Reporter: foozy at lares.dti.ne.jp Hardware: All Status: UNCONFIRMED Version: 2.5.1 Component: Mercurial Product: Mercurial "incoming" information of "hg summary --remote" is not sensitive to the branch specified in destination URL, even though "hg pull"/"hg incoming" are so. this can be reproduced by script below: hg init src echo a > src/a hg -R src commit -Am '#0' hg clone src dst hg -R src branch foo hg -R src commit -m '#1' echo "==== 1 incoming should be in whole history ====" hg -R dst incoming hg -R dst summary --remote echo "==== no incoming should be in default branch ====" hg -R dst incoming "src#default" hg -R dst summary --remote --config paths.default="src#default" In above script, "hg sumary --remote" for "src#default" will show "remote: 1 or more incoming", even though there is no incoming revision on "default" branch. -- You are receiving this mail because: You are on the CC list for the bug. From hg at intevation.org Sun Feb 17 06:00:10 2013 From: hg at intevation.org (Mercurial Commits) Date: Sun, 17 Feb 2013 13:00:10 +0100 Subject: mercurial/crew@18698: 31 outgoing changesets (3 stable) Message-ID: <1361102410.797263.16906.nullmailer@hg.intevation.org> 31 outgoing changesets (3 stable) in mercurial/crew: http://hg.intevation.org/mercurial/crew/rev/4a85ebb5c807 changeset: 18698:4a85ebb5c807 bookmark: @ tag: tip parent: 18695:ec9b9968b7f8 parent: 18697:7d66a44e87ed user: Kevin Bullock date: Fri Feb 15 21:20:24 2013 -0600 summary: merge with stable http://hg.intevation.org/mercurial/crew/rev/7d66a44e87ed changeset: 18697:7d66a44e87ed branch: stable user: Kevin Bullock date: Fri Feb 15 15:06:43 2013 -0600 summary: mergetools: refine vimdiff warning message http://hg.intevation.org/mercurial/crew/rev/f2b1f78cf202 changeset: 18696:f2b1f78cf202 branch: stable parent: 18679:f6f35d646cb5 user: Pierre-Yves David date: Fri Feb 15 11:28:04 2013 +0100 summary: mergetools: vimdiff issue a warning explaining how to abort http://hg.intevation.org/mercurial/crew/rev/ec9b9968b7f8 changeset: 18695:ec9b9968b7f8 user: Kevin Bullock date: Fri Feb 15 15:06:43 2013 -0600 summary: mergetools: refine vimdiff warning message http://hg.intevation.org/mercurial/crew/rev/6a012704c841 changeset: 18694:6a012704c841 user: Pierre-Yves David date: Fri Feb 15 11:28:04 2013 +0100 summary: mergetools: vimdiff issue a warning explaining how to abort http://hg.intevation.org/mercurial/crew/rev/633cd0c46e6a changeset: 18693:633cd0c46e6a user: Simon Heimberg date: Tue Feb 12 22:15:31 2013 +0100 summary: dispatch: also a separate warning message on aliases with --config http://hg.intevation.org/mercurial/crew/rev/af4387d8d1c7 changeset: 18692:af4387d8d1c7 user: Kevin Bullock date: Thu Feb 14 13:56:02 2013 -0600 summary: extensions: remove erroneous comment http://hg.intevation.org/mercurial/crew/rev/4f485bd68f1d changeset: 18691:4f485bd68f1d user: Durham Goode date: Wed Feb 13 12:51:30 2013 -0800 summary: blackbox: do not translate the log messages http://hg.intevation.org/mercurial/crew/rev/4c6f7f0dadab changeset: 18690:4c6f7f0dadab user: Kevin Bullock date: Tue Feb 12 11:36:21 2013 -0600 summary: scmutil: split platform-specific bits into their own modules http://hg.intevation.org/mercurial/crew/rev/12721a20ed30 changeset: 18689:12721a20ed30 user: Kevin Bullock date: Tue Feb 12 16:36:44 2013 +0000 summary: backout: call cmdutil.commit directly instead of commands.commit http://hg.intevation.org/mercurial/crew/rev/79107fad06aa changeset: 18688:79107fad06aa user: Kevin Bullock date: Tue Feb 12 16:32:14 2013 +0000 summary: commit: factor out status printing into a helper function http://hg.intevation.org/mercurial/crew/rev/1d183b33f007 changeset: 18687:1d183b33f007 user: Kevin Bullock date: Tue Feb 12 16:05:00 2013 +0000 summary: backout: remove unnecessary dict copy http://hg.intevation.org/mercurial/crew/rev/0bca4d31f647 changeset: 18686:0bca4d31f647 user: Kevin Bullock date: Tue Feb 12 15:47:30 2013 +0000 summary: backout: remove unnecessary frobbing of addremove option http://hg.intevation.org/mercurial/crew/rev/fafdff7e9c43 changeset: 18685:fafdff7e9c43 user: Kevin Bullock date: Tue Feb 12 15:07:17 2013 +0000 summary: backout: use cmdutil.revert directly instead of commands.revert http://hg.intevation.org/mercurial/crew/rev/c161e4cf77d4 changeset: 18684:c161e4cf77d4 parent: 18683:a343eccd5ee2 parent: 18679:f6f35d646cb5 user: Kevin Bullock date: Wed Feb 13 15:09:43 2013 -0600 summary: merge with stable http://hg.intevation.org/mercurial/crew/rev/a343eccd5ee2 changeset: 18683:a343eccd5ee2 user: Simon Heimberg date: Wed Feb 13 21:51:47 2013 +0100 summary: check-code: warn about line glob match with no glob character (?*/) http://hg.intevation.org/mercurial/crew/rev/408f2202bd80 changeset: 18682:408f2202bd80 user: Simon Heimberg date: Wed Feb 13 22:05:30 2013 +0100 summary: tests: remove glob from output lines containing no glob character http://hg.intevation.org/mercurial/crew/rev/7591ed29e824 changeset: 18681:7591ed29e824 user: Simon Heimberg date: Mon Oct 15 23:28:45 2012 +0200 summary: tests: inform on Windows about unnecessary glob lines http://hg.intevation.org/mercurial/crew/rev/15711d9d8b2c changeset: 18680:15711d9d8b2c parent: 18678:423eee0b0b14 user: Simon Heimberg date: Wed Feb 13 21:58:52 2013 +0100 summary: tests: quickly check if the glob line already matches the output http://hg.intevation.org/mercurial/crew/rev/f6f35d646cb5 changeset: 18679:f6f35d646cb5 branch: stable parent: 18657:d4a79e075303 user: Simon Heimberg date: Wed Feb 13 12:35:57 2013 +0100 summary: tests: append glob to filename output when required (windows) http://hg.intevation.org/mercurial/crew/rev/423eee0b0b14 changeset: 18678:423eee0b0b14 user: Bryan O'Sullivan date: Wed Feb 13 12:20:10 2013 -0800 summary: util: make ensuredirs safer against races http://hg.intevation.org/mercurial/crew/rev/539210ed2069 changeset: 18677:539210ed2069 user: Durham Goode date: Wed Feb 13 11:07:01 2013 -0800 summary: blackbox: only show new heads on incoming http://hg.intevation.org/mercurial/crew/rev/1506eb487ddd changeset: 18676:1506eb487ddd user: Bryan O'Sullivan date: Wed Feb 13 10:54:52 2013 -0800 summary: blackbox: fix copyright http://hg.intevation.org/mercurial/crew/rev/f816aa377e0d changeset: 18675:f816aa377e0d user: Bryan O'Sullivan date: Tue Feb 12 16:02:35 2013 -0800 summary: blackbox: fix a failing pyflakes test http://hg.intevation.org/mercurial/crew/rev/c61b49d059eb changeset: 18674:c61b49d059eb user: Durham Goode date: Sat Feb 09 13:35:30 2013 -0800 summary: blackbox: tests for the blackbox extension http://hg.intevation.org/mercurial/crew/rev/f27598902007 changeset: 18673:f27598902007 user: Durham Goode date: Sat Feb 09 09:09:46 2013 -0800 summary: blackbox: adds a 'blackbox' command for viewing recent logs http://hg.intevation.org/mercurial/crew/rev/b2b4ddc55caa changeset: 18672:b2b4ddc55caa user: Durham Goode date: Sat Feb 09 09:04:48 2013 -0800 summary: blackbox: log incoming changes via ui.log() http://hg.intevation.org/mercurial/crew/rev/1c305128e5b9 changeset: 18671:1c305128e5b9 user: Durham Goode date: Sat Feb 09 09:04:32 2013 -0800 summary: blackbox: logs python and extension hooks via ui.log() http://hg.intevation.org/mercurial/crew/rev/ddc7268da176 changeset: 18670:ddc7268da176 user: Durham Goode date: Sat Feb 09 09:04:14 2013 -0800 summary: blackbox: log the commands that are run http://hg.intevation.org/mercurial/crew/rev/18242716a014 changeset: 18669:18242716a014 user: Durham Goode date: Tue Feb 12 14:08:33 2013 -0800 summary: blackbox: adds a blackbox extension http://hg.intevation.org/mercurial/crew/rev/4034b8d551b1 changeset: 18668:4034b8d551b1 user: Bryan O'Sullivan date: Mon Feb 11 16:15:12 2013 -0800 summary: scmutil: create directories in a race-safe way during update -- Repository URL: http://hg.intevation.org/mercurial/crew From angel.ezquerra at gmail.com Sun Feb 17 06:19:15 2013 From: angel.ezquerra at gmail.com (Angel Ezquerra) Date: Sun, 17 Feb 2013 13:19:15 +0100 Subject: [PATCH 0 of 3 ] pull: add --subrepos flag Message-ID: This requires some tests. I will add them after the first review. The current test suite passes without errors. From angel.ezquerra at gmail.com Sun Feb 17 06:19:16 2013 From: angel.ezquerra at gmail.com (Angel Ezquerra) Date: Sun, 17 Feb 2013 13:19:16 +0100 Subject: [PATCH 1 of 3] pull: add --subrepos flag In-Reply-To: References: Message-ID: # HG changeset patch # User Angel Ezquerra # Date 1360519226 -3600 # Node ID abbd26cca35280fb8f784b3f2c02eef71696c47b # Parent 55b9b294b7544a6a144f627f71f4b770907d5a98 pull: add --subrepos flag The purpose of this new flag is to ensure that you are able to update to any incoming revision without requiring any network access. The idea is to make sure that the repository is self-contained after doing hg pull --subrepos, as long as it already was self-contained before the pull). When the --subrepos flag is enabled, pull will also pull (or clone) all subrepos that are present on the current revision and those that are referenced by any of the incoming revisions. If the incoming revisions refer to subrepos that are not on the working directory yet they will be cloned. If any of the subrepositories changes its pull source (as defined on the .hgsub file) it will be pulled from the current and the new source. This first patch only supports mercurial subrepos (a NotImplementedError exception will be raised for all other subrepo types). Future patches will add support for other subrepo types. This requires some tests (I will add them after review). I ran the whole test suite and all non skipped tests passed (# Ran 426 tests, 29 skipped, 0 failed.). diff --git a/mercurial/commands.py b/mercurial/commands.py --- a/mercurial/commands.py +++ b/mercurial/commands.py @@ -18,6 +18,7 @@ import dagparser, context, simplemerge, graphmod import random, setdiscovery, treediscovery, dagutil, pvec, localrepo import phases, obsolete +import itertools table = {} @@ -4694,6 +4695,7 @@ ('B', 'bookmark', [], _("bookmark to pull"), _('BOOKMARK')), ('b', 'branch', [], _('a specific branch you would like to pull'), _('BRANCH')), + ('S', 'subrepos', None, _('pull current and incoming subrepos')), ] + remoteopts, _('[-u] [-f] [-r REV]... [-e CMD] [--remotecmd CMD] [SOURCE]')) def pull(ui, repo, source="default", **opts): @@ -4738,7 +4740,25 @@ "so a rev cannot be specified.") raise util.Abort(err) + oldtip = len(repo) modheads = repo.pull(other, heads=revs, force=opts.get('force')) + + # update current and new subrepos + if opts.get('subrepos'): + # pull (or clone) the subrepos that are referenced by the + # current revision or by any of the incoming revisions + substopull = {} + revstocheck = itertools.chain(['.'], repo.changelog.revs(oldtip)) + for rev in revstocheck: + ctx = repo[rev] + for sname, sinfo in ctx.substate.items(): + substopull[(sname, sinfo,)] = ctx + + # note that we must pull the subrepos before calling postincoming + # to avoid pulling them again if --update is also set + for (sname, sinfo), ctx in substopull.items(): + ctx.sub(sname).pull(sinfo[0]) + bookmarks.updatefromremote(ui, repo, other, source) if checkout: checkout = str(repo.changelog.rev(other.lookup(checkout))) diff --git a/mercurial/subrepo.py b/mercurial/subrepo.py --- a/mercurial/subrepo.py +++ b/mercurial/subrepo.py @@ -330,6 +330,11 @@ """ raise NotImplementedError + def pull(self, source): + """pull from the given parent repository source + """ + raise NotImplementedError + def get(self, state, overwrite=False): """run whatever commands are needed to put the subrepo into this state @@ -528,6 +533,10 @@ self._repo.ui.note(_('removing subrepo %s\n') % subrelpath(self)) hg.clean(self._repo, node.nullid, False) + def pull(self, source): + state = (source, None, 'hg') + return self._get(state) + def _get(self, state): source, revision, kind = state if revision not in self._repo: diff --git a/tests/test-debugcomplete.t b/tests/test-debugcomplete.t --- a/tests/test-debugcomplete.t +++ b/tests/test-debugcomplete.t @@ -204,7 +204,7 @@ init: ssh, remotecmd, insecure log: follow, follow-first, date, copies, keyword, rev, removed, only-merges, user, only-branch, branch, prune, patch, git, limit, no-merges, stat, graph, style, template, include, exclude merge: force, rev, preview, tool - pull: update, force, rev, bookmark, branch, ssh, remotecmd, insecure + pull: update, force, rev, bookmark, branch, subrepos, ssh, remotecmd, insecure push: force, rev, bookmark, branch, new-branch, ssh, remotecmd, insecure remove: after, force, include, exclude serve: accesslog, daemon, daemon-pipefds, errorlog, port, address, prefix, name, web-conf, webdir-conf, pid-file, stdio, cmdserver, templates, style, ipv6, certificate From angel.ezquerra at gmail.com Sun Feb 17 06:19:17 2013 From: angel.ezquerra at gmail.com (Angel Ezquerra) Date: Sun, 17 Feb 2013 13:19:17 +0100 Subject: [PATCH 2 of 3] subrepo: add pull --subrepos support to git subrepos In-Reply-To: References: Message-ID: <33063dc38f45ef3a707d.1361103557@Angel-PC.localdomain> # HG changeset patch # User Angel Ezquerra # Date 1360519814 -3600 # Node ID 33063dc38f45ef3a707ddf95f1a716e370315840 # Parent abbd26cca35280fb8f784b3f2c02eef71696c47b subrepo: add pull --subrepos support to git subrepos Note that I am not a git subrepo user myself so please review this carefully. diff --git a/mercurial/subrepo.py b/mercurial/subrepo.py --- a/mercurial/subrepo.py +++ b/mercurial/subrepo.py @@ -1059,19 +1059,22 @@ self._subsource = source return _abssource(self) + def pull(self, source): + self._fetch(source, None) + def _fetch(self, source, revision): if self._gitmissing(): source = self._abssource(source) self._ui.status(_('cloning subrepo %s from %s\n') % (self._relpath, source)) self._gitnodir(['clone', source, self._abspath]) - if self._githavelocally(revision): + if revision is not None and self._githavelocally(revision): return self._ui.status(_('pulling subrepo %s from %s\n') % (self._relpath, self._gitremote('origin'))) # try only origin: the originally cloned repo self._gitcommand(['fetch']) - if not self._githavelocally(revision): + if revision is not None and not self._githavelocally(revision): raise util.Abort(_("revision %s does not exist in subrepo %s\n") % (revision, self._relpath)) From angel.ezquerra at gmail.com Sun Feb 17 06:19:18 2013 From: angel.ezquerra at gmail.com (Angel Ezquerra) Date: Sun, 17 Feb 2013 13:19:18 +0100 Subject: [PATCH 3 of 3] subrepo: add pull --subrepos support to svn subrepos In-Reply-To: References: Message-ID: # HG changeset patch # User Angel Ezquerra # Date 1360519887 -3600 # Node ID a47dcdb3e4338b6ddf361e16653fafe7d7ead27e # Parent 33063dc38f45ef3a707ddf95f1a716e370315840 subrepo: add pull --subrepos support to svn subrepos Pulling does not make sense for subversion subrepos. This change just makes sure that we do not raise NotImplementedError when we try to pull from subversion subrepos. diff --git a/mercurial/subrepo.py b/mercurial/subrepo.py --- a/mercurial/subrepo.py +++ b/mercurial/subrepo.py @@ -884,6 +884,10 @@ if _updateprompt(self._ui, self, dirty, wcrev, new): self.get(state, False) + def pull(self, opts): + # pull is a no-op for SVN + return True + def push(self, opts): # push is a no-op for SVN return True From trot.thunder at gmail.com Sun Feb 17 06:41:19 2013 From: trot.thunder at gmail.com (Takumi IINO) Date: Sun, 17 Feb 2013 21:41:19 +0900 Subject: [PATCH STABLE] hgweb: show correct error message for i18n environment Message-ID: <788242e9369672359cf6.1361104879@iino-no-MacBook-Air.local> # HG changeset patch # User Takumi IINO # Date 1360919234 -32400 # Branch stable # Node ID 788242e9369672359cf65a4fd111554674385351 # Parent 227479f61db9d169c1afea6fa0a9dce7288d4932 hgweb: show correct error message for i18n environment If exception is error.LookupError and running in i18n environment, below condition is always true. Because msg is translated and dosen't contain 'manifest'. if util.safehasattr(err, 'name') and 'manifest' not in msg: This patch creates a new exception class and uses it instead of string match. diff --git a/mercurial/context.py b/mercurial/context.py --- a/mercurial/context.py +++ b/mercurial/context.py @@ -291,16 +291,16 @@ try: return self._manifest[path], self._manifest.flags(path) except KeyError: - raise error.LookupError(self._node, path, - _('not found in manifest')) + raise error.ManifestLookupError(self._node, path, + _('not found in manifest')) if '_manifestdelta' in self.__dict__ or path in self.files(): if path in self._manifestdelta: return (self._manifestdelta[path], self._manifestdelta.flags(path)) node, flag = self._repo.manifest.find(self._changeset[0], path) if not node: - raise error.LookupError(self._node, path, - _('not found in manifest')) + raise error.ManifestLookupError(self._node, path, + _('not found in manifest')) return node, flag diff --git a/mercurial/error.py b/mercurial/error.py --- a/mercurial/error.py +++ b/mercurial/error.py @@ -27,6 +27,9 @@ def __str__(self): return RevlogError.__str__(self) +class ManifestLookupError(LookupError): + pass + class CommandError(Exception): """Exception raised on errors in parsing the command line.""" diff --git a/mercurial/hgweb/hgweb_mod.py b/mercurial/hgweb/hgweb_mod.py --- a/mercurial/hgweb/hgweb_mod.py +++ b/mercurial/hgweb/hgweb_mod.py @@ -245,7 +245,8 @@ except (error.LookupError, error.RepoLookupError), err: req.respond(HTTP_NOT_FOUND, ctype) msg = str(err) - if util.safehasattr(err, 'name') and 'manifest' not in msg: + if (util.safehasattr(err, 'name') and + not isinstance(err, error.ManifestLookupError)): msg = 'revision not found: %s' % err.name return tmpl('error', error=msg) except (error.RepoError, error.RevlogError), inst: From foozy at lares.dti.ne.jp Sun Feb 17 09:26:34 2013 From: foozy at lares.dti.ne.jp (FUJIWARA Katsunori) Date: Mon, 18 Feb 2013 00:26:34 +0900 Subject: [PATCH 0 of 3 STABLE] fix problems around incoming/outgoing handling Message-ID: This patch series fixes problem around incoming/outgoing handling. From foozy at lares.dti.ne.jp Sun Feb 17 09:26:36 2013 From: foozy at lares.dti.ne.jp (FUJIWARA Katsunori) Date: Mon, 18 Feb 2013 00:26:36 +0900 Subject: [PATCH 2 of 3 STABLE] commands: make outgoing-like commands sensitive to branch in URL (issue3829) In-Reply-To: References: Message-ID: <373c150caa5f20ae975e.1361114796@juju> # HG changeset patch # User FUJIWARA Katsunori # Date 1361113469 -32400 # Branch stable # Node ID 373c150caa5f20ae975e086b8f211811afbd1687 # Parent f63d2a3d62855a430b7a4323bbfaef1e696dc471 commands: make outgoing-like commands sensitive to branch in URL (issue3829) Before this patch, commands below are not sensitive to the branch specified in the URL of the destination repository, even though "hg push"/"hg outgoing" are so: - hg histedit --outgoing - hg summary --remote These invoke "discovery.findcommonoutgoing()" without "onlyheads" argument, so it returns revisions on branches other than the one specified in the URL, too. This patch specifies heads revisions, which are already detected by "hg.addbranchrevs()" and "repo.lookup()", as "onlyheads" to "discovery.findcommonoutgoing()" to limit calculation of outgoing revisions. This patch also removes "repo.changelog.nodesbetween()" invocations in largefiles extension, because it is meaningless if "discovery.findcommonoutgoing()" is invoked with "onlyheads". diff --git a/hgext/histedit.py b/hgext/histedit.py --- a/hgext/histedit.py +++ b/hgext/histedit.py @@ -459,7 +459,7 @@ # contains special revset characters like ":" the revset # parser can choke. parent = [node.hex(n) for n in discovery.findcommonoutgoing( - repo, other, [], force=opts.get('force')).missing[0:1]] + repo, other, revs, force=opts.get('force')).missing[0:1]] else: if opts.get('force'): raise util.Abort(_('--force only allowed with --outgoing')) diff --git a/hgext/largefiles/overrides.py b/hgext/largefiles/overrides.py --- a/hgext/largefiles/overrides.py +++ b/hgext/largefiles/overrides.py @@ -1000,15 +1000,15 @@ remote = hg.peer(repo, opts, dest) except error.RepoError: return None - outgoing = discovery.findcommonoutgoing(repo, remote.peer(), force=False) + outgoing = discovery.findcommonoutgoing(repo, remote.peer(), + onlyheads=revs, force=False) if not outgoing.missing: return outgoing.missing - o = repo.changelog.nodesbetween(outgoing.missing, revs)[0] if opts.get('newest_first'): - o.reverse() + outgoing.missing.reverse() toupload = set() - for n in o: + for n in outgoing.missing: parents = [p for p in repo.changelog.parents(n) if p != node.nullid] ctx = repo[n] files = set(ctx.files()) diff --git a/hgext/largefiles/reposetup.py b/hgext/largefiles/reposetup.py --- a/hgext/largefiles/reposetup.py +++ b/hgext/largefiles/reposetup.py @@ -406,11 +406,11 @@ def push(self, remote, force=False, revs=None, newbranch=False): outgoing = discovery.findcommonoutgoing(repo, remote.peer(), + onlyheads=revs, force=force) if outgoing.missing: toupload = set() - o = self.changelog.nodesbetween(outgoing.missing, revs)[0] - for n in o: + for n in outgoing.missing: parents = [p for p in self.changelog.parents(n) if p != node_.nullid] ctx = self[n] diff --git a/mercurial/commands.py b/mercurial/commands.py --- a/mercurial/commands.py +++ b/mercurial/commands.py @@ -5691,8 +5691,10 @@ other = hg.peer(repo, {}, dest) commoninc = None ui.debug('comparing with %s\n' % util.hidepassword(dest)) + if revs: + revs = [repo.lookup(rev) for rev in revs] repo.ui.pushbuffer() - outgoing = discovery.findcommonoutgoing(repo, other, + outgoing = discovery.findcommonoutgoing(repo, other, onlyheads=revs, commoninc=commoninc) repo.ui.popbuffer() o = outgoing.missing diff --git a/tests/test-histedit-outgoing.t b/tests/test-histedit-outgoing.t --- a/tests/test-histedit-outgoing.t +++ b/tests/test-histedit-outgoing.t @@ -82,3 +82,24 @@ # 0 files updated, 0 files merged, 0 files removed, 0 files unresolved $ cd .. + +test sensitivity to branch in URL (issue3829): + + $ cd r2 + $ hg -q update 2 + $ hg -q branch foo + $ hg commit -m 'create foo branch' + $ HGEDITOR=cat hg histedit --outgoing '../r#foo' | grep -v comparing | grep -v searching + pick f26599ee3441 6 create foo branch + + # Edit history between f26599ee3441 and f26599ee3441 + # + # Commands: + # p, pick = use commit + # e, edit = use commit, but stop for amending + # f, fold = use commit, but fold into previous commit (combines N and N-1) + # d, drop = remove commit from history + # m, mess = edit message without changing commit content + # + 0 files updated, 0 files merged, 0 files removed, 0 files unresolved + $ cd .. diff --git a/tests/test-largefiles.t b/tests/test-largefiles.t --- a/tests/test-largefiles.t +++ b/tests/test-largefiles.t @@ -2111,4 +2111,72 @@ b +test sensitivity to branch in URL (issue3829): + + $ cd clone2 + $ hg -q update 0 + $ hg -q branch foo + $ echo c > c + $ hg add --large c + $ hg -q commit -m 'create foo branch' + Invoking status precommit hook + A c + + $ hg outgoing --large --template '{rev}\n' + comparing with $TESTTMP/issue3651/src + searching for changes + 1 + 2 + searching for changes + largefiles to upload: + b + c + + $ hg summary --large --remote + parent: 2:d8c88cf19687 tip + create foo branch + branch: foo + commit: (clean) + update: (current) + remote: 2 outgoing + searching for changes + largefiles: 2 to upload + + $ hg outgoing --large --template '{rev}\n' --config paths.default='../src#default' + comparing with $TESTTMP/issue3651/src + searching for changes + 1 + searching for changes + largefiles to upload: + b + + $ hg summary --large --remote --config paths.default='../src#default' + parent: 2:d8c88cf19687 tip + create foo branch + branch: foo + commit: (clean) + update: (current) + remote: 1 outgoing + searching for changes + largefiles: 1 to upload + + $ ls -1 ../src/.hg/largefiles + 3f786850e387550fdab836ed7e6dc881de23001b + dirstate + $ hg -q push '../src#default' + $ ls -1 ../src/.hg/largefiles + 3f786850e387550fdab836ed7e6dc881de23001b + 89e6c98d92887913cadf06b2adb97f26cde4849b + dirstate + $ hg outgoing --large --template '{rev}\n' + comparing with $TESTTMP/issue3651/src + searching for changes + 2 + searching for changes + largefiles to upload: + c + + $ cd .. + + $ cd .. diff --git a/tests/test-url-rev.t b/tests/test-url-rev.t --- a/tests/test-url-rev.t +++ b/tests/test-url-rev.t @@ -80,8 +80,25 @@ date: Thu Jan 01 00:00:00 1970 +0000 summary: add a + $ hg -q outgoing '../clone' + 2:faba9097cad4 + 3:4cd725637392 + $ hg --config paths.default='../clone' summary --remote + parent: 3:4cd725637392 tip + add bar + branch: default + commit: (clean) + update: (current) + remote: 2 outgoing $ hg -q outgoing '../clone#foo' 2:faba9097cad4 + $ hg --config paths.default='../clone#foo' summary --remote + parent: 3:4cd725637392 tip + add bar + branch: default + commit: (clean) + update: (current) + remote: 1 outgoing $ hg -q push '../clone#foo' From foozy at lares.dti.ne.jp Sun Feb 17 09:26:37 2013 From: foozy at lares.dti.ne.jp (FUJIWARA Katsunori) Date: Mon, 18 Feb 2013 00:26:37 +0900 Subject: [PATCH 3 of 3 STABLE] summary: make "incoming" information sensitive to branch in URL (issue3830) In-Reply-To: References: Message-ID: <606365294a9994c715fb.1361114797@juju> # HG changeset patch # User FUJIWARA Katsunori # Date 1361113469 -32400 # Branch stable # Node ID 606365294a9994c715fb426a7efb37b68de9b46e # Parent 373c150caa5f20ae975e086b8f211811afbd1687 summary: make "incoming" information sensitive to branch in URL (issue3830) Before this patch, "incoming" information of "hg summary --remote" is not sensitive to the branch specified in the URL of the destination repository, even though "hg pull"/"hg incoming" are so. "hg summary" invokes "discovery.findcommonincoming()" without "heads" argument, so it returns revisions on branches other than the one specified in the URL, too. This patch looks head revisions up against "other" repository, and invokes "discovery.findcommonincoming()" with list of them as "heads" to limit calculation of incoming revisions. diff --git a/mercurial/commands.py b/mercurial/commands.py --- a/mercurial/commands.py +++ b/mercurial/commands.py @@ -5677,9 +5677,11 @@ other = hg.peer(repo, {}, source) revs, checkout = hg.addbranchrevs(repo, other, branches, opts.get('rev')) + if revs: + revs = [other.lookup(rev) for rev in revs] ui.debug('comparing with %s\n' % util.hidepassword(source)) repo.ui.pushbuffer() - commoninc = discovery.findcommonincoming(repo, other) + commoninc = discovery.findcommonincoming(repo, other, heads=revs) _common, incoming, _rheads = commoninc repo.ui.popbuffer() if incoming: diff --git a/tests/test-url-rev.t b/tests/test-url-rev.t --- a/tests/test-url-rev.t +++ b/tests/test-url-rev.t @@ -100,6 +100,16 @@ update: (current) remote: 1 outgoing + $ hg -q --cwd ../clone incoming + 2:faba9097cad4 + $ hg --cwd ../clone summary --remote + parent: 1:cd2a86ecc814 tip + change a + branch: foo + commit: (clean) + update: (current) + remote: 1 or more incoming + $ hg -q push '../clone#foo' $ hg --cwd ../clone heads @@ -115,6 +125,16 @@ date: Thu Jan 01 00:00:00 1970 +0000 summary: add a + $ hg -q --cwd ../clone incoming + [1] + $ hg --cwd ../clone summary --remote + parent: 1:cd2a86ecc814 + change a + branch: foo + commit: (clean) + update: 1 new changesets (update) + remote: (synced) + $ cd .. $ cd clone From foozy at lares.dti.ne.jp Sun Feb 17 09:26:35 2013 From: foozy at lares.dti.ne.jp (FUJIWARA Katsunori) Date: Mon, 18 Feb 2013 00:26:35 +0900 Subject: [PATCH 1 of 3 STABLE] bundle: treat branches created newly on the local correctly (issue3828) In-Reply-To: References: Message-ID: # HG changeset patch # User FUJIWARA Katsunori # Date 1361113468 -32400 # Branch stable # Node ID f63d2a3d62855a430b7a4323bbfaef1e696dc471 # Parent d4a79e075303dafbe8d226d119f3e9ead1c48d53 bundle: treat branches created newly on the local correctly (issue3828) Before this patch, "hg bundle --branch foo other" fails to create bundle file, if specified "foo" branch is created newly on the local repository. "hg bundle" uses "hg.addbranchrevs(repo, other, ...)" to look branch names up, even though other outgoing-like implementation uses "hg.addbranchrevs(repo, repo, ...)". In the former invocation, "other" repository recognizes such branches as unknown, so execution is aborted. This patch uses "hg.addbranchrevs(repo, repo, ..)" in "hg bundle" to bundle revisions on such branches correctly. diff --git a/mercurial/commands.py b/mercurial/commands.py --- a/mercurial/commands.py +++ b/mercurial/commands.py @@ -1066,7 +1066,7 @@ dest = ui.expandpath(dest or 'default-push', dest or 'default') dest, branches = hg.parseurl(dest, opts.get('branch')) other = hg.peer(repo, opts, dest) - revs, checkout = hg.addbranchrevs(repo, other, branches, revs) + revs, checkout = hg.addbranchrevs(repo, repo, branches, revs) heads = revs and map(repo.lookup, revs) or revs outgoing = discovery.findcommonoutgoing(repo, other, onlyheads=heads, diff --git a/tests/test-bundle.t b/tests/test-bundle.t --- a/tests/test-bundle.t +++ b/tests/test-bundle.t @@ -522,6 +522,21 @@ [255] $ cd .. +test to bundle revisions on the newly created branch (issue3828): + + $ hg -q clone -U test test-clone + $ cd test + + $ hg -q branch foo + $ hg commit -m "create foo branch" + $ hg -q outgoing ../test-clone + 9:b4f5acb1ee27 + $ hg -q bundle --branch foo foo.hg ../test-clone + $ hg -R foo.hg -q log -r "bundle()" + 9:b4f5acb1ee27 + + $ cd .. + test for http://mercurial.selenic.com/bts/issue1144 test that verify bundle does not traceback From foozy at lares.dti.ne.jp Sun Feb 17 10:08:06 2013 From: foozy at lares.dti.ne.jp (FUJIWARA Katsunori) Date: Mon, 18 Feb 2013 01:08:06 +0900 Subject: [PATCH] revset: use "repo.changelog" instead of "list(repo)" for resource efficiency Message-ID: <06fb2582618f43400b38.1361117286@juju> # HG changeset patch # User FUJIWARA Katsunori # Date 1361115858 -32400 # Node ID 06fb2582618f43400b38ac4c791410d2fc748d2c # Parent f12804d3ff801b989cb2aab1aad93047a8db46f1 revset: use "repo.changelog" instead of "list(repo)" for resource efficiency Before this patch, some revset predicates use "list(repo)" as "subset" to indicate "all revisions in the repo", and it immediately creates the list object containing such revisions, even though it may not be used: for example, "stringset" omits checking whether the revision number corresponding to the specified string is contained in "subset" or not, if "len(subset) == len(repo)". This patch uses "repo.changelog" instead of "list(repo)" for resource efficiency. diff --git a/mercurial/revset.py b/mercurial/revset.py --- a/mercurial/revset.py +++ b/mercurial/revset.py @@ -239,7 +239,7 @@ def dagrange(repo, subset, x, y): if subset: - r = list(repo) + r = repo.changelog xs = _revsbetween(repo, getset(repo, r, x), getset(repo, r, y)) s = set(subset) return [r for r in xs if r in s] @@ -286,14 +286,14 @@ """ # i18n: "ancestor" is a keyword l = getlist(x) - rl = list(repo) + cl = repo.changelog anc = None - # (getset(repo, rl, i) for i in l) generates a list of lists + # (getset(repo, cl, i) for i in l) generates a list of lists rev = repo.changelog.rev ancestor = repo.changelog.ancestor node = repo.changelog.node - for revs in (getset(repo, rl, i) for i in l): + for revs in (getset(repo, cl, i) for i in l): for r in revs: if anc is None: anc = r @@ -305,7 +305,7 @@ return [] def _ancestors(repo, subset, x, followfirst=False): - args = getset(repo, list(repo), x) + args = getset(repo, repo.changelog, x) if not args: return [] s = set(_revancestors(repo, args, followfirst)) | set(args) @@ -432,7 +432,7 @@ else: return [r for r in subset if matcher(repo[r].branch())] - s = getset(repo, list(repo), x) + s = getset(repo, repo.changelog, x) b = set() for r in s: b.add(repo[r].branch()) @@ -511,7 +511,7 @@ """``children(set)`` Child changesets of changesets in set. """ - s = set(getset(repo, list(repo), x)) + s = set(getset(repo, repo.changelog, x)) cs = _children(repo, subset, s) return [r for r in subset if r in cs] @@ -592,7 +592,7 @@ return l def _descendants(repo, subset, x, followfirst=False): - args = getset(repo, list(repo), x) + args = getset(repo, repo.changelog, x) if not args: return [] s = set(_revdescendants(repo, args, followfirst)) | set(args) @@ -616,9 +616,9 @@ is the same as passing all(). """ if x is not None: - args = set(getset(repo, list(repo), x)) + args = set(getset(repo, repo.changelog, x)) else: - args = set(getall(repo, list(repo), x)) + args = set(getall(repo, repo.changelog, x)) dests = set() @@ -932,7 +932,7 @@ # i18n: "limit" is a keyword raise error.ParseError(_("limit expects a number")) ss = set(subset) - os = getset(repo, list(repo), l[0])[:lim] + os = getset(repo, repo.changelog, l[0])[:lim] return [r for r in os if r in ss] def last(repo, subset, x): @@ -950,14 +950,14 @@ # i18n: "last" is a keyword raise error.ParseError(_("last expects a number")) ss = set(subset) - os = getset(repo, list(repo), l[0])[-lim:] + os = getset(repo, repo.changelog, l[0])[-lim:] return [r for r in os if r in ss] def maxrev(repo, subset, x): """``max(set)`` Changeset with highest revision number in set. """ - os = getset(repo, list(repo), x) + os = getset(repo, repo.changelog, x) if os: m = max(os) if m in subset: @@ -994,7 +994,7 @@ """``min(set)`` Changeset with lowest revision number in set. """ - os = getset(repo, list(repo), x) + os = getset(repo, repo.changelog, x) if os: m = min(os) if m in subset: @@ -1044,9 +1044,9 @@ for the first operation is selected. """ if x is not None: - args = set(getset(repo, list(repo), x)) + args = set(getset(repo, repo.changelog, x)) else: - args = set(getall(repo, list(repo), x)) + args = set(getall(repo, repo.changelog, x)) def _firstsrc(rev): src = _getrevsource(repo, rev) @@ -1096,7 +1096,7 @@ ps = set() cl = repo.changelog - for r in getset(repo, list(repo), x): + for r in getset(repo, cl, x): ps.add(cl.parentrevs(r)[0]) return [r for r in subset if r in ps] @@ -1114,7 +1114,7 @@ ps = set() cl = repo.changelog - for r in getset(repo, list(repo), x): + for r in getset(repo, cl, x): ps.add(cl.parentrevs(r)[1]) return [r for r in subset if r in ps] @@ -1128,7 +1128,7 @@ ps = set() cl = repo.changelog - for r in getset(repo, list(repo), x): + for r in getset(repo, cl, x): ps.update(cl.parentrevs(r)) return [r for r in subset if r in ps] From kbullock+mercurial at ringworld.org Sun Feb 17 17:09:38 2013 From: kbullock+mercurial at ringworld.org (Kevin Bullock) Date: Sun, 17 Feb 2013 17:09:38 -0600 Subject: [PATCH 1 of 3 STABLE] bundle: treat branches created newly on the local correctly (issue3828) In-Reply-To: References: Message-ID: <6FE969BF-44C6-4F4A-900D-689950D91B21@ringworld.org> On 17 Feb 2013, at 9:26 AM, FUJIWARA Katsunori wrote: > # HG changeset patch > # User FUJIWARA Katsunori > # Date 1361113468 -32400 > # Branch stable > # Node ID f63d2a3d62855a430b7a4323bbfaef1e696dc471 > # Parent d4a79e075303dafbe8d226d119f3e9ead1c48d53 > bundle: treat branches created newly on the local correctly (issue3828) Queued this one for stable, thanks. pacem in terris / ??? / ?????? / ????????? / ?? Kevin R. Bullock From angel.ezquerra at gmail.com Sun Feb 17 17:13:59 2013 From: angel.ezquerra at gmail.com (Angel Ezquerra) Date: Mon, 18 Feb 2013 00:13:59 +0100 Subject: [PATCH 0 of 2 V5] hgweb: teach archive how to handle file patterns Message-ID: This new series does not really let archive download patterns anymore. Instead we only allow downloading a directory or a file. From angel.ezquerra at gmail.com Sun Feb 17 17:14:00 2013 From: angel.ezquerra at gmail.com (Angel Ezquerra) Date: Mon, 18 Feb 2013 00:14:00 +0100 Subject: [PATCH 1 of 2 V5] test-archive: gracefully handle HTTPErrors on get-with-headers In-Reply-To: References: Message-ID: <2f7b559540108a021cba.1361142840@Angel-PC.localdomain> # HG changeset patch # User Angel Ezquerra # Date 1360141605 -3600 # Node ID 2f7b559540108a021cba31c0c7affa011ef119cc # Parent 013fcd112f13f31a35ea6a40d8cd1c6923cdaf20 test-archive: gracefully handle HTTPErrors on get-with-headers This avoids pritting out a traceback when a get-with-headers call causes hgweb to respond with an HTTPError code. diff --git a/tests/test-archive.t b/tests/test-archive.t --- a/tests/test-archive.t +++ b/tests/test-archive.t @@ -69,10 +69,18 @@ > msvcrt.setmode(sys.stdout.fileno(), os.O_BINARY) > except ImportError: > pass - > node, archive = sys.argv[1:] - > f = urllib2.urlopen('http://127.0.0.1:%s/?cmd=archive;node=%s;type=%s' - > % (os.environ['HGPORT'], node, archive)) - > sys.stdout.write(f.read()) + > if len(sys.argv) <= 3: + > node, archive = sys.argv[1:] + > requeststr = 'cmd=archive;node=%s;type=%s' % (node, archive) + > else: + > node, archive, file = sys.argv[1:] + > requeststr = 'cmd=archive;node=%s;type=%s;file=%s' % (node, archive, file) + > try: + > f = urllib2.urlopen('http://127.0.0.1:%s/?%s' + > % (os.environ['HGPORT'], requeststr)) + > sys.stdout.write(f.read()) + > except urllib2.HTTPError, e: + > sys.stderr.write(str(e) + '\n') > EOF $ python getarchive.py "$TIP" gz | gunzip | tar tf - 2>/dev/null test-archive-2c0277f05ed4/.hg_archival.txt From angel.ezquerra at gmail.com Sun Feb 17 17:14:01 2013 From: angel.ezquerra at gmail.com (Angel Ezquerra) Date: Mon, 18 Feb 2013 00:14:01 +0100 Subject: [PATCH 2 of 2 V5] hgweb: teach archive how to download a specific directory or file In-Reply-To: References: Message-ID: <45216cdf25a89a639290.1361142841@Angel-PC.localdomain> # HG changeset patch # User Angel Ezquerra # Date 1360493525 -3600 # Node ID 45216cdf25a89a6392901a10fde16b7f96307cc5 # Parent 2f7b559540108a021cba31c0c7affa011ef119cc hgweb: teach archive how to download a specific directory or file The archive web command now takes into account the "file" request entry, if one is provided. The provided "file" is processed as a "path" corresponding to a directory or file that will be downloaded. With this change hgweb can to process requests such as: http://mercurial.selenic.com/hg/archive/tip.zip/mercurial/templates This will download all files on the mercurial/templates directory as a zip file. It is not possible to specify file patterns. Those will be rejected with a 403 reply fromthe server. Note that this is a first step to add support for downloading directories from the web interface. Currently the only way to use this feature is by manually constructing the URL that you want to download. We will have to modify the archiveentry map entry on the different templates so that it adds the current folder path to the archive links. This revision also adds a two tests for this feature to test-archive.t. The first tests the selective archive feature and the second tests that the server rejects patterns. diff --git a/mercurial/hgweb/webcommands.py b/mercurial/hgweb/webcommands.py --- a/mercurial/hgweb/webcommands.py +++ b/mercurial/hgweb/webcommands.py @@ -816,6 +816,17 @@ if cnode == key or key == 'tip': arch_version = short(cnode) name = "%s-%s" % (reponame, arch_version) + + ctx = webutil.changectx(web.repo, req) + pats = [] + file = req.form.get('file', None) + defaultpat = 'path' + if file: + pats = [req.form['file'][0]] + if ':' in pats[0]: + msg = 'Archive pattern not allowed: %s' % pats[0] + raise ErrorResponse(HTTP_FORBIDDEN, msg) + mimetype, artype, extension, encoding = web.archive_specs[type_] headers = [ ('Content-Disposition', 'attachment; filename=%s%s' % (name, extension)) @@ -825,9 +836,9 @@ req.headers.extend(headers) req.respond(HTTP_OK, mimetype) - ctx = webutil.changectx(web.repo, req) + matchfn = scmutil.match(ctx, pats, default=defaultpat) archival.archive(web.repo, req, cnode, artype, prefix=name, - matchfn=scmutil.match(ctx, []), + matchfn=matchfn, subrepos=web.configbool("web", "archivesubrepos")) return [] diff --git a/tests/test-archive.t b/tests/test-archive.t --- a/tests/test-archive.t +++ b/tests/test-archive.t @@ -100,6 +100,13 @@ testing: test-archive-2c0277f05ed4/baz/bletch OK testing: test-archive-2c0277f05ed4/foo OK No errors detected in compressed data of archive.zip. + $ python getarchive.py "$TIP" gz baz | gunzip | tar tf - 2>/dev/null + test-archive-2c0277f05ed4/baz/bletch + +test that we reject unsafe patterns + + $ python getarchive.py "$TIP" gz relre:baz + HTTP Error 403: Archive pattern not allowed: relre:baz $ "$TESTDIR/killdaemons.py" $DAEMON_PIDS From mercurial-bugs at selenic.com Sun Feb 17 12:39:59 2013 From: mercurial-bugs at selenic.com (mercurial-bugs at selenic.com) Date: Sun, 17 Feb 2013 18:39:59 +0000 Subject: [Bug 3831] New: rebase across unrelated trees leaves root with multiple parents Message-ID: http://bz.selenic.com/show_bug.cgi?id=3831 Priority: normal Bug ID: 3831 CC: mercurial-devel at selenic.com Assignee: bugzilla at selenic.com Summary: rebase across unrelated trees leaves root with multiple parents Severity: bug Classification: Unclassified OS: Windows Reporter: jaraco at jaraco.com Hardware: PC Status: UNCONFIRMED Version: unspecified Component: rebase Product: Mercurial I recently encountered a situation where a rebase leaves the rebased changeset with the original ancestry present. Here's a simple reproduction with Mercurial 2.4.2. PS C:\Users\jaraco> hg init x PS C:\Users\jaraco> cd x PS C:\Users\jaraco\x> touch a PS C:\Users\jaraco\x> hg add a PS C:\Users\jaraco\x> hg ci -m "1" PS C:\Users\jaraco\x> hg update null 0 files updated, 0 files merged, 1 files removed, 0 files unresolved PS C:\Users\jaraco\x> touch a PS C:\Users\jaraco\x> hg add a PS C:\Users\jaraco\x> hg ci -m "1 (two)" created new head PS C:\Users\jaraco\x> thgw log PS C:\Users\jaraco\x> cat > a foo PS C:\Users\jaraco\x> hg ci -m "Edit" PS C:\Users\jaraco\x> hg log changeset: 2:41e2fa94ff99 tag: tip user: Jason R. Coombs date: Sun Feb 17 18:12:03 2013 -0500 summary: Edit changeset: 1:f42354edd70b parent: -1:000000000000 user: Jason R. Coombs date: Sun Feb 17 18:11:06 2013 -0500 summary: 1 (two) changeset: 0:9984c651bc1b user: Jason R. Coombs date: Sun Feb 17 18:10:46 2013 -0500 summary: 1 PS C:\Users\jaraco\x> hg rebase -s 2 -d 0 merging a saved backup bundle to C:\Users\jaraco\x\.hg\strip-backup\41e2fa94ff99-backup.hg PS C:\Users\jaraco\x> hg log changeset: 2:c3f0325c6930 tag: tip parent: 0:9984c651bc1b parent: 1:f42354edd70b user: Jason R. Coombs date: Sun Feb 17 18:12:03 2013 -0500 summary: Edit changeset: 1:f42354edd70b parent: -1:000000000000 user: Jason R. Coombs date: Sun Feb 17 18:11:06 2013 -0500 summary: 1 (two) changeset: 0:9984c651bc1b user: Jason R. Coombs date: Sun Feb 17 18:10:46 2013 -0500 summary: 1 As you can see, the rebased change now appears with parents in both 0 and 1. My expectation based on other rebases I've done is that the rebased change should be moved, not merged. My goal in moving the tree is to strip the changeset at rev 1, but keep change 2. Because of this behavior, it's not possible to remove 1. Do you have any suggestions for (a) how I might be doing this wrong, (b) if there is a workaround, or (c) confirm this is undesirable behavior (a bug) and suggest when it might be fixed? -- You are receiving this mail because: You are on the CC list for the bug. From hgbuildbot at kublai.com Sun Feb 17 18:01:15 2013 From: hgbuildbot at kublai.com (hgbuildbot at kublai.com) Date: Sun, 17 Feb 2013 16:01:15 -0800 Subject: buildbot failure in Mercurial on hg tests (stable) Message-ID: <20130218000116.9217025E03@hgbuildbot.cs.ubc.ca> The Buildbot has detected a new failure on builder hg tests (stable) while building hg. Full details are available at: http://hgbuildbot.kublai.com/builders/hg%20tests%20%28stable%29/builds/305 Buildbot URL: http://hgbuildbot.kublai.com/ Buildslave for this Build: p64.osuosl.test Build Reason: scheduler Build Source Stamp: [branch stable] 61c8327ced503bf7a1996337af711e0f4a58d4c0 Blamelist: FUJIWARA Katsunori BUILD FAILED: failed http2 sincerely, -The Buildbot From pierre-yves.david at ens-lyon.org Sun Feb 17 18:03:18 2013 From: pierre-yves.david at ens-lyon.org (Pierre-Yves David) Date: Mon, 18 Feb 2013 01:03:18 +0100 Subject: [PATCH 2 of 2 RFCv2] commands: introduce stash command In-Reply-To: <06dd5eda17402c1e89a1.1360887323@idan> References: <06dd5eda17402c1e89a1.1360887323@idan> Message-ID: On 15 f?vr. 2013, at 01:15, Idan Kamara wrote: > # HG changeset patch > # User Idan Kamara > # Date 1360886982 -7200 > # Node ID 06dd5eda17402c1e89a1aa212e340b146394fad8 > # Parent d4c029076cf2213ad680a53dfd32b0886b2b7be0 > commands: introduce stash command I'm very happy to see this happening. Having a sane and stable solution to shelve/unshelve is very important. I not sure that putting that as a core command is the right things to do. I would expect the command to be introduced in an extension before getting into core. > Stashes are unnamed (by default) and can be listed using --list and inspected > with -s/--show. Is there real usage for unnamed stash? don't we want to force the user to provide a minimal description ? > Referring to stashes is done either by index (as shown in --list) or name (if > one was given). If neither is specified, the most recent stash is chosen. Most recent rules seems sane. > A stash is saved as a regular secret commit in the repository Note that once it is hidden, it does not needs to be secret. Its already excluded from exchanges. > and is identified by a bookmark under a special namespace '.hg/stash/'. Muh? what does stash as do do with bookmark? Can't you keep the label internally? (and expose them in revset if needed) > It is hidden from the user and isn't exchanged with other repositories. > When a stash is popped or deleted, it is stripped from the repository or marked obsolete if obsolete is enabled. If you use obsolescence markers, you have to ensure that people can recreate the "same stash" with a different commit hash. In the same way it seems that you are storing stash commit as plain standard commit (including commit message content), this open the way to unfortunate collision between stash and standard changeset. > It's currently not possible to stash when an mq patch is applied. Unless mq > sometime in the future stops the use of strip (unlikely, mainly due to lack of > interest in touching it), this won't change. Your check is too weak. User can qimport stash parent and qpop them. You need stronger check in MQ I'll do a more technical review later. Having smaller patches would help people wiling to review it. Thanks again for working on this. -- Pierre-Yves David From hg at intevation.org Sun Feb 17 18:05:09 2013 From: hg at intevation.org (Mercurial Commits) Date: Mon, 18 Feb 2013 01:05:09 +0100 Subject: mercurial@18697: 30 new changesets (1 stable) Message-ID: <1361145909.532985.8676.nullmailer@hg.intevation.org> 30 new changesets (1 stable) in mercurial: http://selenic.com/repo/hg//rev/4034b8d551b1 changeset: 18668:4034b8d551b1 user: Bryan O'Sullivan date: Mon Feb 11 16:15:12 2013 -0800 summary: scmutil: create directories in a race-safe way during update http://selenic.com/repo/hg//rev/18242716a014 changeset: 18669:18242716a014 user: Durham Goode date: Tue Feb 12 14:08:33 2013 -0800 summary: blackbox: adds a blackbox extension http://selenic.com/repo/hg//rev/ddc7268da176 changeset: 18670:ddc7268da176 user: Durham Goode date: Sat Feb 09 09:04:14 2013 -0800 summary: blackbox: log the commands that are run http://selenic.com/repo/hg//rev/1c305128e5b9 changeset: 18671:1c305128e5b9 user: Durham Goode date: Sat Feb 09 09:04:32 2013 -0800 summary: blackbox: logs python and extension hooks via ui.log() http://selenic.com/repo/hg//rev/b2b4ddc55caa changeset: 18672:b2b4ddc55caa user: Durham Goode date: Sat Feb 09 09:04:48 2013 -0800 summary: blackbox: log incoming changes via ui.log() http://selenic.com/repo/hg//rev/f27598902007 changeset: 18673:f27598902007 user: Durham Goode date: Sat Feb 09 09:09:46 2013 -0800 summary: blackbox: adds a 'blackbox' command for viewing recent logs http://selenic.com/repo/hg//rev/c61b49d059eb changeset: 18674:c61b49d059eb user: Durham Goode date: Sat Feb 09 13:35:30 2013 -0800 summary: blackbox: tests for the blackbox extension http://selenic.com/repo/hg//rev/f816aa377e0d changeset: 18675:f816aa377e0d user: Bryan O'Sullivan date: Tue Feb 12 16:02:35 2013 -0800 summary: blackbox: fix a failing pyflakes test http://selenic.com/repo/hg//rev/1506eb487ddd changeset: 18676:1506eb487ddd user: Bryan O'Sullivan date: Wed Feb 13 10:54:52 2013 -0800 summary: blackbox: fix copyright http://selenic.com/repo/hg//rev/539210ed2069 changeset: 18677:539210ed2069 user: Durham Goode date: Wed Feb 13 11:07:01 2013 -0800 summary: blackbox: only show new heads on incoming http://selenic.com/repo/hg//rev/423eee0b0b14 changeset: 18678:423eee0b0b14 user: Bryan O'Sullivan date: Wed Feb 13 12:20:10 2013 -0800 summary: util: make ensuredirs safer against races http://selenic.com/repo/hg//rev/f6f35d646cb5 changeset: 18679:f6f35d646cb5 branch: stable parent: 18657:d4a79e075303 user: Simon Heimberg date: Wed Feb 13 12:35:57 2013 +0100 summary: tests: append glob to filename output when required (windows) http://selenic.com/repo/hg//rev/15711d9d8b2c changeset: 18680:15711d9d8b2c parent: 18678:423eee0b0b14 user: Simon Heimberg date: Wed Feb 13 21:58:52 2013 +0100 summary: tests: quickly check if the glob line already matches the output http://selenic.com/repo/hg//rev/7591ed29e824 changeset: 18681:7591ed29e824 user: Simon Heimberg date: Mon Oct 15 23:28:45 2012 +0200 summary: tests: inform on Windows about unnecessary glob lines http://selenic.com/repo/hg//rev/408f2202bd80 changeset: 18682:408f2202bd80 user: Simon Heimberg date: Wed Feb 13 22:05:30 2013 +0100 summary: tests: remove glob from output lines containing no glob character http://selenic.com/repo/hg//rev/a343eccd5ee2 changeset: 18683:a343eccd5ee2 user: Simon Heimberg date: Wed Feb 13 21:51:47 2013 +0100 summary: check-code: warn about line glob match with no glob character (?*/) http://selenic.com/repo/hg//rev/c161e4cf77d4 changeset: 18684:c161e4cf77d4 parent: 18683:a343eccd5ee2 parent: 18679:f6f35d646cb5 user: Kevin Bullock date: Wed Feb 13 15:09:43 2013 -0600 summary: merge with stable http://selenic.com/repo/hg//rev/fafdff7e9c43 changeset: 18685:fafdff7e9c43 user: Kevin Bullock date: Tue Feb 12 15:07:17 2013 +0000 summary: backout: use cmdutil.revert directly instead of commands.revert http://selenic.com/repo/hg//rev/0bca4d31f647 changeset: 18686:0bca4d31f647 user: Kevin Bullock date: Tue Feb 12 15:47:30 2013 +0000 summary: backout: remove unnecessary frobbing of addremove option http://selenic.com/repo/hg//rev/1d183b33f007 changeset: 18687:1d183b33f007 user: Kevin Bullock date: Tue Feb 12 16:05:00 2013 +0000 summary: backout: remove unnecessary dict copy http://selenic.com/repo/hg//rev/79107fad06aa changeset: 18688:79107fad06aa user: Kevin Bullock date: Tue Feb 12 16:32:14 2013 +0000 summary: commit: factor out status printing into a helper function http://selenic.com/repo/hg//rev/12721a20ed30 changeset: 18689:12721a20ed30 user: Kevin Bullock date: Tue Feb 12 16:36:44 2013 +0000 summary: backout: call cmdutil.commit directly instead of commands.commit http://selenic.com/repo/hg//rev/4c6f7f0dadab changeset: 18690:4c6f7f0dadab user: Kevin Bullock date: Tue Feb 12 11:36:21 2013 -0600 summary: scmutil: split platform-specific bits into their own modules http://selenic.com/repo/hg//rev/4f485bd68f1d changeset: 18691:4f485bd68f1d user: Durham Goode date: Wed Feb 13 12:51:30 2013 -0800 summary: blackbox: do not translate the log messages http://selenic.com/repo/hg//rev/af4387d8d1c7 changeset: 18692:af4387d8d1c7 user: Kevin Bullock date: Thu Feb 14 13:56:02 2013 -0600 summary: extensions: remove erroneous comment http://selenic.com/repo/hg//rev/633cd0c46e6a changeset: 18693:633cd0c46e6a user: Simon Heimberg date: Tue Feb 12 22:15:31 2013 +0100 summary: dispatch: also a separate warning message on aliases with --config http://selenic.com/repo/hg//rev/6a012704c841 changeset: 18694:6a012704c841 user: Pierre-Yves David date: Fri Feb 15 11:28:04 2013 +0100 summary: mergetools: vimdiff issue a warning explaining how to abort http://selenic.com/repo/hg//rev/ec9b9968b7f8 changeset: 18695:ec9b9968b7f8 user: Kevin Bullock date: Fri Feb 15 15:06:43 2013 -0600 summary: mergetools: refine vimdiff warning message http://selenic.com/repo/hg//rev/d23f61b6617f changeset: 18696:d23f61b6617f user: Matt Mackall date: Sun Feb 17 14:41:31 2013 -0600 summary: httppeer: avoid large dumps when we don't see an hgweb repo http://selenic.com/repo/hg//rev/4921b5c2aeed changeset: 18697:4921b5c2aeed tag: tip user: Matt Mackall date: Sun Feb 17 14:34:53 2013 -0600 summary: httppeer: improve protocol check -- Repository URL: http://selenic.com/repo/hg/ From hgbuildbot at kublai.com Sun Feb 17 20:12:55 2013 From: hgbuildbot at kublai.com (hgbuildbot at kublai.com) Date: Sun, 17 Feb 2013 18:12:55 -0800 Subject: buildbot failure in Mercurial on hg tests Message-ID: <20130218021256.03AA127023@hgbuildbot.cs.ubc.ca> The Buildbot has detected a new failure on builder hg tests while building hg. Full details are available at: http://hgbuildbot.kublai.com/builders/hg%20tests/builds/506 Buildbot URL: http://hgbuildbot.kublai.com/ Buildslave for this Build: p64.osuosl.test Build Reason: scheduler Build Source Stamp: [branch default] 4921b5c2aeed8a6bb0918503f7802508538f01e5 Blamelist: Matt Mackall BUILD FAILED: failed http2 sincerely, -The Buildbot From foozy at lares.dti.ne.jp Mon Feb 18 00:09:59 2013 From: foozy at lares.dti.ne.jp (FUJIWARA Katsunori) Date: Mon, 18 Feb 2013 15:09:59 +0900 Subject: [PATCH 2 of 3 STABLE] commands: make outgoing-like commands sensitive to branch in URL (issue3829) In-Reply-To: <373c150caa5f20ae975e.1361114796@juju> References: <373c150caa5f20ae975e.1361114796@juju> Message-ID: At Mon, 18 Feb 2013 00:26:36 +0900, FUJIWARA Katsunori wrote: > > # HG changeset patch > # User FUJIWARA Katsunori > # Date 1361113469 -32400 > # Branch stable > # Node ID 373c150caa5f20ae975e086b8f211811afbd1687 > # Parent f63d2a3d62855a430b7a4323bbfaef1e696dc471 > commands: make outgoing-like commands sensitive to branch in URL (issue3829) > > Before this patch, commands below are not sensitive to the branch > specified in the URL of the destination repository, even though "hg > push"/"hg outgoing" are so: > > - hg histedit --outgoing > - hg summary --remote > > These invoke "discovery.findcommonoutgoing()" without "onlyheads" > argument, so it returns revisions on branches other than the one > specified in the URL, too. > > This patch specifies heads revisions, which are already detected by > "hg.addbranchrevs()" and "repo.lookup()", as "onlyheads" to > "discovery.findcommonoutgoing()" to limit calculation of outgoing > revisions. > > This patch also removes "repo.changelog.nodesbetween()" invocations in > largefiles extension, because it is meaningless if > "discovery.findcommonoutgoing()" is invoked with "onlyheads". I folded also modifications for largefiles into this patch, because of similar "discovery.findcommonoutgoing()" fix. But this is not bug fix, but a kind of refactoring. So, I'll split this into bug fix for summary/histedit and refactoring for largefiles, and resend them separately. ---------------------------------------------------------------------- [FUJIWARA Katsunori] foozy at lares.dti.ne.jp From hg at intevation.org Mon Feb 18 06:00:06 2013 From: hg at intevation.org (Mercurial Commits) Date: Mon, 18 Feb 2013 13:00:06 +0100 Subject: mercurial/crew@18699: 4 outgoing changesets (3 stable) Message-ID: <1361188806.804158.31901.nullmailer@hg.intevation.org> 4 outgoing changesets (3 stable) in mercurial/crew: http://hg.intevation.org/mercurial/crew/rev/61c8327ced50 changeset: 18699:61c8327ced50 branch: stable tag: tip parent: 18697:7d66a44e87ed user: FUJIWARA Katsunori date: Mon Feb 18 00:04:28 2013 +0900 summary: bundle: treat branches created newly on the local correctly (issue3828) http://hg.intevation.org/mercurial/crew/rev/4a85ebb5c807 changeset: 18698:4a85ebb5c807 bookmark: @ parent: 18695:ec9b9968b7f8 parent: 18697:7d66a44e87ed user: Kevin Bullock date: Fri Feb 15 21:20:24 2013 -0600 summary: merge with stable http://hg.intevation.org/mercurial/crew/rev/7d66a44e87ed changeset: 18697:7d66a44e87ed branch: stable user: Kevin Bullock date: Fri Feb 15 15:06:43 2013 -0600 summary: mergetools: refine vimdiff warning message http://hg.intevation.org/mercurial/crew/rev/f2b1f78cf202 changeset: 18696:f2b1f78cf202 branch: stable parent: 18679:f6f35d646cb5 user: Pierre-Yves David date: Fri Feb 15 11:28:04 2013 +0100 summary: mergetools: vimdiff issue a warning explaining how to abort -- Repository URL: http://hg.intevation.org/mercurial/crew From idankk86 at gmail.com Mon Feb 18 06:10:41 2013 From: idankk86 at gmail.com (Idan Kamara) Date: Mon, 18 Feb 2013 14:10:41 +0200 Subject: [PATCH 2 of 2 RFCv2] commands: introduce stash command In-Reply-To: References: <06dd5eda17402c1e89a1.1360887323@idan> Message-ID: On Mon, Feb 18, 2013 at 2:03 AM, Pierre-Yves David < pierre-yves.david at ens-lyon.org> wrote: > > > On 15 f?vr. 2013, at 01:15, Idan Kamara wrote: > > > # HG changeset patch > > # User Idan Kamara > > # Date 1360886982 -7200 > > # Node ID 06dd5eda17402c1e89a1aa212e340b146394fad8 > > # Parent d4c029076cf2213ad680a53dfd32b0886b2b7be0 > > commands: introduce stash command > > I'm very happy to see this happening. Having a sane and stable solution to > shelve/unshelve is very important. > > I not sure that putting that as a core command is the right things to do. > I would expect the command to be introduced in an extension before getting > into core. I guess that's fine since it relies on some fairly new features in core. I just hope it won't require all sorts of glue code to work properly as an extension. How do others feel? > > > Stashes are unnamed (by default) and can be listed using --list and > > inspected > > with -s/--show. > > Is there real usage for unnamed stash? don't we want to force the user to > provide a minimal description ? Of course, it's a lot faster to do: $ hg stash $ hg up $ hg stash -p Than to start thinking of an unused name. > > > Referring to stashes is done either by index (as shown in --list) or > > name (if > > one was given). If neither is specified, the most recent stash is > > chosen. > > Most recent rules seems sane. > > > A stash is saved as a regular secret commit in the repository > > Note that once it is hidden, it does not needs to be secret. Its already > excluded from exchanges. Ok, so I'm slightly confused. Does secret imply hidden? Do I want it to be hidden or secret? > > > and is identified by a bookmark under a special namespace '.hg/stash/'. > > Muh? what does stash as do do with bookmark? Can't you keep the label > internally? (and expose them in revset if needed) Keep it internally how? A dedicated file in .hg/? Why not use an existing mechanism? > > > It is hidden from the user and isn't exchanged with other repositories. > > > When a stash is popped or deleted, it is stripped from the repository or > > marked obsolete if obsolete is enabled. > > If you use obsolescence markers, you have to ensure that people can > recreate the "same stash" with a different commit hash. > > In the same way it seems that you are storing stash commit as plain > standard commit (including commit message content), this open the way to > unfortunate collision between stash and standard changeset. Interesting, I'll look into it. > > > It's currently not possible to stash when an mq patch is applied. Unless > > mq > > sometime in the future stops the use of strip (unlikely, mainly due to > > lack of > > interest in touching it), this won't change. > > Your check is too weak. User can qimport stash parent and qpop them. You > need stronger check in MQ Right.. I haven't really thoroughly tested how it behaves with MQ yet. -------------- next part -------------- An HTML attachment was scrubbed... URL: From laurens.nospam at grauw.nl Mon Feb 18 06:46:32 2013 From: laurens.nospam at grauw.nl (Laurens Holst) Date: Mon, 18 Feb 2013 13:46:32 +0100 Subject: [PATCH 2 of 2 RFCv2] commands: introduce stash command In-Reply-To: References: <06dd5eda17402c1e89a1.1360887323@idan> Message-ID: <512222A8.2010600@grauw.nl> Op 18-02-13 01:03, Pierre-Yves David schreef: >> Stashes are unnamed (by default) and can be listed using --list and inspected >> with -s/--show. I don?t really like changing the meaning of a command with options; I always preferred having ?hg branches? and ?hg branch? as separate commands (as opposed to how Git does it). Similarly, I would prefer hg stashes to list them, and hg stash to make them. > Is there real usage for unnamed stash? don't we want to force the user to provide a minimal description ? I almost never specify names with stashes, not in Mercurial nor git. I think that?s also always been one of the big advantages of Mercurial vs. git; that you don?t need to think about branch names and can just quickly create an anonymous one. Same principle applies to stashes. ~Laurens From pierre-yves.david at logilab.fr Mon Feb 18 07:41:16 2013 From: pierre-yves.david at logilab.fr (Pierre-Yves David) Date: Mon, 18 Feb 2013 14:41:16 +0100 Subject: [PATCH 2 of 2 RFCv2] commands: introduce stash command In-Reply-To: References: <06dd5eda17402c1e89a1.1360887323@idan> Message-ID: <20130218134116.GA13873@crater2.logilab.fr> On Mon, Feb 18, 2013 at 02:10:41PM +0200, Idan Kamara wrote: > On Mon, Feb 18, 2013 at 2:03 AM, Pierre-Yves David < > pierre-yves.david at ens-lyon.org> wrote: > > > > > > On 15 f?vr. 2013, at 01:15, Idan Kamara wrote: > > > > > # HG changeset patch > > > # User Idan Kamara > > > # Date 1360886982 -7200 > > > # Node ID 06dd5eda17402c1e89a1aa212e340b146394fad8 > > > # Parent d4c029076cf2213ad680a53dfd32b0886b2b7be0 > > > commands: introduce stash command > > > > I'm very happy to see this happening. Having a sane and stable solution to > > shelve/unshelve is very important. > > > > I not sure that putting that as a core command is the right things to do. > > I would expect the command to be introduced in an extension before getting > > into core. > > I guess that's fine since it relies on some fairly new features in core. > I just hope it won't require all sorts of glue code to work properly as an > extension. > > How do others feel? To clarify my point I would prefer it to be a separated extensions for a few month. It will validate the approach leaves the door open for some UI and behavior adjustement. > > > Stashes are unnamed (by default) and can be listed using --list and > > > inspected > > > with -s/--show. > > > > Is there real usage for unnamed stash? don't we want to force the user to > > provide a minimal description ? > > Of course, it's a lot faster to do: > > $ hg stash > $ hg up > $ hg stash -p > > Than to start thinking of an unused name. not really convinced. I would probably always use $ hg stash wip $ hg up $ hg stash -p wip Where having wip already taken is an highlight that something is wrong. (I'm not telling your approach is wrong) > > > Referring to stashes is done either by index (as shown in --list) or > > > name (if > > > one was given). If neither is specified, the most recent stash is > > > chosen. > > > > Most recent rules seems sane. > > > > > A stash is saved as a regular secret commit in the repository > > > > Note that once it is hidden, it does not needs to be secret. Its already > > excluded from exchanges. > > Ok, so I'm slightly confused. Does secret imply hidden? Do I want it > to be hidden or secret? You want it to be hidden. It does not needs to be secret to be excluded from pull and push. visible = all() - hidden() served = all() - (hidden() or secret() > > > and is identified by a bookmark under a special namespace '.hg/stash/'. > > > > Muh? what does stash as do do with bookmark? Can't you keep the label > > internally? (and expose them in revset if needed) > > Keep it internally how? A dedicated file in .hg/? Why not use an > existing mechanism? Yes a dedicated file in .hg/store/ As far as I understand stash id: - Does not behaves as bookmarks, - Does not moves like bookmarks, - Are not exchanged like bookmarks, If its does not look like a bookmarks, it is not a bookmark. (reverse duck typing) -- Pierre-Yves David http://www.logilab.fr/ -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 198 bytes Desc: Digital signature URL: From sean.michael.farley at gmail.com Mon Feb 18 11:26:03 2013 From: sean.michael.farley at gmail.com (Sean Farley) Date: Mon, 18 Feb 2013 11:26:03 -0600 Subject: [PATCH 2 of 2 RFCv2] commands: introduce stash command In-Reply-To: <512222A8.2010600@grauw.nl> References: <06dd5eda17402c1e89a1.1360887323@idan> <512222A8.2010600@grauw.nl> Message-ID: Laurens Holst writes: > Op 18-02-13 01:03, Pierre-Yves David schreef: >>> Stashes are unnamed (by default) and can be listed using --list and inspected >>> with -s/--show. > I don?t really like changing the meaning of a command with options; I > always preferred having ?hg branches? and ?hg branch? as separate > commands (as opposed to how Git does it). > > Similarly, I would prefer hg stashes to list them, and hg stash to make > them. > >> Is there real usage for unnamed stash? don't we want to force the user to provide a minimal description ? > I almost never specify names with stashes, not in Mercurial nor git. > > I think that?s also always been one of the big advantages of Mercurial > vs. git; that you don?t need to think about branch names and can just > quickly create an anonymous one. Same principle applies to stashes. I'll have to agree here with Laurens. 90% - 95% of the time that I want to stash is because some command needs to muck with the working directory (e.g. histedit, rebase, etc.). Therefore, I really don't care about the name of the stash most of the time. Of course, if histedit, rebase, et al. could be improved to use memctx, then I might change my tune :-) From raf at durin42.com Mon Feb 18 15:13:27 2013 From: raf at durin42.com (Augie Fackler) Date: Mon, 18 Feb 2013 16:13:27 -0500 Subject: histedit and rebase using memctx (was: Re: [PATCH 2 of 2 RFCv2] commands: introduce stash command) In-Reply-To: References: <06dd5eda17402c1e89a1.1360887323@idan> <512222A8.2010600@grauw.nl> Message-ID: <47864460-51D0-4748-AA2B-5357031F9D84@durin42.com> On Feb 18, 2013, at 12:26 PM, Sean Farley wrote: > Of course, if histedit, rebase, et al. could be improved to use memctx, > then I might change my tune :-) The problem (as I see it) with that is that both rebase and histedit can drop into a manual conflict resolution phase that requires the working copy to be clean. If we had some generalized (safe) stashing mechanism (which a stash command could use), I'd be a fan of wiring that into histedit and rebase. From kbullock+mercurial at ringworld.org Mon Feb 18 15:30:05 2013 From: kbullock+mercurial at ringworld.org (Kevin Bullock) Date: Mon, 18 Feb 2013 15:30:05 -0600 Subject: [PATCH 2 of 2 RFCv2] commands: introduce stash command In-Reply-To: References: <06dd5eda17402c1e89a1.1360887323@idan> Message-ID: On Feb 18, 2013, at 6:10 AM, Idan Kamara wrote: > On Mon, Feb 18, 2013 at 2:03 AM, Pierre-Yves David wrote: > > > > > > On 15 f?vr. 2013, at 01:15, Idan Kamara wrote: > > > > > # HG changeset patch > > > # User Idan Kamara > > > # Date 1360886982 -7200 > > > # Node ID 06dd5eda17402c1e89a1aa212e340b146394fad8 > > > # Parent d4c029076cf2213ad680a53dfd32b0886b2b7be0 > > > commands: introduce stash command > > > > I'm very happy to see this happening. Having a sane and stable solution to > > shelve/unshelve is very important. > > > > I not sure that putting that as a core command is the right things to do. > > I would expect the command to be introduced in an extension before getting > > into core. > > I guess that's fine since it relies on some fairly new features in core. > I just hope it won't require all sorts of glue code to work properly as an > extension. > > How do others feel? I'd rather see it as an extension first as well. > > > Stashes are unnamed (by default) and can be listed using --list and > > > inspected > > > with -s/--show. > > > > Is there real usage for unnamed stash? don't we want to force the user to > > provide a minimal description ? Forcing the user to think up a name kills most of the usefulness of this feature. If I want to stash some work in progress in my working dir, it's because my mind is already onto the next thing I have to work on. I want to get the current cruft out of the way as quickly as possible. > > > and is identified by a bookmark under a special namespace '.hg/stash/'. > > > > Muh? what does stash as do do with bookmark? Can't you keep the label > > internally? (and expose them in revset if needed) > > Keep it internally how? A dedicated file in .hg/? Why not use an > existing mechanism? I agree with Pierre-Yves, using bookmarks for this would be a little wonky. Seems motivated by the implementation details of Git's stash more than anything else. pacem in terris / ??? / ?????? / ????????? / ?? Kevin R. Bullock From sean.michael.farley at gmail.com Mon Feb 18 15:57:42 2013 From: sean.michael.farley at gmail.com (Sean Farley) Date: Mon, 18 Feb 2013 15:57:42 -0600 Subject: histedit and rebase using memctx (was: Re: [PATCH 2 of 2 RFCv2] commands: introduce stash command) In-Reply-To: <47864460-51D0-4748-AA2B-5357031F9D84@durin42.com> References: <06dd5eda17402c1e89a1.1360887323@idan> <512222A8.2010600@grauw.nl> <47864460-51D0-4748-AA2B-5357031F9D84@durin42.com> Message-ID: Augie Fackler writes: > On Feb 18, 2013, at 12:26 PM, Sean Farley wrote: > >> Of course, if histedit, rebase, et al. could be improved to use memctx, >> then I might change my tune :-) > > The problem (as I see it) with that is that both rebase and histedit can drop into a manual conflict resolution phase that requires the working copy to be clean. > > If we had some generalized (safe) stashing mechanism (which a stash command could use), I'd be a fan of wiring that into histedit and rebase. That's a good point. But it'd only need to happen when there's a conflict. Here's hoping that David's patches get incorporated soon :-) From mercurial-bugs at selenic.com Mon Feb 18 21:48:28 2013 From: mercurial-bugs at selenic.com (mercurial-bugs at selenic.com) Date: Tue, 19 Feb 2013 03:48:28 +0000 Subject: [Bug 3832] New: hglib fails to import due to STARTF_USESHOWWINDOW not in subprocess python 2.6.6 Message-ID: http://bz.selenic.com/show_bug.cgi?id=3832 Priority: normal Bug ID: 3832 CC: mercurial-devel at selenic.com Assignee: bugzilla at selenic.com Summary: hglib fails to import due to STARTF_USESHOWWINDOW not in subprocess python 2.6.6 Severity: bug Classification: Unclassified OS: Windows Reporter: gadgetsteve at hotmail.com Hardware: PC Status: UNCONFIRMED Version: unspecified Component: Mercurial Product: Mercurial Import of hglib fails on NT with python 2.6.6 giving error message: Python 2.6.6 (r266:84297, Aug 24 2010, 18:46:32) [MSC v.1500 32 bit (Int win32 Type "help", "copyright", "credits" or "license" for more information. >>> import hglib Traceback (most recent call last): File "", line 1, in File "c:\Python26\lib\site-packages\hglib\__init__.py", line 1, in References: Message-ID: # HG changeset patch # User Steve Barnes # Date 1361263154 0 # Node ID 97b7c13ff8173c257143b9bcabb8ad726ade98cc # Parent 5fe53db61aa433018de8b0ee296db868f666cee7 util: cope with missing subprocess.startf_useshowwindow in python 2.6.x on nt (issue3832) On WinNT with Python 2.6.x import hglib fails because subprocess has no STARTF_USESHOWWINDOW member this patch checks for the availability before using it. diff -r 5fe53db61aa4 -r 97b7c13ff817 hglib/util.py --- a/hglib/util.py Fri Feb 08 03:51:42 2013 -0800 +++ b/hglib/util.py Tue Feb 19 08:39:14 2013 +0000 @@ -163,7 +163,8 @@ startupinfo = None if os.name == 'nt': startupinfo = subprocess.STARTUPINFO() - startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW + if hasattr(subprocess, 'STARTF_USESHOWWINDOW'): # Not all pythons have this + startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW def popen(args, env={}): environ = None -------------- next part -------------- An HTML attachment was scrubbed... URL: From laurens.nospam at grauw.nl Tue Feb 19 03:33:57 2013 From: laurens.nospam at grauw.nl (Laurens Holst) Date: Tue, 19 Feb 2013 10:33:57 +0100 Subject: histedit and rebase using memctx In-Reply-To: <47864460-51D0-4748-AA2B-5357031F9D84@durin42.com> References: <06dd5eda17402c1e89a1.1360887323@idan> <512222A8.2010600@grauw.nl> <47864460-51D0-4748-AA2B-5357031F9D84@durin42.com> Message-ID: <51234705.2090209@grauw.nl> Op 18-02-13 22:13, Augie Fackler schreef: > On Feb 18, 2013, at 12:26 PM, Sean Farley wrote: > >> Of course, if histedit, rebase, et al. could be improved to use memctx, >> then I might change my tune :-) > The problem (as I see it) with that is that both rebase and histedit can drop into a manual conflict resolution phase that requires the working copy to be clean. Actually, personally I think it would be great if it would abort in that case. That would allow you to merge only when it?s a simple one without conflicts. I submitted patches for such a thing once. [1] ~Laurens [1] http://www.selenic.com/pipermail/mercurial-devel/2011-December/036520.html From pierre-yves.david at logilab.fr Tue Feb 19 05:01:50 2013 From: pierre-yves.david at logilab.fr (Pierre-Yves David) Date: Tue, 19 Feb 2013 12:01:50 +0100 Subject: [PATCH 2 of 2 RFCv2] commands: introduce stash command In-Reply-To: References: <06dd5eda17402c1e89a1.1360887323@idan> <512222A8.2010600@grauw.nl> Message-ID: <20130219110150.GA17508@crater2.logilab.fr> On Mon, Feb 18, 2013 at 11:26:03AM -0600, Sean Farley wrote: > > Laurens Holst writes: > > > Op 18-02-13 01:03, Pierre-Yves David schreef: > >>> Stashes are unnamed (by default) and can be listed using --list and inspected > >>> with -s/--show. > > I don?t really like changing the meaning of a command with options; I > > always preferred having ?hg branches? and ?hg branch? as separate > > commands (as opposed to how Git does it). > > > > Similarly, I would prefer hg stashes to list them, and hg stash to make > > them. > > > >> Is there real usage for unnamed stash? don't we want to force the user to provide a minimal description ? > > I almost never specify names with stashes, not in Mercurial nor git. > > > > I think that?s also always been one of the big advantages of Mercurial > > vs. git; that you don?t need to think about branch names and can just > > quickly create an anonymous one. Same principle applies to stashes. > > I'll have to agree here with Laurens. 90% - 95% of the time that I want > to stash is because some command needs to muck with the working > directory (e.g. histedit, rebase, etc.). Therefore, I really don't care > about the name of the stash most of the time. > > Of course, if histedit, rebase, et al. could be improved to use memctx, > then I might change my tune :-) We could have histedit, rebase, update gains a --stash option to automatically stash/unstash. Maybe even automatically do that but it sound a bit too bold. -- Pierre-Yves David http://www.logilab.fr/ -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 198 bytes Desc: Digital signature URL: From hg at intevation.org Tue Feb 19 06:00:06 2013 From: hg at intevation.org (Mercurial Commits) Date: Tue, 19 Feb 2013 13:00:06 +0100 Subject: mercurial/crew@18699: 4 outgoing changesets (3 stable) Message-ID: <1361275206.557591.14147.nullmailer@hg.intevation.org> 4 outgoing changesets (3 stable) in mercurial/crew: http://hg.intevation.org/mercurial/crew/rev/61c8327ced50 changeset: 18699:61c8327ced50 branch: stable tag: tip parent: 18697:7d66a44e87ed user: FUJIWARA Katsunori date: Mon Feb 18 00:04:28 2013 +0900 summary: bundle: treat branches created newly on the local correctly (issue3828) http://hg.intevation.org/mercurial/crew/rev/4a85ebb5c807 changeset: 18698:4a85ebb5c807 bookmark: @ parent: 18695:ec9b9968b7f8 parent: 18697:7d66a44e87ed user: Kevin Bullock date: Fri Feb 15 21:20:24 2013 -0600 summary: merge with stable http://hg.intevation.org/mercurial/crew/rev/7d66a44e87ed changeset: 18697:7d66a44e87ed branch: stable user: Kevin Bullock date: Fri Feb 15 15:06:43 2013 -0600 summary: mergetools: refine vimdiff warning message http://hg.intevation.org/mercurial/crew/rev/f2b1f78cf202 changeset: 18696:f2b1f78cf202 branch: stable parent: 18679:f6f35d646cb5 user: Pierre-Yves David date: Fri Feb 15 11:28:04 2013 +0100 summary: mergetools: vimdiff issue a warning explaining how to abort -- Repository URL: http://hg.intevation.org/mercurial/crew From denis at laxalde.org Tue Feb 19 04:46:14 2013 From: denis at laxalde.org (Denis Laxalde) Date: Tue, 19 Feb 2013 11:46:14 +0100 Subject: [PATCH 2 of 2 RFCv2] commands: introduce stash command In-Reply-To: <06dd5eda17402c1e89a1.1360887323@idan> References: <06dd5eda17402c1e89a1.1360887323@idan> Message-ID: Idan Kamara wrote: > Referring to stashes is done either by index (as shown in --list) or name (if > one was given). If neither is specified, the most recent stash is chosen. Wouldn't make more sense to use parent relationships to order stashes? E.g., if I pop/apply a stash without specifying its name, I'd rather want the one that is on top of the closest parent of my current position than the most recent one that appeared in the repository (which might be in some unrelated branch or so). From mercurial-bugs at selenic.com Tue Feb 19 02:59:25 2013 From: mercurial-bugs at selenic.com (mercurial-bugs at selenic.com) Date: Tue, 19 Feb 2013 08:59:25 +0000 Subject: [Bug 3833] New: hg annotate broken by changeset that did not touch the file Message-ID: http://bz.selenic.com/show_bug.cgi?id=3833 Priority: urgent Bug ID: 3833 CC: jruderman at gmail.com, justin.lebar+bug at gmail.com, mercurial-devel at selenic.com, philringnalda at gmail.com Assignee: bugzilla at selenic.com Summary: hg annotate broken by changeset that did not touch the file Severity: bug Classification: Unclassified OS: All Reporter: jwatt at jwatt.org Hardware: All Status: UNCONFIRMED Version: unspecified Component: Mercurial Product: Mercurial In Mozilla's mozilla-central repo, a few days ago the blame for at least one of the files was messed up by a changeset that did not touch that file. Specifically: http://hg.mozilla.org/mozilla-central/annotate/e8f8a3f6f1f6/content/svg/content/src/nsSVGFilters.cpp Blame is showing rev 121949 as having been the last changeset to touch most (but NOT all) of the lines in that file. That changeset simply did not touch that file though. Neither has that file been renamed (that's the same name and location it's always had). So something seems worryingly broken here. -- You are receiving this mail because: You are on the CC list for the bug. From raf at durin42.com Tue Feb 19 10:06:17 2013 From: raf at durin42.com (Augie Fackler) Date: Tue, 19 Feb 2013 11:06:17 -0500 Subject: histedit and rebase using memctx In-Reply-To: <51234705.2090209@grauw.nl> References: <06dd5eda17402c1e89a1.1360887323@idan> <512222A8.2010600@grauw.nl> <47864460-51D0-4748-AA2B-5357031F9D84@durin42.com> <51234705.2090209@grauw.nl> Message-ID: On Tue, Feb 19, 2013 at 4:33 AM, Laurens Holst wrote: > Op 18-02-13 22:13, Augie Fackler schreef: >> >> On Feb 18, 2013, at 12:26 PM, Sean Farley >> wrote: >> >>> Of course, if histedit, rebase, et al. could be improved to use memctx, >>> then I might change my tune :-) >> >> The problem (as I see it) with that is that both rebase and histedit can >> drop into a manual conflict resolution phase that requires the working copy >> to be clean. > > > Actually, personally I think it would be great if it would abort in that > case. Breaks my workflow heavily, so I wouldn't welcome this. > That would allow you to merge only when it?s a simple one without > conflicts. I submitted patches for such a thing once. [1] > > ~Laurens > > [1] > http://www.selenic.com/pipermail/mercurial-devel/2011-December/036520.html From kbullock+mercurial at ringworld.org Tue Feb 19 11:18:56 2013 From: kbullock+mercurial at ringworld.org (Kevin Bullock) Date: Tue, 19 Feb 2013 11:18:56 -0600 Subject: [PATCH 2 of 2 RFCv2] commands: introduce stash command In-Reply-To: References: <06dd5eda17402c1e89a1.1360887323@idan> Message-ID: <029F8711-3C3E-473C-9045-BED44AE53660@ringworld.org> On Feb 19, 2013, at 4:46 AM, Denis Laxalde wrote: > Idan Kamara wrote: >> Referring to stashes is done either by index (as shown in --list) or name (if >> one was given). If neither is specified, the most recent stash is chosen. > > Wouldn't make more sense to use parent relationships to order stashes? > E.g., if I pop/apply a stash without specifying its name, I'd rather want the one that is on top of the closest parent of my current position than the most recent one that appeared in the repository (which might be in some unrelated branch or so). Not necessarily. I often start working on a change e.g. on the stable branch, then realize that it should really be done on default. 'stash' is a logical way to move working-directory changes across branches without having to either (a) really commit, or (b) update to the common ancestor, then up to the target head. I think picking the most recent stash is reasonable. Either way, referring to the changes explicitly by the identifier shown in --list isn't too hard. pacem in terris / ??? / ?????? / ????????? / ?? Kevin R. Bullock From bos at serpentine.com Tue Feb 19 12:10:08 2013 From: bos at serpentine.com (Bryan O'Sullivan) Date: Tue, 19 Feb 2013 10:10:08 -0800 Subject: util.makedirs is missing a "notindexed" parameters In-Reply-To: References: Message-ID: On Sat, Feb 16, 2013 at 1:36 AM, Angel Ezquerra wrote: > Wouldn't it make sense to be able to disable indexing on windows when > creating a directory recursively? > Yep - that looks like something that was simply missed while it was being written. -------------- next part -------------- An HTML attachment was scrubbed... URL: From bos at serpentine.com Tue Feb 19 12:27:40 2013 From: bos at serpentine.com (Bryan O'Sullivan) Date: Tue, 19 Feb 2013 10:27:40 -0800 Subject: [PATCH] revset: use "repo.changelog" instead of "list(repo)" for resource efficiency In-Reply-To: <06fb2582618f43400b38.1361117286@juju> References: <06fb2582618f43400b38.1361117286@juju> Message-ID: On Sun, Feb 17, 2013 at 8:08 AM, FUJIWARA Katsunori wrote: > This patch uses "repo.changelog" instead of "list(repo)" for resource > efficiency. > What effect does this have on performance? -------------- next part -------------- An HTML attachment was scrubbed... URL: From bos at serpentine.com Tue Feb 19 12:29:14 2013 From: bos at serpentine.com (Bryan O'Sullivan) Date: Tue, 19 Feb 2013 10:29:14 -0800 Subject: [PATCH 2 of 3] worker: fix a race in SIGINT handling In-Reply-To: References: Message-ID: <9ef52f0a93a0cba93974.1361298554@australite.local> # HG changeset patch # User Bryan O'Sullivan # Date 1361297550 28800 # Node ID 9ef52f0a93a0cba939742743ff59e4c2a2463fab # Parent aa2394d75dcc1fb33f3f548013874acdfbaf845f worker: fix a race in SIGINT handling This is almost impossible to trigger due to the tiny time window involved. diff --git a/mercurial/worker.py b/mercurial/worker.py --- a/mercurial/worker.py +++ b/mercurial/worker.py @@ -75,9 +75,12 @@ def worker(ui, costperarg, func, statica def _posixworker(ui, func, staticargs, args): rfd, wfd = os.pipe() workers = _numworkers(ui) + oldhandler = signal.getsignal(signal.SIGINT) + signal.signal(signal.SIGINT, signal.SIG_IGN) for pargs in partition(args, workers): pid = os.fork() if pid == 0: + signal.signal(signal.SIGINT, oldhandler) try: os.close(rfd) for i, item in func(*(staticargs + (pargs,))): @@ -87,8 +90,6 @@ def _posixworker(ui, func, staticargs, a os._exit(255) os.close(wfd) fp = os.fdopen(rfd, 'rb', 0) - oldhandler = signal.getsignal(signal.SIGINT) - signal.signal(signal.SIGINT, signal.SIG_IGN) def cleanup(): # python 2.4 is too dumb for try/yield/finally signal.signal(signal.SIGINT, oldhandler) From bos at serpentine.com Tue Feb 19 12:29:13 2013 From: bos at serpentine.com (Bryan O'Sullivan) Date: Tue, 19 Feb 2013 10:29:13 -0800 Subject: [PATCH 1 of 3] worker: on error, exit similarly to the first failing worker Message-ID: # HG changeset patch # User Bryan O'Sullivan # Date 1361297550 28800 # Node ID aa2394d75dcc1fb33f3f548013874acdfbaf845f # Parent a326a3b6e3959bba37502a05169cf2797150f4c4 worker: on error, exit similarly to the first failing worker Previously, if a worker failed, we exited with status 1. We now exit with the correct exit code (killing ourselves if necessary). diff --git a/mercurial/worker.py b/mercurial/worker.py --- a/mercurial/worker.py +++ b/mercurial/worker.py @@ -92,11 +92,15 @@ def _posixworker(ui, func, staticargs, a def cleanup(): # python 2.4 is too dumb for try/yield/finally signal.signal(signal.SIGINT, oldhandler) - problems = 0 + problem = None for i in xrange(workers): - problems |= os.wait()[1] - if problems: - sys.exit(1) + pid, st = os.wait() + if st and not problem: + problem = _exitstatus(st) + if problem: + if problem < 0: + os.kill(os.getpid(), -problem) + sys.exit(problem) try: for line in fp: l = line.split(' ', 1) @@ -106,8 +110,18 @@ def _posixworker(ui, func, staticargs, a raise cleanup() +def _posixexitstatus(code): + '''convert a posix exit status into the same form returned by + os.spawnv''' + if os.WIFEXITED(code): + return os.WEXITSTATUS(code) + elif os.WIFSIGNALED(code): + return -os.WTERMSIG(code) + raise ValueError('unexpected exit status %d' % code) + if os.name != 'nt': _platformworker = _posixworker + _exitstatus = _posixexitstatus def partition(lst, nslices): '''partition a list into N slices of equal size''' From bos at serpentine.com Tue Feb 19 12:29:15 2013 From: bos at serpentine.com (Bryan O'Sullivan) Date: Tue, 19 Feb 2013 10:29:15 -0800 Subject: [PATCH 3 of 3] worker: handle worker failures more aggressively In-Reply-To: References: Message-ID: <42c14cff887e20d033db.1361298555@australite.local> # HG changeset patch # User Bryan O'Sullivan # Date 1361297550 28800 # Node ID 42c14cff887e20d033dbaa8f8c00100e807a1149 # Parent 9ef52f0a93a0cba939742743ff59e4c2a2463fab worker: handle worker failures more aggressively We now wait for worker processes in a separate thread, so that we can spot failures in a timely way, wihout waiting for the progress pipe to drain. If a worker fails, we recover the pre-parallel-update behaviour of failing early by killing its peers before propagating the failure. diff --git a/mercurial/worker.py b/mercurial/worker.py --- a/mercurial/worker.py +++ b/mercurial/worker.py @@ -6,7 +6,7 @@ # GNU General Public License version 2 or any later version. from i18n import _ -import os, signal, sys, util +import os, signal, sys, threading, util def countcpus(): '''try to count the number of CPUs on the system''' @@ -77,6 +77,7 @@ def _posixworker(ui, func, staticargs, a workers = _numworkers(ui) oldhandler = signal.getsignal(signal.SIGINT) signal.signal(signal.SIGINT, signal.SIG_IGN) + pids, problem = [], [0] for pargs in partition(args, workers): pid = os.fork() if pid == 0: @@ -88,25 +89,40 @@ def _posixworker(ui, func, staticargs, a os._exit(0) except KeyboardInterrupt: os._exit(255) + pids.append(pid) + pids.reverse() os.close(wfd) fp = os.fdopen(rfd, 'rb', 0) - def cleanup(): - # python 2.4 is too dumb for try/yield/finally - signal.signal(signal.SIGINT, oldhandler) - problem = None - for i in xrange(workers): + def killworkers(): + # if one worker bails, there's no good reason to wait for the rest + for p in pids: + try: + os.kill(p, signal.SIGTERM) + except OSError, err: + if err.errno != errno.ESRCH: + raise + def waitforworkers(): + for p in pids: pid, st = os.wait() if st and not problem: - problem = _exitstatus(st) - if problem: - if problem < 0: - os.kill(os.getpid(), -problem) - sys.exit(problem) + problem[0] = _exitstatus(st) + killworkers() + t = threading.Thread(target=waitforworkers) + t.start() + def cleanup(): + signal.signal(signal.SIGINT, oldhandler) + t.join() + status = problem[0] + if status: + if status < 0: + os.kill(os.getpid(), -status) + sys.exit(status) try: for line in fp: l = line.split(' ', 1) yield int(l[0]), l[1][:-1] except: # re-raises + killworkers() cleanup() raise cleanup() From bos at serpentine.com Tue Feb 19 12:30:45 2013 From: bos at serpentine.com (Bryan O'Sullivan) Date: Tue, 19 Feb 2013 10:30:45 -0800 Subject: [PATCH] largefiles: don't cache largefiles for pulled heads by default In-Reply-To: References: Message-ID: On Sat, Feb 9, 2013 at 1:09 PM, wrote: > largefiles: don't cache largefiles for pulled heads by default > Crewed, thanks for your patience. -------------- next part -------------- An HTML attachment was scrubbed... URL: From kbullock+mercurial at ringworld.org Tue Feb 19 12:42:11 2013 From: kbullock+mercurial at ringworld.org (Kevin Bullock) Date: Tue, 19 Feb 2013 12:42:11 -0600 Subject: [PATCH 1 of 3] worker: on error, exit similarly to the first failing worker In-Reply-To: References: Message-ID: <98418775-E060-4118-91FC-CA965DDAECE4@ringworld.org> On Feb 19, 2013, at 12:29 PM, Bryan O'Sullivan wrote: > # HG changeset patch > # User Bryan O'Sullivan > # Date 1361297550 28800 > # Node ID aa2394d75dcc1fb33f3f548013874acdfbaf845f > # Parent a326a3b6e3959bba37502a05169cf2797150f4c4 > worker: on error, exit similarly to the first failing worker > > Previously, if a worker failed, we exited with status 1. We now exit > with the correct exit code (killing ourselves if necessary). > > diff --git a/mercurial/worker.py b/mercurial/worker.py > --- a/mercurial/worker.py > +++ b/mercurial/worker.py > @@ -92,11 +92,15 @@ def _posixworker(ui, func, staticargs, a > def cleanup(): > # python 2.4 is too dumb for try/yield/finally > signal.signal(signal.SIGINT, oldhandler) > - problems = 0 > + problem = None > for i in xrange(workers): > - problems |= os.wait()[1] > - if problems: > - sys.exit(1) > + pid, st = os.wait() > + if st and not problem: > + problem = _exitstatus(st) What happens if _exitstatus raises a ValueError here? pacem in terris / ??? / ?????? / ????????? / ?? Kevin R. Bullock From idankk86 at gmail.com Tue Feb 19 13:00:45 2013 From: idankk86 at gmail.com (Idan Kamara) Date: Tue, 19 Feb 2013 21:00:45 +0200 Subject: [PATCH 3 of 3] worker: handle worker failures more aggressively In-Reply-To: <42c14cff887e20d033db.1361298555@australite.local> References: <42c14cff887e20d033db.1361298555@australite.local> Message-ID: On Tue, Feb 19, 2013 at 8:29 PM, Bryan O'Sullivan wrote: > > # HG changeset patch > # User Bryan O'Sullivan > # Date 1361297550 28800 > # Node ID 42c14cff887e20d033dbaa8f8c00100e807a1149 > # Parent 9ef52f0a93a0cba939742743ff59e4c2a2463fab > worker: handle worker failures more aggressively > > We now wait for worker processes in a separate thread, so that we can > spot failures in a timely way, wihout waiting for the progress pipe > to drain. > > If a worker fails, we recover the pre-parallel-update behaviour of > failing early by killing its peers before propagating the failure. > > diff --git a/mercurial/worker.py b/mercurial/worker.py > --- a/mercurial/worker.py > +++ b/mercurial/worker.py > @@ -6,7 +6,7 @@ > # GNU General Public License version 2 or any later version. > > from i18n import _ > -import os, signal, sys, util > +import os, signal, sys, threading, util > > def countcpus(): > '''try to count the number of CPUs on the system''' > @@ -77,6 +77,7 @@ def _posixworker(ui, func, staticargs, a > workers = _numworkers(ui) > oldhandler = signal.getsignal(signal.SIGINT) > signal.signal(signal.SIGINT, signal.SIG_IGN) > + pids, problem = [], [0] > for pargs in partition(args, workers): > pid = os.fork() > if pid == 0: > @@ -88,25 +89,40 @@ def _posixworker(ui, func, staticargs, a > os._exit(0) > except KeyboardInterrupt: > os._exit(255) > + pids.append(pid) > + pids.reverse() Ok, so the last created child will be the first in pids. > os.close(wfd) > fp = os.fdopen(rfd, 'rb', 0) > - def cleanup(): > - # python 2.4 is too dumb for try/yield/finally > - signal.signal(signal.SIGINT, oldhandler) > - problem = None > - for i in xrange(workers): > + def killworkers(): > + # if one worker bails, there's no good reason to wait for the > rest > + for p in pids: > + try: > + os.kill(p, signal.SIGTERM) > + except OSError, err: > + if err.errno != errno.ESRCH: > + raise > + def waitforworkers(): > + for p in pids: > pid, st = os.wait() And here you're waiting for it to finish, but what happens if for some reason one of the previous children fails first? Why not use select on the children and also spare the thread? -------------- next part -------------- An HTML attachment was scrubbed... URL: From dirkjan at ochtman.nl Tue Feb 19 13:08:07 2013 From: dirkjan at ochtman.nl (Dirkjan Ochtman) Date: Tue, 19 Feb 2013 20:08:07 +0100 Subject: [PATCH] revset: use "repo.changelog" instead of "list(repo)" for resource efficiency In-Reply-To: <06fb2582618f43400b38.1361117286@juju> References: <06fb2582618f43400b38.1361117286@juju> Message-ID: On Sun, Feb 17, 2013 at 5:08 PM, FUJIWARA Katsunori wrote: > # HG changeset patch > # User FUJIWARA Katsunori > # Date 1361115858 -32400 > # Node ID 06fb2582618f43400b38ac4c791410d2fc748d2c > # Parent f12804d3ff801b989cb2aab1aad93047a8db46f1 > revset: use "repo.changelog" instead of "list(repo)" for resource efficiency Doesn't that kill the filtering? IIRC Pierre-Yves was moving in the other direction on these kinds of things. Cheers, Dirkjan From kbullock+mercurial at ringworld.org Tue Feb 19 13:31:54 2013 From: kbullock+mercurial at ringworld.org (Kevin Bullock) Date: Tue, 19 Feb 2013 13:31:54 -0600 Subject: [PATCH] revset: use "repo.changelog" instead of "list(repo)" for resource efficiency In-Reply-To: References: <06fb2582618f43400b38.1361117286@juju> Message-ID: <3DE2EC35-0904-450B-9EEB-E272EFDFF6EE@ringworld.org> On Feb 19, 2013, at 1:08 PM, Dirkjan Ochtman wrote: > On Sun, Feb 17, 2013 at 5:08 PM, FUJIWARA Katsunori > wrote: >> # HG changeset patch >> # User FUJIWARA Katsunori >> # Date 1361115858 -32400 >> # Node ID 06fb2582618f43400b38ac4c791410d2fc748d2c >> # Parent f12804d3ff801b989cb2aab1aad93047a8db46f1 >> revset: use "repo.changelog" instead of "list(repo)" for resource efficiency > > Doesn't that kill the filtering? IIRC Pierre-Yves was moving in the > other direction on these kinds of things. Nope, repo.changelog is filtered on a filtered repo object. pacem in terris / ??? / ?????? / ????????? / ?? Kevin R. Bullock From bos at serpentine.com Tue Feb 19 13:53:43 2013 From: bos at serpentine.com (Bryan O'Sullivan) Date: Tue, 19 Feb 2013 11:53:43 -0800 Subject: [PATCH 3 of 3] worker: handle worker failures more aggressively In-Reply-To: References: <42c14cff887e20d033db.1361298555@australite.local> Message-ID: On Tue, Feb 19, 2013 at 11:00 AM, Idan Kamara wrote: > And here you're waiting for it to finish, but what happens > if for some reason one of the previous children fails first? > os.wait waits for any process to finish. None of the values in the list of pids is used in that loop. > Why not use select on the children and also spare the thread? > select works on file descriptors, not pids. We need some mechanism to catch early-exiting children immediately. We could possibly do that by having a pipe per child and detect EOF on each pipe, but that's way more work. (It might turn out to be necessary at some point, e.g. for Windows, but I don't want to further complicate the code until I know that said complexity is necessary.) -------------- next part -------------- An HTML attachment was scrubbed... URL: From idankk86 at gmail.com Tue Feb 19 13:56:33 2013 From: idankk86 at gmail.com (Idan Kamara) Date: Tue, 19 Feb 2013 21:56:33 +0200 Subject: [PATCH 3 of 3] worker: handle worker failures more aggressively In-Reply-To: References: <42c14cff887e20d033db.1361298555@australite.local> Message-ID: On Tue, Feb 19, 2013 at 9:53 PM, Bryan O'Sullivan wrote: > > On Tue, Feb 19, 2013 at 11:00 AM, Idan Kamara wrote: >> >> And here you're waiting for it to finish, but what happens >> if for some reason one of the previous children fails first? > > os.wait waits for any process to finish. None of the values in the list of > pids is used in that loop. Oh, missed that. > >> >> Why not use select on the children and also spare the thread? > > select works on file descriptors, not pids. We need some mechanism to > catch early-exiting children immediately. We could possibly do that by > having a pipe per child and detect EOF on each pipe, but that's way more > work. (It might turn out to be necessary at some point, e.g. for Windows, > but I don't want to further complicate the code until I know that said > complexity is necessary.) Makes sense, thanks for clarifying. -------------- next part -------------- An HTML attachment was scrubbed... URL: From idankk86 at gmail.com Tue Feb 19 14:04:31 2013 From: idankk86 at gmail.com (Idan Kamara) Date: Tue, 19 Feb 2013 22:04:31 +0200 Subject: [PATCH] Issue 3832 - STARTF_USESHOWWINDOW not available on WinNT Python 2.6.6 In-Reply-To: References: Message-ID: There are some newline issues here, consider using the patchbomb extension. On Tue, Feb 19, 2013 at 11:11 AM, Steve Barnes wrote: > # HG changeset patch > > ** > > # User Steve Barnes *** > * > > # Date 1361263154 0**** > > # Node ID 97b7c13ff8173c257143b9bcabb8ad726ade98cc**** > > # Parent 5fe53db61aa433018de8b0ee296db868f666cee7**** > > util: cope with missing subprocess.startf_useshowwindow in python 2.6.x on > nt (issue3832)**** > > ** ** > > On WinNT with Python 2.6.x import hglib fails because subprocess has no > STARTF_USESHOWWINDOW **** > > member this patch checks for the availability before using it. > Forgive my Windows ignorance, but is this file missing from WinNT or is it just missing from Python while running on that Windows version? If I recall correctly, this flag hides the console window that pops up, does it show on WinNT without this flag? -------------- next part -------------- An HTML attachment was scrubbed... URL: From mercurial-bugs at selenic.com Tue Feb 19 09:11:41 2013 From: mercurial-bugs at selenic.com (mercurial-bugs at selenic.com) Date: Tue, 19 Feb 2013 15:11:41 +0000 Subject: [Bug 3834] New: Ctrl+C when pager is running sometimes leaves console unresponding Message-ID: http://bz.selenic.com/show_bug.cgi?id=3834 Priority: normal Bug ID: 3834 CC: mercurial-devel at selenic.com Assignee: bugzilla at selenic.com Summary: Ctrl+C when pager is running sometimes leaves console unresponding Severity: bug Classification: Unclassified OS: Linux Reporter: idankk86 at gmail.com Hardware: PC Status: UNCONFIRMED Version: 2.5.1 Component: pager Product: Mercurial After running 'hg help revsets' and hitting Ctrl+C at some point, this traceback appeared (can't reproduce reliably, but seen it a few times): An alternative syntax is "x..y". "x:y" All changesets with revision numbers between x and y, both inclusive. Either endpoint can be left out, they default to 0 and tip. :Error in atexit._run_exitfuncs: Traceback (most recent call last): File "/usr/lib/python2.7/atexit.py", line 24, in _run_exitfuncs func(*targs, **kargs) File "/home/idan/dev/hg/local-hg/hgext/pager.py", line 100, in killpager pager.wait() File "/usr/lib/python2.7/subprocess.py", line 1301, in wait pid, sts = _eintr_retry_call(os.waitpid, self.pid, 0) File "/usr/lib/python2.7/subprocess.py", line 478, in _eintr_retry_call return func(*args) KeyboardInterrupt Error in sys.exitfunc: Traceback (most recent call last): File "/usr/lib/python2.7/atexit.py", line 24, in _run_exitfuncs func(*targs, **kargs) File "/home/idan/dev/hg/local-hg/hgext/pager.py", line 100, in killpager pager.wait() File "/usr/lib/python2.7/subprocess.py", line 1301, in wait pid, sts = _eintr_retry_call(os.waitpid, self.pid, 0) File "/usr/lib/python2.7/subprocess.py", line 478, in _eintr_retry_call return func(*args) KeyboardInterrupt ^C Console doesn't respond to key presses afterwards. Pager is set to 'less -FSRX'. -- You are receiving this mail because: You are on the CC list for the bug. From idankk86 at gmail.com Tue Feb 19 14:14:20 2013 From: idankk86 at gmail.com (Idan Kamara) Date: Tue, 19 Feb 2013 22:14:20 +0200 Subject: [PATCH 2 of 2 RFCv2] commands: introduce stash command In-Reply-To: <029F8711-3C3E-473C-9045-BED44AE53660@ringworld.org> References: <06dd5eda17402c1e89a1.1360887323@idan> <029F8711-3C3E-473C-9045-BED44AE53660@ringworld.org> Message-ID: On Tue, Feb 19, 2013 at 7:18 PM, Kevin Bullock < kbullock+mercurial at ringworld.org> wrote: > > On Feb 19, 2013, at 4:46 AM, Denis Laxalde wrote: > > > Idan Kamara wrote: > >> Referring to stashes is done either by index (as shown in --list) or name (if > >> one was given). If neither is specified, the most recent stash is chosen. > > > > Wouldn't make more sense to use parent relationships to order stashes? > > E.g., if I pop/apply a stash without specifying its name, I'd rather want the one that is on top of the closest parent of my current position than the most recent one that appeared in the repository (which might be in some unrelated branch or so). > > Not necessarily. I often start working on a change e.g. on the stable branch, then realize that it should really be done on default. 'stash' is a logical way to move working-directory changes across branches without having to either (a) really commit, or (b) update to the common ancestor, then up to the target head. > > I think picking the most recent stash is reasonable. Either way, referring to the changes explicitly by the identifier shown in --list isn't too hard. We could also add revset support and then one could do: $ hg stash -p 'first(.:: and stashed())' -------------- next part -------------- An HTML attachment was scrubbed... URL: From angel.ezquerra at gmail.com Tue Feb 19 14:45:40 2013 From: angel.ezquerra at gmail.com (Angel Ezquerra) Date: Tue, 19 Feb 2013 21:45:40 +0100 Subject: util.makedirs is missing a "notindexed" parameters In-Reply-To: References: Message-ID: On Tue, Feb 19, 2013 at 7:10 PM, Bryan O'Sullivan wrote: > On Sat, Feb 16, 2013 at 1:36 AM, Angel Ezquerra > wrote: >> >> Wouldn't it make sense to be able to disable indexing on windows when >> creating a directory recursively? > > > Yep - that looks like something that was simply missed while it was being > written. That's what I thought. I ended up adding that as an optional parameter to util.makedirs on the 3rd patch on my "subrepo: do not push mercurial subreos whose store is clean" series: http://permalink.gmane.org/gmane.comp.version-control.mercurial.devel/59202 Cheers, Angel From bos at serpentine.com Tue Feb 19 14:54:04 2013 From: bos at serpentine.com (Bryan O'Sullivan) Date: Tue, 19 Feb 2013 12:54:04 -0800 Subject: [PATCH 1 of 3 v2] worker: on error, exit similarly to the first failing worker Message-ID: # HG changeset patch # User Bryan O'Sullivan # Date 1361307231 28800 # Node ID bd5bb50f9f1660152459d13b921e599b8af96b13 # Parent c0d3f22e904a4899c61150af296af79a05a9e0c2 worker: on error, exit similarly to the first failing worker Previously, if a worker failed, we exited with status 1. We now exit with the correct exit code (killing ourselves if necessary). diff --git a/mercurial/worker.py b/mercurial/worker.py --- a/mercurial/worker.py +++ b/mercurial/worker.py @@ -92,11 +92,16 @@ def _posixworker(ui, func, staticargs, a def cleanup(): # python 2.4 is too dumb for try/yield/finally signal.signal(signal.SIGINT, oldhandler) - problems = 0 + problem = None for i in xrange(workers): - problems |= os.wait()[1] - if problems: - sys.exit(1) + pid, st = os.wait() + st = _exitstatus(st) + if st and not problem: + problem = st + if problem: + if problem < 0: + os.kill(os.getpid(), -problem) + sys.exit(problem) try: for line in fp: l = line.split(' ', 1) @@ -106,8 +111,19 @@ def _posixworker(ui, func, staticargs, a raise cleanup() +def _posixexitstatus(code): + '''convert a posix exit status into the same form returned by + os.spawnv + + returns None if the process was stopped instead of exiting''' + if os.WIFEXITED(code): + return os.WEXITSTATUS(code) + elif os.WIFSIGNALED(code): + return -os.WTERMSIG(code) + if os.name != 'nt': _platformworker = _posixworker + _exitstatus = _posixexitstatus def partition(lst, nslices): '''partition a list into N slices of equal size''' From bos at serpentine.com Tue Feb 19 14:54:05 2013 From: bos at serpentine.com (Bryan O'Sullivan) Date: Tue, 19 Feb 2013 12:54:05 -0800 Subject: [PATCH 2 of 3 v2] worker: fix a race in SIGINT handling In-Reply-To: References: Message-ID: # HG changeset patch # User Bryan O'Sullivan # Date 1361307231 28800 # Node ID e0bdbbb4e62ae8e1b588d39f514b59557fe75cfc # Parent bd5bb50f9f1660152459d13b921e599b8af96b13 worker: fix a race in SIGINT handling This is almost impossible to trigger due to the tiny time window involved. diff --git a/mercurial/worker.py b/mercurial/worker.py --- a/mercurial/worker.py +++ b/mercurial/worker.py @@ -75,9 +75,12 @@ def worker(ui, costperarg, func, statica def _posixworker(ui, func, staticargs, args): rfd, wfd = os.pipe() workers = _numworkers(ui) + oldhandler = signal.getsignal(signal.SIGINT) + signal.signal(signal.SIGINT, signal.SIG_IGN) for pargs in partition(args, workers): pid = os.fork() if pid == 0: + signal.signal(signal.SIGINT, oldhandler) try: os.close(rfd) for i, item in func(*(staticargs + (pargs,))): @@ -87,8 +90,6 @@ def _posixworker(ui, func, staticargs, a os._exit(255) os.close(wfd) fp = os.fdopen(rfd, 'rb', 0) - oldhandler = signal.getsignal(signal.SIGINT) - signal.signal(signal.SIGINT, signal.SIG_IGN) def cleanup(): # python 2.4 is too dumb for try/yield/finally signal.signal(signal.SIGINT, oldhandler) From bos at serpentine.com Tue Feb 19 14:54:06 2013 From: bos at serpentine.com (Bryan O'Sullivan) Date: Tue, 19 Feb 2013 12:54:06 -0800 Subject: [PATCH 3 of 3 v2] worker: handle worker failures more aggressively In-Reply-To: References: Message-ID: # HG changeset patch # User Bryan O'Sullivan # Date 1361307231 28800 # Node ID aeca36ccd9a5c9dc5894fdd5456c3eb29a65b672 # Parent e0bdbbb4e62ae8e1b588d39f514b59557fe75cfc worker: handle worker failures more aggressively We now wait for worker processes in a separate thread, so that we can spot failures in a timely way, wihout waiting for the progress pipe to drain. If a worker fails, we recover the pre-parallel-update behaviour of failing early by killing its peers before propagating the failure. diff --git a/mercurial/worker.py b/mercurial/worker.py --- a/mercurial/worker.py +++ b/mercurial/worker.py @@ -6,7 +6,7 @@ # GNU General Public License version 2 or any later version. from i18n import _ -import os, signal, sys, util +import os, signal, sys, threading, util def countcpus(): '''try to count the number of CPUs on the system''' @@ -77,6 +77,7 @@ def _posixworker(ui, func, staticargs, a workers = _numworkers(ui) oldhandler = signal.getsignal(signal.SIGINT) signal.signal(signal.SIGINT, signal.SIG_IGN) + pids, problem = [], [0] for pargs in partition(args, workers): pid = os.fork() if pid == 0: @@ -88,26 +89,40 @@ def _posixworker(ui, func, staticargs, a os._exit(0) except KeyboardInterrupt: os._exit(255) + pids.append(pid) + pids.reverse() os.close(wfd) fp = os.fdopen(rfd, 'rb', 0) + def killworkers(): + # if one worker bails, there's no good reason to wait for the rest + for p in pids: + try: + os.kill(p, signal.SIGTERM) + except OSError, err: + if err.errno != errno.ESRCH: + raise + def waitforworkers(): + for _ in pids: + st = _exitstatus(os.wait()[1]) + if st and not problem: + problem[0] = st + killworkers() + t = threading.Thread(target=waitforworkers) + t.start() def cleanup(): - # python 2.4 is too dumb for try/yield/finally signal.signal(signal.SIGINT, oldhandler) - problem = None - for i in xrange(workers): - pid, st = os.wait() - st = _exitstatus(st) - if st and not problem: - problem = st - if problem: - if problem < 0: - os.kill(os.getpid(), -problem) - sys.exit(problem) + t.join() + status = problem[0] + if status: + if status < 0: + os.kill(os.getpid(), -status) + sys.exit(status) try: for line in fp: l = line.split(' ', 1) yield int(l[0]), l[1][:-1] except: # re-raises + killworkers() cleanup() raise cleanup() From bos at serpentine.com Tue Feb 19 14:54:18 2013 From: bos at serpentine.com (Bryan O'Sullivan) Date: Tue, 19 Feb 2013 12:54:18 -0800 Subject: [PATCH 1 of 3] worker: on error, exit similarly to the first failing worker In-Reply-To: <98418775-E060-4118-91FC-CA965DDAECE4@ringworld.org> References: <98418775-E060-4118-91FC-CA965DDAECE4@ringworld.org> Message-ID: On Tue, Feb 19, 2013 at 10:42 AM, Kevin Bullock < kbullock+mercurial at ringworld.org> wrote: > What happens if _exitstatus raises a ValueError here? > Good point - fixed in v2. -------------- next part -------------- An HTML attachment was scrubbed... URL: From diptongo at gmail.com Tue Feb 19 16:23:59 2013 From: diptongo at gmail.com (Isaac Jurado) Date: Tue, 19 Feb 2013 23:23:59 +0100 Subject: [PATCH 3 of 3] worker: handle worker failures more aggressively In-Reply-To: <42c14cff887e20d033db.1361298555@australite.local> References: <42c14cff887e20d033db.1361298555@australite.local> Message-ID: <20130219222359.GA3735@findus> Replying Bryan O'Sullivan: > # HG changeset patch > # User Bryan O'Sullivan > # Date 1361297550 28800 > # Node ID 42c14cff887e20d033dbaa8f8c00100e807a1149 > # Parent 9ef52f0a93a0cba939742743ff59e4c2a2463fab > worker: handle worker failures more aggressively > > We now wait for worker processes in a separate thread, so that we can > spot failures in a timely way, wihout waiting for the progress pipe > to drain. > > If a worker fails, we recover the pre-parallel-update behaviour of > failing early by killing its peers before propagating the failure. > > diff --git a/mercurial/worker.py b/mercurial/worker.py > --- a/mercurial/worker.py > +++ b/mercurial/worker.py > @@ -6,7 +6,7 @@ > # GNU General Public License version 2 or any later version. > > from i18n import _ > -import os, signal, sys, util > +import os, signal, sys, threading, util > > def countcpus(): > '''try to count the number of CPUs on the system''' > @@ -77,6 +77,7 @@ def _posixworker(ui, func, staticargs, a > workers = _numworkers(ui) > oldhandler = signal.getsignal(signal.SIGINT) > signal.signal(signal.SIGINT, signal.SIG_IGN) > + pids, problem = [], [0] > for pargs in partition(args, workers): > pid = os.fork() > if pid == 0: > @@ -88,25 +89,40 @@ def _posixworker(ui, func, staticargs, a > os._exit(0) > except KeyboardInterrupt: > os._exit(255) > + pids.append(pid) > + pids.reverse() > os.close(wfd) > fp = os.fdopen(rfd, 'rb', 0) > - def cleanup(): > - # python 2.4 is too dumb for try/yield/finally > - signal.signal(signal.SIGINT, oldhandler) > - problem = None > - for i in xrange(workers): > + def killworkers(): > + # if one worker bails, there's no good reason to wait for the rest > + for p in pids: > + try: > + os.kill(p, signal.SIGTERM) > + except OSError, err: > + if err.errno != errno.ESRCH: > + raise > + def waitforworkers(): > + for p in pids: > pid, st = os.wait() > if st and not problem: > - problem = _exitstatus(st) > - if problem: > - if problem < 0: > - os.kill(os.getpid(), -problem) > - sys.exit(problem) > + problem[0] = _exitstatus(st) This single element list looks quite strange. Does it have to do with working around the closure or the scoping? Just curious. > + killworkers() > + t = threading.Thread(target=waitforworkers) > + t.start() Please pardon my ignorance, but the execution flow is starting to get confusing. If I understood correctly, the idea is to kill the other children whenever one fails, right? What about putting all workers in the same process group, but different to the parent? Something like: workers = _numworkers(ui) pgid = 0 for pargs in partition(args, workers): pid = os.fork() if pid == 0: try: os.setpgid(0, pgid) os.close(rfd) for i, item in func(...): os.write(...) os._exit(0) except KeyboardInterrupt: os.kill(0, signal.SIGTERM) # I can kill my siblings os._exit(255) elif not pgid: # Place the rest of the children in the same group as the # first pgid = pid I hope it helps. Regards. -- Isaac Jurado "The noblest pleasure is the joy of understanding." Leonardo da Vinci From bos at serpentine.com Tue Feb 19 16:29:16 2013 From: bos at serpentine.com (Bryan O'Sullivan) Date: Tue, 19 Feb 2013 14:29:16 -0800 Subject: [PATCH 3 of 3] worker: handle worker failures more aggressively In-Reply-To: <20130219222359.GA3735@findus> References: <42c14cff887e20d033db.1361298555@australite.local> <20130219222359.GA3735@findus> Message-ID: On Tue, Feb 19, 2013 at 2:23 PM, Isaac Jurado wrote: > > + problem[0] = _exitstatus(st) > > This single element list looks quite strange. Does it have to do with > working around the closure or the scoping? Welcome to Python, where we can't have nice lexically scoped things. > + t = threading.Thread(target=waitforworkers) > > + t.start() > > Please pardon my ignorance, but the execution flow is starting to get > confusing. If I understood correctly, the idea is to kill the other > children whenever one fails, right? > Yes. > What about putting all workers in the same process group, but different > to the parent? Process groups only exist on Unix. This code should (mostly?) work untouched on other platforms. -------------- next part -------------- An HTML attachment was scrubbed... URL: From diptongo at gmail.com Tue Feb 19 16:59:23 2013 From: diptongo at gmail.com (Isaac Jurado) Date: Tue, 19 Feb 2013 23:59:23 +0100 Subject: [PATCH 3 of 3] worker: handle worker failures more aggressively In-Reply-To: References: <42c14cff887e20d033db.1361298555@australite.local> <20130219222359.GA3735@findus> Message-ID: <20130219225923.GB3735@findus> Replying Bryan O'Sullivan: > >> + t = threading.Thread(target=waitforworkers) >> + t.start() >> >> Please pardon my ignorance, but the execution flow is starting to get >> confusing. If I understood correctly, the idea is to kill the other >> children whenever one fails, right? >> > > Yes. > >> What about putting all workers in the same process group, but >> different to the parent? > > Process groups only exist on Unix. This code should (mostly?) work > untouched on other platforms. Oh, I didn't catch that. As of the current code, your other emails and the name _posixworker() I assumed, probably wrong, that the Windows implementation would have its own idiosyncrasies. Therefore, I was already aware that process groups only exist on Unix. But so does os.fork(). Am I missing something? Cheers. -- Isaac Jurado "The noblest pleasure is the joy of understanding." Leonardo da Vinci From bos at serpentine.com Tue Feb 19 17:10:19 2013 From: bos at serpentine.com (Bryan O'Sullivan) Date: Tue, 19 Feb 2013 15:10:19 -0800 Subject: [PATCH 3 of 3] worker: handle worker failures more aggressively In-Reply-To: <20130219225923.GB3735@findus> References: <42c14cff887e20d033db.1361298555@australite.local> <20130219222359.GA3735@findus> <20130219225923.GB3735@findus> Message-ID: On Tue, Feb 19, 2013 at 2:59 PM, Isaac Jurado wrote: > Oh, I didn't catch that. As of the current code, your other emails and > the name _posixworker() I assumed, probably wrong, that the Windows > implementation would have its own idiosyncrasies. > Yes, but I'm trying to keep as much of the code portable as reasonable, so that if someone ports the worker code to Windows, it's minimally invasive. -------------- next part -------------- An HTML attachment was scrubbed... URL: From bos at serpentine.com Tue Feb 19 17:47:06 2013 From: bos at serpentine.com (Bryan O'Sullivan) Date: Tue, 19 Feb 2013 15:47:06 -0800 Subject: [PATCH 1 of 2] cmdutil: use a small initial window with --limit Message-ID: <77b02f572b752fcbec87.1361317626@australite.thefacebook.com> # HG changeset patch # User Bryan O'Sullivan # Date 1361317585 28800 # Node ID 77b02f572b752fcbec87f576564880ec1dc9023b # Parent aeca36ccd9a5c9dc5894fdd5456c3eb29a65b672 cmdutil: use a small initial window with --limit In a large repo, running a command like "log -l1 -p" was expensive because it would always traverse 8 commits, as 8 was the initial window size. We now choose the lesser of 8 or the limit, speeding up the "log -l1 -p" case by a factor of 5. diff --git a/mercurial/cmdutil.py b/mercurial/cmdutil.py --- a/mercurial/cmdutil.py +++ b/mercurial/cmdutil.py @@ -1210,6 +1210,13 @@ def walkchangerevs(repo, match, opts, pr if ff.match(x): wanted.discard(x) + # Choose a small initial window if we will probably only visit a + # few commits. + limit = loglimit(opts) + windowsize = 8 + if limit: + windowsize = min(limit, windowsize) + # Now that wanted is correctly initialized, we can iterate over the # revision range, yielding only revisions in wanted. def iterate(): @@ -1221,7 +1228,7 @@ def walkchangerevs(repo, match, opts, pr def want(rev): return rev in wanted - for i, window in increasingwindows(0, len(revs)): + for i, window in increasingwindows(0, len(revs), windowsize): nrevs = [rev for rev in revs[i:i + window] if want(rev)] for rev in sorted(nrevs): fns = fncache.get(rev) From bos at serpentine.com Tue Feb 19 17:47:07 2013 From: bos at serpentine.com (Bryan O'Sullivan) Date: Tue, 19 Feb 2013 15:47:07 -0800 Subject: [PATCH 2 of 2] commands: exit from the log loop at the right time In-Reply-To: <77b02f572b752fcbec87.1361317626@australite.thefacebook.com> References: <77b02f572b752fcbec87.1361317626@australite.thefacebook.com> Message-ID: <4dfcc703b38581beafbf.1361317627@australite.thefacebook.com> # HG changeset patch # User Bryan O'Sullivan # Date 1361317587 28800 # Node ID 4dfcc703b38581beafbf85ba5ae971943ecb70d5 # Parent 77b02f572b752fcbec87f576564880ec1dc9023b commands: exit from the log loop at the right time Previously, we'd run the iterator one more time than necessary, potentially doing a lot of extra work in the process. diff --git a/mercurial/commands.py b/mercurial/commands.py --- a/mercurial/commands.py +++ b/mercurial/commands.py @@ -4215,10 +4215,10 @@ def log(ui, repo, *pats, **opts): displayer.show(ctx, copies=copies, matchfn=revmatchfn) for ctx in cmdutil.walkchangerevs(repo, matchfn, opts, prep): + if displayer.flush(ctx.rev()): + count += 1 if count == limit: break - if displayer.flush(ctx.rev()): - count += 1 displayer.close() @command('manifest', From raf at durin42.com Tue Feb 19 19:35:13 2013 From: raf at durin42.com (Augie Fackler) Date: Tue, 19 Feb 2013 20:35:13 -0500 Subject: [PATCH RFC] commit: add --reuse-message for keeping the old commit message during amend In-Reply-To: <20130214102301.GB17607@crater2.logilab.fr> References: <1360731362.12295.24.camel@calx> <2B10A89294DA6740AC6155F56842F9CE0565A924@PRN-MBX01-2.TheFacebook.com> <20130214102301.GB17607@crater2.logilab.fr> Message-ID: <50143F8D-DA41-4976-918D-8BCA470377B8@durin42.com> On Feb 14, 2013, at 5:23 AM, Pierre-Yves David wrote: > On Wed, Feb 13, 2013 at 07:42:44PM +0000, Durham Goode wrote: >> On 2/12/13 8:56 PM, "Matt Mackall" wrote: >>> >>> I'm now inclined to think that 'hg commit --amend' will eventually be >>> replaced by 'hg amend', which will have a different default. Then we'll >>> deprecate --amend on commit. >>> >>> So I think we should leave this alone. But I don't think we've got quite >>> enough experience here to add the new amend command yet. > > In evolve, I'll probably drop the internal "hg amend" code in favor of using "hg commit > --amend" with an altered editor. Hm. I think it's bad practice for extensions to alter the behavior of off the shelf commands with off the shelf flags - I've done that in the past and always regretted it. > >> >> >> If anyone feels strongly about getting the extra commit flag in, speak up. >> For Facebook's purposes we will just add an amend alias for our users >> that does 'hg --config ui.editor=true commit --amend' while we wait for >> the real 'hg amend'. > > Note that you have to fix --config in alias first :-) > >> As for having amend experience, as I've started using evolve more I've >> found I use an amend flows in three ways: >> >> 1. (most common) Amending the code in the current commit >> 2. Amending the code in a commit further down. >> 3. (least common) Amending the commit description. > > My most common usage are #1 and #3. I usually the "." commit as a "staging area" > slowly adding content and writing the commit message at the end. > > The #2 operation is multi step > > a) rebase your change on target commit (as hg update with dirty wc does) > b) amend > c) hg evolve --all descendant > > It's probably something that we'll want but that requires first class support for multi step operation. Otherwise user will get terribly confused. > >> So my ideal "hg amend" would do #1 by default, #2 with "hg amend --to >> 'tip~2'", and #3 with "hg amend -e". #2 is the only crazy one, but I've >> been using a script that does it in one step and it makes editing chains >> of commits much much easier. > > -- > Pierre-Yves David > > http://www.logilab.fr/ > From sid0 at fb.com Tue Feb 19 19:42:58 2013 From: sid0 at fb.com (Siddharth Agarwal) Date: Tue, 19 Feb 2013 17:42:58 -0800 Subject: [PATCH] Issue 3832 - STARTF_USESHOWWINDOW not available on WinNT Python 2.6.6 In-Reply-To: References: Message-ID: <51242A22.2090608@fb.com> On 02/19/2013 01:11 AM, Steve Barnes wrote: > > # HG changeset patch > > # User Steve Barnes > > # Date 1361263154 0 > > # Node ID 97b7c13ff8173c257143b9bcabb8ad726ade98cc > > # Parent 5fe53db61aa433018de8b0ee296db868f666cee7 > > util: cope with missing subprocess.startf_useshowwindow in python > 2.6.x on nt (issue3832) > This is too long. I'd suggest something like "util: hardcode STARTF_USESHOWWINDOW" with a note in the full message explaining why (it isn't present in some newer versions of Python). > - startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW > > + if hasattr(subprocess, 'STARTF_USESHOWWINDOW'): # Not all > pythons have this > > + startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW > Why not just hardcode the value? That's 1 according to http://msdn.microsoft.com/en-us/library/windows/desktop/ms686331%28v=vs.85%29.aspx. From sid0 at fb.com Tue Feb 19 19:44:29 2013 From: sid0 at fb.com (Siddharth Agarwal) Date: Tue, 19 Feb 2013 17:44:29 -0800 Subject: [PATCH] Issue 3832 - STARTF_USESHOWWINDOW not available on WinNT Python 2.6.6 In-Reply-To: <51242A22.2090608@fb.com> References: <51242A22.2090608@fb.com> Message-ID: <51242A7D.8080404@fb.com> On 02/19/2013 05:42 PM, Siddharth Agarwal wrote: > > "util: hardcode STARTF_USESHOWWINDOW" (with the issue number at the end, of course) From raf at durin42.com Tue Feb 19 20:01:31 2013 From: raf at durin42.com (Augie Fackler) Date: Tue, 19 Feb 2013 21:01:31 -0500 Subject: [PATCH 2 of 2] commands: exit from the log loop at the right time In-Reply-To: <4dfcc703b38581beafbf.1361317627@australite.thefacebook.com> References: <77b02f572b752fcbec87.1361317626@australite.thefacebook.com> <4dfcc703b38581beafbf.1361317627@australite.thefacebook.com> Message-ID: <093D42E9-8AFB-4B7A-A8E2-4A282EF1FF4F@durin42.com> Both of these LGTM On Feb 19, 2013, at 6:47 PM, Bryan O'Sullivan wrote: > # HG changeset patch > # User Bryan O'Sullivan > # Date 1361317587 28800 > # Node ID 4dfcc703b38581beafbf85ba5ae971943ecb70d5 > # Parent 77b02f572b752fcbec87f576564880ec1dc9023b > commands: exit from the log loop at the right time > > Previously, we'd run the iterator one more time than necessary, > potentially doing a lot of extra work in the process. > > diff --git a/mercurial/commands.py b/mercurial/commands.py > --- a/mercurial/commands.py > +++ b/mercurial/commands.py > @@ -4215,10 +4215,10 @@ def log(ui, repo, *pats, **opts): > displayer.show(ctx, copies=copies, matchfn=revmatchfn) > > for ctx in cmdutil.walkchangerevs(repo, matchfn, opts, prep): > + if displayer.flush(ctx.rev()): > + count += 1 > if count == limit: > break > - if displayer.flush(ctx.rev()): > - count += 1 > displayer.close() > > @command('manifest', > _______________________________________________ > Mercurial-devel mailing list > Mercurial-devel at selenic.com > http://selenic.com/mailman/listinfo/mercurial-devel From matt_harbison at yahoo.com Tue Feb 19 23:57:33 2013 From: matt_harbison at yahoo.com (Matt Harbison) Date: Wed, 20 Feb 2013 05:57:33 +0000 (UTC) Subject: [PATCH 1 of 3] pull: add --subrepos flag References: Message-ID: On Sun, 17 Feb 2013 13:19:16 +0100, Angel Ezquerra wrote: > # HG changeset patch > # User Angel Ezquerra > # Date 1360519226 -3600 > # Node ID abbd26cca35280fb8f784b3f2c02eef71696c47b > # Parent 55b9b294b7544a6a144f627f71f4b770907d5a98 > pull: add --subrepos flag > > The purpose of this new flag is to ensure that you are able to update to any > incoming revision without requiring any network access. The idea is to make sure > that the repository is self-contained after doing hg pull --subrepos, as long as > it already was self-contained before the pull). > > When the --subrepos flag is enabled, pull will also pull (or clone) all subrepos > that are present on the current revision and those that are referenced by any of > the incoming revisions. I haven't gotten a chance to really play with this yet, so I'm going more off the comments here- I apologize if these answers should be obvious, but I'm not familiar enough with some of the code. - Is there an easy way to tell if the repo is/was self contained? (Maybe incoming -S?) - Is the 'self-contained' bit to limit overhead on each pull, or is there another reason this can't ensure the result is self contained? 'Push' and 'outgoing -S' recognize (almost) everything going in the other direction, so it might be nice to have the same capability with a form of pull. (I may have found a push bug that I haven't gotten back to yet.) - The full subrepo gets pulled, even revs not committed to the parent? I think that's a good thing, because regularly get burned when I 'pull -u' the tree to another machine and then go to apply the rest of a patch queue to the subrepo. I'll try to experiment with this some in the next few days. I ran into issues with what I'm working on (push, outgoing) with deeply nested subrepos, and also when a parent locks in an earlier subrepo version. I wonder if deeply nested subrepos will be a problem here since hgsubrepo.pull() doesn't walk its subrepos and pull them. --Matt From gilles.moris at free.fr Wed Feb 20 00:02:43 2013 From: gilles.moris at free.fr (Gilles Moris) Date: Wed, 20 Feb 2013 07:02:43 +0100 Subject: [PATCH 2 of 2 RFCv2] commands: introduce stash command In-Reply-To: <029F8711-3C3E-473C-9045-BED44AE53660@ringworld.org> References: <029F8711-3C3E-473C-9045-BED44AE53660@ringworld.org> Message-ID: <201302200702.44347.gilles.moris@free.fr> On Tuesday 19 February 2013 06:18:56 pm Kevin Bullock wrote: > Not necessarily. I often start working on a change e.g. on the stable > branch, then realize that it should really be done on default. 'stash' is a > logical way to move working-directory changes across branches without > having to either (a) really commit, or (b) update to the common ancestor, > then up to the target head. But this is another story: it is because the merge engine cannot handle cross branches merge. I would prefer that the update command be fixed instead. This seems the equivalent of the graft command for the working directory, so possibly the infrastructure for that might be almost in place. Regards. Gilles. From gadgetsteve at hotmail.com Wed Feb 20 00:03:04 2013 From: gadgetsteve at hotmail.com (Steve Barnes) Date: Wed, 20 Feb 2013 06:03:04 +0000 Subject: [PATCH] Issue 3832 - STARTF_USESHOWWINDOW not available on WinNT Python 2.6.6 In-Reply-To: <51242A22.2090608@fb.com> References: <51242A22.2090608@fb.com> Message-ID: On 20/02/13 01:42, Siddharth Agarwal wrote: > On 02/19/2013 01:11 AM, Steve Barnes wrote: >> >> # HG changeset patch >> >> # User Steve Barnes >> >> # Date 1361263154 0 >> >> # Node ID 97b7c13ff8173c257143b9bcabb8ad726ade98cc >> >> # Parent 5fe53db61aa433018de8b0ee296db868f666cee7 >> >> util: cope with missing subprocess.startf_useshowwindow in python >> 2.6.x on nt (issue3832) >> > > This is too long. I'd suggest something like > > "util: hardcode STARTF_USESHOWWINDOW" > > with a note in the full message explaining why (it isn't present in > some newer versions of Python). > >> - startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW >> >> + if hasattr(subprocess, 'STARTF_USESHOWWINDOW'): # Not all >> pythons have this >> >> + startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW >> > > Why not just hardcode the value? That's 1 according to > http://msdn.microsoft.com/en-us/library/windows/desktop/ms686331%28v=vs.85%29.aspx. > > Personally I am never comfortable with adding mystery hard coded values nor with sending undocumented - as in not a part of the user interface flags to a library call. The way that I suggested will use the flag as it is if it available and ignore it if it is not. Just my 2c worth. Steve -- Steve /Gadget/ Barnes -------------- next part -------------- An HTML attachment was scrubbed... URL: From bboissin at gmail.com Wed Feb 20 01:48:40 2013 From: bboissin at gmail.com (Benoit Boissinot) Date: Wed, 20 Feb 2013 08:48:40 +0100 Subject: [PATCH 2 of 2] commands: exit from the log loop at the right time In-Reply-To: <093D42E9-8AFB-4B7A-A8E2-4A282EF1FF4F@durin42.com> References: <77b02f572b752fcbec87.1361317626@australite.thefacebook.com> <4dfcc703b38581beafbf.1361317627@australite.thefacebook.com> <093D42E9-8AFB-4B7A-A8E2-4A282EF1FF4F@durin42.com> Message-ID: On Wed, Feb 20, 2013 at 3:01 AM, Augie Fackler wrote: > Both of these LGTM > +1 (started reviewing before seeing the LGTM). Thanks, Benoit > > On Feb 19, 2013, at 6:47 PM, Bryan O'Sullivan wrote: > > > # HG changeset patch > > # User Bryan O'Sullivan > > # Date 1361317587 28800 > > # Node ID 4dfcc703b38581beafbf85ba5ae971943ecb70d5 > > # Parent 77b02f572b752fcbec87f576564880ec1dc9023b > > commands: exit from the log loop at the right time > > > > Previously, we'd run the iterator one more time than necessary, > > potentially doing a lot of extra work in the process. > > > > diff --git a/mercurial/commands.py b/mercurial/commands.py > > --- a/mercurial/commands.py > > +++ b/mercurial/commands.py > > @@ -4215,10 +4215,10 @@ def log(ui, repo, *pats, **opts): > > displayer.show(ctx, copies=copies, matchfn=revmatchfn) > > > > for ctx in cmdutil.walkchangerevs(repo, matchfn, opts, prep): > > + if displayer.flush(ctx.rev()): > > + count += 1 > > if count == limit: > > break > > - if displayer.flush(ctx.rev()): > > - count += 1 > > displayer.close() > > > > @command('manifest', > > _______________________________________________ > > Mercurial-devel mailing list > > Mercurial-devel at selenic.com > > http://selenic.com/mailman/listinfo/mercurial-devel > > _______________________________________________ > Mercurial-devel mailing list > Mercurial-devel at selenic.com > http://selenic.com/mailman/listinfo/mercurial-devel > -------------- next part -------------- An HTML attachment was scrubbed... URL: From diptongo at gmail.com Wed Feb 20 02:20:57 2013 From: diptongo at gmail.com (Isaac Jurado) Date: Wed, 20 Feb 2013 09:20:57 +0100 Subject: [PATCH 3 of 3] worker: handle worker failures more aggressively In-Reply-To: References: <42c14cff887e20d033db.1361298555@australite.local> <20130219222359.GA3735@findus> <20130219225923.GB3735@findus> Message-ID: On Wed, Feb 20, 2013 at 12:10 AM, Bryan O'Sullivan wrote: > On Tue, Feb 19, 2013 at 2:59 PM, Isaac Jurado wrote: >> >> Oh, I didn't catch that. As of the current code, your other emails and >> the name _posixworker() I assumed, probably wrong, that the Windows >> implementation would have its own idiosyncrasies. > > > Yes, but I'm trying to keep as much of the code portable as reasonable, so > that if someone ports the worker code to Windows, it's minimally invasive. Allright. Then forgive me for insisting on this one more time: What's the plan for Windows? Threads or processes? -- Isaac Jurado "The noblest pleasure is the joy of understanding" Leonardo da Vinci From denis at laxalde.org Wed Feb 20 02:24:41 2013 From: denis at laxalde.org (Denis Laxalde) Date: Wed, 20 Feb 2013 09:24:41 +0100 Subject: [PATCH 2 of 2 RFCv2] commands: introduce stash command In-Reply-To: <029F8711-3C3E-473C-9045-BED44AE53660@ringworld.org> References: <06dd5eda17402c1e89a1.1360887323@idan> <029F8711-3C3E-473C-9045-BED44AE53660@ringworld.org> Message-ID: <51248849.3060404@laxalde.org> Kevin Bullock a ?crit : > On Feb 19, 2013, at 4:46 AM, Denis Laxalde wrote: > >> Idan Kamara wrote: >>> Referring to stashes is done either by index (as shown in --list) or name (if >>> one was given). If neither is specified, the most recent stash is chosen. >> >> Wouldn't make more sense to use parent relationships to order stashes? >> E.g., if I pop/apply a stash without specifying its name, I'd rather want the one that is on top of the closest parent of my current position than the most recent one that appeared in the repository (which might be in some unrelated branch or so). > > Not necessarily. I often start working on a change e.g. on the stable branch, then realize that it should really be done on default. 'stash' is a logical way to move working-directory changes across branches without having to either (a) really commit, or (b) update to the common ancestor, then up to the target head. > > I think picking the most recent stash is reasonable. Either way, referring to the changes explicitly by the identifier shown in --list isn't too hard. The reason I suggested this is that this would minimize the risks of conflicts during unstash. A simple case where the ordering by appearance would (possibly) lead to conflict: - work on head A - stash - work on head B, (hack, hack) - stash - update to head A - unstash This is a typical use case of stash (namely interrupted workflow for urgent fix). And having to explicitly name the stash to pop in such case seems awkward to me, whereas poping based on ancestor would just work. -- Denis Laxalde From pierre-yves.david at ens-lyon.org Wed Feb 20 04:47:10 2013 From: pierre-yves.david at ens-lyon.org (Pierre-Yves David) Date: Wed, 20 Feb 2013 11:47:10 +0100 Subject: [PATCH 2 of 2 RFCv2] commands: introduce stash command In-Reply-To: <201302200702.44347.gilles.moris@free.fr> References: <029F8711-3C3E-473C-9045-BED44AE53660@ringworld.org> <201302200702.44347.gilles.moris@free.fr> Message-ID: <2CE47245-4DAC-48AD-8BAD-3CE9C856E472@ens-lyon.org> On 20 f?vr. 2013, at 07:02, Gilles Moris wrote: > On Tuesday 19 February 2013 06:18:56 pm Kevin Bullock wrote: >> Not necessarily. I often start working on a change e.g. on the stable >> branch, then realize that it should really be done on default. 'stash' is a >> logical way to move working-directory changes across branches without >> having to either (a) really commit, or (b) update to the common ancestor, >> then up to the target head. > > But this is another story: it is because the merge engine cannot handle cross > branches merge. I would prefer that the update command be fixed instead. This > seems the equivalent of the graft command for the working directory, so > possibly the infrastructure for that might be almost in place. The merge engine can handle that just fine. Its a deliberate User interface choice. -- Pierre-Yves David From gilles.moris at free.fr Wed Feb 20 05:00:03 2013 From: gilles.moris at free.fr (Gilles Moris) Date: Wed, 20 Feb 2013 12:00:03 +0100 Subject: [PATCH 2 of 2 RFCv2] commands: introduce stash command In-Reply-To: <2CE47245-4DAC-48AD-8BAD-3CE9C856E472@ens-lyon.org> References: <201302200702.44347.gilles.moris@free.fr> <2CE47245-4DAC-48AD-8BAD-3CE9C856E472@ens-lyon.org> Message-ID: <201302201200.04062.gilles.moris@free.fr> On Wednesday 20 February 2013 11:47:10 am Pierre-Yves David wrote: > On 20 f?vr. 2013, at 07:02, Gilles Moris wrote: > > On Tuesday 19 February 2013 06:18:56 pm Kevin Bullock wrote: > >> Not necessarily. I often start working on a change e.g. on the stable > >> branch, then realize that it should really be done on default. 'stash' > >> is a logical way to move working-directory changes across branches > >> without having to either (a) really commit, or (b) update to the common > >> ancestor, then up to the target head. > > > > But this is another story: it is because the merge engine cannot handle > > cross branches merge. I would prefer that the update command be fixed > > instead. This seems the equivalent of the graft command for the working > > directory, so possibly the infrastructure for that might be almost in > > place. > > The merge engine can handle that just fine. Its a deliberate User interface > choice. So for this particular use case, it would be better to do $ hg update --crossbranch otherbranch Than: $ hg stash wip $ hg update otherbranch $ hg stash -p wip And this would, by the way, work fine with MQ. Regards. Gilles. From hg at intevation.org Wed Feb 20 06:00:06 2013 From: hg at intevation.org (Mercurial Commits) Date: Wed, 20 Feb 2013 13:00:06 +0100 Subject: mercurial/crew@18704: 7 outgoing changesets (3 stable) Message-ID: <1361361606.842591.29301.nullmailer@hg.intevation.org> 7 outgoing changesets (3 stable) in mercurial/crew: http://hg.intevation.org/mercurial/crew/rev/f17680992123 changeset: 18704:f17680992123 bookmark: @ tag: tip parent: 18703:a8204cef4c5a parent: 18699:61c8327ced50 user: Kevin Bullock date: Tue Feb 19 13:35:39 2013 -0600 summary: merge with stable http://hg.intevation.org/mercurial/crew/rev/a8204cef4c5a changeset: 18703:a8204cef4c5a parent: 18702:4921b5c2aeed parent: 18700:d69585a5c5c0 user: Kevin Bullock date: Tue Feb 19 13:35:25 2013 -0600 summary: merge with main http://hg.intevation.org/mercurial/crew/rev/d69585a5c5c0 changeset: 18700:d69585a5c5c0 parent: 18698:4a85ebb5c807 user: Na'Tosha Bard date: Sat Feb 09 21:07:42 2013 +0000 summary: largefiles: don't cache largefiles for pulled heads by default http://hg.intevation.org/mercurial/crew/rev/61c8327ced50 changeset: 18699:61c8327ced50 branch: stable parent: 18697:7d66a44e87ed user: FUJIWARA Katsunori date: Mon Feb 18 00:04:28 2013 +0900 summary: bundle: treat branches created newly on the local correctly (issue3828) http://hg.intevation.org/mercurial/crew/rev/4a85ebb5c807 changeset: 18698:4a85ebb5c807 parent: 18695:ec9b9968b7f8 parent: 18697:7d66a44e87ed user: Kevin Bullock date: Fri Feb 15 21:20:24 2013 -0600 summary: merge with stable http://hg.intevation.org/mercurial/crew/rev/7d66a44e87ed changeset: 18697:7d66a44e87ed branch: stable user: Kevin Bullock date: Fri Feb 15 15:06:43 2013 -0600 summary: mergetools: refine vimdiff warning message http://hg.intevation.org/mercurial/crew/rev/f2b1f78cf202 changeset: 18696:f2b1f78cf202 branch: stable parent: 18679:f6f35d646cb5 user: Pierre-Yves David date: Fri Feb 15 11:28:04 2013 +0100 summary: mergetools: vimdiff issue a warning explaining how to abort -- Repository URL: http://hg.intevation.org/mercurial/crew From foozy at lares.dti.ne.jp Wed Feb 20 07:02:27 2013 From: foozy at lares.dti.ne.jp (FUJIWARA Katsunori) Date: Wed, 20 Feb 2013 22:02:27 +0900 Subject: [PATCH] revset: use "repo.changelog" instead of "list(repo)" for resource efficiency In-Reply-To: References: <06fb2582618f43400b38.1361117286@juju> Message-ID: At Tue, 19 Feb 2013 10:27:40 -0800, Bryan O'Sullivan wrote: > > [1 ] > On Sun, Feb 17, 2013 at 8:08 AM, FUJIWARA Katsunori > wrote: > > > This patch uses "repo.changelog" instead of "list(repo)" for resource > > efficiency. > > > > What effect does this have on performance? I expected this patch to prevent from immediate creation of "list" object containing integers corresponded to all revisions in repository, because it may be very large and not be used. For example, "revset.stringset()" omits "x in subset" check, if "len(subset) == len(repo)": "len(list(repo)) == len(repo)" is always True, if there is no hidden revision. But, I overlooked that: - changelog has "__iter__()" but not "__contains__()". it decreases performance, because each "x in cl" causes "__iter__()" invocation - some codes outside revset module also invoke "revset.getset()" with "list(repo)" IMHO, "repo" itself seems to be good to take place of "list(repo)": "repo" should have all of "__iter__()", "__len__()" and "__contains_()". I'll try to resend refined one. ---------------------------------------------------------------------- [FUJIWARA Katsunori] foozy at lares.dti.ne.jp From foozy at lares.dti.ne.jp Wed Feb 20 07:02:40 2013 From: foozy at lares.dti.ne.jp (FUJIWARA Katsunori) Date: Wed, 20 Feb 2013 22:02:40 +0900 Subject: [PATCH] revset: use "repo.changelog" instead of "list(repo)" for resource efficiency In-Reply-To: <3DE2EC35-0904-450B-9EEB-E272EFDFF6EE@ringworld.org> References: <06fb2582618f43400b38.1361117286@juju> <3DE2EC35-0904-450B-9EEB-E272EFDFF6EE@ringworld.org> Message-ID: At Tue, 19 Feb 2013 13:31:54 -0600, Kevin Bullock wrote: > > On Feb 19, 2013, at 1:08 PM, Dirkjan Ochtman wrote: > > > On Sun, Feb 17, 2013 at 5:08 PM, FUJIWARA Katsunori > > wrote: > >> # HG changeset patch > >> # User FUJIWARA Katsunori > >> # Date 1361115858 -32400 > >> # Node ID 06fb2582618f43400b38ac4c791410d2fc748d2c > >> # Parent f12804d3ff801b989cb2aab1aad93047a8db46f1 > >> revset: use "repo.changelog" instead of "list(repo)" for resource efficiency > > > > Doesn't that kill the filtering? IIRC Pierre-Yves was moving in the > > other direction on these kinds of things. > > Nope, repo.changelog is filtered on a filtered repo object. Yes, repo.changelog is filtered. But I found my own mistake around hidden revisions. "list(repo)" uses "changelog.__iter__()" to create list object as subset. So, "len(subset) == len(repo)" is not True, when there are some hidden revisions. This causes "x in subset" check in "stringset()" below: def stringset(repo, subset, x): x = repo[x].rev() if x == -1 and len(subset) == len(repo): return [-1] if len(subset) == len(repo) or x in subset: ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ return [x] return [] But "repo.changelog" as subset causes "len(subset) == len(repo)" always, so ID of hidden revision specified directly in revset expression is treated as valid one, even if --hidden is not specified in command line. So, this patch should also add "repo.filteredrevs" check into above code. I'll try to resend refined one. ---------------------------------------------------------------------- [FUJIWARA Katsunori] foozy at lares.dti.ne.jp From mercurial-bugs at selenic.com Wed Feb 20 02:03:31 2013 From: mercurial-bugs at selenic.com (mercurial-bugs at selenic.com) Date: Wed, 20 Feb 2013 08:03:31 +0000 Subject: [Bug 3835] New: Add relative path option for hg status Message-ID: http://bz.selenic.com/show_bug.cgi?id=3835 Priority: normal Bug ID: 3835 CC: mercurial-devel at selenic.com Assignee: bugzilla at selenic.com Summary: Add relative path option for hg status Severity: feature Classification: Unclassified OS: All Reporter: barraponto at gmail.com Hardware: All Status: UNCONFIRMED Version: unspecified Component: Mercurial Product: Mercurial The `hg status` command outputs paths relative to the repository root, by default. One can override this behavior by passing a directory as an argument, to output the paths relative to it. eg: `hg status .` would output the paths relative to the current path, identical to `git status` behavior. Setting hgrc to behave like that by default is somewhat awkward. See [this StackOverflow question][1] for proposed solutions. But it should be easier, something like this in .hgrc should be enough: [ui] relative_paths = 1 I expect this to be feasible, although I'm not sure relative_paths is the best name for this setting. Also, I don't know whether it should change the behavior of any other command than status (think of commands that output paths). [1]: http://stackoverflow.com/questions/833326/mercurial-hg-status-and-relative-paths -- You are receiving this mail because: You are on the CC list for the bug. From sid0 at fb.com Wed Feb 20 11:04:07 2013 From: sid0 at fb.com (Siddharth Agarwal) Date: Wed, 20 Feb 2013 09:04:07 -0800 Subject: [PATCH] Issue 3832 - STARTF_USESHOWWINDOW not available on WinNT Python 2.6.6 In-Reply-To: References: <51242A22.2090608@fb.com> Message-ID: <51250207.6060608@fb.com> On 02/19/2013 10:03 PM, Steve Barnes wrote: > Personally I am never comfortable with adding mystery hard coded > values nor with sending undocumented - as in not a part of the user > interface flags to a library call. It isn't a mystery or undocumented if it's on MSDN. You could do STARTF_USESHOWWINDOW = 1 ... startupinfo.dwFlags |= STARTF_USESHOWWINDOW > The way that I suggested will use the flag as it is if it available > and ignore it if it is not. The flag is always available, it just isn't always defined on the subprocess module. From mercurial-bugs at selenic.com Wed Feb 20 06:43:39 2013 From: mercurial-bugs at selenic.com (mercurial-bugs at selenic.com) Date: Wed, 20 Feb 2013 12:43:39 +0000 Subject: [Bug 3836] New: Please provide a way for a push hook to detect the pushing hg's version Message-ID: http://bz.selenic.com/show_bug.cgi?id=3836 Priority: normal Bug ID: 3836 CC: mercurial-devel at selenic.com Assignee: bugzilla at selenic.com Summary: Please provide a way for a push hook to detect the pushing hg's version Severity: feature Classification: Unclassified OS: All Reporter: jwatt at jwatt.org Hardware: All Status: UNCONFIRMED Version: unspecified Component: Mercurial Product: Mercurial It would help greatly in avoiding any further erosion of blame in public mozilla repositories (from bug 3833) if we could detect when a client pushing changesets is version < 2.5. -- You are receiving this mail because: You are on the CC list for the bug. From mpm at selenic.com Wed Feb 20 12:42:39 2013 From: mpm at selenic.com (Matt Mackall) Date: Wed, 20 Feb 2013 12:42:39 -0600 Subject: [PATCH RFC] commit: add --reuse-message for keeping the old commit message during amend In-Reply-To: <50143F8D-DA41-4976-918D-8BCA470377B8@durin42.com> References: <1360731362.12295.24.camel@calx> <2B10A89294DA6740AC6155F56842F9CE0565A924@PRN-MBX01-2.TheFacebook.com> <20130214102301.GB17607@crater2.logilab.fr> <50143F8D-DA41-4976-918D-8BCA470377B8@durin42.com> Message-ID: <1361385759.12295.160.camel@calx> On Tue, 2013-02-19 at 20:35 -0500, Augie Fackler wrote: > On Feb 14, 2013, at 5:23 AM, Pierre-Yves David wrote: > > > On Wed, Feb 13, 2013 at 07:42:44PM +0000, Durham Goode wrote: > >> On 2/12/13 8:56 PM, "Matt Mackall" wrote: > >>> > >>> I'm now inclined to think that 'hg commit --amend' will eventually be > >>> replaced by 'hg amend', which will have a different default. Then we'll > >>> deprecate --amend on commit. > >>> > >>> So I think we should leave this alone. But I don't think we've got quite > >>> enough experience here to add the new amend command yet. > > > > In evolve, I'll probably drop the internal "hg amend" code in favor of using "hg commit > > --amend" with an altered editor. > > Hm. I think it's bad practice for extensions to alter the behavior of > off the shelf commands with off the shelf flags - I've done that in > the past and always regretted it. I think you misread his proposal. -- Mathematics is the supreme nostalgia of our time. From bos at serpentine.com Wed Feb 20 12:52:41 2013 From: bos at serpentine.com (Bryan O'Sullivan) Date: Wed, 20 Feb 2013 10:52:41 -0800 Subject: [PATCH] revset: use "repo.changelog" instead of "list(repo)" for resource efficiency In-Reply-To: References: <06fb2582618f43400b38.1361117286@juju> Message-ID: On Wed, Feb 20, 2013 at 5:02 AM, FUJIWARA Katsunori wrote: > I expected this patch to prevent from immediate creation of "list" > object containing integers corresponded to all revisions in > repository, because it may be very large and not be used. > The contrib/perf.py extension is useful for quantifying this sort of thing. Revsets are very performance sensitive, and it's all too easy to regress performance if you don't measure it. I'd appreciate it if you could post some before/after numbers for this patch. -------------- next part -------------- An HTML attachment was scrubbed... URL: From bos at serpentine.com Wed Feb 20 12:59:42 2013 From: bos at serpentine.com (Bryan O'Sullivan) Date: Wed, 20 Feb 2013 10:59:42 -0800 Subject: [PATCH 3 of 3] worker: handle worker failures more aggressively In-Reply-To: References: <42c14cff887e20d033db.1361298555@australite.local> <20130219222359.GA3735@findus> <20130219225923.GB3735@findus> Message-ID: On Wed, Feb 20, 2013 at 12:20 AM, Isaac Jurado wrote: > What's the plan for Windows? Threads or processes? > Threads won't help, because update is partly CPU bound and threads will all serialize on the GIL. So if there's to be an answer for Windows, it has to be processes, presumably started via os.spawnv. I'm in no rush to implement a Windows solution. I don't expect an approach based on the multiprocessing module to be useful, because (a) people do all kinds of perverse packaging things on Windows that are unlikely to work with multiprocessing and (b) the multiprocessing module adds a ton of overhead, so you have to do a lot of work to overcome its communication costs. (We can't use any of the various "Windows has something sort of like fork(2)" approaches either, because they are all terribly broken.) -------------- next part -------------- An HTML attachment was scrubbed... URL: From noreply+2868786732 at blendr.com Wed Feb 20 14:01:51 2013 From: noreply+2868786732 at blendr.com (Blendr) Date: Wed, 20 Feb 2013 20:01:51 +0000 Subject: =?UTF-8?B?4piFIE1lcmN1cmlhbC1kZXZlbCwgTmljb2xhcyBsZWZ0IGEgbWVzc2FnZSBmb3IgeW91?= Message-ID: Nicolas left a message for you Its sender and content will be shown only to you and you can delete it at any time. You can instantly reply to it, using the message exchange system. To find out what was written to you, just follow this link: http://eu1.blendr.com/0312806378/in/IP2tVaUwGoc/?lang_id=106&g=57&m=21&mid=51252bae00000000006a0000013598ae01b865cc013c Some other people in the area who are on Badoo Deffekt (, ) Michelle (, ) Dyingblackrose (Zurich, Switzerland) http://eu1.blendr.com/0312806378/in/IP2tVaUwGoc/?lang_id=106&g=57&m=21&mid=51252bae00000000006a0000013598ae01b865cc013c If clicking the links in this message does not work, copy and paste them into the address bar of your browser. This email is a part of delivering a message sent by Nicolas on the system. If you received this email by mistake, please just ignore it. After a short time the message will be removed from the system. Have fun! The Blendr Team Blendr is powered by Badoo. You have received this email from Badoo Trading Limited (postal address below). If you do not wish to receive further email communications from Badoo, http://eu1.blendr.com/impersonation.phtml?lang_id=106&email=mercurial-devel%40selenic.com&block_code=369f01&m=21&mid=51252bae00000000006a0000013598ae01b865cc013c here to opt out. Badoo Trading Limited is a limited company registered in England and Wales under CRN 7540255 with its registered office at Media Village, 131 - 151 Great Titchfield Street, London, W1W 5BB. -------------- next part -------------- An HTML attachment was scrubbed... URL: From bos at serpentine.com Wed Feb 20 14:39:38 2013 From: bos at serpentine.com (Bryan O'Sullivan) Date: Wed, 20 Feb 2013 12:39:38 -0800 Subject: [PATCH] match: more accurately report when we're always going to match Message-ID: <7c4e5ad8fa43d211c2d0.1361392778@australite.thefacebook.com> # HG changeset patch # User Bryan O'Sullivan # Date 1361392772 28800 # Node ID 7c4e5ad8fa43d211c2d068f981b91acf350be3df # Parent 67ee5291969274900517384d864da73c7928552e match: more accurately report when we're always going to match This improves the performance of log --patch and --stat by about 20% for moderately large manifests (e.g. mozilla-central) for the common case of no -I/-X patterns. diff --git a/mercurial/match.py b/mercurial/match.py --- a/mercurial/match.py +++ b/mercurial/match.py @@ -62,6 +62,7 @@ class match(object): self._files = [] self._anypats = bool(include or exclude) self._ctx = ctx + self._always = False if include: pats = _normalize(include, 'glob', root, cwd, auditor) @@ -103,6 +104,7 @@ class match(object): m = lambda f: not em(f) else: m = lambda f: True + self._always = True self.matchfn = m self._fmap = set(self._files) @@ -130,7 +132,7 @@ class match(object): def anypats(self): return self._anypats def always(self): - return False + return self._always class exact(match): def __init__(self, root, cwd, files): @@ -139,8 +141,7 @@ class exact(match): class always(match): def __init__(self, root, cwd): match.__init__(self, root, cwd, []) - def always(self): - return True + self._always = True class narrowmatcher(match): """Adapt a matcher to work on a subdirectory only. @@ -175,6 +176,7 @@ class narrowmatcher(match): self._cwd = matcher._cwd self._path = path self._matcher = matcher + self._always = matcher._always self._files = [f[len(path) + 1:] for f in matcher._files if f.startswith(path + "/")] From nicdumz at gmail.com Wed Feb 20 16:31:03 2013 From: nicdumz at gmail.com (Nicolas Dumazet) Date: Wed, 20 Feb 2013 23:31:03 +0100 Subject: =?UTF-8?Q?Re=3A_=E2=98=85_Mercurial=2Ddevel=2C_Nicolas_left_a_message_for_?= =?UTF-8?Q?you?= In-Reply-To: <20130220200759.DF7C974167@waste.org> References: <20130220200759.DF7C974167@waste.org> Message-ID: Stupid, stupid android app. Sorry for the noise. 2013/2/20 Blendr > ** > See this email in English, > Deutsch, > Fran?ais, > Italiano, > Espa?ol, > Portugu?sor 35 > other languages > . > Nicolas left a message for you Only you can see the sender and content of > your message, and you can delete it anytime. You can instantly reply using > our message exchange system: > > > *Check your message > * > ------------------------------ > > Some other people in the area who are on Badoo > > > Deffekt > , > Michelle > , > > Dyingblackrose > Zurich, Switzerland > > This email is part of our delivery procedure for the message sent by > Nicolas. If you have received this email by mistake, please ignore it. The > message will be deleted soon. > > Have fun! > The Blendr Team > > Blendr is powered by Badoo. You have received this email from Badoo > Trading Limited (postal address below). If you do not wish to receive > further email communications from Badoo, click herehere to opt out. > Badoo Trading Limited is a limited company registered in England and Wales > under CRN 7540255 with its registered office at Media Village, 131 - 151 > Great Titchfield Street, London, W1W 5BB. > > _______________________________________________ > Mercurial-devel mailing list > Mercurial-devel at selenic.com > http://selenic.com/mailman/listinfo/mercurial-devel > > -- Nicolas Dumazet ? NicDumZ -------------- next part -------------- An HTML attachment was scrubbed... URL: From angel.ezquerra at gmail.com Wed Feb 20 17:19:34 2013 From: angel.ezquerra at gmail.com (Angel Ezquerra) Date: Thu, 21 Feb 2013 00:19:34 +0100 Subject: [PATCH 1 of 3] pull: add --subrepos flag In-Reply-To: References: Message-ID: On Wed, Feb 20, 2013 at 6:57 AM, Matt Harbison wrote: > On Sun, 17 Feb 2013 13:19:16 +0100, Angel Ezquerra wrote: > >> # HG changeset patch >> # User Angel Ezquerra >> # Date 1360519226 -3600 >> # Node ID abbd26cca35280fb8f784b3f2c02eef71696c47b >> # Parent 55b9b294b7544a6a144f627f71f4b770907d5a98 >> pull: add --subrepos flag >> >> The purpose of this new flag is to ensure that you are able to update to any >> incoming revision without requiring any network access. The idea is to make sure >> that the repository is self-contained after doing hg pull --subrepos, as long as >> it already was self-contained before the pull). >> >> When the --subrepos flag is enabled, pull will also pull (or clone) all subrepos >> that are present on the current revision and those that are referenced by any of >> the incoming revisions. > > I haven't gotten a chance to really play with this yet, so I'm going more off the > comments here- I apologize if these answers should be obvious, but I'm not familiar > enough with some of the code. > > - Is there an easy way to tell if the repo is/was self contained? (Maybe > incoming -S?) No there is not. I don't think incoming -S would do the trick since that would just tell you if there are _new_ incoming revisions on some of the _current_ subrepos. A repo is "self-contained" if it is possible to update to any of its revisions withing requiring a pull of one or more of its subrepos. I don't know of any existing mercurial command that would be able to give you that information. > - Is the 'self-contained' bit to limit overhead on each pull, or is there another > reason this can't ensure the result is self contained? 'Push' and 'outgoing -S' > recognize (almost) everything going in the other direction, so it might be nice > to have the same capability with a form of pull. (I may have found a push bug > that I haven't gotten back to yet.) I'm not sure I understand what you mean. I don't think you (we?) must give too much importance to this "self-contained" concept. It is just a way for me to explain the purpose of the patch, and specially to explain why we must look for subrepos on all the new incoming revisions, and why we cannot just limit ourselves to pulling the subrepos on the current revisions (short answer: because new subrepos may appear on the new, incoming revisions). My patch explicitly says that hg pull -S will only make your subrepo self-contained if it was already self-contained before. This is in order to avoid having to look for subrepos on all the repo history, rather than just looking for subrepos on the incoming revision (and the current one). > - The full subrepo gets pulled, even revs not committed to the parent? I think > that's a good thing, because regularly get burned when I 'pull -u' the tree to > another machine and then go to apply the rest of a patch queue to the subrepo. Yes. It is perhaps not optimal but I think it is simpler. In addition if different parent repo revisions point to different revisions on a subrepo there is no way for us to tell which of those subrepo revisions is the one that is closes to tip, or which ones are ancestors of the other ones, etc. As a result we would need to perform as many pulls on a given repo as the number of different revisions of that subrepo that were referenced on the parent repo. That is complex and slow, so it is much simpler and possibly faster (in some cases at least) to just pull all revisions from each subrepo. > I'll try to experiment with this some in the next few days. I ran into issues with > what I'm working on (push, outgoing) with deeply nested subrepos, and also when a > parent locks in an earlier subrepo version. I wonder if deeply nested subrepos will > be a problem here since hgsubrepo.pull() doesn't walk its subrepos and pull them. I must confess that I have not tried that too much. We should definitely do this recursively. That being said I hope to get some feedback on the current version that I sent to the list first. Cheers, Angel From matt_harbison at yahoo.com Wed Feb 20 22:55:22 2013 From: matt_harbison at yahoo.com (Matt Harbison) Date: Wed, 20 Feb 2013 23:55:22 -0500 Subject: [PATCH 1 of 3] pull: add --subrepos flag In-Reply-To: References: Message-ID: <5125A8BA.8020106@yahoo.com> Angel Ezquerra wrote: > On Wed, Feb 20, 2013 at 6:57 AM, Matt > Harbison wrote: >> On Sun, 17 Feb 2013 13:19:16 +0100, Angel Ezquerra wrote: >> >>> # HG changeset patch # User Angel >>> Ezquerra # Date 1360519226 -3600 # Node >>> ID abbd26cca35280fb8f784b3f2c02eef71696c47b # Parent >>> 55b9b294b7544a6a144f627f71f4b770907d5a98 pull: add --subrepos >>> flag >>> >>> The purpose of this new flag is to ensure that you are able to >>> update to any incoming revision without requiring any network >>> access. The idea is to make sure that the repository is >>> self-contained after doing hg pull --subrepos, as long as it >>> already was self-contained before the pull). >>> >>> When the --subrepos flag is enabled, pull will also pull (or >>> clone) all subrepos that are present on the current revision and >>> those that are referenced by any of the incoming revisions. >> I haven't gotten a chance to really play with this yet, so I'm >> going more off the comments here- I apologize if these answers >> should be obvious, but I'm not familiar enough with some of the >> code. >> >> - Is there an easy way to tell if the repo is/was self contained? >> (Maybe incoming -S?) > > No there is not. I don't think incoming -S would do the trick since > that would just tell you if there are _new_ incoming revisions on > some of the _current_ subrepos. A repo is "self-contained" if it is > possible to update to any of its revisions withing requiring a pull > of one or more of its subrepos. > > I don't know of any existing mercurial command that would be able to > give you that information. > >> - Is the 'self-contained' bit to limit overhead on each pull, or is >> there another reason this can't ensure the result is self >> contained? 'Push' and 'outgoing -S' recognize (almost) everything >> going in the other direction, so it might be nice to have the same >> capability with a form of pull. (I may have found a push bug that >> I haven't gotten back to yet.) > > I'm not sure I understand what you mean. Consider this (contrived) case: 1) push a repo and subrepo to remote (remote is now self contained) 2) strip or rollback the remote subrepo 3) a top level local repo push will repopulate the remote subrepo Now reverse it: 1) pull a repo and subrepo from remote (local is self contained) 2) strip or rollback the local subrepo 3) nothing is incoming top level, so the subrepo isn't repopulated (if you've updated to a working dir without that subrepo). I'm not sure if there's a less contrived case, or if this matters too much. I guess I was just wondering aloud about the symmetry between push and pull -S (this is certainly much better than it was). I realize you can't do such a thing without crawling most of the history. Are there large public repositories that use subrepos? I'm wondering what the performance hit would be. (It's easy for me to think something is a good idea when I only have small repos and wouldn't notice the hit.) FWIW, largefiles works the same way- if you don't clone or pull with --all-largefiles, there's no single command to go back and get the files for all revisions that are not incoming. That leaves the user wondering if they really can disconnect from the central repo. > I don't think you (we?) must give too much importance to this > "self-contained" concept. It is just a way for me to explain the > purpose of the patch, and specially to explain why we must look for > subrepos on all the new incoming revisions, and why we cannot just > limit ourselves to pulling the subrepos on the current revisions > (short answer: because new subrepos may appear on the new, incoming > revisions). > > My patch explicitly says that hg pull -S will only make your subrepo > self-contained if it was already self-contained before. This is in > order to avoid having to look for subrepos on all the repo history, > rather than just looking for subrepos on the incoming revision (and > the current one). > >> - The full subrepo gets pulled, even revs not committed to the >> parent? I think that's a good thing, because regularly get burned >> when I 'pull -u' the tree to another machine and then go to apply >> the rest of a patch queue to the subrepo. > > Yes. It is perhaps not optimal but I think it is simpler. In > addition if different parent repo revisions point to different > revisions on a subrepo there is no way for us to tell which of those > subrepo revisions is the one that is closes to tip, or which ones > are ancestors of the other ones, etc. As a result we would need to > perform as many pulls on a given repo as the number of different > revisions of that subrepo that were referenced on the parent repo. > That is complex and slow, so it is much simpler and possibly faster > (in some cases at least) to just pull all revisions from each > subrepo. OK, I misread the code- I thought each subrepo was getting a pull at each revision, which I figured would be slow. I attached a test patch below- there's nothing special about it, but it helped me with my pull and outgoing changes (some comments probably still reflect this), so I changed that to pull and incoming to test your patch. - I think I see a double pull of a subrepo (search for "hg pull -S -r 3"). - I wonder if the code in this patch can be leveraged to make incoming print all of the stuff 'pull -S' will grab in the future. >> I'll try to experiment with this some in the next few days. I ran >> into issues with what I'm working on (push, outgoing) with deeply >> nested subrepos, and also when a parent locks in an earlier subrepo >> version. I wonder if deeply nested subrepos will be a problem here >> since hgsubrepo.pull() doesn't walk its subrepos and pull them. > > I must confess that I have not tried that too much. We should > definitely do this recursively. That being said I hope to get some > feedback on the current version that I sent to the list first. Sorry, I got crossed up on that too. hgsubrepo.pull() ends up calling _repo.pull(), so it does recurse. The test below indicates that clone won't recurse- it reminds that an update is needed. (Maybe clone needs a -S too as part of these changes? If you aren't walking the history, I don't see a way around that because nothing is incoming after a clone, so you won't see subrepos of a cloned subrepo.) The other thing worth a test is largefiles- the --all-largefiles option isn't passed to subrepos, so as it stands, 'pull -S' won't let you really disconnect, because largefiles in subrepos won't be cached. That can be fixed later. > Cheers, > > Angel > # HG changeset patch # Parent 5515fe1a8cbf0097440d327e901ddcaa7f1afa04 # User Matt Harbison # Date 1361421052 18000 tests: adapt various 'push -S -r' tests to 'pull -S' diff --git a/tests/test-issue2314.t b/tests/test-issue2314.t new file mode 100644 --- /dev/null +++ b/tests/test-issue2314.t @@ -0,0 +1,174 @@ + $ cat >> $HGRCPATH < [alias] + > slog = log --template '{rev}:{node|short} {desc|firstline}\n' + > sout = outgoing --template '{rev}:{node|short} {desc|firstline}\n' + > sin = incoming --template '{rev}:{node|short} {desc|firstline}\n' + > EOF + +It appears that if the subrepo doesn't exist at the time of the clone, +both out and push will abort. I thought this worked... Avoid the +issue for now by initing an empty repo where the subrepo will go + $ hg init dest +# XXX: pull aborts even though these are empty?! +# $ hg init dest/sub +# $ hg init dest/sub/subsub + $ hg clone -q dest src + $ hg init src/sub + $ cd src + + $ echo '0' > sub/foo.txt + $ hg add -R sub sub/foo.txt + $ hg ci -R sub -m "standalone subrepo commit" + + $ echo '1' > sub/foo.txt + $ echo 'sub = sub' > .hgsub + $ hg add .hgsub + $ hg ci -S -m "lock in subrepo @ 1" + committing subrepository sub + +Add a grandchild to test all paths + $ hg init sub/subsub + $ echo 'subsub' > sub/subsub/bar.txt + $ hg add -R sub/subsub sub/subsub/bar.txt + $ echo 'subsub = subsub' > sub/.hgsub + $ hg add -R sub sub/.hgsub + + $ echo '2' > sub/foo.txt + $ hg ci -S -m "lock in subrepo @ 2" + committing subrepository sub + committing subrepository sub\subsub + + $ echo '3' > sub/foo.txt + $ hg ci -R sub -m "standalone subrepo commit @ 3" + +Add a grandchild to test all paths +XXX: This subrepo won't get pushed, even with current code!! + $ hg init sub/phantom + $ echo 'phantom' > sub/phantom/bar.txt + $ hg add -R sub/phantom sub/phantom/bar.txt +# XXX: this should be '>>' instead of '>' + $ echo 'phantom = phantom' > sub/.hgsub + $ echo '4' > sub/foo.txt + $ hg ci -S -m "lock in subrepo @ 4 (shouldn't be seen in subrepo listing with push -r 1)" + committing subrepository sub + committing subrepository sub\phantom + $ echo '5' > sub/foo.txt + $ hg ci -R sub -m "standalone subrepo commit @ 5" + +Change the subrepo back to a previous rev to make sure that if tip of +parent is pushed, all of the required csets in the subrepo are also +pushed regardless of what the parent tip has locked in. + $ hg up -R sub -r 2 + 3 files updated, 0 files merged, 0 files removed, 0 files unresolved + $ hg ci -S -m "lock in subrepo @ 2 (again)" +# $ echo '2.1' > sub/foo.txt +# $ hg ci -R sub -m "standalone subrepo commit @ 2.1" + +The tree built in src + $ hg slog + 3:b6ef204e81fa lock in subrepo @ 2 (again) + 2:0aa0d45d1538 lock in subrepo @ 4 (shouldn't be seen in subrepo listing with push -r 1) + 1:000653a98f7b lock in subrepo @ 2 + 0:c4c54d98a77b lock in subrepo @ 1 +The tree in src/sub + $ hg slog -R sub + 5:5b1b79eebbd2 standalone subrepo commit @ 5 + 4:cac37e36a35f lock in subrepo @ 4 (shouldn't be seen in subrepo listing with push -r 1) + 3:4aef09d75093 standalone subrepo commit @ 3 + 2:f9f5c072ebeb lock in subrepo @ 2 + 1:30154f8598be lock in subrepo @ 1 + 0:5879cf081918 standalone subrepo commit + + +Test the various forms of 'incoming' + +The current form where entire subrepo is pushed + $ hg sin -S --config paths.default=. -R ../dest + comparing with $TESTTMP\src + 0:c4c54d98a77b lock in subrepo @ 1 + 1:000653a98f7b lock in subrepo @ 2 + 2:0aa0d45d1538 lock in subrepo @ 4 (shouldn't be seen in subrepo listing with push -r 1) + 3:b6ef204e81fa lock in subrepo @ 2 (again) + +This shouldn't push all of the subrepo + $ hg sin -S -r 1 --config paths.default=. -R ../dest + comparing with $TESTTMP\src + 0:c4c54d98a77b lock in subrepo @ 1 + 1:000653a98f7b lock in subrepo @ 2 + +This should push all of the subrepo that has been locked in +(i.e. NOT @ 5) + $ hg sin -S -r tip --config paths.default=. -R ../dest + comparing with $TESTTMP\src + 0:c4c54d98a77b lock in subrepo @ 1 + 1:000653a98f7b lock in subrepo @ 2 + 2:0aa0d45d1538 lock in subrepo @ 4 (shouldn't be seen in subrepo listing with push -r 1) + 3:b6ef204e81fa lock in subrepo @ 2 (again) + +This should want to pull the subsub repo + $ hg pull -S -r 1 --config paths.default=. -R ../dest + pulling from $TESTTMP\src + adding changesets + adding manifests + adding file changes + added 2 changesets with 3 changes to 2 files + cloning subrepo sub from $TESTTMP/src/sub + pulling subrepo sub from $TESTTMP/src/sub + searching for changes + no changes found + (run 'hg update' to get a working copy) + + $ hg slog -R ../dest + 1:000653a98f7b lock in subrepo @ 2 + 0:c4c54d98a77b lock in subrepo @ 1 + $ hg slog -R ../dest/sub + 5:5b1b79eebbd2 standalone subrepo commit @ 5 + 4:cac37e36a35f lock in subrepo @ 4 (shouldn't be seen in subrepo listing with push -r 1) + 3:4aef09d75093 standalone subrepo commit @ 3 + 2:f9f5c072ebeb lock in subrepo @ 2 + 1:30154f8598be lock in subrepo @ 1 + 0:5879cf081918 standalone subrepo commit + +This should want to pull subrepo rev 4, even though rev 2 is locked in +here + $ hg sin -S -r 3 --config paths.default=. -R ../dest + comparing with $TESTTMP\src + searching for changes + 2:0aa0d45d1538 lock in subrepo @ 4 (shouldn't be seen in subrepo listing with push -r 1) + 3:b6ef204e81fa lock in subrepo @ 2 (again) + +..and this should pull subrepo rev 4 + $ hg pull -S -r 3 --config paths.default=. -R ../dest + pulling from $TESTTMP\src + searching for changes + adding changesets + adding manifests + adding file changes + added 2 changesets with 2 changes to 1 files + pulling subrepo sub from $TESTTMP/src/sub + searching for changes + no changes found + pulling subrepo sub from $TESTTMP/src/sub + searching for changes + no changes found + (run 'hg update' to get a working copy) + +Pull all subrepo revs locked into the parent + $ hg pull -S -r tip --config paths.default=. -R ../dest + pulling from $TESTTMP\src + no changes found + + $ hg slog -R ../dest/sub + 5:5b1b79eebbd2 standalone subrepo commit @ 5 + 4:cac37e36a35f lock in subrepo @ 4 (shouldn't be seen in subrepo listing with push -r 1) + 3:4aef09d75093 standalone subrepo commit @ 3 + 2:f9f5c072ebeb lock in subrepo @ 2 + 1:30154f8598be lock in subrepo @ 1 + 0:5879cf081918 standalone subrepo commit + +And finally the legacy push does a full subrepo push. It seems like +the exit code might be wrong given that it pushes a subrepo. + $ hg pull -S --config paths.default=. -R ../dest + pulling from $TESTTMP\src + searching for changes + no changes found From diptongo at gmail.com Thu Feb 21 02:22:03 2013 From: diptongo at gmail.com (Isaac Jurado) Date: Thu, 21 Feb 2013 09:22:03 +0100 Subject: [PATCH 3 of 3] worker: handle worker failures more aggressively In-Reply-To: References: <42c14cff887e20d033db.1361298555@australite.local> <20130219222359.GA3735@findus> <20130219225923.GB3735@findus> Message-ID: On Wed, Feb 20, 2013 at 7:59 PM, Bryan O'Sullivan wrote: > On Wed, Feb 20, 2013 at 12:20 AM, Isaac Jurado wrote: >> >> What's the plan for Windows? Threads or processes? > > Threads won't help, because update is partly CPU bound and threads > will all serialize on the GIL. > > So if there's to be an answer for Windows, it has to be processes, > presumably started via os.spawnv. > > I'm in no rush to implement a Windows solution. I don't expect an > approach based on the multiprocessing module to be useful, because (a) > people do all kinds of perverse packaging things on Windows that are > unlikely to work with multiprocessing and (b) the multiprocessing > module adds a ton of overhead, so you have to do a lot of work to > overcome its communication costs. > > (We can't use any of the various "Windows has something sort of like > fork(2)" approaches either, because they are all terribly broken.) That's my point. Working with processes on Windows is going to be different enough from the other platforms, right? And let me quote your earlier response: > Process groups only exist on Unix. This code should (mostly?) work > untouched on other platforms. Don't you see a bit of contradiction here? Please, don't get me wrong, maybe I'm just failing to accept that my process group suggestion is not as smart as I think it was. But you have to understand that the given reasoning about discarding Unix-only features is, at best, quite confusing. Specially when talking about the process model. My apologies for being a bit of an ass, but I'm very interested in how these patches evolve. Regards. -- Isaac Jurado "The noblest pleasure is the joy of understanding" Leonardo da Vinci From sterkrig at myopera.com Thu Feb 21 05:03:17 2013 From: sterkrig at myopera.com (Nikolaj Sjujskij) Date: Thu, 21 Feb 2013 15:03:17 +0400 Subject: Bugzilla server's system time In-Reply-To: <1360970681.12295.127.camel@calx> References: <20130214224457.GA3634@findus> <1360970681.12295.127.camel@calx> Message-ID: Den 2013-02-16 03:24:41 skrev Matt Mackall : > On Thu, 2013-02-14 at 23:44 +0100, Isaac Jurado wrote: >> Hi, >> >> I think the bugzilla server's clock is not on time. I posted a comment >> ten minutes ago and it appears as 17:40:53 UTC when it should have been >> 22:40:53 UTC. Maybe it's just the timezone, locale or the Bugzilla >> configuration. > > The server's time was correct, however it's in the EST timezone and > Bugzilla defaults users to the server's timezone. I've changed the > default to UTC. There's something still incorrect about time there. I have Europe/Moscow (UTC+4) set in my user preferences and a few minutes ago I've added a comment: http://bz.selenic.com/show_bug.cgi?id=3836#c3. Its date is displayed like "2013-02-21 09:52:34 MSK" which is... er... actually, I don't know what it is. Doesn't seem like usual "UTC as local" or vice versa. As of writing, it's 14:59:05, which is 10:59 UTC. Gentoo bugzilla displays time as expected. From hg at intevation.org Thu Feb 21 06:00:08 2013 From: hg at intevation.org (Mercurial Commits) Date: Thu, 21 Feb 2013 13:00:08 +0100 Subject: mercurial/crew@18709: 12 outgoing changesets (3 stable) Message-ID: <1361448008.127215.11977.nullmailer@hg.intevation.org> 12 outgoing changesets (3 stable) in mercurial/crew: http://hg.intevation.org/mercurial/crew/rev/6b786dc88612 changeset: 18709:6b786dc88612 bookmark: @ tag: tip user: Bryan O'Sullivan date: Wed Feb 20 11:31:41 2013 -0800 summary: commands: exit from the log loop at the right time http://hg.intevation.org/mercurial/crew/rev/49ef9d0ca815 changeset: 18708:49ef9d0ca815 user: Bryan O'Sullivan date: Wed Feb 20 11:31:38 2013 -0800 summary: cmdutil: use a small initial window with --limit http://hg.intevation.org/mercurial/crew/rev/9955fc5ee24b changeset: 18707:9955fc5ee24b user: Bryan O'Sullivan date: Wed Feb 20 11:31:34 2013 -0800 summary: worker: handle worker failures more aggressively http://hg.intevation.org/mercurial/crew/rev/86524a70c0f6 changeset: 18706:86524a70c0f6 user: Bryan O'Sullivan date: Wed Feb 20 11:31:31 2013 -0800 summary: worker: fix a race in SIGINT handling http://hg.intevation.org/mercurial/crew/rev/d1a2b086d058 changeset: 18705:d1a2b086d058 user: Bryan O'Sullivan date: Wed Feb 20 11:31:27 2013 -0800 summary: worker: on error, exit similarly to the first failing worker http://hg.intevation.org/mercurial/crew/rev/f17680992123 changeset: 18704:f17680992123 parent: 18703:a8204cef4c5a parent: 18699:61c8327ced50 user: Kevin Bullock date: Tue Feb 19 13:35:39 2013 -0600 summary: merge with stable http://hg.intevation.org/mercurial/crew/rev/a8204cef4c5a changeset: 18703:a8204cef4c5a parent: 18702:4921b5c2aeed parent: 18700:d69585a5c5c0 user: Kevin Bullock date: Tue Feb 19 13:35:25 2013 -0600 summary: merge with main http://hg.intevation.org/mercurial/crew/rev/d69585a5c5c0 changeset: 18700:d69585a5c5c0 parent: 18698:4a85ebb5c807 user: Na'Tosha Bard date: Sat Feb 09 21:07:42 2013 +0000 summary: largefiles: don't cache largefiles for pulled heads by default http://hg.intevation.org/mercurial/crew/rev/61c8327ced50 changeset: 18699:61c8327ced50 branch: stable parent: 18697:7d66a44e87ed user: FUJIWARA Katsunori date: Mon Feb 18 00:04:28 2013 +0900 summary: bundle: treat branches created newly on the local correctly (issue3828) http://hg.intevation.org/mercurial/crew/rev/4a85ebb5c807 changeset: 18698:4a85ebb5c807 parent: 18695:ec9b9968b7f8 parent: 18697:7d66a44e87ed user: Kevin Bullock date: Fri Feb 15 21:20:24 2013 -0600 summary: merge with stable http://hg.intevation.org/mercurial/crew/rev/7d66a44e87ed changeset: 18697:7d66a44e87ed branch: stable user: Kevin Bullock date: Fri Feb 15 15:06:43 2013 -0600 summary: mergetools: refine vimdiff warning message http://hg.intevation.org/mercurial/crew/rev/f2b1f78cf202 changeset: 18696:f2b1f78cf202 branch: stable parent: 18679:f6f35d646cb5 user: Pierre-Yves David date: Fri Feb 15 11:28:04 2013 +0100 summary: mergetools: vimdiff issue a warning explaining how to abort -- Repository URL: http://hg.intevation.org/mercurial/crew From ronny.voelker at elaxy.de Thu Feb 21 08:04:43 2013 From: ronny.voelker at elaxy.de (=?iso-8859-1?Q?V=F6lker_Ronny?=) Date: Thu, 21 Feb 2013 14:04:43 +0000 Subject: [PATCH] Fix meld.args in mergetools.rc: add -o $output Message-ID: <679C86927552B447B2A1522BFC65B7E323F9B223@srv-cob-vm-0059.elaxy.org> # HG changeset patch # User Ronny Voelker # Date 1361454565 -3600 # Node ID 138968bb44d36a06393ecb82c74490914f7598bc # Parent 4921b5c2aeed8a6bb0918503f7802508538f01e5 Fix meld.args in mergetools.rc: add -o $output Without this argument meld saves the result of a merge in $base. This is a temporary file, which is ignored by Mercurial. So the result of the merge is lost. diff -r 4921b5c2aeed -r 138968bb44d3 contrib/mergetools.hgrc --- a/contrib/mergetools.hgrc Sun Feb 17 14:34:53 2013 -0600 +++ b/contrib/mergetools.hgrc Thu Feb 21 14:49:25 2013 +0100 @@ -25,7 +25,7 @@ gpyfm.gui=True meld.gui=True -meld.args=--label='local' $local --label='base' $base --label='other' $other +meld.args=--label='local' $local --label='base' $base --label='other' $other -o $output meld.diffargs=-a --label='$plabel1' $parent --label='$clabel' $child tkdiff.args=$local $other -a $base -o $output -------------- next part -------------- An HTML attachment was scrubbed... URL: From lists at durin42.com Thu Feb 21 09:44:03 2013 From: lists at durin42.com (Augie Fackler) Date: Thu, 21 Feb 2013 10:44:03 -0500 Subject: [PATCH] match: more accurately report when we're always going to match In-Reply-To: <7c4e5ad8fa43d211c2d0.1361392778@australite.thefacebook.com> References: <7c4e5ad8fa43d211c2d0.1361392778@australite.thefacebook.com> Message-ID: LGTM On Wed, Feb 20, 2013 at 3:39 PM, Bryan O'Sullivan wrote: > # HG changeset patch > # User Bryan O'Sullivan > # Date 1361392772 28800 > # Node ID 7c4e5ad8fa43d211c2d068f981b91acf350be3df > # Parent 67ee5291969274900517384d864da73c7928552e > match: more accurately report when we're always going to match > > This improves the performance of log --patch and --stat by about > 20% for moderately large manifests (e.g. mozilla-central) for the > common case of no -I/-X patterns. > > diff --git a/mercurial/match.py b/mercurial/match.py > --- a/mercurial/match.py > +++ b/mercurial/match.py > @@ -62,6 +62,7 @@ class match(object): > self._files = [] > self._anypats = bool(include or exclude) > self._ctx = ctx > + self._always = False > > if include: > pats = _normalize(include, 'glob', root, cwd, auditor) > @@ -103,6 +104,7 @@ class match(object): > m = lambda f: not em(f) > else: > m = lambda f: True > + self._always = True > > self.matchfn = m > self._fmap = set(self._files) > @@ -130,7 +132,7 @@ class match(object): > def anypats(self): > return self._anypats > def always(self): > - return False > + return self._always > > class exact(match): > def __init__(self, root, cwd, files): > @@ -139,8 +141,7 @@ class exact(match): > class always(match): > def __init__(self, root, cwd): > match.__init__(self, root, cwd, []) > - def always(self): > - return True > + self._always = True > > class narrowmatcher(match): > """Adapt a matcher to work on a subdirectory only. > @@ -175,6 +176,7 @@ class narrowmatcher(match): > self._cwd = matcher._cwd > self._path = path > self._matcher = matcher > + self._always = matcher._always > > self._files = [f[len(path) + 1:] for f in matcher._files > if f.startswith(path + "/")] > _______________________________________________ > Mercurial-devel mailing list > Mercurial-devel at selenic.com > http://selenic.com/mailman/listinfo/mercurial-devel From bos at serpentine.com Thu Feb 21 12:09:46 2013 From: bos at serpentine.com (Bryan O'Sullivan) Date: Thu, 21 Feb 2013 10:09:46 -0800 Subject: [PATCH 3 of 3] worker: handle worker failures more aggressively In-Reply-To: References: <42c14cff887e20d033db.1361298555@australite.local> <20130219222359.GA3735@findus> <20130219225923.GB3735@findus> Message-ID: On Thu, Feb 21, 2013 at 12:22 AM, Isaac Jurado wrote: > That's my point. Working with processes on Windows is going to be > different enough from the other platforms, right? > Okay, I'm confused. Are you looking for me to do something, or just passing the time? -------------- next part -------------- An HTML attachment was scrubbed... URL: From angel.ezquerra at gmail.com Thu Feb 21 12:10:48 2013 From: angel.ezquerra at gmail.com (Angel Ezquerra) Date: Thu, 21 Feb 2013 19:10:48 +0100 Subject: [PATCH] Fix meld.args in mergetools.rc: add -o $output In-Reply-To: <679C86927552B447B2A1522BFC65B7E323F9B223@srv-cob-vm-0059.elaxy.org> References: <679C86927552B447B2A1522BFC65B7E323F9B223@srv-cob-vm-0059.elaxy.org> Message-ID: On Thu, Feb 21, 2013 at 3:04 PM, V?lker Ronny wrote: > # HG changeset patch > > # User Ronny Voelker > > # Date 1361454565 -3600 > > # Node ID 138968bb44d36a06393ecb82c74490914f7598bc > > # Parent 4921b5c2aeed8a6bb0918503f7802508538f01e5 > > Fix meld.args in mergetools.rc: add -o $output > > > > Without this argument meld saves the result of a merge in $base. > > This is a temporary file, which is ignored by Mercurial. > > So the result of the merge is lost. > > > > diff -r 4921b5c2aeed -r 138968bb44d3 contrib/mergetools.hgrc > > --- a/contrib/mergetools.hgrc Sun Feb 17 14:34:53 2013 -0600 > > +++ b/contrib/mergetools.hgrc Thu Feb 21 14:49:25 2013 +0100 > > @@ -25,7 +25,7 @@ > > gpyfm.gui=True > > meld.gui=True > > -meld.args=--label='local' $local --label='base' $base --label='other' > $other > > +meld.args=--label='local' $local --label='base' $base --label='other' > $other -o $output > > meld.diffargs=-a --label='$plabel1' $parent --label='$clabel' $child > > tkdiff.args=$local $other -a $base -o $output I just tried using meld (on windows) with TortoiseHg, using the current meld configuration (i.e. without your patch). As far as I can tell it seems to work fine. The only slightly weird thing is that you must make (and save) your changes on the "local" panel. So is this really necessary? Probably I'm missing something... What I really don't like is the fact that the order of the diff panels that meld shows is: local - base - other This makes it _very_ hard to tell the difference between local and other. It would be nice if it could be turned around (i.e. base-local-other). Or better yet, it would be nice if Meld could do a proper "3-way merge" (with 4 panels) as KDiff3 does. Cheers, Angel From steve at borho.org Thu Feb 21 12:28:50 2013 From: steve at borho.org (Steve Borho) Date: Thu, 21 Feb 2013 12:28:50 -0600 Subject: [PATCH] Fix meld.args in mergetools.rc: add -o $output In-Reply-To: References: <679C86927552B447B2A1522BFC65B7E323F9B223@srv-cob-vm-0059.elaxy.org> Message-ID: On Thu, Feb 21, 2013 at 12:10 PM, Angel Ezquerra wrote: > On Thu, Feb 21, 2013 at 3:04 PM, V?lker Ronny > wrote: > > # HG changeset patch > > > > # User Ronny Voelker > > > > # Date 1361454565 -3600 > > > > # Node ID 138968bb44d36a06393ecb82c74490914f7598bc > > > > # Parent 4921b5c2aeed8a6bb0918503f7802508538f01e5 > > > > Fix meld.args in mergetools.rc: add -o $output > > > > > > > > Without this argument meld saves the result of a merge in $base. > > > > This is a temporary file, which is ignored by Mercurial. > > > > So the result of the merge is lost. > > > > > > > > diff -r 4921b5c2aeed -r 138968bb44d3 contrib/mergetools.hgrc > > > > --- a/contrib/mergetools.hgrc Sun Feb 17 14:34:53 2013 -0600 > > > > +++ b/contrib/mergetools.hgrc Thu Feb 21 14:49:25 2013 > +0100 > > > > @@ -25,7 +25,7 @@ > > > > gpyfm.gui=True > > > > meld.gui=True > > > > -meld.args=--label='local' $local --label='base' $base --label='other' > > $other > > > > +meld.args=--label='local' $local --label='base' $base --label='other' > > $other -o $output > > > > meld.diffargs=-a --label='$plabel1' $parent --label='$clabel' $child > > > > tkdiff.args=$local $other -a $base -o $output > > I just tried using meld (on windows) with TortoiseHg, using the > current meld configuration (i.e. without your patch). As far as I can > tell it seems to work fine. The only slightly weird thing is that you > must make (and save) your changes on the "local" panel. > > So is this really necessary? Probably I'm missing something... > > What I really don't like is the fact that the order of the diff panels > that meld shows is: > > local - base - other > > This makes it _very_ hard to tell the difference between local and > other. It would be nice if it could be turned around (i.e. > base-local-other). Or better yet, it would be nice if Meld could do a > proper "3-way merge" (with 4 panels) as KDiff3 does. > The Meld model is a lot closer to Araxis Merge than to KDiff3. The way I would prefer for it to work would be for the center pane to be named "merged" and for the trivial changes from both local and other to be pre-applied to the merge pane. As it is you have to do the trivial merges manually. -- Steve Borho -------------- next part -------------- An HTML attachment was scrubbed... URL: From hgbuildbot at kublai.com Thu Feb 21 14:59:54 2013 From: hgbuildbot at kublai.com (hgbuildbot at kublai.com) Date: Thu, 21 Feb 2013 12:59:54 -0800 Subject: buildbot success in Mercurial on hg tests Message-ID: <20130221205955.33285203D4@hgbuildbot.cs.ubc.ca> The Buildbot has detected a restored build on builder hg tests while building hg. Full details are available at: http://hgbuildbot.kublai.com/builders/hg%20tests/builds/509 Buildbot URL: http://hgbuildbot.kublai.com/ Buildslave for this Build: p64.osuosl.test Build Reason: scheduler Build Source Stamp: [branch default] e3ddb406875790a390e6aa9b2492d62c68bfcd39 Blamelist: Kevin Bullock Build succeeded! sincerely, -The Buildbot From snidely.too at gmail.com Thu Feb 21 15:15:46 2013 From: snidely.too at gmail.com (Dave S) Date: Thu, 21 Feb 2013 13:15:46 -0800 Subject: [PATCH 0 of 9] Move and refactor bundling logic In-Reply-To: References: Message-ID: On Thu, Feb 14, 2013 at 11:40 AM, Sune Foldager wrote: > Benoit and I worked on this at the sprint, following the bundle format 2 > discussion. >From your post, Angel's, and others, it looks like quite a bit got done at the sprint. Has anyone put together a blog or summary of all the excitment? (Any pictures of guilty parties?) /dps -- test signature -- please apply at front gate on Tuesdays only. From bos at serpentine.com Thu Feb 21 15:33:01 2013 From: bos at serpentine.com (Bryan O'Sullivan) Date: Thu, 21 Feb 2013 13:33:01 -0800 Subject: [PATCH 1 of 2] util: generalize bytecount to unitcount Message-ID: <19d3300883ce1407d0b5.1361482381@australite.local> # HG changeset patch # User Bryan O'Sullivan # Date 1361482359 28800 # Node ID 19d3300883ce1407d0b527549a82f25d3f182873 # Parent 5779b305bf3a9192823252b8caf2240124238706 util: generalize bytecount to unitcount This gives us a function we can reuse to count units of other kinds. diff --git a/mercurial/util.py b/mercurial/util.py --- a/mercurial/util.py +++ b/mercurial/util.py @@ -1268,7 +1268,18 @@ def ellipsis(text, maxlength=400): except (UnicodeDecodeError, UnicodeEncodeError): return _ellipsis(text, maxlength)[0] -_byteunits = ( +def unitcount(*unittable): + '''return a count of some quantity formatted as a readable string''' + + def go(count): + for multiplier, divisor, format in unittable: + if count >= divisor * multiplier: + return format % (count / float(divisor)) + return unittable[-1][2] % count + + return go + +bytecount = unitcount( (100, 1 << 30, _('%.0f GB')), (10, 1 << 30, _('%.1f GB')), (1, 1 << 30, _('%.2f GB')), @@ -1281,14 +1292,6 @@ def ellipsis(text, maxlength=400): (1, 1, _('%.0f bytes')), ) -def bytecount(nbytes): - '''return byte count formatted as readable string, with units''' - - for multiplier, divisor, format in _byteunits: - if nbytes >= divisor * multiplier: - return format % (nbytes / float(divisor)) - return _byteunits[-1][2] % nbytes - def uirepr(s): # Avoid double backslash in Windows path repr() return repr(s).replace('\\\\', '\\') From bos at serpentine.com Thu Feb 21 15:33:02 2013 From: bos at serpentine.com (Bryan O'Sullivan) Date: Thu, 21 Feb 2013 13:33:02 -0800 Subject: [PATCH 2 of 2] util: add a timed function for use during development In-Reply-To: <19d3300883ce1407d0b5.1361482381@australite.local> References: <19d3300883ce1407d0b5.1361482381@australite.local> Message-ID: <95cb8d7754a7a28f52f8.1361482382@australite.local> # HG changeset patch # User Bryan O'Sullivan # Date 1361482360 28800 # Node ID 95cb8d7754a7a28f52f82a332bf1163eb6dea202 # Parent 19d3300883ce1407d0b527549a82f25d3f182873 util: add a timed function for use during development I often want to measure the cost of a function call before/after an optimization, where using top level "hg --time" timing introduces enough other noise that I can't tell if my efforts are having an effect. This decorator allows a developer to measure a function's cost with finer granularity. diff --git a/mercurial/util.py b/mercurial/util.py --- a/mercurial/util.py +++ b/mercurial/util.py @@ -1872,3 +1872,45 @@ def isatty(fd): return fd.isatty() except AttributeError: return False + +timecount = unitcount( + (1, 1e3, _('%.0f s')), + (100, 1, _('%.1f s')), + (10, 1, _('%.2f s')), + (1, 1, _('%.3f s')), + (100, 1e-3, _('%.1f ms')), + (10, 1e-3, _('%.2f ms')), + (1, 1e-3, _('%.3f ms')), + (100, 1e-6, _('%.1f us')), + (10, 1e-6, _('%.2f us')), + (1, 1e-6, _('%.3f us')), + (100, 1e-9, _('%.1f ns')), + (10, 1e-9, _('%.2f ns')), + (1, 1e-9, _('%.3f ns')), + ) + +_timenesting = [0] + +def timed(func): + '''Report the execution time of a function call to stderr. + + During development, use as a decorator when you need to measure + the cost of a function, e.g. as follows: + + @util.timed + def foo(a, b, c): + pass + ''' + + def wrapper(*args, **kwargs): + start = time.time() + _timenesting[0] += 2 + try: + return func(*args, **kwargs) + finally: + elapsed = time.time() - start + _timenesting[0] -= 2 + sys.stderr.write('%s%s: %s\n' % + (' ' * _timenesting[0], func.__name__, + timecount(elapsed))) + return wrapper From bos at serpentine.com Thu Feb 21 15:45:54 2013 From: bos at serpentine.com (Bryan O'Sullivan) Date: Thu, 21 Feb 2013 13:45:54 -0800 Subject: [PATCH] localrepo: iterate over manifest key/value pairs in status Message-ID: <8fa59ad66baa06631baf.1361483154@australite.local> # HG changeset patch # User Bryan O'Sullivan # Date 1361483151 28800 # Node ID 8fa59ad66baa06631baf4b6c3eb2ec8c5d85786d # Parent 95cb8d7754a7a28f52f82a332bf1163eb6dea202 localrepo: iterate over manifest key/value pairs in status This saves us a couple of dict lookups in the common case, and improves the performance of the status method by 5% (measured with util.timed) in a repo with a large manifest. diff --git a/mercurial/localrepo.py b/mercurial/localrepo.py --- a/mercurial/localrepo.py +++ b/mercurial/localrepo.py @@ -1532,12 +1532,12 @@ class localrepository(object): modified, added, clean = [], [], [] withflags = mf1.withflags() | mf2.withflags() - for fn in mf2: + for fn, mf2node in mf2.iteritems(): if fn in mf1: if (fn not in deleted and ((fn in withflags and mf1.flags(fn) != mf2.flags(fn)) or - (mf1[fn] != mf2[fn] and - (mf2[fn] or ctx1[fn].cmp(ctx2[fn]))))): + (mf1[fn] != mf2node and + (mf2node or ctx1[fn].cmp(ctx2[fn]))))): modified.append(fn) elif listclean: clean.append(fn) From diptongo at gmail.com Thu Feb 21 15:58:48 2013 From: diptongo at gmail.com (Isaac Jurado) Date: Thu, 21 Feb 2013 22:58:48 +0100 Subject: [PATCH 3 of 3] worker: handle worker failures more aggressively In-Reply-To: References: <42c14cff887e20d033db.1361298555@australite.local> <20130219222359.GA3735@findus> <20130219225923.GB3735@findus> Message-ID: <20130221215848.GA3680@findus> Replying Bryan O'Sullivan: > On Thu, Feb 21, 2013 at 12:22 AM, Isaac Jurado wrote: > >> That's my point. Working with processes on Windows is going to be >> different enough from the other platforms, right? > > Okay, I'm confused. Are you looking for me to do something, or just > passing the time? Last time I reply on this, I promise. Let me summarize what, from my point of view, has happened. - You submitted a patch that uses a monitor thread on the parent process in order to detect a children failure early and finish the rest of the children. - I suggested to leave that task to the children processes by putting all of them in the same process group and "broadcasting" a signal on failure. Which could circumvent the need for threading the parent process. - You replied that process groups are Unix only and you wanted to maximize code portability. - I was confused, since os.fork() and atomic writes to pipes are also Unix only (POSIX in particular). So I tried to ask for a better explanation, as politely as possible. Specially since mailing list discussions tend to heat up very quickly and, between you and me, you are the authority. I don't want any trouble. - After a pair of replies, you told me, more or less, that Windows is a whole different story. Statement that I found very contradictory from the first argument rejecting the use of process groups. Therefore, when, in theroy, I was trying to understand the resasonings behind some design decisions, in practice I was unwillingly passing the time. As I said, there's no point in taking this discussion further. Whatever you write will be fine, even if apparently contradictory and if I have any complaint, I'll send a patch. Sorry for the confusion. Best regards. -- Isaac Jurado "The noblest pleasure is the joy of understanding." Leonardo da Vinci From bos at serpentine.com Thu Feb 21 16:05:58 2013 From: bos at serpentine.com (Bryan O'Sullivan) Date: Thu, 21 Feb 2013 14:05:58 -0800 Subject: [PATCH 3 of 3] worker: handle worker failures more aggressively In-Reply-To: <20130221215848.GA3680@findus> References: <42c14cff887e20d033db.1361298555@australite.local> <20130219222359.GA3735@findus> <20130219225923.GB3735@findus> <20130221215848.GA3680@findus> Message-ID: On Thu, Feb 21, 2013 at 1:58 PM, Isaac Jurado wrote: > - I was confused, since os.fork() and atomic writes to pipes are also > Unix only (POSIX in particular). I see. Thanks for explaining what you were looking for. So, insofar as there's a Windows plan (and my hope is that someone else will pick up the baton there and figure it out), it is not very interesting yet: when developing the Windows code, refactor the process startup code in the worker module so that the Unix-specific stuff is more self-contained. I didn't do that early on because I don't have Windows code sitting around to suggest what shape the portability stuff should have. That's all. The process killing code is already portable as far as I can tell, so based on my current understanding, it can stay as it is. By the way, I think that small writes to pipes may possibly be atomic on Windows, although the WriteFile documentation doesn't state this clearly anywhere. -------------- next part -------------- An HTML attachment was scrubbed... URL: From hgbuildbot at kublai.com Thu Feb 21 16:51:54 2013 From: hgbuildbot at kublai.com (hgbuildbot at kublai.com) Date: Thu, 21 Feb 2013 14:51:54 -0800 Subject: buildbot failure in Mercurial on hg tests Message-ID: <20130221225154.C5C58254DF@hgbuildbot.cs.ubc.ca> The Buildbot has detected a new failure on builder hg tests while building hg. Full details are available at: http://hgbuildbot.kublai.com/builders/hg%20tests/builds/510 Buildbot URL: http://hgbuildbot.kublai.com/ Buildslave for this Build: p64.osuosl.test Build Reason: scheduler Build Source Stamp: [branch default] 8728579f6bdc794723dd452c704b96012c7fec20 Blamelist: Bryan O'Sullivan BUILD FAILED: failed http2 sincerely, -The Buildbot From angel.ezquerra at gmail.com Fri Feb 22 00:28:44 2013 From: angel.ezquerra at gmail.com (Angel Ezquerra) Date: Fri, 22 Feb 2013 07:28:44 +0100 Subject: [PATCH 1 of 3] pull: add --subrepos flag In-Reply-To: <5125A8BA.8020106@yahoo.com> References: <5125A8BA.8020106@yahoo.com> Message-ID: On Thu, Feb 21, 2013 at 5:55 AM, Matt Harbison wrote: > Angel Ezquerra wrote: >> >> On Wed, Feb 20, 2013 at 6:57 AM, Matt >> Harbison wrote: >>> >>> On Sun, 17 Feb 2013 13:19:16 +0100, Angel Ezquerra wrote: >>> >>>> # HG changeset patch # User Angel >>>> Ezquerra # Date 1360519226 -3600 # Node >>>> ID abbd26cca35280fb8f784b3f2c02eef71696c47b # Parent >>>> 55b9b294b7544a6a144f627f71f4b770907d5a98 pull: add --subrepos >>>> flag >>>> >>>> The purpose of this new flag is to ensure that you are able to >>>> update to any incoming revision without requiring any network >>>> access. The idea is to make sure that the repository is >>>> self-contained after doing hg pull --subrepos, as long as it >>>> already was self-contained before the pull). >>>> >>>> When the --subrepos flag is enabled, pull will also pull (or >>>> clone) all subrepos that are present on the current revision and >>>> those that are referenced by any of the incoming revisions. >>> >>> I haven't gotten a chance to really play with this yet, so I'm >>> going more off the comments here- I apologize if these answers >>> should be obvious, but I'm not familiar enough with some of the >>> code. >>> >>> - Is there an easy way to tell if the repo is/was self contained? >>> (Maybe incoming -S?) >> >> >> No there is not. I don't think incoming -S would do the trick since >> that would just tell you if there are _new_ incoming revisions on >> some of the _current_ subrepos. A repo is "self-contained" if it is >> possible to update to any of its revisions withing requiring a pull >> of one or more of its subrepos. >> >> I don't know of any existing mercurial command that would be able to >> give you that information. >> >>> - Is the 'self-contained' bit to limit overhead on each pull, or is >>> there another reason this can't ensure the result is self >>> contained? 'Push' and 'outgoing -S' recognize (almost) everything >>> going in the other direction, so it might be nice to have the same >>> capability with a form of pull. (I may have found a push bug that >>> I haven't gotten back to yet.) >> >> >> I'm not sure I understand what you mean. > > > Consider this (contrived) case: > > 1) push a repo and subrepo to remote (remote is now self contained) > 2) strip or rollback the remote subrepo > 3) a top level local repo push will repopulate the remote subrepo > > Now reverse it: > > 1) pull a repo and subrepo from remote (local is self contained) > 2) strip or rollback the local subrepo > 3) nothing is incoming top level, so the subrepo isn't repopulated (if > you've updated to a working dir without that subrepo). > > I'm not sure if there's a less contrived case, or if this matters too > much. I guess I was just wondering aloud about the symmetry between > push and pull -S (this is certainly much better than it was). I don't think this is a very big deal because "pull --subrepos" also performs a pull on all the repositories that are found on the current revision. I think this would fix your contrived case. The only corner case that would not be properly handled by this would be the case in which pull --subrepos cloned a _new_ subrepo that is not found on the current revision (i.e. that is introduced on one of the cloned revisions) and then you striped some revisions from that "future subrepo". In that case would would still be able to get the missing revisions as you would do today, i.e. by updating to the offending revision. You could also use the onsub extension (which is shipped with TortoiseHg). BTW, the more I use the onsub extension the more I am convinced that it should be distributed with mercurial, and even that the onsub command itself should become a built-in command. That being said, if we did want to also handle this very small corner case there are at least a couple of possible solutions: 1. make the --subrepos flag take a revset that would tell it which revisions to look for subrepos to pull. 2. make --subrepos also look for subrepos on the descendants of the current revision. #1 would be nice _if_ we could also skip the revset to get the behavior that the current patch proposes. However I don't think that is possible to have a flag that can optionally take a parameter. #2... maybe that is too much overhead for such a small corner case? Additionally, I wonder if it would make sense to change the current pull behavior a little, by checking if any of the subrepos that are present on the _current_ parent revision point to a revision that does not exist, and if that is the case fulling from them _up to that revision_? I think the parent pull time is an excellent time to do this kind of stuff since you already know that you have an internet connection... > I realize you can't do such a thing without crawling most of the > history. Are there large public repositories that use subrepos? I'm > wondering what the performance hit would be. (It's easy for me to think > something is a good idea when I only have small repos and wouldn't > notice the hit.) We have repositories with thousands of files and more than 20 subrepos. I don't know if you would consider that big... > FWIW, largefiles works the same way- if you don't clone or pull with > --all-largefiles, there's no single command to go back and get the files > for all revisions that are not incoming. That leaves the user wondering > if they really can disconnect from the central repo. That is true. It would be nice to be able to do that. However there is a difference between largefiles and subrepos. Largefiles tries to only get the files that you need, when you need them _by design_. Subrepos is not meant (IMHO) to do that (or at least it is not necessary for subrepos to fulfill its main purpose, which is to track "submodules"). >> I don't think you (we?) must give too much importance to this >> "self-contained" concept. It is just a way for me to explain the >> purpose of the patch, and specially to explain why we must look for >> subrepos on all the new incoming revisions, and why we cannot just >> limit ourselves to pulling the subrepos on the current revisions >> (short answer: because new subrepos may appear on the new, incoming >> revisions). >> >> My patch explicitly says that hg pull -S will only make your subrepo >> self-contained if it was already self-contained before. This is in >> order to avoid having to look for subrepos on all the repo history, >> rather than just looking for subrepos on the incoming revision (and >> the current one). >> >>> - The full subrepo gets pulled, even revs not committed to the >>> parent? I think that's a good thing, because regularly get burned >>> when I 'pull -u' the tree to another machine and then go to apply >>> the rest of a patch queue to the subrepo. >> >> >> Yes. It is perhaps not optimal but I think it is simpler. In >> addition if different parent repo revisions point to different >> revisions on a subrepo there is no way for us to tell which of those >> subrepo revisions is the one that is closes to tip, or which ones >> are ancestors of the other ones, etc. As a result we would need to >> perform as many pulls on a given repo as the number of different >> revisions of that subrepo that were referenced on the parent repo. >> That is complex and slow, so it is much simpler and possibly faster >> (in some cases at least) to just pull all revisions from each >> subrepo. > > > OK, I misread the code- I thought each subrepo was getting a pull at > each revision, which I figured would be slow. I attached a test patch > below- there's nothing special about it, but it helped me with my pull > and outgoing changes (some comments probably still reflect this), so I > changed that to pull and incoming to test your patch. > > - I think I see a double pull of a subrepo (search for "hg pull -S -r 3"). You are right. There is a problem with the current version of the patch. It will clone the same repo multiple times if the same subrepo refers to different revisions. I will resend with a fix. BTW, where do you think the tests for this new feature should go? Should it go into one of the test-pull*.t files or in one of the test-subrepo*.t files? Do you think the test that you propose in that patch would be enough to test this new feature? Maybe it could be made a bit simpler? > - I wonder if the code in this patch can be leveraged to make incoming > print all of the stuff 'pull -S' will grab in the future. In theory that would be certainly possible. At least we could run the same "look for subrepos to pull" code and show the list of subrepos that would be pulled and then run incoming on them. The main problem is that incoming already has a --subrepos flag, which does something slightly different... I'm not sure that could be changed... >>> I'll try to experiment with this some in the next few days. I ran >>> into issues with what I'm working on (push, outgoing) with deeply >>> nested subrepos, and also when a parent locks in an earlier subrepo >>> version. I wonder if deeply nested subrepos will be a problem here >>> since hgsubrepo.pull() doesn't walk its subrepos and pull them. >> >> >> I must confess that I have not tried that too much. We should >> definitely do this recursively. That being said I hope to get some >> feedback on the current version that I sent to the list first. > > > Sorry, I got crossed up on that too. hgsubrepo.pull() ends up calling > _repo.pull(), so it does recurse. You are right. That's nice! :-) > The test below indicates that clone won't > recurse- it reminds that an update is needed. (Maybe clone needs a -S too > as part of these changes? If you aren't walking the history, I > don't see a way around that because nothing is incoming after a clone, > so you won't see subrepos of a cloned subrepo.) I guess that would make sense in another patch. > The other thing worth a test is largefiles- the --all-largefiles > option isn't passed to subrepos, so as it stands, 'pull -S' won't let > you really disconnect, because largefiles in subrepos won't be cached. That > can be fixed later. I agree. We do not really use largefiles (yet) so we have not come across this (yet) but I'm sure this is something we would like to improve as well. One last thing, did you have time to have a look at the code of the patch series itself? I plan to send an slighly changed version of the patch series that will only change the first patch to fix the issue you found (the fix is minimal so the code should be almost the same). Do you have any comments? Thanks for looking into this. Angel From ronny.voelker at elaxy.de Fri Feb 22 04:19:32 2013 From: ronny.voelker at elaxy.de (=?iso-8859-1?Q?V=F6lker_Ronny?=) Date: Fri, 22 Feb 2013 10:19:32 +0000 Subject: [PATCH] Fix meld.args in mergetools.rc: add -o $output Message-ID: <679C86927552B447B2A1522BFC65B7E323FA0570@srv-cob-vm-0060.elaxy.org> Angel Ezquerra wrote: >I just tried using meld (on windows) with TortoiseHg, using the >current meld configuration (i.e. without your patch). As far as I can >tell it seems to work fine. The only slightly weird thing is that you >must make (and save) your changes on the "local" panel. > >So is this really necessary? Probably I'm missing something... > >What I really don't like is the fact that the order of the diff panels >that meld shows is: > >local - base - other > >This makes it _very_ hard to tell the difference between local and >other. It would be nice if it could be turned around (i.e. >base-local-other). Or better yet, it would be nice if Meld could do a >proper "3-way merge" (with 4 panels) as KDiff3 does. > Steve Borho wrote: >The Meld model is a lot closer to Araxis Merge than to KDiff3. > I agree with Steve. It looks closer to Araxis Merge, where the middle pane contains the base version and is at the same time the target of merge operations. The 'Merge mode'-example on http://meldmerge.org/features.html supports this view. >The way I would prefer for it to work would be for the center pane to be named "merged" and for the trivial changes from both local and other to be pre-applied to the >merge pane. As it is you have to do the trivial merges manually. I'm using Meld 1.5.3 on Ubuntu12.04. It has a menu item Changes->Merge all non-conflicting, which does what you want. I found no way to trigger this behavior automatically at startup. Maybe the latest version has an option to do this. Renaming the middle pane may be a good idea, but I think it should be consistent across all merge tools with the same model. Maybe the order of the panes should be consistent too (the order for Meld is local-base-other, the order for Araxis Merge is other-base-local ). Anyway, I think that's another change. Ronny From gilles.moris at free.fr Fri Feb 22 04:22:07 2013 From: gilles.moris at free.fr (Gilles Moris) Date: Fri, 22 Feb 2013 11:22:07 +0100 Subject: [PATCH RFC] update: add an option to allow to merge local changes when crossing branches Message-ID: <567106adefd309717d8f.1361528527@fc8> # HG changeset patch # User Gilles Moris # Date 1361528509 -3600 # Node ID 567106adefd309717d8f0538197dc7dde45d34f1 # Parent 013fcd112f13f31a35ea6a40d8cd1c6923cdaf20 update: add an option to allow to merge local changes when crossing branches *NOT READY FOR INCLUSION* Normally, it is not possible to update to another branch with local changes. One have to use "hg update --clean" to discard changes and force the update. One workaround is to update to the common ancestor of the branches, and then to the other branch. This workaround is not well known by users. I introduce an update --merge option that enables to rebase the local changes in one step. However, I have still some questions about how to design it: I/ option naming * I used --merge as it seems pretty but though could be confused with changesets merge * --rebase could be used, may be ,ore accurate, but IMO too tied to the rebase extension * --crossbranches would not be a good idea, as we probably don't want to allow crossing branches if a revision is not explicitely provided, whether there are some local changes or not * other possibilities: --reseat, --move, ... * last possibility: no option, allow by default to merge local changes, we've got --check if we want to block. By the way, this would greatly simplify both the code and the help content. The help content is currently partially lying: "If the changeset is not a descendant or ancestor of the working directory's parent, the update is aborted." Was true before, but since many releases we allow to cross branch for clean working directory and an explicit release. "-c --check update across branches if no uncommitted changes" Again wrong, this option aborts on any dirty working dir, whether we cross branches or not. So no option might be more consistent with the evolution of the CLI. II/ options conflict handling If we add a new option, we need it to have it mutually exclusive with --clean or --check options. Do we want --merge be overridden by --check and --clean, so that a user could habe --merge as an alias default? III/ internal API changes I choose the least impacting API change, since I am expecting many extensions to use those API hg.updaterepo() and merge.update(), even if we are not bound to keep internal APIs. subrepos and largefiles are clients for instance. Is the approach OK? IV/ help and tests will need to be updated once design choices are done. diff -r 013fcd112f13 -r 567106adefd3 mercurial/commands.py --- a/mercurial/commands.py Sat Feb 09 11:00:42 2013 +0100 +++ b/mercurial/commands.py Fri Feb 22 11:21:49 2013 +0100 @@ -5906,10 +5906,13 @@ [('C', 'clean', None, _('discard uncommitted changes (no backup)')), ('c', 'check', None, _('update across branches if no uncommitted changes')), + ('m', 'merge', None, + _('merge local changes when updating to another branch')), ('d', 'date', '', _('tipmost revision matching date'), _('DATE')), ('r', 'rev', '', _('revision'), _('REV'))], _('[-c] [-C] [-d DATE] [[-r] REV]')) -def update(ui, repo, node=None, rev=None, clean=False, date=None, check=False): +def update(ui, repo, node=None, rev=None, clean=False, date=None, check=False, + merge=False): """update working directory (or switch revisions) Update the repository's working directory to the specified @@ -5998,7 +6001,7 @@ if clean: ret = hg.clean(repo, rev) else: - ret = hg.update(repo, rev) + ret = hg.update(repo, rev, merge) if not ret and movemarkfrom: if bookmarks.update(repo, [movemarkfrom], repo['.'].node()): diff -r 013fcd112f13 -r 567106adefd3 mercurial/hg.py --- a/mercurial/hg.py Sat Feb 09 11:00:42 2013 +0100 +++ b/mercurial/hg.py Fri Feb 22 11:21:49 2013 +0100 @@ -449,17 +449,17 @@ repo.ui.status(_("%d files updated, %d files merged, " "%d files removed, %d files unresolved\n") % stats) -def updaterepo(repo, node, overwrite): +def updaterepo(repo, node, overwrite, merge=False): """Update the working directory to node. When overwrite is set, changes are clobbered, merged else returns stats (see pydoc mercurial.merge.applyupdates)""" - return mergemod.update(repo, node, False, overwrite, None) + return mergemod.update(repo, node, False, overwrite, None, wdmerge=merge) -def update(repo, node): +def update(repo, node, merge=False): """update the working directory to node, merging linear changes""" - stats = updaterepo(repo, node, False) + stats = updaterepo(repo, node, False, merge) _showstats(repo, stats) if stats[3]: repo.ui.status(_("use 'hg resolve' to retry unresolved file merges\n")) diff -r 013fcd112f13 -r 567106adefd3 mercurial/merge.py --- a/mercurial/merge.py Sat Feb 09 11:00:42 2013 +0100 +++ b/mercurial/merge.py Fri Feb 22 11:21:49 2013 +0100 @@ -545,7 +545,7 @@ repo.dirstate.drop(f) def update(repo, node, branchmerge, force, partial, ancestor=None, - mergeancestor=False): + mergeancestor=False, wdmerge=False): """ Perform a merge between the working directory and the given node @@ -557,6 +557,7 @@ is only allowed between different named branches. This flag is used by rebase extension as a temporary fix and should be avoided in general. + wdmerge = allow update to rebase local changes across branches The table below shows all the behaviors of the update command given the -c and -C or no options, whether the working directory @@ -633,11 +634,13 @@ if pa == p1 or pa == p2: # linear pass # all good elif wc.dirty(missing=True): - raise util.Abort(_("crosses branches (merge branches or use" - " --clean to discard changes)")) + if not wdmerge: + raise util.Abort(_("crosses branches (merge branches or " + "use --merge to rebase your changes)")) + pa = p1 elif onode is None: raise util.Abort(_("crosses branches (merge branches or update" - " --check to force update)")) + " --merge to force update)")) else: # Allow jumping branches if clean and specific rev given pa = p1 From hg at intevation.org Fri Feb 22 06:00:08 2013 From: hg at intevation.org (Mercurial Commits) Date: Fri, 22 Feb 2013 13:00:08 +0100 Subject: mercurial/crew@18711: 14 outgoing changesets (3 stable) Message-ID: <1361534408.270247.28354.nullmailer@hg.intevation.org> 14 outgoing changesets (3 stable) in mercurial/crew: http://hg.intevation.org/mercurial/crew/rev/8728579f6bdc changeset: 18711:8728579f6bdc bookmark: @ tag: tip user: Bryan O'Sullivan date: Thu Feb 21 12:55:39 2013 -0800 summary: match: more accurately report when we're always going to match http://hg.intevation.org/mercurial/crew/rev/e3ddb4068757 changeset: 18710:e3ddb4068757 user: Kevin Bullock date: Thu Feb 21 13:16:02 2013 -0600 summary: scmutil: fix NameError on windows http://hg.intevation.org/mercurial/crew/rev/6b786dc88612 changeset: 18709:6b786dc88612 user: Bryan O'Sullivan date: Wed Feb 20 11:31:41 2013 -0800 summary: commands: exit from the log loop at the right time http://hg.intevation.org/mercurial/crew/rev/49ef9d0ca815 changeset: 18708:49ef9d0ca815 user: Bryan O'Sullivan date: Wed Feb 20 11:31:38 2013 -0800 summary: cmdutil: use a small initial window with --limit http://hg.intevation.org/mercurial/crew/rev/9955fc5ee24b changeset: 18707:9955fc5ee24b user: Bryan O'Sullivan date: Wed Feb 20 11:31:34 2013 -0800 summary: worker: handle worker failures more aggressively http://hg.intevation.org/mercurial/crew/rev/86524a70c0f6 changeset: 18706:86524a70c0f6 user: Bryan O'Sullivan date: Wed Feb 20 11:31:31 2013 -0800 summary: worker: fix a race in SIGINT handling http://hg.intevation.org/mercurial/crew/rev/d1a2b086d058 changeset: 18705:d1a2b086d058 user: Bryan O'Sullivan date: Wed Feb 20 11:31:27 2013 -0800 summary: worker: on error, exit similarly to the first failing worker http://hg.intevation.org/mercurial/crew/rev/f17680992123 changeset: 18704:f17680992123 parent: 18703:a8204cef4c5a parent: 18699:61c8327ced50 user: Kevin Bullock date: Tue Feb 19 13:35:39 2013 -0600 summary: merge with stable http://hg.intevation.org/mercurial/crew/rev/a8204cef4c5a changeset: 18703:a8204cef4c5a parent: 18702:4921b5c2aeed parent: 18700:d69585a5c5c0 user: Kevin Bullock date: Tue Feb 19 13:35:25 2013 -0600 summary: merge with main http://hg.intevation.org/mercurial/crew/rev/d69585a5c5c0 changeset: 18700:d69585a5c5c0 parent: 18698:4a85ebb5c807 user: Na'Tosha Bard date: Sat Feb 09 21:07:42 2013 +0000 summary: largefiles: don't cache largefiles for pulled heads by default http://hg.intevation.org/mercurial/crew/rev/61c8327ced50 changeset: 18699:61c8327ced50 branch: stable parent: 18697:7d66a44e87ed user: FUJIWARA Katsunori date: Mon Feb 18 00:04:28 2013 +0900 summary: bundle: treat branches created newly on the local correctly (issue3828) http://hg.intevation.org/mercurial/crew/rev/4a85ebb5c807 changeset: 18698:4a85ebb5c807 parent: 18695:ec9b9968b7f8 parent: 18697:7d66a44e87ed user: Kevin Bullock date: Fri Feb 15 21:20:24 2013 -0600 summary: merge with stable http://hg.intevation.org/mercurial/crew/rev/7d66a44e87ed changeset: 18697:7d66a44e87ed branch: stable user: Kevin Bullock date: Fri Feb 15 15:06:43 2013 -0600 summary: mergetools: refine vimdiff warning message http://hg.intevation.org/mercurial/crew/rev/f2b1f78cf202 changeset: 18696:f2b1f78cf202 branch: stable parent: 18679:f6f35d646cb5 user: Pierre-Yves David date: Fri Feb 15 11:28:04 2013 +0100 summary: mergetools: vimdiff issue a warning explaining how to abort -- Repository URL: http://hg.intevation.org/mercurial/crew From angel.ezquerra at gmail.com Fri Feb 22 06:25:21 2013 From: angel.ezquerra at gmail.com (Angel Ezquerra) Date: Fri, 22 Feb 2013 13:25:21 +0100 Subject: [PATCH] Fix meld.args in mergetools.rc: add -o $output In-Reply-To: <679C86927552B447B2A1522BFC65B7E323FA0570@srv-cob-vm-0060.elaxy.org> References: <679C86927552B447B2A1522BFC65B7E323FA0570@srv-cob-vm-0060.elaxy.org> Message-ID: On Fri, Feb 22, 2013 at 11:19 AM, V?lker Ronny wrote: > > Angel Ezquerra wrote: > >>I just tried using meld (on windows) with TortoiseHg, using the >>current meld configuration (i.e. without your patch). As far as I can >>tell it seems to work fine. The only slightly weird thing is that you >>must make (and save) your changes on the "local" panel. >> >>So is this really necessary? Probably I'm missing something... >> >>What I really don't like is the fact that the order of the diff panels >>that meld shows is: >> >>local - base - other >> >>This makes it _very_ hard to tell the difference between local and >>other. It would be nice if it could be turned around (i.e. >>base-local-other). Or better yet, it would be nice if Meld could do a >>proper "3-way merge" (with 4 panels) as KDiff3 does. >> > > Steve Borho wrote: >>The Meld model is a lot closer to Araxis Merge than to KDiff3. >> > > I agree with Steve. It looks closer to Araxis Merge, where the middle pane contains the base version and is at the same time the target of merge operations. > The 'Merge mode'-example on http://meldmerge.org/features.html supports this view. > >>The way I would prefer for it to work would be for the center pane to be named "merged" and for the trivial changes from both local and other to be pre-applied to the >merge pane. As it is you have to do the trivial merges manually. I agree with Steve. If the center panel is where the merge must happen, it should be named something other than base, which means a different thing, and it should contain the results of the merge. > I'm using Meld 1.5.3 on Ubuntu12.04. It has a menu item Changes->Merge all non-conflicting, which does what you want. I found no way to trigger this behavior automatically at startup. Maybe the latest version has an option to do this. I just checked the meld -h output and it does not seem to be a new option for that. I could bring it up on the meld mailing list. > Renaming the middle pane may be a good idea, but I think it should be consistent across all merge tools with the same model. > Maybe the order of the panes should be consistent too (the order for Meld is local-base-other, the order for Araxis Merge is other-base-local ). > Anyway, I think that's another change. I still do not understand why you need to use -o. On my brief tests the current configuration seems to work fine. Cheers, Angel From angel.ezquerra at gmail.com Fri Feb 22 06:26:29 2013 From: angel.ezquerra at gmail.com (Angel Ezquerra) Date: Fri, 22 Feb 2013 13:26:29 +0100 Subject: [PATCH RFC] update: add an option to allow to merge local changes when crossing branches In-Reply-To: <567106adefd309717d8f.1361528527@fc8> References: <567106adefd309717d8f.1361528527@fc8> Message-ID: On Fri, Feb 22, 2013 at 11:22 AM, Gilles Moris wrote: > # HG changeset patch > # User Gilles Moris > # Date 1361528509 -3600 > # Node ID 567106adefd309717d8f0538197dc7dde45d34f1 > # Parent 013fcd112f13f31a35ea6a40d8cd1c6923cdaf20 > update: add an option to allow to merge local changes when crossing branches > > *NOT READY FOR INCLUSION* > > Normally, it is not possible to update to another branch with local changes. > One have to use "hg update --clean" to discard changes and force the update. > One workaround is to update to the common ancestor of the branches, and then > to the other branch. This workaround is not well known by users. > > I introduce an update --merge option that enables to rebase the local changes > in one step. > > However, I have still some questions about how to design it: > I/ option naming > * I used --merge as it seems pretty but though could be confused with > changesets merge > * --rebase could be used, may be ,ore accurate, but IMO too tied to the rebase > extension > * --crossbranches would not be a good idea, as we probably don't want to allow > crossing branches if a revision is not explicitely provided, whether there > are some local changes or not > * other possibilities: --reseat, --move, ... > * last possibility: no option, allow by default to merge local changes, we've > got --check if we want to block. By the way, this would greatly simplify both > the code and the help content. The help content is currently partially lying: > "If the changeset is not a descendant or ancestor of the working > directory's parent, the update is aborted." > Was true before, but since many releases we allow to cross branch for clean > working directory and an explicit release. > "-c --check update across branches if no uncommitted changes" > Again wrong, this option aborts on any dirty working dir, whether we cross > branches or not. > So no option might be more consistent with the evolution of the CLI. What about --force? It would let you do an update where the regular update would not let you... Cheers, Angel From ronny.voelker at elaxy.de Fri Feb 22 07:06:25 2013 From: ronny.voelker at elaxy.de (=?iso-8859-1?Q?V=F6lker_Ronny?=) Date: Fri, 22 Feb 2013 13:06:25 +0000 Subject: [PATCH] Fix meld.args in mergetools.rc: add -o $output Message-ID: <679C86927552B447B2A1522BFC65B7E323FA178B@srv-cob-vm-0060.elaxy.org> Angel Ezquerra wrote: >I still do not understand why you need to use -o. On my brief tests the current configuration seems to work fine. You deliberately edited the left pane (local) and saved it, right? I'm merging from the left pane (local) and the right pane (other) into the middle pane (base). The mentioned menu item "Changes->Merge all non-conflicting does exactly" the same (so this way of merging seems to be preferred by Meld). At the end, the content of the middle pane has to be saved. Without -o the middle pane is saved into the underlying file (base). This is a temporary file, created (and later ignored) by Mercurial So my changes are lost after closing Meld. With -o my changes (in the middle pane) are saved into $output, which is the file, mercurial is using as the result of the merge. Ronny -----Urspr?ngliche Nachricht----- Von: ezquerra at gmail.com [mailto:ezquerra at gmail.com] Im Auftrag von Angel Ezquerra Gesendet: Freitag, 22. Februar 2013 13:25 An: V?lker Ronny Cc: Steve Borho; mercurial-devel at selenic.com Betreff: Re: [PATCH] Fix meld.args in mergetools.rc: add -o $output On Fri, Feb 22, 2013 at 11:19 AM, V?lker Ronny wrote: > > Angel Ezquerra wrote: > >>I just tried using meld (on windows) with TortoiseHg, using the >>current meld configuration (i.e. without your patch). As far as I can >>tell it seems to work fine. The only slightly weird thing is that you >>must make (and save) your changes on the "local" panel. >> >>So is this really necessary? Probably I'm missing something... >> >>What I really don't like is the fact that the order of the diff panels >>that meld shows is: >> >>local - base - other >> >>This makes it _very_ hard to tell the difference between local and >>other. It would be nice if it could be turned around (i.e. >>base-local-other). Or better yet, it would be nice if Meld could do a >>proper "3-way merge" (with 4 panels) as KDiff3 does. >> > > Steve Borho wrote: >>The Meld model is a lot closer to Araxis Merge than to KDiff3. >> > > I agree with Steve. It looks closer to Araxis Merge, where the middle pane contains the base version and is at the same time the target of merge operations. > The 'Merge mode'-example on http://meldmerge.org/features.html supports this view. > >>The way I would prefer for it to work would be for the center pane to be named "merged" and for the trivial changes from both local and other to be pre-applied to the >merge pane. As it is you have to do the trivial merges manually. I agree with Steve. If the center panel is where the merge must happen, it should be named something other than base, which means a different thing, and it should contain the results of the merge. > I'm using Meld 1.5.3 on Ubuntu12.04. It has a menu item Changes->Merge all non-conflicting, which does what you want. I found no way to trigger this behavior automatically at startup. Maybe the latest version has an option to do this. I just checked the meld -h output and it does not seem to be a new option for that. I could bring it up on the meld mailing list. > Renaming the middle pane may be a good idea, but I think it should be consistent across all merge tools with the same model. > Maybe the order of the panes should be consistent too (the order for Meld is local-base-other, the order for Araxis Merge is other-base-local ). > Anyway, I think that's another change. I still do not understand why you need to use -o. On my brief tests the current configuration seems to work fine. Cheers, Angel From laurens.nospam at grauw.nl Fri Feb 22 07:24:54 2013 From: laurens.nospam at grauw.nl (Laurens Holst) Date: Fri, 22 Feb 2013 14:24:54 +0100 Subject: [PATCH RFC] update: add an option to allow to merge local changes when crossing branches In-Reply-To: References: <567106adefd309717d8f.1361528527@fc8> Message-ID: <512771A6.8080209@grauw.nl> Op 22-02-13 13:26, Angel Ezquerra schreef: > On Fri, Feb 22, 2013 at 11:22 AM, Gilles Moris wrote: >> # HG changeset patch >> # User Gilles Moris >> # Date 1361528509 -3600 >> # Node ID 567106adefd309717d8f0538197dc7dde45d34f1 >> # Parent 013fcd112f13f31a35ea6a40d8cd1c6923cdaf20 >> update: add an option to allow to merge local changes when crossing branches >> >> *NOT READY FOR INCLUSION* >> >> Normally, it is not possible to update to another branch with local changes. >> One have to use "hg update --clean" to discard changes and force the update. >> One workaround is to update to the common ancestor of the branches, and then >> to the other branch. This workaround is not well known by users. >> >> I introduce an update --merge option that enables to rebase the local changes >> in one step. >> >> However, I have still some questions about how to design it: >> I/ option naming >> * I used --merge as it seems pretty but though could be confused with >> changesets merge >> * --rebase could be used, may be ,ore accurate, but IMO too tied to the rebase >> extension >> * --crossbranches would not be a good idea, as we probably don't want to allow >> crossing branches if a revision is not explicitely provided, whether there >> are some local changes or not >> * other possibilities: --reseat, --move, ... >> * last possibility: no option, allow by default to merge local changes, we've >> got --check if we want to block. By the way, this would greatly simplify both >> the code and the help content. The help content is currently partially lying: >> "If the changeset is not a descendant or ancestor of the working >> directory's parent, the update is aborted." >> Was true before, but since many releases we allow to cross branch for clean >> working directory and an explicit release. >> "-c --check update across branches if no uncommitted changes" >> Again wrong, this option aborts on any dirty working dir, whether we cross >> branches or not. >> So no option might be more consistent with the evolution of the CLI. > What about --force? It would let you do an update where the regular > update would not let you... I?m not entirely clear why this isn?t the default? Any update with local changes is performing a merge anyway (with all its risks for conflicts), so why would updating across branches need to be prohibited? It?s just a matter of setting base to the common ancestor instead of working copy parent, right? ~Laurens From laurens.nospam at grauw.nl Fri Feb 22 07:27:08 2013 From: laurens.nospam at grauw.nl (Laurens Holst) Date: Fri, 22 Feb 2013 14:27:08 +0100 Subject: [PATCH RFC] update: add an option to allow to merge local changes when crossing branches In-Reply-To: <512771A6.8080209@grauw.nl> References: <567106adefd309717d8f.1361528527@fc8> <512771A6.8080209@grauw.nl> Message-ID: <5127722C.6030604@grauw.nl> Op 22-02-13 14:24, Laurens Holst schreef: > Op 22-02-13 13:26, Angel Ezquerra schreef: >> On Fri, Feb 22, 2013 at 11:22 AM, Gilles Moris >> wrote: >>> # HG changeset patch >>> # User Gilles Moris >>> # Date 1361528509 -3600 >>> # Node ID 567106adefd309717d8f0538197dc7dde45d34f1 >>> # Parent 013fcd112f13f31a35ea6a40d8cd1c6923cdaf20 >>> update: add an option to allow to merge local changes when crossing >>> branches >>> >>> *NOT READY FOR INCLUSION* >>> >>> Normally, it is not possible to update to another branch with local >>> changes. >>> One have to use "hg update --clean" to discard changes and force the >>> update. >>> One workaround is to update to the common ancestor of the branches, >>> and then >>> to the other branch. This workaround is not well known by users. >>> >>> I introduce an update --merge option that enables to rebase the >>> local changes >>> in one step. >>> >>> However, I have still some questions about how to design it: >>> I/ option naming >>> * I used --merge as it seems pretty but though could be confused with >>> changesets merge >>> * --rebase could be used, may be ,ore accurate, but IMO too tied to >>> the rebase >>> extension >>> * --crossbranches would not be a good idea, as we probably don't >>> want to allow >>> crossing branches if a revision is not explicitely provided, >>> whether there >>> are some local changes or not >>> * other possibilities: --reseat, --move, ... >>> * last possibility: no option, allow by default to merge local >>> changes, we've >>> got --check if we want to block. By the way, this would greatly >>> simplify both >>> the code and the help content. The help content is currently >>> partially lying: >>> "If the changeset is not a descendant or ancestor of the working >>> directory's parent, the update is aborted." >>> Was true before, but since many releases we allow to cross branch >>> for clean >>> working directory and an explicit release. >>> "-c --check update across branches if no uncommitted changes" >>> Again wrong, this option aborts on any dirty working dir, whether >>> we cross >>> branches or not. >>> So no option might be more consistent with the evolution of the CLI. >> What about --force? It would let you do an update where the regular >> update would not let you... > > I?m not entirely clear why this isn?t the default? Any update with > local changes is performing a merge anyway (with all its risks for > conflicts), so why would updating across branches need to be > prohibited? It?s just a matter of setting base to the common ancestor > instead of working copy parent, right? Sorry, I said something stupid there, please ignore that last sentence :). Anyway, my point is, why can?t it do it this by default. ~Laurens From gilles.moris at free.fr Fri Feb 22 08:54:18 2013 From: gilles.moris at free.fr (Gilles Moris) Date: Fri, 22 Feb 2013 15:54:18 +0100 Subject: [PATCH RFC] update: add an option to allow to merge local changes when crossing branches In-Reply-To: <5127722C.6030604@grauw.nl> References: <567106adefd309717d8f.1361528527@fc8> <512771A6.8080209@grauw.nl> <5127722C.6030604@grauw.nl> Message-ID: <201302221554.19537.gilles.moris@free.fr> On Friday 22 February 2013 02:27:08 pm Laurens Holst wrote: > Op 22-02-13 14:24, Laurens Holst schreef: > > Op 22-02-13 13:26, Angel Ezquerra schreef: > >> On Fri, Feb 22, 2013 at 11:22 AM, Gilles Moris > >> > >> wrote: > >>> # HG changeset patch > >>> # User Gilles Moris > >>> # Date 1361528509 -3600 > >>> # Node ID 567106adefd309717d8f0538197dc7dde45d34f1 > >>> # Parent 013fcd112f13f31a35ea6a40d8cd1c6923cdaf20 > >>> update: add an option to allow to merge local changes when crossing > >>> branches > >>> > >>> *NOT READY FOR INCLUSION* > >>> > >>> Normally, it is not possible to update to another branch with local > >>> changes. > >>> One have to use "hg update --clean" to discard changes and force the > >>> update. > >>> One workaround is to update to the common ancestor of the branches, > >>> and then > >>> to the other branch. This workaround is not well known by users. > >>> > >>> I introduce an update --merge option that enables to rebase the > >>> local changes > >>> in one step. > >>> > >>> However, I have still some questions about how to design it: > >>> I/ option naming > >>> * I used --merge as it seems pretty but though could be confused with > >>> changesets merge > >>> * --rebase could be used, may be ,ore accurate, but IMO too tied to > >>> the rebase > >>> extension > >>> * --crossbranches would not be a good idea, as we probably don't > >>> want to allow > >>> crossing branches if a revision is not explicitely provided, > >>> whether there > >>> are some local changes or not > >>> * other possibilities: --reseat, --move, ... > >>> * last possibility: no option, allow by default to merge local > >>> changes, we've > >>> got --check if we want to block. By the way, this would greatly > >>> simplify both > >>> the code and the help content. The help content is currently > >>> partially lying: > >>> "If the changeset is not a descendant or ancestor of the working > >>> directory's parent, the update is aborted." > >>> Was true before, but since many releases we allow to cross branch > >>> for clean > >>> working directory and an explicit release. > >>> "-c --check update across branches if no uncommitted changes" > >>> Again wrong, this option aborts on any dirty working dir, whether > >>> we cross > >>> branches or not. > >>> So no option might be more consistent with the evolution of the CLI. > >> > >> What about --force? It would let you do an update where the regular > >> update would not let you... > > > > I?m not entirely clear why this isn?t the default? Any update with > > local changes is performing a merge anyway (with all its risks for > > conflicts), so why would updating across branches need to be > > prohibited? It?s just a matter of setting base to the common ancestor > > instead of working copy parent, right? > > Sorry, I said something stupid there, please ignore that last sentence :). > > Anyway, my point is, why can?t it do it this by default. > > ~Laurens > I think the rationale is that there are more probabilities to run into conflicts when jumping to another branch. This is questionable though, as if you are going far back in the past, the risk of conflicts is even higher, but you are allowed as this is linear. And I am not aware of any way to abort the merge of a working directory once started. If you screwed your merge, you're done. So I would rather be consistent and be able to always merge local changes by default as you said, and find a way to abort and revert a merge of the working directory. May be saving the current changes in an .hg/undo.update file before updating... Regards. Gilles. From markuszapke at gmx.net Fri Feb 22 09:02:03 2013 From: markuszapke at gmx.net (=?UTF-8?B?TWFya3VzIFphcGtlLUdyw7xuZGVtYW5u?=) Date: Fri, 22 Feb 2013 16:02:03 +0100 Subject: [PATCH RESEND] hgweb: add group authorization In-Reply-To: <511A3107.2020400@gmx.net> References: <51138D89.2060904@kiilerich.com> <511A3107.2020400@gmx.net> Message-ID: <5127886B.4090706@gmx.net> Markus Zapke-Gr?ndemann schrieb: > Markus Zapke-Gr?ndemann schrieb: >> # HG changeset patch >> # User Markus Zapke-Gr?ndemann >> # Date 1360231888 -3600 >> # Node ID d2dbfdee987a51efb6f4ad69e3b116aa22553326 >> # Parent 2fefd1170bf269e26bb304553009f38e0117c342 >> hgweb: add group authorization. > Here is a description how to use group authorization. This is also part of the > patch for the documentation. > > > With the patch it is possible to use groups together with usernames in the > allow_read, allow_write, deny_read and deny_write lists. A group name is > prefixed by an @. Groups can either be groups defined in the groups_section > (explained below) or Unix groups. If a group from the groups_section has the > same name as an Unix group it is used instead. > > > The groups_section > > Name of hgrc section used to define groups for authorization. > Default is web.groups. Use the section to define the groups used > by authorization. > > Example: > > [web] > allow_read = @devs > > [web.groups] > devs = alice, bob, clara, david > > Groups can contain other groups: > > [web] > allow_read = @devs, @testers > allow_push = @devs > > [web.groups] > devs = alice, bob, clara, david > ci = hudson > testers = @ci, lisa, mario I changed the patch as proposed by Mads and explained the functionality in my last email. Is there still anything missing or is the group authorization feature not wanted? Regards Markus From martin at geisler.net Fri Feb 22 09:03:55 2013 From: martin at geisler.net (Martin Geisler) Date: Fri, 22 Feb 2013 16:03:55 +0100 Subject: [PATCH RFC] update: add an option to allow to merge local changes when crossing branches In-Reply-To: <5127722C.6030604@grauw.nl> (sfid-20130222_152006_142594_954FE0C2) (Laurens Holst's message of "Fri, 22 Feb 2013 14:27:08 +0100") References: <567106adefd309717d8f.1361528527@fc8> <512771A6.8080209@grauw.nl> <5127722C.6030604@grauw.nl> Message-ID: <87wqu0tmp0.fsf@go.home> Laurens Holst writes: > Anyway, my point is, why can?t it do it this by default. I always do $ hg update 'ancestor(., $TARGET)' $ hg update $TARGET when I get the warning about crossing branches and so far it has worked fine -- but maybe there is a subtle bug somewhere that makes that a bad idea? -- Martin Geisler From mercurial-bugs at selenic.com Fri Feb 22 05:17:46 2013 From: mercurial-bugs at selenic.com (mercurial-bugs at selenic.com) Date: Fri, 22 Feb 2013 11:17:46 +0000 Subject: [Bug 3837] New: committing divergent head on closed branch should say it's reopening the branch Message-ID: http://bz.selenic.com/show_bug.cgi?id=3837 Priority: normal Bug ID: 3837 CC: mercurial-devel at selenic.com Assignee: bugzilla at selenic.com Summary: committing divergent head on closed branch should say it's reopening the branch Severity: bug Classification: Unclassified OS: Mac OS Reporter: kbullock+mercurial at ringworld.org Hardware: PC Status: UNCONFIRMED Version: 2.5 Component: Mercurial Product: Mercurial Going from 0 -> 1 open heads on a branch doesn't print a message to that effect, if you don't commit on top of the --close-branch commit: $ hg init a $ cd a $ echo a>a $ hg ci -Am0 adding a $ hg ci --close-branch -m'1 (close branch)' $ hg up 0 0 files updated, 0 files merged, 0 files removed, 0 files unresolved $ hg heads $ echo b>a $ hg ci -m2 $ Here I would expect to see the message 'reopening closed branch head' or something similar (maybe just 'reopening closed branch "default"'). -- You are receiving this mail because: You are on the CC list for the bug. From kbullock+mercurial at ringworld.org Fri Feb 22 10:33:59 2013 From: kbullock+mercurial at ringworld.org (Kevin Bullock) Date: Fri, 22 Feb 2013 10:33:59 -0600 Subject: [PATCH RFC] update: add an option to allow to merge local changes when crossing branches In-Reply-To: <87wqu0tmp0.fsf@go.home> References: <567106adefd309717d8f.1361528527@fc8> <512771A6.8080209@grauw.nl> <5127722C.6030604@grauw.nl> <87wqu0tmp0.fsf@go.home> Message-ID: <80B2B4E4-C221-43BF-BCE7-A13EF7819A05@ringworld.org> On 22 Feb 2013, at 9:03 AM, Martin Geisler wrote: > Laurens Holst writes: > >> Anyway, my point is, why can?t it do it this by default. > > I always do > > $ hg update 'ancestor(., $TARGET)' > $ hg update $TARGET > > when I get the warning about crossing branches and so far it has worked > fine -- but maybe there is a subtle bug somewhere that makes that a bad > idea? Not really a bug, but it is one more merge than would strictly be necessary. pacem in terris / ??? / ?????? / ????????? / ?? Kevin R. Bullock From kbullock+mercurial at ringworld.org Fri Feb 22 10:50:57 2013 From: kbullock+mercurial at ringworld.org (Kevin Bullock) Date: Fri, 22 Feb 2013 10:50:57 -0600 Subject: [PATCH RFC] update: add an option to allow to merge local changes when crossing branches In-Reply-To: <512771A6.8080209@grauw.nl> References: <567106adefd309717d8f.1361528527@fc8> <512771A6.8080209@grauw.nl> Message-ID: <7E8EBF7C-C984-4E02-A327-01A854C291B9@ringworld.org> On 22 Feb 2013, at 7:24 AM, Laurens Holst wrote: > I?m not entirely clear why this isn?t the default? Any update with local changes is performing a merge anyway (with all its risks for conflicts), so why would updating across branches need to be prohibited? Much greater likelihood of conflicts, and no way to get your local changes back if you want to bail. In a normal linear update with changes in the working copy, all Mercurial has to do is apply the changes in the working dir to the target head, and write the result back into the working copy. To update across branches, it would have to apply _all_ the changes between the common ancestor and the working copy, and write the result into the working copy. Thus the likelihood of clobbering uncommitted changes is much greater (and much more subject to operator error in your merge tool of choice). pacem in terris / ??? / ?????? / ????????? / ?? Kevin R. Bullock From mpm at selenic.com Fri Feb 22 11:15:13 2013 From: mpm at selenic.com (Matt Mackall) Date: Fri, 22 Feb 2013 11:15:13 -0600 Subject: [PATCH RFC] update: add an option to allow to merge local changes when crossing branches In-Reply-To: <512771A6.8080209@grauw.nl> References: <567106adefd309717d8f.1361528527@fc8> <512771A6.8080209@grauw.nl> Message-ID: <1361553313.11033.8.camel@calx> On Fri, 2013-02-22 at 14:24 +0100, Laurens Holst wrote: > Op 22-02-13 13:26, Angel Ezquerra schreef: > > On Fri, Feb 22, 2013 at 11:22 AM, Gilles Moris wrote: > >> # HG changeset patch > >> # User Gilles Moris > >> # Date 1361528509 -3600 > >> # Node ID 567106adefd309717d8f0538197dc7dde45d34f1 > >> # Parent 013fcd112f13f31a35ea6a40d8cd1c6923cdaf20 > >> update: add an option to allow to merge local changes when crossing branches > >> > >> *NOT READY FOR INCLUSION* > >> > >> Normally, it is not possible to update to another branch with local changes. > >> One have to use "hg update --clean" to discard changes and force the update. > >> One workaround is to update to the common ancestor of the branches, and then > >> to the other branch. This workaround is not well known by users. > >> > >> I introduce an update --merge option that enables to rebase the local changes > >> in one step. > >> > >> However, I have still some questions about how to design it: > >> I/ option naming > >> * I used --merge as it seems pretty but though could be confused with > >> changesets merge > >> * --rebase could be used, may be ,ore accurate, but IMO too tied to the rebase > >> extension > >> * --crossbranches would not be a good idea, as we probably don't want to allow > >> crossing branches if a revision is not explicitely provided, whether there > >> are some local changes or not > >> * other possibilities: --reseat, --move, ... > >> * last possibility: no option, allow by default to merge local changes, we've > >> got --check if we want to block. By the way, this would greatly simplify both > >> the code and the help content. The help content is currently partially lying: > >> "If the changeset is not a descendant or ancestor of the working > >> directory's parent, the update is aborted." > >> Was true before, but since many releases we allow to cross branch for clean > >> working directory and an explicit release. > >> "-c --check update across branches if no uncommitted changes" > >> Again wrong, this option aborts on any dirty working dir, whether we cross > >> branches or not. > >> So no option might be more consistent with the evolution of the CLI. > > What about --force? It would let you do an update where the regular > > update would not let you... > > I?m not entirely clear why this isn?t the default? Because it was once the default and many users shot themselves in the foot (and blamed us) and now we know better. -- Mathematics is the supreme nostalgia of our time. From mpm at selenic.com Fri Feb 22 11:17:34 2013 From: mpm at selenic.com (Matt Mackall) Date: Fri, 22 Feb 2013 11:17:34 -0600 Subject: [PATCH RESEND] hgweb: add group authorization In-Reply-To: <5127886B.4090706@gmx.net> References: <51138D89.2060904@kiilerich.com> <511A3107.2020400@gmx.net> <5127886B.4090706@gmx.net> Message-ID: <1361553454.11033.9.camel@calx> On Fri, 2013-02-22 at 16:02 +0100, Markus Zapke-Gr?ndemann wrote: > Markus Zapke-Gr?ndemann schrieb: > > Markus Zapke-Gr?ndemann schrieb: > >> # HG changeset patch > >> # User Markus Zapke-Gr?ndemann > >> # Date 1360231888 -3600 > >> # Node ID d2dbfdee987a51efb6f4ad69e3b116aa22553326 > >> # Parent 2fefd1170bf269e26bb304553009f38e0117c342 > >> hgweb: add group authorization. > > Here is a description how to use group authorization. This is also part of the > > patch for the documentation. > > > > > > With the patch it is possible to use groups together with usernames in the > > allow_read, allow_write, deny_read and deny_write lists. A group name is > > prefixed by an @. Groups can either be groups defined in the groups_section > > (explained below) or Unix groups. If a group from the groups_section has the > > same name as an Unix group it is used instead. > > > > > > The groups_section > > > > Name of hgrc section used to define groups for authorization. > > Default is web.groups. Use the section to define the groups used > > by authorization. > > > > Example: > > > > [web] > > allow_read = @devs > > > > [web.groups] > > devs = alice, bob, clara, david > > > > Groups can contain other groups: > > > > [web] > > allow_read = @devs, @testers > > allow_push = @devs > > > > [web.groups] > > devs = alice, bob, clara, david > > ci = hudson > > testers = @ci, lisa, mario > I changed the patch as proposed by Mads and explained the functionality in my > last email. Is there still anything missing or is the group authorization > feature not wanted? I've only seen one version of the patch? -- Mathematics is the supreme nostalgia of our time. From bos at serpentine.com Fri Feb 22 13:20:21 2013 From: bos at serpentine.com (Bryan O'Sullivan) Date: Fri, 22 Feb 2013 11:20:21 -0800 Subject: [PATCH] localrepo: iterate over manifest key/value pairs in status In-Reply-To: <8fa59ad66baa06631baf.1361483154@australite.local> References: <8fa59ad66baa06631baf.1361483154@australite.local> Message-ID: On Thu, Feb 21, 2013 at 1:45 PM, Bryan O'Sullivan wrote: > localrepo: iterate over manifest key/value pairs in status > Pushed to crew because dead simple. -------------- next part -------------- An HTML attachment was scrubbed... URL: From hgbuildbot at kublai.com Fri Feb 22 13:52:46 2013 From: hgbuildbot at kublai.com (hgbuildbot at kublai.com) Date: Fri, 22 Feb 2013 11:52:46 -0800 Subject: buildbot success in Mercurial on hg tests Message-ID: <20130222195247.1F1EB20BC7@hgbuildbot.cs.ubc.ca> The Buildbot has detected a restored build on builder hg tests while building hg. Full details are available at: http://hgbuildbot.kublai.com/builders/hg%20tests/builds/511 Buildbot URL: http://hgbuildbot.kublai.com/ Buildslave for this Build: p64.osuosl.test Build Reason: scheduler Build Source Stamp: [branch default] 7790d69af6d6bd72b4d5495c6a75abdc75cbeb33 Blamelist: Bryan O'Sullivan Build succeeded! sincerely, -The Buildbot From hg at intevation.org Fri Feb 22 13:55:08 2013 From: hg at intevation.org (Mercurial Commits) Date: Fri, 22 Feb 2013 20:55:08 +0100 Subject: mercurial@18716: 19 new changesets (3 stable) Message-ID: <1361562908.011816.10914.nullmailer@hg.intevation.org> 19 new changesets (3 stable) in mercurial: http://selenic.com/repo/hg//rev/f2b1f78cf202 changeset: 18698:f2b1f78cf202 branch: stable parent: 18679:f6f35d646cb5 user: Pierre-Yves David date: Fri Feb 15 11:28:04 2013 +0100 summary: mergetools: vimdiff issue a warning explaining how to abort http://selenic.com/repo/hg//rev/7d66a44e87ed changeset: 18699:7d66a44e87ed branch: stable user: Kevin Bullock date: Fri Feb 15 15:06:43 2013 -0600 summary: mergetools: refine vimdiff warning message http://selenic.com/repo/hg//rev/4a85ebb5c807 changeset: 18700:4a85ebb5c807 parent: 18695:ec9b9968b7f8 parent: 18699:7d66a44e87ed user: Kevin Bullock date: Fri Feb 15 21:20:24 2013 -0600 summary: merge with stable http://selenic.com/repo/hg//rev/61c8327ced50 changeset: 18701:61c8327ced50 branch: stable parent: 18699:7d66a44e87ed user: FUJIWARA Katsunori date: Mon Feb 18 00:04:28 2013 +0900 summary: bundle: treat branches created newly on the local correctly (issue3828) http://selenic.com/repo/hg//rev/32292ad53f9f changeset: 18702:32292ad53f9f parent: 18697:4921b5c2aeed parent: 18700:4a85ebb5c807 user: Matt Mackall date: Mon Feb 18 13:20:59 2013 -0600 summary: merge with crew http://selenic.com/repo/hg//rev/5bef0655f2e9 changeset: 18703:5bef0655f2e9 parent: 18702:32292ad53f9f parent: 18701:61c8327ced50 user: Matt Mackall date: Mon Feb 18 13:21:27 2013 -0600 summary: merge with stable http://selenic.com/repo/hg//rev/d69585a5c5c0 changeset: 18704:d69585a5c5c0 parent: 18700:4a85ebb5c807 user: Na'Tosha Bard date: Sat Feb 09 21:07:42 2013 +0000 summary: largefiles: don't cache largefiles for pulled heads by default http://selenic.com/repo/hg//rev/a8204cef4c5a changeset: 18705:a8204cef4c5a parent: 18697:4921b5c2aeed parent: 18704:d69585a5c5c0 user: Kevin Bullock date: Tue Feb 19 13:35:25 2013 -0600 summary: merge with main http://selenic.com/repo/hg//rev/f17680992123 changeset: 18706:f17680992123 parent: 18705:a8204cef4c5a parent: 18701:61c8327ced50 user: Kevin Bullock date: Tue Feb 19 13:35:39 2013 -0600 summary: merge with stable http://selenic.com/repo/hg//rev/d1a2b086d058 changeset: 18707:d1a2b086d058 user: Bryan O'Sullivan date: Wed Feb 20 11:31:27 2013 -0800 summary: worker: on error, exit similarly to the first failing worker http://selenic.com/repo/hg//rev/86524a70c0f6 changeset: 18708:86524a70c0f6 user: Bryan O'Sullivan date: Wed Feb 20 11:31:31 2013 -0800 summary: worker: fix a race in SIGINT handling http://selenic.com/repo/hg//rev/9955fc5ee24b changeset: 18709:9955fc5ee24b user: Bryan O'Sullivan date: Wed Feb 20 11:31:34 2013 -0800 summary: worker: handle worker failures more aggressively http://selenic.com/repo/hg//rev/49ef9d0ca815 changeset: 18710:49ef9d0ca815 user: Bryan O'Sullivan date: Wed Feb 20 11:31:38 2013 -0800 summary: cmdutil: use a small initial window with --limit http://selenic.com/repo/hg//rev/6b786dc88612 changeset: 18711:6b786dc88612 user: Bryan O'Sullivan date: Wed Feb 20 11:31:41 2013 -0800 summary: commands: exit from the log loop at the right time http://selenic.com/repo/hg//rev/e3ddb4068757 changeset: 18712:e3ddb4068757 user: Kevin Bullock date: Thu Feb 21 13:16:02 2013 -0600 summary: scmutil: fix NameError on windows http://selenic.com/repo/hg//rev/8728579f6bdc changeset: 18713:8728579f6bdc user: Bryan O'Sullivan date: Thu Feb 21 12:55:39 2013 -0800 summary: match: more accurately report when we're always going to match http://selenic.com/repo/hg//rev/7790d69af6d6 changeset: 18714:7790d69af6d6 user: Bryan O'Sullivan date: Fri Feb 22 10:05:22 2013 -0800 summary: localrepo: iterate over manifest key/value pairs in status http://selenic.com/repo/hg//rev/c4ff927b6f68 changeset: 18715:c4ff927b6f68 parent: 18703:5bef0655f2e9 user: Matt Mackall date: Fri Feb 22 13:45:46 2013 -0600 summary: templater: properly handle file_copies with % http://selenic.com/repo/hg//rev/963468e9f9e5 changeset: 18716:963468e9f9e5 tag: tip parent: 18715:c4ff927b6f68 parent: 18714:7790d69af6d6 user: Matt Mackall date: Fri Feb 22 13:46:54 2013 -0600 summary: merge with crew -- Repository URL: http://selenic.com/repo/hg/ From angel.ezquerra at gmail.com Fri Feb 22 14:11:19 2013 From: angel.ezquerra at gmail.com (Angel Ezquerra) Date: Fri, 22 Feb 2013 21:11:19 +0100 Subject: [PATCH] Fix meld.args in mergetools.rc: add -o $output In-Reply-To: <679C86927552B447B2A1522BFC65B7E323FA178B@srv-cob-vm-0060.elaxy.org> References: <679C86927552B447B2A1522BFC65B7E323FA178B@srv-cob-vm-0060.elaxy.org> Message-ID: On Fri, Feb 22, 2013 at 2:06 PM, V?lker Ronny wrote: > Angel Ezquerra wrote: > >>I still do not understand why you need to use -o. On my brief tests the current configuration seems to work fine. > > You deliberately edited the left pane (local) and saved it, right? > > I'm merging from the left pane (local) and the right pane (other) into the middle pane (base). > The mentioned menu item "Changes->Merge all non-conflicting does exactly" the same (so this way of merging seems to be preferred by Meld). > At the end, the content of the middle pane has to be saved. > Without -o the middle pane is saved into the underlying file (base). This is a temporary file, created (and later ignored) by Mercurial > So my changes are lost after closing Meld. > With -o my changes (in the middle pane) are saved into $output, which is the file, mercurial is using as the result of the merge. > > Ronny I see. In that case I think you also must change the label of the center panel to make it clear that it is the merge panel, not the base. When I read base I did not think of editing that panel. BTW, I don't know if you noticed but we do bottom post on this mailing list. Cheers, Angel From martin at geisler.net Fri Feb 22 14:30:06 2013 From: martin at geisler.net (Martin Geisler) Date: Fri, 22 Feb 2013 21:30:06 +0100 Subject: [PATCH RFC] update: add an option to allow to merge local changes when crossing branches In-Reply-To: <80B2B4E4-C221-43BF-BCE7-A13EF7819A05@ringworld.org> (sfid-20130222_182010_294290_8E812C9B) (Kevin Bullock's message of "Fri, 22 Feb 2013 10:33:59 -0600") References: <567106adefd309717d8f.1361528527@fc8> <512771A6.8080209@grauw.nl> <5127722C.6030604@grauw.nl> <87wqu0tmp0.fsf@go.home> <80B2B4E4-C221-43BF-BCE7-A13EF7819A05@ringworld.org> Message-ID: <877gm0ks6p.fsf@hbox.dyndns.org> Kevin Bullock writes: > On 22 Feb 2013, at 9:03 AM, Martin Geisler wrote: > >> Laurens Holst writes: >> >>> Anyway, my point is, why can?t it do it this by default. >> >> I always do >> >> $ hg update 'ancestor(., $TARGET)' >> $ hg update $TARGET >> >> when I get the warning about crossing branches and so far it has worked >> fine -- but maybe there is a subtle bug somewhere that makes that a bad >> idea? > > Not really a bug, but it is one more merge than would strictly be > necessary. That is true with the work-around I use today, but if it was implemented internally, then I think it could be done with a single merge as one would expect. -- Martin Geisler -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 835 bytes Desc: not available URL: From martin at geisler.net Fri Feb 22 14:35:02 2013 From: martin at geisler.net (Martin Geisler) Date: Fri, 22 Feb 2013 21:35:02 +0100 Subject: [PATCH RFC] update: add an option to allow to merge local changes when crossing branches In-Reply-To: <7E8EBF7C-C984-4E02-A327-01A854C291B9@ringworld.org> (sfid-20130222_182012_048566_C471E6A9) (Kevin Bullock's message of "Fri, 22 Feb 2013 10:50:57 -0600") References: <567106adefd309717d8f.1361528527@fc8> <512771A6.8080209@grauw.nl> <7E8EBF7C-C984-4E02-A327-01A854C291B9@ringworld.org> Message-ID: <8738wokryh.fsf@hbox.dyndns.org> Kevin Bullock writes: > On 22 Feb 2013, at 7:24 AM, Laurens Holst wrote: > >> I?m not entirely clear why this isn?t the default? Any update with >> local changes is performing a merge anyway (with all its risks for >> conflicts), so why would updating across branches need to be >> prohibited? > > Much greater likelihood of conflicts, and no way to get your local > changes back if you want to bail. We do save the original files when merging a dirty working copy into a target revisioon -- 'hg resolve --tool internal:local' will give them back to you even though they were never committed anywhere. I don't know why you say the risk of conflicts is greater here than with any other update/merge? > In a normal linear update with changes in the working copy, all > Mercurial has to do is apply the changes in the working dir to the > target head, and write the result back into the working copy. It actually does a normal three-way merge as if you had temporarily commited your changes and now rebase the temporary commit to the target for your update. > To update across branches, it would have to apply _all_ the changes > between the common ancestor and the working copy, and write the result > into the working copy. Thus the likelihood of clobbering uncommitted > changes is much greater (and much more subject to operator error in > your merge tool of choice). I think you're saying that an update the crosses branches will tend to "span" a greater range of revisions than an update that is linear. That seems reasonable, but the underlying merge problem ought to be the same as if you had done a linear update across a big span of revisions. -- Martin Geisler -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 835 bytes Desc: not available URL: From kbullock+mercurial at ringworld.org Fri Feb 22 14:54:37 2013 From: kbullock+mercurial at ringworld.org (Kevin Bullock) Date: Fri, 22 Feb 2013 14:54:37 -0600 Subject: [PATCH RFC] update: add an option to allow to merge local changes when crossing branches In-Reply-To: <8738wokryh.fsf@hbox.dyndns.org> References: <567106adefd309717d8f.1361528527@fc8> <512771A6.8080209@grauw.nl> <7E8EBF7C-C984-4E02-A327-01A854C291B9@ringworld.org> <8738wokryh.fsf@hbox.dyndns.org> Message-ID: <1033C124-F628-48EE-8B5E-F091571EDFF7@ringworld.org> On 22 Feb 2013, at 2:35 PM, Martin Geisler wrote: > Kevin Bullock writes: > >> On 22 Feb 2013, at 7:24 AM, Laurens Holst wrote: >> >>> I?m not entirely clear why this isn?t the default? Any update with >>> local changes is performing a merge anyway (with all its risks for >>> conflicts), so why would updating across branches need to be >>> prohibited? >> >> Much greater likelihood of conflicts, and no way to get your local >> changes back if you want to bail. > > We do save the original files when merging a dirty working copy into a > target revisioon -- 'hg resolve --tool internal:local' will give them > back to you even though they were never committed anywhere. Huh, how long have we been doing that? And more importantly, if we allowed a cross-branch update, how would you get them back _after updating back to your original place_? > I don't know why you say the risk of conflicts is greater here than with > any other update/merge? Simply because you're merging a larger set of changes, as you get to below. >> In a normal linear update with changes in the working copy, all >> Mercurial has to do is apply the changes in the working dir to the >> target head, and write the result back into the working copy. > > It actually does a normal three-way merge as if you had temporarily > commited your changes and now rebase the temporary commit to the target > for your update. That's what I was describing, yes: base is the working copy parent, and the two merge 'heads' are the target rev and the uncommitted working copy changes. >> To update across branches, it would have to apply _all_ the changes >> between the common ancestor and the working copy, and write the result >> into the working copy. Thus the likelihood of clobbering uncommitted >> changes is much greater (and much more subject to operator error in >> your merge tool of choice). > > I think you're saying that an update the crosses branches will tend to > "span" a greater range of revisions than an update that is linear. > > That seems reasonable, but the underlying merge problem ought to be the > same as if you had done a linear update across a big span of revisions. The theoretical problem is the same, but the _usability_ problem is very different, both because of a likely larger set of conflicts (merge early and often!), and because you'd have to do something different to get back to your original state (and we'd likely have to track more state outside of history). pacem in terris / ??? / ?????? / ????????? / ?? Kevin R. Bullock From hgbuildbot at kublai.com Fri Feb 22 16:00:30 2013 From: hgbuildbot at kublai.com (hgbuildbot at kublai.com) Date: Fri, 22 Feb 2013 14:00:30 -0800 Subject: buildbot failure in Mercurial on hg tests Message-ID: <20130222220031.88B93254F3@hgbuildbot.cs.ubc.ca> The Buildbot has detected a new failure on builder hg tests while building hg. Full details are available at: http://hgbuildbot.kublai.com/builders/hg%20tests/builds/512 Buildbot URL: http://hgbuildbot.kublai.com/ Buildslave for this Build: p64.osuosl.test Build Reason: scheduler Build Source Stamp: [branch default] 963468e9f9e59625eb11c0c0981829b295b06632 Blamelist: Matt Mackall BUILD FAILED: failed run-tests.py (python2.5) sincerely, -The Buildbot From hg at intevation.org Fri Feb 22 16:45:07 2013 From: hg at intevation.org (Mercurial Commits) Date: Fri, 22 Feb 2013 23:45:07 +0100 Subject: mercurial@18718: 2 new changesets Message-ID: <1361573107.994366.16008.nullmailer@hg.intevation.org> 2 new changesets in mercurial: http://selenic.com/repo/hg//rev/fcc4b55876c3 changeset: 18717:fcc4b55876c3 user: Matt Mackall date: Fri Feb 22 15:17:33 2013 -0600 summary: pager: catch ctrl-c on exit (issue3834) http://selenic.com/repo/hg//rev/c8c3887a24c1 changeset: 18718:c8c3887a24c1 tag: tip user: Matt Mackall date: Fri Feb 22 16:40:27 2013 -0600 summary: convert: stabilize cvsps commitid sort order -- Repository URL: http://selenic.com/repo/hg/ From mpm at selenic.com Fri Feb 22 17:04:35 2013 From: mpm at selenic.com (Matt Mackall) Date: Fri, 22 Feb 2013 17:04:35 -0600 Subject: Bugzilla server's system time In-Reply-To: References: <20130214224457.GA3634@findus> <1360970681.12295.127.camel@calx> Message-ID: <1361574275.11033.25.camel@calx> On Thu, 2013-02-21 at 15:03 +0400, Nikolaj Sjujskij wrote: > Den 2013-02-16 03:24:41 skrev Matt Mackall : > > > On Thu, 2013-02-14 at 23:44 +0100, Isaac Jurado wrote: > >> Hi, > >> > >> I think the bugzilla server's clock is not on time. I posted a comment > >> ten minutes ago and it appears as 17:40:53 UTC when it should have been > >> 22:40:53 UTC. Maybe it's just the timezone, locale or the Bugzilla > >> configuration. > > > > The server's time was correct, however it's in the EST timezone and > > Bugzilla defaults users to the server's timezone. I've changed the > > default to UTC. > There's something still incorrect about time there. I have Europe/Moscow > (UTC+4) set in my user preferences and a few minutes ago I've added a > comment: http://bz.selenic.com/show_bug.cgi?id=3836#c3. Its date is > displayed like "2013-02-21 09:52:34 MSK" which is... er... actually, I > don't know what it is. Doesn't seem like usual "UTC as local" or vice > versa. As of writing, it's 14:59:05, which is 10:59 UTC. Gentoo bugzilla > displays time as expected. I'm at a loss, then. There's a total of one timezone setting in Bugzilla, and I've toggled it. The system clock and timezone on the server are correct. Short of setting the system timezone to UTC, there's not much I can do. -- Mathematics is the supreme nostalgia of our time. From markuszapke at gmx.net Fri Feb 22 17:43:01 2013 From: markuszapke at gmx.net (=?UTF-8?B?TWFya3VzIFphcGtlLUdyw7xuZGVtYW5u?=) Date: Sat, 23 Feb 2013 00:43:01 +0100 Subject: [PATCH RESEND] hgweb: add group authorization In-Reply-To: <1361553454.11033.9.camel@calx> References: <51138D89.2060904@kiilerich.com> <511A3107.2020400@gmx.net> <5127886B.4090706@gmx.net> <1361553454.11033.9.camel@calx> Message-ID: <51280285.80108@gmx.net> Matt Mackall schrieb: > On Fri, 2013-02-22 at 16:02 +0100, Markus Zapke-Gr?ndemann wrote: >> Markus Zapke-Gr?ndemann schrieb: >>> Markus Zapke-Gr?ndemann schrieb: >>>> # HG changeset patch >>>> # User Markus Zapke-Gr?ndemann >>>> # Date 1360231888 -3600 >>>> # Node ID d2dbfdee987a51efb6f4ad69e3b116aa22553326 >>>> # Parent 2fefd1170bf269e26bb304553009f38e0117c342 >>>> hgweb: add group authorization. >>> Here is a description how to use group authorization. This is also part of the >>> patch for the documentation. >>> >>> >>> With the patch it is possible to use groups together with usernames in the >>> allow_read, allow_write, deny_read and deny_write lists. A group name is >>> prefixed by an @. Groups can either be groups defined in the groups_section >>> (explained below) or Unix groups. If a group from the groups_section has the >>> same name as an Unix group it is used instead. >>> >>> >>> The groups_section >>> >>> Name of hgrc section used to define groups for authorization. >>> Default is web.groups. Use the section to define the groups used >>> by authorization. >>> >>> Example: >>> >>> [web] >>> allow_read = @devs >>> >>> [web.groups] >>> devs = alice, bob, clara, david >>> >>> Groups can contain other groups: >>> >>> [web] >>> allow_read = @devs, @testers >>> allow_push = @devs >>> >>> [web.groups] >>> devs = alice, bob, clara, david >>> ci = hudson >>> testers = @ci, lisa, mario >> I changed the patch as proposed by Mads and explained the functionality in my >> last email. Is there still anything missing or is the group authorization >> feature not wanted? > > I've only seen one version of the patch? > I resent the patch with all unnecessary stuff removed on Feb 7: http://selenic.com/pipermail/mercurial-devel/2013-February/048710.html The explaination of the group authorization functionality is quoted above. I would like to know if there is anything missing or wrong. Thanks Markus From hgbuildbot at kublai.com Fri Feb 22 18:26:29 2013 From: hgbuildbot at kublai.com (hgbuildbot at kublai.com) Date: Fri, 22 Feb 2013 16:26:29 -0800 Subject: buildbot success in Mercurial on hg tests Message-ID: <20130223002629.A7974254F3@hgbuildbot.cs.ubc.ca> The Buildbot has detected a restored build on builder hg tests while building hg. Full details are available at: http://hgbuildbot.kublai.com/builders/hg%20tests/builds/513 Buildbot URL: http://hgbuildbot.kublai.com/ Buildslave for this Build: p64.osuosl.test Build Reason: scheduler Build Source Stamp: [branch default] c8c3887a24c1ee30b0afbdb6812e64bb64b400e6 Blamelist: Matt Mackall Build succeeded! sincerely, -The Buildbot From diptongo at gmail.com Fri Feb 22 19:35:44 2013 From: diptongo at gmail.com (Isaac Jurado) Date: Sat, 23 Feb 2013 02:35:44 +0100 Subject: Bugzilla server's system time In-Reply-To: <1361574275.11033.25.camel@calx> References: <20130214224457.GA3634@findus> <1360970681.12295.127.camel@calx> <1361574275.11033.25.camel@calx> Message-ID: <20130223013544.GA23697@findus> Replying Matt Mackall: >On Thu, 2013-02-21 at 15:03 +0400, Nikolaj Sjujskij wrote: >> Den 2013-02-16 03:24:41 skrev Matt Mackall : >> >>> On Thu, 2013-02-14 at 23:44 +0100, Isaac Jurado wrote: >>>> Hi, >>>> >>>> I think the bugzilla server's clock is not on time. I posted a >>>> comment ten minutes ago and it appears as 17:40:53 UTC when it >>>> should have been 22:40:53 UTC. Maybe it's just the timezone, >>>> locale or the Bugzilla configuration. >>> >>> The server's time was correct, however it's in the EST timezone and >>> Bugzilla defaults users to the server's timezone. I've changed the >>> default to UTC. >> >> There's something still incorrect about time there. I have >> Europe/Moscow (UTC+4) set in my user preferences and a few minutes >> ago I've added a comment: >> http://bz.selenic.com/show_bug.cgi?id=3836#c3. Its date is displayed >> like "2013-02-21 09:52:34 MSK" which is... er... actually, I don't >> know what it is. Doesn't seem like usual "UTC as local" or vice >> versa. As of writing, it's 14:59:05, which is 10:59 UTC. Gentoo >> bugzilla displays time as expected. > > I'm at a loss, then. There's a total of one timezone setting in > Bugzilla, and I've toggled it. The system clock and timezone on the > server are correct. Short of setting the system timezone to UTC, > there's not much I can do. Nikolaj is right. I just made a change to see the timestamp at 1:22 AM UTC and the bugzilla page shows a 5 hour lapse: 20:22 PM UTC of the day before. After changing my preferences to my time zone (CET), the same page makes the conversion properly, but still with the wrong hour: 21:22 PM CET. It looks like Bugzilla is working allright, and the problem may come from a system misconfiguration. Or maybe even the NTP daemon is not working properly, who knows? -- Isaac Jurado "The noblest pleasure is the joy of understanding." Leonardo da Vinci From diptongo at gmail.com Fri Feb 22 19:41:59 2013 From: diptongo at gmail.com (Isaac Jurado) Date: Sat, 23 Feb 2013 02:41:59 +0100 Subject: Bugzilla server's system time In-Reply-To: <20130223013544.GA23697@findus> References: <20130214224457.GA3634@findus> <1360970681.12295.127.camel@calx> <1361574275.11033.25.camel@calx> <20130223013544.GA23697@findus> Message-ID: <20130223014159.GB23697@findus> Replying Isaac Jurado: > > Nikolaj is right. I just made a change to see the timestamp at 1:22 > AM UTC and the bugzilla page shows a 5 hour lapse: 20:22 PM UTC of the > day before. > > After changing my preferences to my time zone (CET), the same page > makes the conversion properly, but still with the wrong hour: 21:22 PM > CET. > > It looks like Bugzilla is working allright, and the problem may come > from a system misconfiguration. Or maybe even the NTP daemon is not > working properly, who knows? As a bouns feedback. I just checked the mail notification sent by Bugzilla, which was also wrong (20:22 +000 instead of 1:22 +000). If the Date: header is added by the local MTA and not by Bugzilla, then there is something wrong with the system time. Cheeres. -- Isaac Jurado "The noblest pleasure is the joy of understanding." Leonardo da Vinci From mercurial-bugs at selenic.com Fri Feb 22 21:30:23 2013 From: mercurial-bugs at selenic.com (mercurial-bugs at selenic.com) Date: Sat, 23 Feb 2013 03:30:23 +0000 Subject: [Bug 3838] New: BTS timezone trouble Message-ID: http://bz.selenic.com/show_bug.cgi?id=3838 Priority: normal Bug ID: 3838 CC: mercurial-devel at selenic.com Assignee: bugzilla at selenic.com Summary: BTS timezone trouble Severity: bug Classification: Unclassified OS: Linux Reporter: mpm at selenic.com Hardware: PC Status: UNCONFIRMED Version: unspecified Component: Mercurial Product: Mercurial BTS reportedly not giving right timestamps. Creating a bug for testing. -- You are receiving this mail because: You are on the CC list for the bug. From hgbuildbot at kublai.com Fri Feb 22 22:00:12 2013 From: hgbuildbot at kublai.com (hgbuildbot at kublai.com) Date: Fri, 22 Feb 2013 20:00:12 -0800 Subject: buildbot success in Mercurial on OS X 10.7 hg tests Message-ID: <20130223040012.7850F2991A@hgbuildbot.cs.ubc.ca> The Buildbot has detected a restored build on builder OS X 10.7 hg tests while building hg. Full details are available at: http://hgbuildbot.kublai.com/builders/OS%20X%2010.7%20hg%20tests/builds/424 Buildbot URL: http://hgbuildbot.kublai.com/ Buildslave for this Build: lion Build Reason: scheduler Build Source Stamp: [branch default] c8c3887a24c1ee30b0afbdb6812e64bb64b400e6 Blamelist: Matt Mackall Build succeeded! sincerely, -The Buildbot From martin at geisler.net Sat Feb 23 05:24:19 2013 From: martin at geisler.net (Martin Geisler) Date: Sat, 23 Feb 2013 12:24:19 +0100 Subject: [PATCH RFC] update: add an option to allow to merge local changes when crossing branches In-Reply-To: <1033C124-F628-48EE-8B5E-F091571EDFF7@ringworld.org> (sfid-20130222_232014_218600_7DEE864F) (Kevin Bullock's message of "Fri, 22 Feb 2013 14:54:37 -0600") References: <567106adefd309717d8f.1361528527@fc8> <512771A6.8080209@grauw.nl> <7E8EBF7C-C984-4E02-A327-01A854C291B9@ringworld.org> <8738wokryh.fsf@hbox.dyndns.org> <1033C124-F628-48EE-8B5E-F091571EDFF7@ringworld.org> Message-ID: <87y5efjmsc.fsf@hbox.dyndns.org> Kevin Bullock writes: > On 22 Feb 2013, at 2:35 PM, Martin Geisler wrote: > >> Kevin Bullock writes: >> >>> On 22 Feb 2013, at 7:24 AM, Laurens Holst wrote: >>> >>>> I?m not entirely clear why this isn?t the default? Any update with >>>> local changes is performing a merge anyway (with all its risks for >>>> conflicts), so why would updating across branches need to be >>>> prohibited? >>> >>> Much greater likelihood of conflicts, and no way to get your local >>> changes back if you want to bail. >> >> We do save the original files when merging a dirty working copy into a >> target revisioon -- 'hg resolve --tool internal:local' will give them >> back to you even though they were never committed anywhere. > > Huh, how long have we been doing that? And more importantly, if we > allowed a cross-branch update, how would you get them back _after > updating back to your original place_? We've been doing it for ages, but despite my best efforts, it keeps surprising even very experienced users and developers :) As for getting the dirty files back after updating somewhere and back again, then it is a bit tricky. You need to make sure that your working copy has the dirty files after the first update. So after hg update $SOMEWHERE hg resolve --all --tool internal:local the files look like they did in your dirty working copy. If you do hg update $BACK hg resove --all --tool internal:local you will be back to where you started. If you modified the files after the first update, then it is the modified version you see after the second resolve. >> I don't know why you say the risk of conflicts is greater here than >> with any other update/merge? > > Simply because you're merging a larger set of changes, as you get to > below. As you say, a merge because of a dirty working copy will use * working copy parent (base) * dirty working copy (local) * update target (other) That ought to be an easy merge regardless of the update target since the difference between base and local is "small". I say "small" because I expect the diff present in the dirty working copy to be one commit. That is much smaller than most branch merges where the distance from local/other to base is 10, 100 or more commits. >>> To update across branches, it would have to apply _all_ the changes >>> between the common ancestor and the working copy, and write the >>> result into the working copy. Thus the likelihood of clobbering >>> uncommitted changes is much greater (and much more subject to >>> operator error in your merge tool of choice). >> >> I think you're saying that an update the crosses branches will tend >> to "span" a greater range of revisions than an update that is linear. >> >> That seems reasonable, but the underlying merge problem ought to be >> the same as if you had done a linear update across a big span of >> revisions. > > The theoretical problem is the same, but the _usability_ problem is > very different, both because of a likely larger set of conflicts > (merge early and often!), and because you'd have to do something > different to get back to your original state (and we'd likely have to > track more state outside of history). The risk of losing changes is certainly greater when they only live inside .hg/merge instead of in permanent history -- 100% agreed. My starting point was only that every single time I've had the "sorry, I wont help you update across branches" message I "fixed" it by updating twice and could continue with my work. -- Martin Geisler -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 835 bytes Desc: not available URL: From kbullock+mercurial at ringworld.org Sat Feb 23 09:07:07 2013 From: kbullock+mercurial at ringworld.org (Kevin Bullock) Date: Sat, 23 Feb 2013 09:07:07 -0600 Subject: [PATCH RFC] update: add an option to allow to merge local changes when crossing branches In-Reply-To: <87y5efjmsc.fsf@hbox.dyndns.org> References: <567106adefd309717d8f.1361528527@fc8> <512771A6.8080209@grauw.nl> <7E8EBF7C-C984-4E02-A327-01A854C291B9@ringworld.org> <8738wokryh.fsf@hbox.dyndns.org> <1033C124-F628-48EE-8B5E-F091571EDFF7@ringworld.org> <87y5efjmsc.fsf@hbox.dyndns.org> Message-ID: <12190966-640B-4627-8927-C72E0308B0B9@ringworld.org> On 23 Feb 2013, at 5:24 AM, Martin Geisler wrote: > Kevin Bullock writes: > >> On 22 Feb 2013, at 2:35 PM, Martin Geisler wrote: >> >>> I don't know why you say the risk of conflicts is greater here than >>> with any other update/merge? >> >> Simply because you're merging a larger set of changes, as you get to >> below. > > As you say, a merge because of a dirty working copy will use > > * working copy parent (base) > * dirty working copy (local) > * update target (other) > > That ought to be an easy merge regardless of the update target since the > difference between base and local is "small". > > I say "small" because I expect the diff present in the dirty working > copy to be one commit. That is much smaller than most branch merges > where the distance from local/other to base is 10, 100 or more commits. I was assuming that a cross-branch update would use: * common ancestor of target and WC (base) * dirty working copy (local) * update target on other branch (other) Is this not what the patch does? > My starting point was only that every single time I've had the "sorry, I > wont help you update across branches" message I "fixed" it by updating > twice and could continue with my work. Yes, no disputing that :) I do the same thing relatively regularly. pacem in terris / ??? / ?????? / ????????? / ?? Kevin R. Bullock From angel.ezquerra at gmail.com Sat Feb 23 12:24:02 2013 From: angel.ezquerra at gmail.com (Angel Ezquerra) Date: Sat, 23 Feb 2013 19:24:02 +0100 Subject: [PATCH RFC] update: add an option to allow to merge local changes when crossing branches In-Reply-To: <87y5efjmsc.fsf@hbox.dyndns.org> References: <567106adefd309717d8f.1361528527@fc8> <512771A6.8080209@grauw.nl> <7E8EBF7C-C984-4E02-A327-01A854C291B9@ringworld.org> <8738wokryh.fsf@hbox.dyndns.org> <1033C124-F628-48EE-8B5E-F091571EDFF7@ringworld.org> <87y5efjmsc.fsf@hbox.dyndns.org> Message-ID: On Sat, Feb 23, 2013 at 12:24 PM, Martin Geisler wrote: > Kevin Bullock writes: > >> On 22 Feb 2013, at 2:35 PM, Martin Geisler wrote: >> >>> Kevin Bullock writes: >>> >>>> On 22 Feb 2013, at 7:24 AM, Laurens Holst wrote: >>>> >>>>> I?m not entirely clear why this isn?t the default? Any update with >>>>> local changes is performing a merge anyway (with all its risks for >>>>> conflicts), so why would updating across branches need to be >>>>> prohibited? >>>> >>>> Much greater likelihood of conflicts, and no way to get your local >>>> changes back if you want to bail. >>> >>> We do save the original files when merging a dirty working copy into a >>> target revisioon -- 'hg resolve --tool internal:local' will give them >>> back to you even though they were never committed anywhere. >> >> Huh, how long have we been doing that? And more importantly, if we >> allowed a cross-branch update, how would you get them back _after >> updating back to your original place_? > > We've been doing it for ages, but despite my best efforts, it keeps > surprising even very experienced users and developers :) > > As for getting the dirty files back after updating somewhere and back > again, then it is a bit tricky. You need to make sure that your working > copy has the dirty files after the first update. > > So after > > hg update $SOMEWHERE > hg resolve --all --tool internal:local > > the files look like they did in your dirty working copy. If you do > > hg update $BACK > hg resove --all --tool internal:local > > you will be back to where you started. If you modified the files after > the first update, then it is the modified version you see after the > second resolve. That is a nice trick Martin! >>> I don't know why you say the risk of conflicts is greater here than >>> with any other update/merge? >> >> Simply because you're merging a larger set of changes, as you get to >> below. > > As you say, a merge because of a dirty working copy will use > > * working copy parent (base) > * dirty working copy (local) > * update target (other) > > That ought to be an easy merge regardless of the update target since the > difference between base and local is "small". > > I say "small" because I expect the diff present in the dirty working > copy to be one commit. That is much smaller than most branch merges > where the distance from local/other to base is 10, 100 or more commits. > >>>> To update across branches, it would have to apply _all_ the changes >>>> between the common ancestor and the working copy, and write the >>>> result into the working copy. Thus the likelihood of clobbering >>>> uncommitted changes is much greater (and much more subject to >>>> operator error in your merge tool of choice). >>> >>> I think you're saying that an update the crosses branches will tend >>> to "span" a greater range of revisions than an update that is linear. >>> >>> That seems reasonable, but the underlying merge problem ought to be >>> the same as if you had done a linear update across a big span of >>> revisions. >> >> The theoretical problem is the same, but the _usability_ problem is >> very different, both because of a likely larger set of conflicts >> (merge early and often!), and because you'd have to do something >> different to get back to your original state (and we'd likely have to >> track more state outside of history). > > The risk of losing changes is certainly greater when they only live > inside .hg/merge instead of in permanent history -- 100% agreed. > > My starting point was only that every single time I've had the "sorry, I > wont help you update across branches" message I "fixed" it by updating > twice and could continue with my work. I also do this somethings although in other cases I either shelve my changes or commit and rebase. It seems that having to update back to an ancestor doubles the changes of making an error while merging? Angel From bboissin at gmail.com Sat Feb 23 16:01:55 2013 From: bboissin at gmail.com (Benoit Boissinot) Date: Sat, 23 Feb 2013 23:01:55 +0100 Subject: [PATCH 1 of 2] util: generalize bytecount to unitcount In-Reply-To: <19d3300883ce1407d0b5.1361482381@australite.local> References: <19d3300883ce1407d0b5.1361482381@australite.local> Message-ID: On Thu, Feb 21, 2013 at 10:33 PM, Bryan O'Sullivan wrote: > # HG changeset patch > # User Bryan O'Sullivan > # Date 1361482359 28800 > # Node ID 19d3300883ce1407d0b527549a82f25d3f182873 > # Parent 5779b305bf3a9192823252b8caf2240124238706 > util: generalize bytecount to unitcount > > This gives us a function we can reuse to count units of other kinds. > > diff --git a/mercurial/util.py b/mercurial/util.py > --- a/mercurial/util.py > +++ b/mercurial/util.py > @@ -1268,7 +1268,18 @@ def ellipsis(text, maxlength=400): > except (UnicodeDecodeError, UnicodeEncodeError): > return _ellipsis(text, maxlength)[0] > > -_byteunits = ( > +def unitcount(*unittable): > + '''return a count of some quantity formatted as a readable string''' > Maybe call it unitcountfn? (or something similar), since it's not directly usable (returns a function). (I also think the docstring could be improved). Otherwise looks good to me. Cheers, Benoit -------------- next part -------------- An HTML attachment was scrubbed... URL: From bboissin at gmail.com Sat Feb 23 16:05:04 2013 From: bboissin at gmail.com (Benoit Boissinot) Date: Sat, 23 Feb 2013 23:05:04 +0100 Subject: [PATCH 2 of 2] util: add a timed function for use during development In-Reply-To: <95cb8d7754a7a28f52f8.1361482382@australite.local> References: <19d3300883ce1407d0b5.1361482381@australite.local> <95cb8d7754a7a28f52f8.1361482382@australite.local> Message-ID: On Thu, Feb 21, 2013 at 10:33 PM, Bryan O'Sullivan wrote: > # HG changeset patch > # User Bryan O'Sullivan > # Date 1361482360 28800 > # Node ID 95cb8d7754a7a28f52f82a332bf1163eb6dea202 > # Parent 19d3300883ce1407d0b527549a82f25d3f182873 > util: add a timed function for use during development > > I often want to measure the cost of a function call before/after > an optimization, where using top level "hg --time" timing introduces > enough other noise that I can't tell if my efforts are having an > effect. > > This decorator allows a developer to measure a function's cost with > finer granularity. > > diff --git a/mercurial/util.py b/mercurial/util.py > --- a/mercurial/util.py > +++ b/mercurial/util.py > @@ -1872,3 +1872,45 @@ def isatty(fd): > return fd.isatty() > except AttributeError: > return False > + > +timecount = unitcount( > + (1, 1e3, _('%.0f s')), > + (100, 1, _('%.1f s')), > + (10, 1, _('%.2f s')), > + (1, 1, _('%.3f s')), > + (100, 1e-3, _('%.1f ms')), > + (10, 1e-3, _('%.2f ms')), > + (1, 1e-3, _('%.3f ms')), > + (100, 1e-6, _('%.1f us')), > + (10, 1e-6, _('%.2f us')), > + (1, 1e-6, _('%.3f us')), > + (100, 1e-9, _('%.1f ns')), > + (10, 1e-9, _('%.2f ns')), > + (1, 1e-9, _('%.3f ns')), > + ) > + > +_timenesting = [0] > + > +def timed(func): > + '''Report the execution time of a function call to stderr. > + > + During development, use as a decorator when you need to measure > + the cost of a function, e.g. as follows: > + > + @util.timed > + def foo(a, b, c): > + pass > + ''' > + > + def wrapper(*args, **kwargs): > + start = time.time() > + _timenesting[0] += 2 > I'm a bit puzzled by the 2. Any hint? > + try: > + return func(*args, **kwargs) > + finally: > + elapsed = time.time() - start > + _timenesting[0] -= 2 > + sys.stderr.write('%s%s: %s\n' % > + (' ' * _timenesting[0], func.__name__, > + timecount(elapsed))) > + return wrapper > _______________________________________________ > Mercurial-devel mailing list > Mercurial-devel at selenic.com > http://selenic.com/mailman/listinfo/mercurial-devel > -------------- next part -------------- An HTML attachment was scrubbed... URL: From simohe at besonet.ch Sat Feb 23 16:10:49 2013 From: simohe at besonet.ch (Simon Heimberg) Date: Sat, 23 Feb 2013 23:10:49 +0100 Subject: [PATCH 0 of 2] add and remove glob to test output Message-ID: This patches where written after watching the output of a windows build at hgbuildbot[1]. patch 1 fixes a test failure on windows by appending glob patch 2 removes unnecessary glob lines. They were printed prefixed with "Info, unnecessary glob:" in the output of run-tests.py. The modifications in test-subrepo.t look a bit suspect. Why does pushthing subrepo s to $TESTTMP/t/s not need a glob, but pushing subrepo s/ss to $TESTTMP/t/s/ss needs it? Which of the four slashes is written as a backslash? I did not run the tests on windows because I do not have a machine able to do this. [1] http://hgbildbot.kublai.com/builders/Windows%202008%20R2%20hg%20tests/builds/450 From simohe at besonet.ch Sat Feb 23 16:10:50 2013 From: simohe at besonet.ch (Simon Heimberg) Date: Sat, 23 Feb 2013 23:10:50 +0100 Subject: [PATCH 1 of 2] tests: append glob to filename output when required for windows In-Reply-To: References: Message-ID: <3660cfb8b145e88b7722.1361657450@deb64virt.virtual> # HG changeset patch # User Simon Heimberg # Date 1361653658 -3600 # Branch stable # Node ID 3660cfb8b145e88b77228a1676d5c37113d93595 # Parent 7790d69af6d6bd72b4d5495c6a75abdc75cbeb33 tests: append glob to filename output when required for windows The test failed on windows before this patch. diff -r 7790d69af6d6 -r 3660cfb8b145 tests/test-blackbox.t --- a/tests/test-blackbox.t Fri Feb 22 10:05:22 2013 -0800 +++ b/tests/test-blackbox.t Sat Feb 23 22:07:38 2013 +0100 @@ -48,7 +48,7 @@ adding c $ cd ../blackboxtest2 $ hg pull - pulling from $TESTTMP/blackboxtest + pulling from $TESTTMP/blackboxtest (glob) searching for changes adding changesets adding manifests From simohe at besonet.ch Sat Feb 23 16:10:51 2013 From: simohe at besonet.ch (Simon Heimberg) Date: Sat, 23 Feb 2013 23:10:51 +0100 Subject: [PATCH 2 of 2] tests: remove glob lines which unnecessary match / for \ on windows In-Reply-To: References: Message-ID: <3312b3d481a6e61f9881.1361657451@deb64virt.virtual> # HG changeset patch # User Simon Heimberg # Date 1361656497 -3600 # Branch stable # Node ID 3312b3d481a6e61f988125d4472b53c7a0b00211 # Parent 3660cfb8b145e88b77228a1676d5c37113d93595 tests: remove glob lines which unnecessary match / for \ on windows This lines were reported as unnecessary when running the tests on windows because the path was already printed with a slash and not a backslash. diff -r 3660cfb8b145 -r 3312b3d481a6 tests/test-blackbox.t --- a/tests/test-blackbox.t Sat Feb 23 22:07:38 2013 +0100 +++ b/tests/test-blackbox.t Sat Feb 23 22:54:57 2013 +0100 @@ -57,7 +57,7 @@ (run 'hg update' to get a working copy) $ hg blackbox -l 3 1970/01/01 00:00:00 bob> pull - 1970/01/01 00:00:00 bob> 1 incoming changes - new heads: d02f48003e62 (glob) + 1970/01/01 00:00:00 bob> 1 incoming changes - new heads: d02f48003e62 1970/01/01 00:00:00 bob> pull exited None after * seconds (glob) extension and python hooks - use the eol extension for a pythonhook diff -r 3660cfb8b145 -r 3312b3d481a6 tests/test-diff-color.t --- a/tests/test-diff-color.t Sat Feb 23 22:07:38 2013 +0100 +++ b/tests/test-diff-color.t Sat Feb 23 22:54:57 2013 +0100 @@ -152,7 +152,7 @@ c c \x1b[0;32m+aa\x1b[0m (esc) - \x1b[0;1mdiff --git a/sub/b b/sub/b\x1b[0m (glob) (esc) + \x1b[0;1mdiff --git a/sub/b b/sub/b\x1b[0m (esc) \x1b[0;31;1m--- a/sub/b\x1b[0m (esc) \x1b[0;32;1m+++ b/sub/b\x1b[0m (esc) \x1b[0;35m@@ -1,1 +1,2 @@\x1b[0m (esc) diff -r 3660cfb8b145 -r 3312b3d481a6 tests/test-subrepo.t --- a/tests/test-subrepo.t Sat Feb 23 22:07:38 2013 +0100 +++ b/tests/test-subrepo.t Sat Feb 23 22:54:57 2013 +0100 @@ -269,9 +269,9 @@ $ cd .. $ hg clone t tc updating to branch default - cloning subrepo s from $TESTTMP/t/s (glob) + cloning subrepo s from $TESTTMP/t/s cloning subrepo s/ss from $TESTTMP/t/s/ss (glob) - cloning subrepo t from $TESTTMP/t/t (glob) + cloning subrepo t from $TESTTMP/t/t 3 files updated, 0 files merged, 0 files removed, 0 files unresolved $ cd tc $ hg debugsub @@ -292,10 +292,10 @@ pushing subrepo s/ss to $TESTTMP/t/s/ss (glob) searching for changes no changes found - pushing subrepo s to $TESTTMP/t/s (glob) + pushing subrepo s to $TESTTMP/t/s searching for changes no changes found - pushing subrepo t to $TESTTMP/t/t (glob) + pushing subrepo t to $TESTTMP/t/t searching for changes adding changesets adding manifests @@ -317,7 +317,7 @@ pushing subrepo s/ss to $TESTTMP/t/s/ss (glob) searching for changes no changes found - pushing subrepo s to $TESTTMP/t/s (glob) + pushing subrepo s to $TESTTMP/t/s searching for changes abort: push creates new remote head 12a213df6fa9! (in subrepo s) (did you forget to merge? use push -f to force) @@ -327,13 +327,13 @@ pushing subrepo s/ss to $TESTTMP/t/s/ss (glob) searching for changes no changes found - pushing subrepo s to $TESTTMP/t/s (glob) + pushing subrepo s to $TESTTMP/t/s searching for changes adding changesets adding manifests adding file changes added 1 changesets with 1 changes to 1 files (+1 heads) - pushing subrepo t to $TESTTMP/t/t (glob) + pushing subrepo t to $TESTTMP/t/t searching for changes no changes found searching for changes @@ -366,7 +366,7 @@ should pull t $ hg up - pulling subrepo t from $TESTTMP/t/t (glob) + pulling subrepo t from $TESTTMP/t/t searching for changes adding changesets adding manifests @@ -572,7 +572,7 @@ adding .hgsub $ hg clone repo repo2 updating to branch default - cloning subrepo s from $TESTTMP/repo/s (glob) + cloning subrepo s from $TESTTMP/repo/s 2 files updated, 0 files merged, 0 files removed, 0 files unresolved $ hg -q -R repo2 pull -u $ echo 1 > repo2/s/a From kbullock+mercurial at ringworld.org Sat Feb 23 21:33:21 2013 From: kbullock+mercurial at ringworld.org (Kevin Bullock) Date: Sat, 23 Feb 2013 21:33:21 -0600 Subject: [PATCH 1 of 2 V5] test-archive: gracefully handle HTTPErrors on get-with-headers In-Reply-To: <2f7b559540108a021cba.1361142840@Angel-PC.localdomain> References: <2f7b559540108a021cba.1361142840@Angel-PC.localdomain> Message-ID: On 17 Feb 2013, at 5:14 PM, Angel Ezquerra wrote: > # HG changeset patch > # User Angel Ezquerra > # Date 1360141605 -3600 > # Node ID 2f7b559540108a021cba31c0c7affa011ef119cc > # Parent 013fcd112f13f31a35ea6a40d8cd1c6923cdaf20 > test-archive: gracefully handle HTTPErrors on get-with-headers > > This avoids pritting out a traceback when a get-with-headers call causes hgweb > to respond with an HTTPError code. That's one of two things you did in this patch. The other was optionally adding the 'file' argument to the request string. This should be split up. pacem in terris / ??? / ?????? / ????????? / ?? Kevin R. Bullock From matt_harbison at yahoo.com Sun Feb 24 02:20:52 2013 From: matt_harbison at yahoo.com (Matt Harbison) Date: Sun, 24 Feb 2013 03:20:52 -0500 Subject: [PATCH 1 of 3] pull: add --subrepos flag In-Reply-To: References: <5125A8BA.8020106@yahoo.com> Message-ID: <5129CD64.3050904@yahoo.com> Angel Ezquerra wrote: > On Thu, Feb 21, 2013 at 5:55 AM, Matt Harbison wrote: >> Angel Ezquerra wrote: >>> On Wed, Feb 20, 2013 at 6:57 AM, Matt >>> Harbison wrote: >>>> On Sun, 17 Feb 2013 13:19:16 +0100, Angel Ezquerra wrote: >>>> >>>>> # HG changeset patch # User Angel >>>>> Ezquerra # Date 1360519226 -3600 # Node >>>>> ID abbd26cca35280fb8f784b3f2c02eef71696c47b # Parent >>>>> 55b9b294b7544a6a144f627f71f4b770907d5a98 pull: add --subrepos >>>>> flag >>>>> >>>>> The purpose of this new flag is to ensure that you are able to >>>>> update to any incoming revision without requiring any network >>>>> access. The idea is to make sure that the repository is >>>>> self-contained after doing hg pull --subrepos, as long as it >>>>> already was self-contained before the pull). >>>>> >>>>> When the --subrepos flag is enabled, pull will also pull (or >>>>> clone) all subrepos that are present on the current revision and >>>>> those that are referenced by any of the incoming revisions. >>>> I haven't gotten a chance to really play with this yet, so I'm >>>> going more off the comments here- I apologize if these answers >>>> should be obvious, but I'm not familiar enough with some of the >>>> code. >>>> >>>> - Is there an easy way to tell if the repo is/was self contained? >>>> (Maybe incoming -S?) >>> >>> No there is not. I don't think incoming -S would do the trick since >>> that would just tell you if there are _new_ incoming revisions on >>> some of the _current_ subrepos. A repo is "self-contained" if it is >>> possible to update to any of its revisions withing requiring a pull >>> of one or more of its subrepos. >>> >>> I don't know of any existing mercurial command that would be able to >>> give you that information. >>> >>>> - Is the 'self-contained' bit to limit overhead on each pull, or is >>>> there another reason this can't ensure the result is self >>>> contained? 'Push' and 'outgoing -S' recognize (almost) everything >>>> going in the other direction, so it might be nice to have the same >>>> capability with a form of pull. (I may have found a push bug that >>>> I haven't gotten back to yet.) >>> >>> I'm not sure I understand what you mean. >> >> Consider this (contrived) case: >> >> 1) push a repo and subrepo to remote (remote is now self contained) >> 2) strip or rollback the remote subrepo >> 3) a top level local repo push will repopulate the remote subrepo >> >> Now reverse it: >> >> 1) pull a repo and subrepo from remote (local is self contained) >> 2) strip or rollback the local subrepo >> 3) nothing is incoming top level, so the subrepo isn't repopulated (if >> you've updated to a working dir without that subrepo). >> >> I'm not sure if there's a less contrived case, or if this matters too >> much. I guess I was just wondering aloud about the symmetry between >> push and pull -S (this is certainly much better than it was). > > I don't think this is a very big deal because "pull --subrepos" also > performs a pull on all the repositories that are found on the current > revision. I think this would fix your contrived case. > > The only corner case that would not be properly handled by this would > be the case in which pull --subrepos cloned a _new_ subrepo that is > not found on the current revision (i.e. that is introduced on one of > the cloned revisions) and then you striped some revisions from that > "future subrepo". In that case would would still be able to get the > missing revisions as you would do today, i.e. by updating to the > offending revision. You could also use the onsub extension (which is > shipped with TortoiseHg). > > BTW, the more I use the onsub extension the more I am convinced that > it should be distributed with mercurial, and even that the onsub > command itself should become a built-in command. I'd be fine with that. I haven't used it, but from what I've read, it seems like a useful crutch to do things that aren't currently possible because they aren't well defined, like tagging all repos or opening a branch. But ideally there wouldn't be a need for it with commands that accept a -S. The principle of least surprise says those commands can handle subrepos already. > That being said, if we did want to also handle this very small corner > case there are at least a couple of possible solutions: > > 1. make the --subrepos flag take a revset that would tell it which > revisions to look for subrepos to pull. Why not use the -r option? But really, I think in this case 'pull -S' == 'pull -S -r all()', so I'm not sure if that helps. > 2. make --subrepos also look for subrepos on the descendants of the > current revision. > > #1 would be nice _if_ we could also skip the revset to get the > behavior that the current patch proposes. However I don't think that > is possible to have a flag that can optionally take a parameter. Agreed. A special case parameter isn't nice. > #2... maybe that is too much overhead for such a small corner case? Not sure.. That's why I was asking if there's large repos to benchmark on :-). The other thing I'm wondering is, since we seem to have various caches, maybe caching subrepo info would speed things up? I have no idea what form this would take, or even how the existing caches are invalidated, detect corruption, etc. The construct I've got in my push patches is: f = repo.wjoin('.hgsubstate') revs = repo.revs('(adds(%s) or modifies(%s)) and ::(%ln)', f, f, revs) I'm not sure if this helps cut down overhead- you do have to traverse the whole repo, but you don't have to process the .hgsubstate file for revisions where the subrepos don't change. (Though you referenced having the latest path for the repo, and that can change without affecting .hgsubstate, so this may not be useful anyway.) > Additionally, I wonder if it would make sense to change the current > pull behavior a little, by checking if any of the subrepos that are > present on the _current_ parent revision point to a revision that does > not exist, and if that is the case fulling from them _up to that > revision_? I think the parent pull time is an excellent time to do > this kind of stuff since you already know that you have an internet > connection... Can you show a short test case or pseudo test case of this? I'm not sure what you're suggesting here. Wouldn't the existing pull bring in all of the changes to the tip of each subrepo now? Why back off on that without a -r option? >> I realize you can't do such a thing without crawling most of the >> history. Are there large public repositories that use subrepos? I'm >> wondering what the performance hit would be. (It's easy for me to think >> something is a good idea when I only have small repos and wouldn't >> notice the hit.) > > We have repositories with thousands of files and more than 20 > subrepos. I don't know if you would consider that big... Not sure. I'm assuming that the number of commits is the governing factor when walking the history? But that's almost certainly going to be larger than the toy repos I make, or even the real ones I use at work (still less than 1000 in the subrepo, and probably less than 200 on the parent). Just looking for something to run benchmarks on. >> FWIW, largefiles works the same way- if you don't clone or pull with >> --all-largefiles, there's no single command to go back and get the files >> for all revisions that are not incoming. That leaves the user wondering >> if they really can disconnect from the central repo. > > That is true. It would be nice to be able to do that. However there is > a difference between largefiles and subrepos. Largefiles tries to only > get the files that you need, when you need them _by design_. Subrepos > is not meant (IMHO) to do that (or at least it is not necessary for > subrepos to fulfill its main purpose, which is to track "submodules"). I agree with you about subrepos, but the --all-largefiles flag is a new(ish) feature that lets you override that original largefiles design, so you can disconnect from the central repo. (So a very similar motivation for this.) I was going to put in a command to download missing largefiles, but never got around to it. But I don't think a new command would be an option for subrepos if we don't get this right, because it really is just a pull. If we can change the pull command in the future if there's a need to handle this, then it may not be that big of a deal now. And I suspect the only hinderance to adding it later will be if there's a big performance drop. >>> I don't think you (we?) must give too much importance to this >>> "self-contained" concept. It is just a way for me to explain the >>> purpose of the patch, and specially to explain why we must look for >>> subrepos on all the new incoming revisions, and why we cannot just >>> limit ourselves to pulling the subrepos on the current revisions >>> (short answer: because new subrepos may appear on the new, incoming >>> revisions). >>> >>> My patch explicitly says that hg pull -S will only make your subrepo >>> self-contained if it was already self-contained before. This is in >>> order to avoid having to look for subrepos on all the repo history, >>> rather than just looking for subrepos on the incoming revision (and >>> the current one). >>> >>>> - The full subrepo gets pulled, even revs not committed to the >>>> parent? I think that's a good thing, because regularly get burned >>>> when I 'pull -u' the tree to another machine and then go to apply >>>> the rest of a patch queue to the subrepo. >>> >>> Yes. It is perhaps not optimal but I think it is simpler. In >>> addition if different parent repo revisions point to different >>> revisions on a subrepo there is no way for us to tell which of those >>> subrepo revisions is the one that is closes to tip, or which ones >>> are ancestors of the other ones, etc. As a result we would need to >>> perform as many pulls on a given repo as the number of different >>> revisions of that subrepo that were referenced on the parent repo. >>> That is complex and slow, so it is much simpler and possibly faster >>> (in some cases at least) to just pull all revisions from each >>> subrepo. >> >> OK, I misread the code- I thought each subrepo was getting a pull at >> each revision, which I figured would be slow. I attached a test patch >> below- there's nothing special about it, but it helped me with my pull >> and outgoing changes (some comments probably still reflect this), so I >> changed that to pull and incoming to test your patch. >> >> - I think I see a double pull of a subrepo (search for "hg pull -S -r 3"). > > You are right. There is a problem with the current version of the > patch. It will clone the same repo multiple times if the same subrepo > refers to different revisions. I will resend with a fix. > > BTW, where do you think the tests for this new feature should go? > Should it go into one of the test-pull*.t files or in one of the > test-subrepo*.t files? Do you think the test that you propose in that > patch would be enough to test this new feature? Maybe it could be made > a bit simpler? > I assumed it would go in test-subrepo*t, so anyone hacking on subrepos doesn't have to find it in an obscure test, but I can see the same argument from someone working on pull(). Probably what tips it to subrepo*t though is that there is some existing subrepo infrastructure that doesn't exist in test-pull*t. I'm not sure that it's comprehensive, and there's probably some duplication. I put it together to e.g. test 'push -r 2' then 'push -r 4', and make sure the grandchild repo code path got exercised. Since you aren't doing anything with -r, there may be duplicate pull tests. The incoming tests probably aren't relevant either, though I think they should agree on what they are doing eventually. Those tests also didn't exercise the subrepo pull path (the dests were empty, so clone was used). I marked various potential issues in there with 'XXX'. One thing I did specifically was to skew the rev values between the parent and child, so parent rev 1 doesn't lock in subrepo rev 1. This makes it easier to test with the -r option (which I realize you aren't doing now, but might be a nice to have in the future). >> - I wonder if the code in this patch can be leveraged to make incoming >> print all of the stuff 'pull -S' will grab in the future. > > In theory that would be certainly possible. At least we could run the > same "look for subrepos to pull" code and show the list of subrepos > that would be pulled and then run incoming on them. The main problem > is that incoming already has a --subrepos flag, which does something > slightly different... I'm not sure that could be changed... I think it just recurses into the subrepo and does an incoming on it. If it does something else, it's too subtle for me to have noticed. I've probably stated bits and pieces of this over the course of a week or so, but just to explicitly put it all together, I think in an ideal world we would have new pull/incoming, and push/outgoing agree with the same options, and each group is the reverse of the other. It may be fantasy, but: incoming pull operation current behavior, parent repo only xxx [1] -u current behavior, pull subrepo on update -S -S (this patch) pull parent + all subrepos to tip -S -r -S -r (future) pull parent to rev, revs of subrepos used up to that rev [1] It doesn't seem sensible to add -u to incoming for this, so leaving no equivalent form is probably best. outgoing push operation [2] current, parent only and all respectively -S [3] current, push parent + all subrepos to tip -S -r -r (future) push parent to rev, revs of subrepos used up to that rev [2] It seems buggy to me that the no arg forms disagree, since outgoing's help says "These are the changesets that would be pushed if a push was requested." But that ship has probably already sailed. [3] There is no form of push that takes -S So the last two lines in each table align in functionality and (roughly) in arguments. >>>> I'll try to experiment with this some in the next few days. I ran >>>> into issues with what I'm working on (push, outgoing) with deeply >>>> nested subrepos, and also when a parent locks in an earlier subrepo >>>> version. I wonder if deeply nested subrepos will be a problem here >>>> since hgsubrepo.pull() doesn't walk its subrepos and pull them. >>> >>> I must confess that I have not tried that too much. We should >>> definitely do this recursively. That being said I hope to get some >>> feedback on the current version that I sent to the list first. >> >> Sorry, I got crossed up on that too. hgsubrepo.pull() ends up calling >> _repo.pull(), so it does recurse. > > You are right. That's nice! :-) > >> The test below indicates that clone won't >> recurse- it reminds that an update is needed. (Maybe clone needs a -S too >> as part of these changes? If you aren't walking the history, I >> don't see a way around that because nothing is incoming after a clone, >> so you won't see subrepos of a cloned subrepo.) > > I guess that would make sense in another patch. > >> The other thing worth a test is largefiles- the --all-largefiles >> option isn't passed to subrepos, so as it stands, 'pull -S' won't let >> you really disconnect, because largefiles in subrepos won't be cached. That >> can be fixed later. > > I agree. We do not really use largefiles (yet) so we have not come > across this (yet) but I'm sure this is something we would like to > improve as well. > > One last thing, did you have time to have a look at the code of the > patch series itself? I plan to send an slighly changed version of the > patch series that will only change the first patch to fix the issue > you found (the fix is minimal so the code should be almost the same). > Do you have any comments? I did, but I'm not as well versed in this area of code- that's why I've kept the conversation fairly high level. I was able to follow your commit message and it looks like the code does what it says. Just curious- is specifying None as the revision the right thing to do in pull()? AFAICT, None gives you the working directory... so does that change the results based on what the subrepo is currently updated to? > Thanks for looking into this. > > Angel > From bboissin at gmail.com Sun Feb 24 11:31:21 2013 From: bboissin at gmail.com (Benoit Boissinot) Date: Sun, 24 Feb 2013 18:31:21 +0100 Subject: [PATCH 0 of 2] add and remove glob to test output In-Reply-To: References: Message-ID: Pushed to crew, thanks (the push vs. pull on subrepo indeed sound fishy). On Sat, Feb 23, 2013 at 11:10 PM, Simon Heimberg wrote: > This patches where written after watching the output of a windows build at > hgbuildbot[1]. > > patch 1 fixes a test failure on windows by appending glob > patch 2 removes unnecessary glob lines. They were printed prefixed with > "Info, unnecessary glob:" in the output of run-tests.py. > > The modifications in test-subrepo.t look a bit suspect. Why does > pushthing subrepo s to $TESTTMP/t/s > not need a glob, but > pushing subrepo s/ss to $TESTTMP/t/s/ss > needs it? Which of the four slashes is written as a backslash? > > I did not run the tests on windows because I do not have a machine able to > do > this. > > > [1] > http://hgbildbot.kublai.com/builders/Windows%202008%20R2%20hg%20tests/builds/450 > _______________________________________________ > Mercurial-devel mailing list > Mercurial-devel at selenic.com > http://selenic.com/mailman/listinfo/mercurial-devel > -------------- next part -------------- An HTML attachment was scrubbed... URL: From mpm at selenic.com Sun Feb 24 13:40:56 2013 From: mpm at selenic.com (Matt Mackall) Date: Sun, 24 Feb 2013 13:40:56 -0600 Subject: [PATCH 1 of 2] tests: append glob to filename output when required for windows In-Reply-To: <3660cfb8b145e88b7722.1361657450@deb64virt.virtual> References: <3660cfb8b145e88b7722.1361657450@deb64virt.virtual> Message-ID: <1361734856.11033.42.camel@calx> On Sat, 2013-02-23 at 23:10 +0100, Simon Heimberg wrote: > # HG changeset patch > # User Simon Heimberg > # Date 1361653658 -3600 > # Branch stable > # Node ID 3660cfb8b145e88b77228a1676d5c37113d93595 > # Parent 7790d69af6d6bd72b4d5495c6a75abdc75cbeb33 > tests: append glob to filename output when required for windows > > The test failed on windows before this patch. I think I'm going to start insisting that such patches come with check-code recipes. It's the only hope we have for not hitting these issues constantly. -- Mathematics is the supreme nostalgia of our time. From hgbuildbot at kublai.com Sun Feb 24 16:30:01 2013 From: hgbuildbot at kublai.com (hgbuildbot at kublai.com) Date: Sun, 24 Feb 2013 14:30:01 -0800 Subject: buildbot failure in Mercurial on OS X 10.7 hg tests Message-ID: <20130224223002.4028D29912@hgbuildbot.cs.ubc.ca> The Buildbot has detected a new failure on builder OS X 10.7 hg tests while building hg. Full details are available at: http://hgbuildbot.kublai.com/builders/OS%20X%2010.7%20hg%20tests/builds/425 Buildbot URL: http://hgbuildbot.kublai.com/ Buildslave for this Build: lion Build Reason: scheduler Build Source Stamp: [branch default] 0ade08dcb3c3d9a1418f38bf875d6c737750b19f Blamelist: Simon Heimberg BUILD FAILED: failed run-tests.py (python2.7) pure sincerely, -The Buildbot From mercurial-bugs at selenic.com Sun Feb 24 20:38:10 2013 From: mercurial-bugs at selenic.com (mercurial-bugs at selenic.com) Date: Mon, 25 Feb 2013 02:38:10 +0000 Subject: [Bug 3839] New: hg merge w/o any revision returns IndexError: list index out of range (hg 2.3) Message-ID: http://bz.selenic.com/show_bug.cgi?id=3839 Priority: normal Bug ID: 3839 CC: mercurial-devel at selenic.com Assignee: bugzilla at selenic.com Summary: hg merge w/o any revision returns IndexError: list index out of range (hg 2.3) Severity: bug Classification: Unclassified OS: Linux Reporter: dilipm79 at gmail.com Hardware: PC Status: UNCONFIRMED Version: 2.3 Component: Mercurial Product: Mercurial > hg lg -l7 o 78:2741db467722 devel Added tag REL-0.1 for changeset 32de7130783c (18 minutes ago by Dilip M) tip | | @ 77:bc961b7ec5e5 Polished ui (2 days ago by Dilip M) [redesign] | |\ | o \ 76:67a412b0c9fa devel 3 way merge: (2 months ago by Dilip M) | |\ \ | o | | 75:7bd75655b902 devel display only the leaf in build dir (2 months ago by Dilip M) |/ / / o | | 74:32de7130783c devel final ui (2 months ago by Dilip M) REL-0.1 | | | o | | 73:9d5a9bfe6c7b devel ui - backup (2 months ago by Dilip M) | | | o | | 72:76645d5d6373 devel ui - backup (2 months ago by Dilip M) | | | > hg --debug merge ** unknown exception encountered, please report by visiting ** http://mercurial.selenic.com/wiki/BugTracker ** Python 2.6.5 (r265:79063, Apr 16 2010, 13:09:56) [GCC 4.4.3] ** Mercurial Distributed SCM (version 2.3) ** Extensions loaded: mq, graphlog, color, pager, extdiff Traceback (most recent call last): File "/home/dim/bin/hg", line 38, in mercurial.dispatch.run() File "/home/dim/lib/python/mercurial/dispatch.py", line 28, in run sys.exit((dispatch(request(sys.argv[1:])) or 0) & 255) File "/home/dim/lib/python/mercurial/dispatch.py", line 65, in dispatch return _runcatch(req) File "/home/dim/lib/python/mercurial/dispatch.py", line 88, in _runcatch return _dispatch(req) File "/home/dim/lib/python/mercurial/dispatch.py", line 740, in _dispatch cmdpats, cmdoptions) File "/home/dim/lib/python/mercurial/dispatch.py", line 514, in runcommand ret = _runcommand(ui, options, cmd, d) File "/home/dim/lib/python/mercurial/extensions.py", line 189, in wrap return wrapper(origfn, *args, **kwargs) File "/home/dim/lib/python/hgext/pager.py", line 130, in pagecmd return orig(ui, options, cmd, cmdfunc) File "/home/dim/lib/python/mercurial/extensions.py", line 189, in wrap return wrapper(origfn, *args, **kwargs) File "/home/dim/lib/python/hgext/color.py", line 364, in colorcmd return orig(ui_, opts, cmd, cmdfunc) File "/home/dim/lib/python/mercurial/dispatch.py", line 830, in _runcommand return checkargs() File "/home/dim/lib/python/mercurial/dispatch.py", line 801, in checkargs return cmdfunc() File "/home/dim/lib/python/mercurial/dispatch.py", line 737, in d = lambda: util.checksignature(func)(ui, *args, **cmdoptions) File "/home/dim/lib/python/mercurial/util.py", line 472, in check return func(*args, **kwargs) File "/home/dim/lib/python/mercurial/extensions.py", line 144, in wrap util.checksignature(origfn), *args, **kwargs) File "/home/dim/lib/python/mercurial/util.py", line 472, in check return func(*args, **kwargs) File "/home/dim/lib/python/hgext/mq.py", line 3528, in mqcommand return orig(ui, repo, *args, **kwargs) File "/home/dim/lib/python/mercurial/util.py", line 472, in check return func(*args, **kwargs) File "/home/dim/lib/python/mercurial/commands.py", line 4288, in merge if parent == nbhs[0]: IndexError: list index out of range OS: Ubuntu installed on Virtualbox. > lsb_release -a No LSB modules are available. Distributor ID: Ubuntu Description: Ubuntu 10.04.4 LTS Release: 10.04 Codename: lucid -- You are receiving this mail because: You are on the CC list for the bug. From mercurial-bugs at selenic.com Sun Feb 24 22:01:48 2013 From: mercurial-bugs at selenic.com (mercurial-bugs at selenic.com) Date: Mon, 25 Feb 2013 04:01:48 +0000 Subject: [Bug 3840] New: Unknown exception during "hg import" or "hg serve" Message-ID: http://bz.selenic.com/show_bug.cgi?id=3840 Priority: normal Bug ID: 3840 CC: mercurial-devel at selenic.com Assignee: bugzilla at selenic.com Summary: Unknown exception during "hg import" or "hg serve" Severity: bug Classification: Unclassified OS: Windows Reporter: sempasha at gmail.com Hardware: PC Status: UNCONFIRMED Version: 2.5.1 Component: Mercurial Product: Mercurial Created attachment 1715 --> http://bz.selenic.com/attachment.cgi?id=1715&action=edit patch file I've got "Unknown exception" error when try to import any path to my repo or try to start stand-alone web server with `hg serve` D:\vhosts\wmc.tv>hg import E:\TEMP\UncommittedChanges.patch applying E:\TEMP\UncommittedChanges.patch ** unknown exception encountered, please report by visiting ** http://mercurial.selenic.com/wiki/BugTracker ** Python 2.7.3 (default, Apr 10 2012, 23:24:47) [MSC v.1500 64 bit (AMD64)] ** Mercurial Distributed SCM (version 2.5.1) ** Extensions loaded: Traceback (most recent call last): File "hg", line 38, in File "mercurial\dispatch.pyc", line 28, in run File "mercurial\dispatch.pyc", line 65, in dispatch File "mercurial\dispatch.pyc", line 88, in _runcatch File "mercurial\dispatch.pyc", line 743, in _dispatch File "mercurial\dispatch.pyc", line 514, in runcommand File "mercurial\dispatch.pyc", line 833, in _runcommand File "mercurial\dispatch.pyc", line 804, in checkargs File "mercurial\dispatch.pyc", line 740, in File "mercurial\util.pyc", line 475, in check File "mercurial\commands.pyc", line 3936, in import_ File "mercurial\hg.pyc", line 97, in openpath File "mercurial\url.pyc", line 475, in open File "urllib2.pyc", line 400, in open File "urllib2.pyc", line 418, in _open File "urllib2.pyc", line 378, in _call_chain File "urllib2.pyc", line 1310, in file_open File "urllib2.pyc", line 1335, in open_local_file File "mimetypes.pyc", line 294, in guess_type File "mimetypes.pyc", line 355, in init File "mimetypes.pyc", line 259, in read_windows_registry File "mimetypes.pyc", line 249, in enum_types UnicodeDecodeError: 'ascii' codec can't decode byte 0xe0 in position 0: ordinal not in range(128) D:\vhosts\wmc.tv>hg serve ** unknown exception encountered, please report by visiting ** http://mercurial.selenic.com/wiki/BugTracker ** Python 2.7.3 (default, Apr 10 2012, 23:24:47) [MSC v.1500 64 bit (AMD64)] ** Mercurial Distributed SCM (version 2.5.1) ** Extensions loaded: Traceback (most recent call last): File "hg", line 38, in File "mercurial\dispatch.pyc", line 28, in run File "mercurial\dispatch.pyc", line 65, in dispatch File "mercurial\dispatch.pyc", line 88, in _runcatch File "mercurial\dispatch.pyc", line 743, in _dispatch File "mercurial\dispatch.pyc", line 514, in runcommand File "mercurial\dispatch.pyc", line 833, in _runcommand File "mercurial\dispatch.pyc", line 804, in checkargs File "mercurial\dispatch.pyc", line 740, in File "mercurial\util.pyc", line 475, in check File "mercurial\commands.pyc", line 5361, in serve File "mercurial\cmdutil.pyc", line 501, in service File "mercurial\commands.pyc", line 5326, in init File "mercurial\hgweb\server.pyc", line 322, in create_server File "mimetypes.pyc", line 355, in init File "mimetypes.pyc", line 259, in read_windows_registry File "mimetypes.pyc", line 249, in enum_types UnicodeDecodeError: 'ascii' codec can't decode byte 0xe0 in position 0: ordinal not in range(128) -- You are receiving this mail because: You are on the CC list for the bug. From hg at intevation.org Mon Feb 25 06:00:05 2013 From: hg at intevation.org (Mercurial Commits) Date: Mon, 25 Feb 2013 13:00:05 +0100 Subject: mercurial/crew@18720: 2 outgoing changesets Message-ID: <1361793605.539516.3110.nullmailer@hg.intevation.org> 2 outgoing changesets in mercurial/crew: http://hg.intevation.org/mercurial/crew/rev/0ade08dcb3c3 changeset: 18720:0ade08dcb3c3 tag: tip user: Simon Heimberg date: Sat Feb 23 22:54:57 2013 +0100 summary: tests: remove glob lines which unnecessary match / for \ on windows http://hg.intevation.org/mercurial/crew/rev/9ad13296c581 changeset: 18719:9ad13296c581 user: Simon Heimberg date: Sat Feb 23 22:07:38 2013 +0100 summary: tests: append glob to filename output when required for windows -- Repository URL: http://hg.intevation.org/mercurial/crew From raf at durin42.com Mon Feb 25 09:17:43 2013 From: raf at durin42.com (Augie Fackler) Date: Mon, 25 Feb 2013 10:17:43 -0500 Subject: [PATCH 2 of 2] util: add a timed function for use during development In-Reply-To: References: <19d3300883ce1407d0b5.1361482381@australite.local> <95cb8d7754a7a28f52f8.1361482382@australite.local> Message-ID: <20130225151743.GA27557@arthedain.local> On Sat, Feb 23, 2013 at 11:05:04PM +0100, Benoit Boissinot wrote: > On Thu, Feb 21, 2013 at 10:33 PM, Bryan O'Sullivan wrote: > > > # HG changeset patch > > # User Bryan O'Sullivan > > # Date 1361482360 28800 > > # Node ID 95cb8d7754a7a28f52f82a332bf1163eb6dea202 > > # Parent 19d3300883ce1407d0b527549a82f25d3f182873 > > util: add a timed function for use during development > > > > I often want to measure the cost of a function call before/after > > an optimization, where using top level "hg --time" timing introduces > > enough other noise that I can't tell if my efforts are having an > > effect. > > > > This decorator allows a developer to measure a function's cost with > > finer granularity. > > > > diff --git a/mercurial/util.py b/mercurial/util.py > > --- a/mercurial/util.py > > +++ b/mercurial/util.py > > @@ -1872,3 +1872,45 @@ def isatty(fd): > > return fd.isatty() > > except AttributeError: > > return False > > + > > +timecount = unitcount( > > + (1, 1e3, _('%.0f s')), > > + (100, 1, _('%.1f s')), > > + (10, 1, _('%.2f s')), > > + (1, 1, _('%.3f s')), > > + (100, 1e-3, _('%.1f ms')), > > + (10, 1e-3, _('%.2f ms')), > > + (1, 1e-3, _('%.3f ms')), > > + (100, 1e-6, _('%.1f us')), > > + (10, 1e-6, _('%.2f us')), > > + (1, 1e-6, _('%.3f us')), > > + (100, 1e-9, _('%.1f ns')), > > + (10, 1e-9, _('%.2f ns')), > > + (1, 1e-9, _('%.3f ns')), > > + ) > > + > > +_timenesting = [0] > > + > > +def timed(func): > > + '''Report the execution time of a function call to stderr. > > + > > + During development, use as a decorator when you need to measure > > + the cost of a function, e.g. as follows: > > + > > + @util.timed > > + def foo(a, b, c): > > + pass > > + ''' > > + > > + def wrapper(*args, **kwargs): > > + start = time.time() > > + _timenesting[0] += 2 > > > > I'm a bit puzzled by the 2. Any hint? That's the amount nested timed invocations will indent. It's clever, but clear upon basic reading of the code IMO. > > > > + try: > > + return func(*args, **kwargs) > > + finally: > > + elapsed = time.time() - start > > + _timenesting[0] -= 2 > > + sys.stderr.write('%s%s: %s\n' % > > + (' ' * _timenesting[0], func.__name__, > > + timecount(elapsed))) > > + return wrapper > > _______________________________________________ > > Mercurial-devel mailing list > > Mercurial-devel at selenic.com > > http://selenic.com/mailman/listinfo/mercurial-devel > > > _______________________________________________ > Mercurial-devel mailing list > Mercurial-devel at selenic.com > http://selenic.com/mailman/listinfo/mercurial-devel From cdokolas at gmail.com Mon Feb 25 09:54:13 2013 From: cdokolas at gmail.com (Constantine Dokolas) Date: Mon, 25 Feb 2013 17:54:13 +0200 Subject: Convert extension and splicemap feature Message-ID: I have a subversion repository to convert and splicemaps don't work (I have to use splicemaps because of all the non-standard branch paths). The reason is that there are paths with spaces all over our repository and splicemap lines are split on spaces and commas. I'd like the mercurial developers to consider adding support for URL encoding (i.e. decode "%20"s in the splicemap file) in the convert extension. Thanks in advance, Constantine -- There is a computer disease that anybody who works with computers knows about. It's a very serious disease and it interferes completely with the work. The trouble with computers is that you 'play' with them! - Richard P. Feynman -------------- next part -------------- An HTML attachment was scrubbed... URL: From mercurial-bugs at selenic.com Mon Feb 25 07:48:39 2013 From: mercurial-bugs at selenic.com (mercurial-bugs at selenic.com) Date: Mon, 25 Feb 2013 13:48:39 +0000 Subject: [Bug 3841] New: "hg annotate" against merged revision shows wrong revision Message-ID: http://bz.selenic.com/show_bug.cgi?id=3841 Priority: normal Bug ID: 3841 CC: mercurial-devel at selenic.com Assignee: bugzilla at selenic.com Summary: "hg annotate" against merged revision shows wrong revision Severity: bug Classification: Unclassified OS: All Reporter: foozy at lares.dti.ne.jp Hardware: All Status: UNCONFIRMED Version: 2.5.1 Component: Mercurial Product: Mercurial Below graph is a part of filelog tree of "mercurial/commands.py" in the repository of Mercurial itself. A .. B ....... D -- E ... F -- G \ / / \ / / ..... C ----------- A: df78d8ccac4c B: 574869103985 C: 938dd667ca21 D: 1c0c413cccdd E: c6b912f8b5b2 F: 1e84f1014f33 G: 8db4d406b3d3 "def clone(....)" line in "mercurial/commands.py" is modified at rev "A", and no other revision between "A" to "G" modifies that line: "G" doesn't, too. Then, "hg annotate" should show rev "A" for "def clone(....)" line as source revision against every revisions between "A" to "G", but it shows not "A" but "C" against "G". I found the cause of this issue in the "hist" cache management in "filectx.annotate()". For consistent annotation, "hist[C]" should be kept until building "hist[G]" up, in this case. But in filelog tree above, "G" merges "F" and its ancestor "C", and this causes: - "hist[C]" is purged just after building "hist[E]" up unexpectedly, - "hist[C]" is re-built up just before building "hist[G]" up, and - "hist[C]" is built up incorrectly, because "pcache[C]" is empty at that time: this causes mis-recognition as "all lines are new at C" I already confirmed that changing "hist" or "pcache" purge policy can fix this issue. For example: ==================== --- a/mercurial/context.py Sat Feb 09 17:54:01 2013 +0000 +++ b/mercurial/context.py Tue Feb 26 01:58:13 2013 +0900 @@ -719,7 +719,7 @@ needed[p] -= 1 hist[f] = curr - pcache[f] = [] + del pcache[f] return zip(hist[base][0], hist[base][1].splitlines(True)) ==================== But, such changes seem to decrease performance (by scanning same revisions again and again) and/or resource efficiency (by keeping useless entries). Are there any other ideas ? -- You are receiving this mail because: You are on the CC list for the bug. From mercurial-bugs at selenic.com Mon Feb 25 10:28:11 2013 From: mercurial-bugs at selenic.com (mercurial-bugs at selenic.com) Date: Mon, 25 Feb 2013 16:28:11 +0000 Subject: [Bug 3842] New: problems when pushing with mercurial keyring in opensuse12.1 Message-ID: http://bz.selenic.com/show_bug.cgi?id=3842 Priority: normal Bug ID: 3842 CC: mercurial-devel at selenic.com Assignee: bugzilla at selenic.com Summary: problems when pushing with mercurial keyring in opensuse12.1 Severity: bug Classification: Unclassified OS: Linux Reporter: GurceIsikyildiz at shufflemaster.com Hardware: PC Status: UNCONFIRMED Version: 2.4.1 Component: Mercurial Product: Mercurial I initially reported this issue on the "mercurial-keyring" bug-tracker, but the author felt the issue lied within the "keyring" module it makes use of. https://bitbucket.org/Mekk/mercurial_keyring/issue/23/probs-in-opensuse-121 I've reported it on the "keyring" bug-tracker too. https://bitbucket.org/kang/python-keyring-lib/issue/91/probs-in-opensuse-121 Basically, after installing the mercurial keyring under opensuse 12.1, each time I push I see the following error: searching for changes http authorization required realm: Mecurial Repo user: gurcei (fixed in .hg/hgrc) password: ERROR:dbus.proxies:Introspect error on :1.222:/org/freedesktop/secrets/aliases/default: dbus.exceptions.DBusException: org.freedesktop.Secret.Error.NoSuchObject: The '/org/freedesktop/secrets/aliases/default' object does not exist ERROR:dbus.connection:Unable to set arguments ({'org.freedesktop.Secret.Item.Label': u'gurcei@@http://rapiddev/hg @ Mercurial', 'org.freedesktop.Secret.Item.Attributes': {'username': u'gurcei@@http://rapiddev/hg', 'service': u'Mercurial'}}, dbus.Struct((dbus.ObjectPath('/org/freedesktop/secrets/session/s11'), '', dbus.ByteArray('xxxxx'), 'application/octet-stream'), signature=None), True) according to signature None: : Expected a string or unicode object ** Unknown exception encountered with possibly-broken third-party extension mercurial_keyring ** which supports versions unknown of Mercurial. ** Please disable mercurial_keyring and try your action again. ** If that fixes the bug please report it to the extension author. ** Python 2.7.2 (default, Aug 19 2011, 20:41:43) [GCC] ** Mercurial Distributed SCM (version 2.4.1) ** Extensions loaded: hgk, mercurial_keyring Although recently, I had noticed that the hg-push via hg-keyring was working successfully on another opensuse12.1 virtualbox I used. When I compared the two, it turned out that the only major difference between them was which version of mercurial was installed (the versions of mercurial-keyring + keyring modules were identical). The working opensuse 12.1 vbox used mercurial 2.4. The non-working opensuse 12.1 vbox used mercurial 2.4.1. Upon downgrading to hg v2.4, the hg push via the keyring worked! As a test, I installed the latest mercurial v2.5.1, I still get the same error message as above. So for now, I'll stick with mercurial v2.4 to get around my problems. I'm not sure on who's turf the bug lies exactly, but thought I'd better put this on your radars too, just in-case, as this problem seems to have surfaced from the changes in v2.4.1 and the problem persists till the latest v2.5.1. -- You are receiving this mail because: You are on the CC list for the bug. From mads at kiilerich.com Mon Feb 25 15:40:40 2013 From: mads at kiilerich.com (Mads Kiilerich) Date: Mon, 25 Feb 2013 22:40:40 +0100 Subject: [PATCH 2 of 3 STABLE] commands: make outgoing-like commands sensitive to branch in URL (issue3829) In-Reply-To: References: <373c150caa5f20ae975e.1361114796@juju> Message-ID: <512BDA58.5000002@kiilerich.com> On 02/18/2013 07:09 AM, FUJIWARA Katsunori wrote: > At Mon, 18 Feb 2013 00:26:36 +0900, FUJIWARA Katsunori wrote: >> # HG changeset patch >> # User FUJIWARA Katsunori >> # Date 1361113469 -32400 >> # Branch stable >> # Node ID 373c150caa5f20ae975e086b8f211811afbd1687 >> # Parent f63d2a3d62855a430b7a4323bbfaef1e696dc471 >> commands: make outgoing-like commands sensitive to branch in URL (issue3829) You don't have to file issues for bugs you plan to fix "immediately". You are a developer and know how to use the mercurial-devel list, so there is no need to split the discussion and no need for keeping track of the issue over an extended period of time. [That should perhaps be stated clearly in the guidelines ...] >> Before this patch, commands below are not sensitive to the branch >> specified in the URL of the destination repository, even though "hg >> push"/"hg outgoing" are so: >> >> - hg histedit --outgoing >> - hg summary --remote >> >> These invoke "discovery.findcommonoutgoing()" without "onlyheads" >> argument, so it returns revisions on branches other than the one >> specified in the URL, too. >> >> This patch specifies heads revisions, which are already detected by >> "hg.addbranchrevs()" and "repo.lookup()", as "onlyheads" to >> "discovery.findcommonoutgoing()" to limit calculation of outgoing >> revisions. >> >> This patch also removes "repo.changelog.nodesbetween()" invocations in >> largefiles extension, because it is meaningless if >> "discovery.findcommonoutgoing()" is invoked with "onlyheads". > I folded also modifications for largefiles into this patch, because of > similar "discovery.findcommonoutgoing()" fix. > > But this is not bug fix, but a kind of refactoring. So, I'll split > this into bug fix for summary/histedit That would still seem like something that really should be 2 or more separate changesets, each adding test cases for what they fix. /Mads From mpm at selenic.com Mon Feb 25 16:19:25 2013 From: mpm at selenic.com (Matt Mackall) Date: Mon, 25 Feb 2013 16:19:25 -0600 Subject: [PATCH 2 of 2] tests: remove glob lines which unnecessary match / for \ on windows In-Reply-To: <3312b3d481a6e61f9881.1361657451@deb64virt.virtual> References: <3312b3d481a6e61f9881.1361657451@deb64virt.virtual> Message-ID: <1361830765.11033.73.camel@calx> On Sat, 2013-02-23 at 23:10 +0100, Simon Heimberg wrote: > # HG changeset patch > # User Simon Heimberg > # Date 1361656497 -3600 > # Branch stable > # Node ID 3312b3d481a6e61f988125d4472b53c7a0b00211 > # Parent 3660cfb8b145e88b77228a1676d5c37113d93595 > tests: remove glob lines which unnecessary match / for \ on windows > > This lines were reported as unnecessary when running the tests on windows > because the path was already printed with a slash and not a backslash. I think I'm going to start insisting that such patches come with check-code recipes. It's the only hope we have for not hitting these issues constantly. -- Mathematics is the supreme nostalgia of our time. From mercurial-bugs at selenic.com Mon Feb 25 15:05:59 2013 From: mercurial-bugs at selenic.com (mercurial-bugs at selenic.com) Date: Mon, 25 Feb 2013 21:05:59 +0000 Subject: [Bug 3843] New: Python stuck at 100% CPU rebasing mq patches over rename Message-ID: http://bz.selenic.com/show_bug.cgi?id=3843 Priority: normal Bug ID: 3843 CC: mercurial-devel at selenic.com Assignee: bugzilla at selenic.com Summary: Python stuck at 100% CPU rebasing mq patches over rename Severity: bug Classification: Unclassified OS: Mac OS Reporter: mmn100+selenic at gmail.com Hardware: Macintosh Status: UNCONFIRMED Version: 2.5.1 Component: rebase Product: Mercurial Steps to reproduce: 1) hg clone -r 1f8d24cee3c7 https://hg.mozilla.org/mozilla-central && cd mozilla-central 2) hg qimport https://bugzilla.mozilla.org/attachment.cgi?id=717451 3) hg qpush > $ hg glog -l 2 --style compact > @ 122743[attachment.cgi?id=717451,qbase,qtip,tip]:122731 4bc7ec0db5e2 > 2013-02-25 17:06 -0800 mozilla > | Bug 738491 - Implement the Australis tab shape for Windows. r=dao > | > | o 122742 1f8d24cee3c7 2013-02-22 22:23 +0100 ttaubert > | | Backed out changeset 4d74fe8e6560 (bug 842511) > | | 4) hg pull --rebase -r 7318b2b26843 > added 1 changesets with 1517 changes to 1517 files (+1 heads) > merging browser/base/content/browser.xul > merging browser/themes/windows/browser-aero.css and browser/themes/winstripe/browser-aero.css to browser/themes/windows/browser-aero.css > merging browser/themes/windows/browser.css and browser/themes/winstripe/browser.css to browser/themes/windows/browser.css Merge tool (diffmerge) opens and suppose I choose everything from the left > merging browser/themes/windows/jar.mn and browser/themes/winstripe/jar.mn to browser/themes/windows/jar.mn > tool diffmerge can't handle binary > tool diffmerge can't handle binary > no tool found to merge toolkit/themes/windows/global/icon/close.png > keep (l)ocal or take (o)ther? 5) Choose local or other (doesn't make a difference) > merging toolkit/themes/windows/global/inContentUI.css and toolkit/themes/winstripe/global/inContentUI.css to toolkit/themes/windows/global/inContentUI.css Python uses 100% CPU on a core and doesn't seem to complete. Perhaps I didn't wait long enough for it to complete since there were 1517 changes but they were mostly renames so I don't think it should take more than 30 minutes. I'm going to try leave it going this time. I started at 5:20 PM PST and it's still going 45 minutes later. I'm using hg 2.5.1 but the problem also seemed to happen on 2.4. -- You are receiving this mail because: You are on the CC list for the bug. From mads at kiilerich.com Mon Feb 25 20:39:49 2013 From: mads at kiilerich.com (Mads Kiilerich) Date: Tue, 26 Feb 2013 03:39:49 +0100 Subject: [PATCH stable] templatefilters: add missing import of _ Message-ID: # HG changeset patch # User Mads Kiilerich # Date 1361844560 -3600 # Branch stable # Node ID b1f0fd26bda704357708c73fdeb78f1b6f372238 # Parent 61c8327ced503bf7a1996337af711e0f4a58d4c0 templatefilters: add missing import of _ diff --git a/mercurial/templatefilters.py b/mercurial/templatefilters.py --- a/mercurial/templatefilters.py +++ b/mercurial/templatefilters.py @@ -5,6 +5,7 @@ # This software may be used and distributed according to the terms of the # GNU General Public License version 2 or any later version. +from i18n import _ import cgi, re, os, time, urllib import encoding, node, util, error import hbisect diff --git a/tests/test-template-engine.t b/tests/test-template-engine.t --- a/tests/test-template-engine.t +++ b/tests/test-template-engine.t @@ -44,4 +44,15 @@ 0 97e5f848f0936960273bbf75be6388cd0350a32b -1 0000000000000000000000000000000000000000 -1 0000000000000000000000000000000000000000 -1 0000000000000000000000000000000000000000 + $ hg tip --template '{fill(node, 7)}\n' + hg: parse error: fill expects an integer width + [255] + $ hg tip --template '{fill(node, "7")}\n' + ef4a3af + ceb5370 + e8500df + 6f7b191 + e48998e + 059af + $ cd .. From mads at kiilerich.com Mon Feb 25 20:41:21 2013 From: mads at kiilerich.com (Mads Kiilerich) Date: Tue, 26 Feb 2013 03:41:21 +0100 Subject: [PATCH 1 of 9 stable] largefiles: fix off-by-one error on pull --all-largefiles Message-ID: <7f0cd251905074b0aec1.1361846481@mk-desktop> # HG changeset patch # User Mads Kiilerich # Date 1361846443 -3600 # Branch stable # Node ID 7f0cd251905074b0aec181892efc80fa18507fde # Parent 61c8327ced503bf7a1996337af711e0f4a58d4c0 largefiles: fix off-by-one error on pull --all-largefiles Test output is changed in a case where one revision was pulled, but because of the off-by-one error it thought that 0 revisions were pulled ... and because of another bug it thus (tried to) fetch largefiles for all revisions. After this change it no longer reports failure when it failed while trying to fetch largefiles it shouldn't fetch. Largefiles that it shouldn't fetch but managed to fetch anyway will now correctly be missing later on. This change thus resolves some of unexplained test output introduced in 1e4eb1faba6e. diff --git a/hgext/largefiles/overrides.py b/hgext/largefiles/overrides.py --- a/hgext/largefiles/overrides.py +++ b/hgext/largefiles/overrides.py @@ -746,7 +746,7 @@ if opts.get('all_largefiles'): revspostpull = len(repo) revs = [] - for rev in xrange(revsprepull + 1, revspostpull): + for rev in xrange(revsprepull, revspostpull): revs.append(repo[rev].rev()) lfcommands.downloadlfiles(ui, repo, revs) return result diff --git a/tests/test-largefiles.t b/tests/test-largefiles.t --- a/tests/test-largefiles.t +++ b/tests/test-largefiles.t @@ -919,8 +919,12 @@ $ cd d More rebase testing, but also test that the largefiles are downloaded from -'default' instead of 'default-push' when no source is specified (issue3584). -The error messages go away if repo 'b' is created with --all-largefiles. +'default-push' when no source is specified (issue3584). (The largefile from the +pulled revision is however not downloaded but found in the local cache.) +Largefiles are fetched for the new pulled revision, not for existing revisions, +rebased or not. + + $ [ ! -f .hg/largefiles/e166e74c7303192238d60af5a9c4ce9bef0b7928 ] $ hg pull --rebase --all-largefiles --config paths.default-push=bogus/path --config paths.default=../b pulling from $TESTTMP/b (glob) searching for changes @@ -932,18 +936,9 @@ M sub/normal4 M sub2/large6 saved backup bundle to $TESTTMP/d/.hg/strip-backup/f574fb32bb45-backup.hg (glob) - error getting id eb7338044dc27f9bc59b8dd5a246b065ead7a9c4 from url file:$TESTTMP/b for file large3: can't get file locally (glob) - error getting id eb7338044dc27f9bc59b8dd5a246b065ead7a9c4 from url file:$TESTTMP/b for file sub/large4: can't get file locally (glob) - error getting id eb7338044dc27f9bc59b8dd5a246b065ead7a9c4 from url file:$TESTTMP/b for file large1: can't get file locally (glob) - error getting id eb7338044dc27f9bc59b8dd5a246b065ead7a9c4 from url file:$TESTTMP/b for file sub/large2: can't get file locally (glob) - error getting id eb7338044dc27f9bc59b8dd5a246b065ead7a9c4 from url file:$TESTTMP/b for file sub/large2: can't get file locally (glob) - error getting id 5f78770c0e77ba4287ad6ef3071c9bf9c379742f from url file:$TESTTMP/b for file large1: can't get file locally (glob) - error getting id eb7338044dc27f9bc59b8dd5a246b065ead7a9c4 from url file:$TESTTMP/b for file sub/large2: can't get file locally (glob) - error getting id 4669e532d5b2c093a78eca010077e708a071bb64 from url file:$TESTTMP/b for file large1: can't get file locally (glob) - error getting id 1deebade43c8c498a3c8daddac0244dc55d1331d from url file:$TESTTMP/b for file sub/large2: can't get file locally (glob) 0 additional largefiles cached - 9 largefiles failed to download nothing to rebase + $ [ -f .hg/largefiles/e166e74c7303192238d60af5a9c4ce9bef0b7928 ] $ hg log --template '{rev}:{node|short} {desc|firstline}\n' 9:598410d3eb9a modify normal file largefile in repo d 8:a381d2c8c80e modify normal file and largefile in repo b @@ -1255,6 +1250,12 @@ ($TESTTMP/d/.hg/largefiles/eb7338044dc27f9bc59b8dd5a246b065ead7a9c4: (glob) expected hash eb7338044dc27f9bc59b8dd5a246b065ead7a9c4, but got cfef678f24d3e339944138ecdd8fd85ca21d820f) + changeset 5:9d5af5072dbd: large3 missing + (looked for hash baaf12afde9d8d67f25dab6dced0d2bf77dba47c) + changeset 5:9d5af5072dbd: sub/large4 missing + (looked for hash aeb2210d19f02886dde00dac279729a48471e2f9) + changeset 6:4355d653f84f: large3 missing + (looked for hash 7838695e10da2bb75ac1156565f40a2595fa2fa0) verified contents of 15 revisions of 6 largefiles [1] From mads at kiilerich.com Mon Feb 25 20:41:22 2013 From: mads at kiilerich.com (Mads Kiilerich) Date: Tue, 26 Feb 2013 03:41:22 +0100 Subject: [PATCH 2 of 9 stable] largefiles: fix download of largefiles from an empty list of changesets In-Reply-To: <7f0cd251905074b0aec1.1361846481@mk-desktop> References: <7f0cd251905074b0aec1.1361846481@mk-desktop> Message-ID: <27f081501f9e04320ac9.1361846482@mk-desktop> # HG changeset patch # User Mads Kiilerich # Date 1361846443 -3600 # Branch stable # Node ID 27f081501f9e04320ac94654c61e766764ee159e # Parent 7f0cd251905074b0aec181892efc80fa18507fde largefiles: fix download of largefiles from an empty list of changesets The empty list was interpreted as all revisions - just like None is. The empty list is now handled explicitly. diff --git a/hgext/largefiles/lfcommands.py b/hgext/largefiles/lfcommands.py --- a/hgext/largefiles/lfcommands.py +++ b/hgext/largefiles/lfcommands.py @@ -435,11 +435,12 @@ pass totalsuccess = 0 totalmissing = 0 - for ctx in cmdutil.walkchangerevs(repo, matchfn, {'rev' : rev}, - prepare): - success, missing = cachelfiles(ui, repo, ctx.node()) - totalsuccess += len(success) - totalmissing += len(missing) + if rev != []: # walkchangerevs on empty list would return all revs + for ctx in cmdutil.walkchangerevs(repo, matchfn, {'rev' : rev}, + prepare): + success, missing = cachelfiles(ui, repo, ctx.node()) + totalsuccess += len(success) + totalmissing += len(missing) ui.status(_("%d additional largefiles cached\n") % totalsuccess) if totalmissing > 0: ui.status(_("%d largefiles failed to download\n") % totalmissing) diff --git a/tests/test-largefiles.t b/tests/test-largefiles.t --- a/tests/test-largefiles.t +++ b/tests/test-largefiles.t @@ -1262,6 +1262,16 @@ - cleanup $ rm $TESTTMP/d/.hg/largefiles/eb7338044dc27f9bc59b8dd5a246b065ead7a9c4 +Pulling 0 revisions with --all-largefiles should not fetch for all revisions + + $ hg pull --all-largefiles + pulling from $TESTTMP/d (glob) + searching for changes + no changes found + caching new largefiles + 0 largefiles cached + 0 additional largefiles cached + Merging does not revert to old versions of largefiles and also check that merging after having pulled from a non-default remote works correctly. From mads at kiilerich.com Mon Feb 25 20:41:23 2013 From: mads at kiilerich.com (Mads Kiilerich) Date: Tue, 26 Feb 2013 03:41:23 +0100 Subject: [PATCH 3 of 9 stable] tests: don't rely on broken behaviour in test-largefiles-cache.t In-Reply-To: <7f0cd251905074b0aec1.1361846481@mk-desktop> References: <7f0cd251905074b0aec1.1361846481@mk-desktop> Message-ID: # HG changeset patch # User Mads Kiilerich # Date 1361846443 -3600 # Branch stable # Node ID c92e62e6b93838c00c749e85e4eab243e155dd58 # Parent 27f081501f9e04320ac94654c61e766764ee159e tests: don't rely on broken behaviour in test-largefiles-cache.t The test relied on the bug that 'pull largefiles from branchheads' didn't pull any largefiles from tip revision when it seemed like no largefiles had been checked out before. diff --git a/tests/test-largefiles-cache.t b/tests/test-largefiles-cache.t --- a/tests/test-largefiles-cache.t +++ b/tests/test-largefiles-cache.t @@ -16,6 +16,9 @@ $ echo large > large $ hg add --large large $ hg commit -m 'add largefile' + $ hg rm large + $ hg commit -m 'branchhead without largefile' + $ hg up -qr 0 $ cd .. Discard all cached largefiles in USERCACHE @@ -24,7 +27,7 @@ Create mirror repo, and pull from source without largefile: "pull" is used instead of "clone" for suppression of (1) updating to -tip (= cahcing largefile from source repo), and (2) recording source +tip (= caching largefile from source repo), and (2) recording source repo as "default" path in .hg/hgrc. $ hg init mirror @@ -35,7 +38,7 @@ adding changesets adding manifests adding file changes - added 1 changesets with 1 changes to 1 files + added 2 changesets with 1 changes to 1 files (run 'hg update' to get a working copy) caching new largefiles 0 largefiles cached @@ -44,7 +47,7 @@ but there is no cache file for it. So, hg must treat it as "missing"(!) file. - $ hg update + $ hg update -r0 getting changed largefiles error getting id 7f7097b041ccf68cc5561e9600da4655d21c6d18 from url file:$TESTTMP/mirror for file large: can't get file locally (glob) 0 largefiles updated, 0 removed @@ -61,7 +64,7 @@ Update working directory to tip, again. - $ hg update + $ hg update -r0 getting changed largefiles error getting id 7f7097b041ccf68cc5561e9600da4655d21c6d18 from url file:$TESTTMP/mirror for file large: can't get file locally (glob) 0 largefiles updated, 0 removed @@ -90,6 +93,7 @@ $ chmod 660 large $ echo change >> large $ hg commit -m change + created new head $ ../ls-l.py .hg/largefiles/e151b474069de4ca6898f67ce2f2a7263adf8fea 640 From mads at kiilerich.com Mon Feb 25 20:41:24 2013 From: mads at kiilerich.com (Mads Kiilerich) Date: Tue, 26 Feb 2013 03:41:24 +0100 Subject: [PATCH 4 of 9 stable] largefiles: getstandinmatcher should not depend on existence of directories In-Reply-To: <7f0cd251905074b0aec1.1361846481@mk-desktop> References: <7f0cd251905074b0aec1.1361846481@mk-desktop> Message-ID: <87111ec96b62e837a018.1361846484@mk-desktop> # HG changeset patch # User Mads Kiilerich # Date 1361846443 -3600 # Branch stable # Node ID 87111ec96b62e837a018a753e35371afb8240aa8 # Parent c92e62e6b93838c00c749e85e4eab243e155dd58 largefiles: getstandinmatcher should not depend on existence of directories Looking for a (potentially empty) directory was not reliable - both because it is a reasonable assumption that empty directories can be removed and because it wasn't created in all cases ... such as when pulling to an existing repository. diff --git a/hgext/largefiles/lfutil.py b/hgext/largefiles/lfutil.py --- a/hgext/largefiles/lfutil.py +++ b/hgext/largefiles/lfutil.py @@ -225,13 +225,9 @@ standindir = repo.wjoin(shortname) if pats: pats = [os.path.join(standindir, pat) for pat in pats] - elif os.path.isdir(standindir): + else: # no patterns: relative to repo root pats = [standindir] - else: - # no patterns and no standin dir: return matcher that matches nothing - return match_.match(repo.root, None, [], exact=True) - # no warnings about missing files or directories match = scmutil.match(repo[None], pats, opts) match.bad = lambda f, msg: None diff --git a/tests/test-issue3084.t b/tests/test-issue3084.t --- a/tests/test-issue3084.t +++ b/tests/test-issue3084.t @@ -31,6 +31,8 @@ foo has been turned into a largefile use (l)argefile or keep as (n)ormal file? 0 files updated, 0 files merged, 1 files removed, 0 files unresolved (branch merge, don't forget to commit) + getting changed largefiles + 0 largefiles updated, 0 removed $ hg status $ cat foo diff --git a/tests/test-largefiles-cache.t b/tests/test-largefiles-cache.t --- a/tests/test-largefiles-cache.t +++ b/tests/test-largefiles-cache.t @@ -73,6 +73,20 @@ ! large $ cd .. +Verify that largefiles from pulled branchheads are fetched, also to an empty repo + + $ hg init mirror2 + $ hg -R mirror2 pull src -r0 + pulling from src + adding changesets + adding manifests + adding file changes + added 1 changesets with 1 changes to 1 files + (run 'hg update' to get a working copy) + caching new largefiles + abort: *: '$TESTTMP/mirror2/.hg/largefiles/.7f7097b041ccf68cc5561e9600da4655d21c6d18.*' (glob) + [255] + #if unix-permissions Portable way to print file permissions: From mads at kiilerich.com Mon Feb 25 20:41:25 2013 From: mads at kiilerich.com (Mads Kiilerich) Date: Tue, 26 Feb 2013 03:41:25 +0100 Subject: [PATCH 5 of 9 stable] largefiles: don't assume that .hg/largefiles/ still exists In-Reply-To: <7f0cd251905074b0aec1.1361846481@mk-desktop> References: <7f0cd251905074b0aec1.1361846481@mk-desktop> Message-ID: <80b37590cb47f78ca225.1361846485@mk-desktop> # HG changeset patch # User Mads Kiilerich # Date 1361846443 -3600 # Branch stable # Node ID 80b37590cb47f78ca22554b678627a910c65c6b9 # Parent 87111ec96b62e837a018a753e35371afb8240aa8 largefiles: don't assume that .hg/largefiles/ still exists It might not have been created and it might have been removed. diff --git a/hgext/largefiles/basestore.py b/hgext/largefiles/basestore.py --- a/hgext/largefiles/basestore.py +++ b/hgext/largefiles/basestore.py @@ -59,6 +59,8 @@ missing = [] ui = self.ui + util.makedirs(lfutil.storepath(self.repo, '')) + at = 0 for filename, hash in files: ui.progress(_('getting largefiles'), at, unit='lfile', diff --git a/tests/test-largefiles-cache.t b/tests/test-largefiles-cache.t --- a/tests/test-largefiles-cache.t +++ b/tests/test-largefiles-cache.t @@ -84,8 +84,7 @@ added 1 changesets with 1 changes to 1 files (run 'hg update' to get a working copy) caching new largefiles - abort: *: '$TESTTMP/mirror2/.hg/largefiles/.7f7097b041ccf68cc5561e9600da4655d21c6d18.*' (glob) - [255] + 1 largefiles cached #if unix-permissions From mads at kiilerich.com Mon Feb 25 20:41:26 2013 From: mads at kiilerich.com (Mads Kiilerich) Date: Tue, 26 Feb 2013 03:41:26 +0100 Subject: [PATCH 6 of 9 stable] largefiles: missing largefiles should not be committed as removed In-Reply-To: <7f0cd251905074b0aec1.1361846481@mk-desktop> References: <7f0cd251905074b0aec1.1361846481@mk-desktop> Message-ID: <956919132f14f4245fda.1361846486@mk-desktop> # HG changeset patch # User Mads Kiilerich # Date 1361846443 -3600 # Branch stable # Node ID 956919132f14f4245fda8858a1d190f2ec964778 # Parent 80b37590cb47f78ca22554b678627a910c65c6b9 largefiles: missing largefiles should not be committed as removed Largefiles can easily become missing - for example if it simply isn't available or the download fail. It might even be convenient to be able to work that way in some cases. But commiting missing largefiles as if they had been 'hg remove'd is plain wrong. diff --git a/hgext/largefiles/reposetup.py b/hgext/largefiles/reposetup.py --- a/hgext/largefiles/reposetup.py +++ b/hgext/largefiles/reposetup.py @@ -299,9 +299,9 @@ lfdirstate = lfutil.openlfdirstate(ui, self) dirtymatch = match_.always(self.root, self.getcwd()) s = lfdirstate.status(dirtymatch, [], False, False, False) - modifiedfiles = [] - for i in s: - modifiedfiles.extend(i) + (unsure, modified, added, removed, _missing, _unknown, + _ignored, _clean) = s + modifiedfiles = unsure + modified + added + removed lfiles = lfutil.listlfiles(self) # this only loops through largefiles that exist (not # removed/renamed) diff --git a/tests/test-largefiles.t b/tests/test-largefiles.t --- a/tests/test-largefiles.t +++ b/tests/test-largefiles.t @@ -1261,6 +1261,42 @@ - cleanup $ rm $TESTTMP/d/.hg/largefiles/eb7338044dc27f9bc59b8dd5a246b065ead7a9c4 + $ rm -f .hglf/sub/*.orig + +Update to revision with missing largefile - and make sure it really is missing + + $ rm ${USERCACHE}/7838695e10da2bb75ac1156565f40a2595fa2fa0 + $ hg up -r 6 + getting changed largefiles + error getting id 7838695e10da2bb75ac1156565f40a2595fa2fa0 from url file:$TESTTMP/d for file large3: can't get file locally (glob) + 1 largefiles updated, 2 removed + 4 files updated, 0 files merged, 2 files removed, 0 files unresolved + $ rm normal3 + $ echo >> sub/normal4 + $ hg ci -m 'commit with missing files' + Invoking status precommit hook + M sub/normal4 + ! large3 + ! normal3 + created new head + $ hg st + ! large3 + ! normal3 + $ hg up -r. + 0 files updated, 0 files merged, 0 files removed, 0 files unresolved + $ hg st + ! large3 + ! normal3 + $ hg up -Cr. + getting changed largefiles + error getting id 7838695e10da2bb75ac1156565f40a2595fa2fa0 from url file:$TESTTMP/d for file large3: can't get file locally (glob) + 0 largefiles updated, 0 removed + 1 files updated, 0 files merged, 0 files removed, 0 files unresolved + $ hg st + ! large3 + $ hg rollback + repository tip rolled back to revision 9 (undo commit) + working directory now based on revision 6 Pulling 0 revisions with --all-largefiles should not fetch for all revisions From mads at kiilerich.com Mon Feb 25 20:41:28 2013 From: mads at kiilerich.com (Mads Kiilerich) Date: Tue, 26 Feb 2013 03:41:28 +0100 Subject: [PATCH 8 of 9 stable] largefiles: simplify cachelfiles - don't spend a lot of time checking hashes In-Reply-To: <7f0cd251905074b0aec1.1361846481@mk-desktop> References: <7f0cd251905074b0aec1.1361846481@mk-desktop> Message-ID: # HG changeset patch # User Mads Kiilerich # Date 1361846443 -3600 # Branch stable # Node ID fba3b0f812f9f5db45e03b2bdce12ec7d9b71c79 # Parent 51dfa49cb71bb83e7520003a0c7c6fefccc36519 largefiles: simplify cachelfiles - don't spend a lot of time checking hashes cachelfiles jumped through loops to handle merges and modified files ... but it did apparently no longer have a valid reason to do so. It should just always make sure that the largefiles referenced from the standins are present - no matter which actual largefile is stored in the working directory. If there is no standin then there is nothing to fetch. The old code usually verified the hash of all largefiles every time this function was invoked - for examply by 'update'. This change makes a trivial noop update 5-10 seconds faster on our repo (with the other 50% spent doing another unnecessary hashing of all largefiles). diff --git a/hgext/largefiles/lfcommands.py b/hgext/largefiles/lfcommands.py --- a/hgext/largefiles/lfcommands.py +++ b/hgext/largefiles/lfcommands.py @@ -8,7 +8,7 @@ '''High-level command function for lfconvert, plus the cmdtable.''' -import os +import os, errno import shutil from mercurial import util, match as match_, hg, node, context, error, \ @@ -403,22 +403,13 @@ toget = [] for lfile in lfiles: - # If we are mid-merge, then we have to trust the standin that is in the - # working copy to have the correct hashvalue. This is because the - # original hg.merge() already updated the standin as part of the normal - # merge process -- we just have to update the largefile to match. - if (getattr(repo, "_ismerging", False) and - os.path.exists(repo.wjoin(lfutil.standin(lfile)))): - expectedhash = lfutil.readstandin(repo, lfile) - else: + try: expectedhash = repo[node][lfutil.standin(lfile)].data().strip() - - # if it exists and its hash matches, it might have been locally - # modified before updating and the user chose 'local'. in this case, - # it will not be in any store, so don't look for it. - if ((not os.path.exists(repo.wjoin(lfile)) or - expectedhash != lfutil.hashfile(repo.wjoin(lfile))) and - not lfutil.findfile(repo, expectedhash)): + except IOError, err: + if err.errno == errno.ENOENT: + continue # node must be None and standin wasn't found in wctx + raise + if not lfutil.findfile(repo, expectedhash): toget.append((lfile, expectedhash)) if toget: diff --git a/hgext/largefiles/overrides.py b/hgext/largefiles/overrides.py --- a/hgext/largefiles/overrides.py +++ b/hgext/largefiles/overrides.py @@ -684,15 +684,8 @@ return result def hgmerge(orig, repo, node, force=None, remind=True): - # Mark the repo as being in the middle of a merge, so that - # updatelfiles() will know that it needs to trust the standins in - # the working copy, not in the standins in the current node - repo._ismerging = True - try: - result = orig(repo, node, force, remind) - lfcommands.updatelfiles(repo.ui, repo) - finally: - repo._ismerging = False + result = orig(repo, node, force, remind) + lfcommands.updatelfiles(repo.ui, repo) return result # When we rebase a repository with remotely changed largefiles, we need to From mads at kiilerich.com Mon Feb 25 20:41:29 2013 From: mads at kiilerich.com (Mads Kiilerich) Date: Tue, 26 Feb 2013 03:41:29 +0100 Subject: [PATCH 9 of 9 stable] largefiles: updatelfiles should use working dir standins, not standins from p1 In-Reply-To: <7f0cd251905074b0aec1.1361846481@mk-desktop> References: <7f0cd251905074b0aec1.1361846481@mk-desktop> Message-ID: # HG changeset patch # User Mads Kiilerich # Date 1361846443 -3600 # Branch stable # Node ID bc8da215c814c01d51159593304c0a746246cf33 # Parent fba3b0f812f9f5db45e03b2bdce12ec7d9b71c79 largefiles: updatelfiles should use working dir standins, not standins from p1 This makes a difference when working directory is dirty, especially when merging with a revision for which we don't have largefiles. diff --git a/hgext/largefiles/lfcommands.py b/hgext/largefiles/lfcommands.py --- a/hgext/largefiles/lfcommands.py +++ b/hgext/largefiles/lfcommands.py @@ -450,7 +450,7 @@ if printmessage and lfiles: ui.status(_('getting changed largefiles\n')) printed = True - cachelfiles(ui, repo, '.', lfiles) + cachelfiles(ui, repo, None, lfiles) updated, removed = 0, 0 for f in lfiles: diff --git a/tests/test-largefiles.t b/tests/test-largefiles.t --- a/tests/test-largefiles.t +++ b/tests/test-largefiles.t @@ -1298,6 +1298,25 @@ repository tip rolled back to revision 9 (undo commit) working directory now based on revision 6 +Merge with revision with missing largefile - and make sure it tries to fetch it. + + $ hg up -Cqr null + $ echo f > f + $ hg ci -Am branch + adding f + Invoking status precommit hook + A f + created new head + $ hg merge -r 6 + 4 files updated, 0 files merged, 0 files removed, 0 files unresolved + (branch merge, don't forget to commit) + getting changed largefiles + error getting id 7838695e10da2bb75ac1156565f40a2595fa2fa0 from url file:$TESTTMP/d for file large3: can't get file locally (glob) + 1 largefiles updated, 0 removed + + $ hg rollback -q + $ hg up -Cq + Pulling 0 revisions with --all-largefiles should not fetch for all revisions $ hg pull --all-largefiles From mads at kiilerich.com Mon Feb 25 20:41:27 2013 From: mads at kiilerich.com (Mads Kiilerich) Date: Tue, 26 Feb 2013 03:41:27 +0100 Subject: [PATCH 7 of 9 stable] largefiles: don't let update leave wrong largefiles in wd if fetch fails In-Reply-To: <7f0cd251905074b0aec1.1361846481@mk-desktop> References: <7f0cd251905074b0aec1.1361846481@mk-desktop> Message-ID: <51dfa49cb71bb83e7520.1361846487@mk-desktop> # HG changeset patch # User Mads Kiilerich # Date 1361846443 -3600 # Branch stable # Node ID 51dfa49cb71bb83e7520003a0c7c6fefccc36519 # Parent 956919132f14f4245fda8858a1d190f2ec964778 largefiles: don't let update leave wrong largefiles in wd if fetch fails Situations where a largefile for some reason wasn't available sometimes caused wrong largefile content and state. It has mostly been seen when interrupting download of largefiles ... and when introducing programming errors. Instead we now make sure to delete the old and wrong largefile. A missing file is a well-known error condition and much more reasonable way to handle the situation. diff --git a/hgext/largefiles/lfcommands.py b/hgext/largefiles/lfcommands.py --- a/hgext/largefiles/lfcommands.py +++ b/hgext/largefiles/lfcommands.py @@ -501,6 +501,8 @@ # use normallookup() to allocate entry in largefiles dirstate, # because lack of it misleads lfilesrepo.status() into # recognition that such cache missing files are REMOVED. + if lfile not in repo[None]: # not switched to normal file + util.unlinkpath(abslfile, ignoremissing=True) lfdirstate.normallookup(lfile) return None # don't try to set the mode else: From mads at kiilerich.com Mon Feb 25 21:21:50 2013 From: mads at kiilerich.com (Mads Kiilerich) Date: Tue, 26 Feb 2013 04:21:50 +0100 Subject: [PATCH stable?] largefiles: don't cache largefiles for all new pulled branchheads Message-ID: # HG changeset patch # User Mads Kiilerich # Date 1361848730 -3600 # Branch stable # Node ID edce3a16a9ececeeb4cc212d50dcb1cc81bf4dc6 # Parent 89fd28cd4c011a974aa683a28e7302008f01e81e largefiles: don't cache largefiles for all new pulled branchheads Fetching largefiles for all brancheads doesn't scale to setups with several branches and huge volume of changed largefiles. The only case where it is relevant to fetch when pulling is when pulling from a repository with only temporary access ... but in that case it is essential that --all-largefiles is used anyway. If fetching largefiles from all revisions for some reason is too much, then it is very likely that fetching largefiles from all branchheads is too much too, and a better solution would be to use 'pull -u'. In all other cases the largefiles will be fetched on demand anyway. And with or without this automatic caching of largefiles there will be cases where a workaround must be used anyway - for instance by setting a default pull path with '--config paths.default=...' . This is thus a slight change of behavior, but only in strategy and heuristic for when it is most appropriate to fetch largefiles. There is no fundamental change. diff --git a/hgext/largefiles/overrides.py b/hgext/largefiles/overrides.py --- a/hgext/largefiles/overrides.py +++ b/hgext/largefiles/overrides.py @@ -722,20 +722,7 @@ if not source: source = 'default' repo.lfpullsource = source - oldheads = lfutil.getcurrentheads(repo) result = orig(ui, repo, source, **opts) - # If we do not have the new largefiles for any new heads we pulled, we - # will run into a problem later if we try to merge or rebase with one of - # these heads, so cache the largefiles now directly into the system - # cache. - ui.status(_("caching new largefiles\n")) - numcached = 0 - heads = lfutil.getcurrentheads(repo) - newheads = set(heads).difference(set(oldheads)) - for head in newheads: - (cached, missing) = lfcommands.cachelfiles(ui, repo, head) - numcached += len(cached) - ui.status(_("%d largefiles cached\n") % numcached) if opts.get('all_largefiles'): revspostpull = len(repo) revs = [] diff --git a/tests/test-largefiles-cache.t b/tests/test-largefiles-cache.t --- a/tests/test-largefiles-cache.t +++ b/tests/test-largefiles-cache.t @@ -40,8 +40,6 @@ adding file changes added 2 changesets with 1 changes to 1 files (run 'hg update' to get a working copy) - caching new largefiles - 0 largefiles cached Update working directory to "tip", which requires largefile("large"), but there is no cache file for it. So, hg must treat it as @@ -83,8 +81,6 @@ adding file changes added 1 changesets with 1 changes to 1 files (run 'hg update' to get a working copy) - caching new largefiles - 1 largefiles cached #if unix-permissions diff --git a/tests/test-largefiles.t b/tests/test-largefiles.t --- a/tests/test-largefiles.t +++ b/tests/test-largefiles.t @@ -883,9 +883,7 @@ adding file changes added 6 changesets with 16 changes to 8 files (run 'hg update' to get a working copy) - caching new largefiles - 3 largefiles cached - 3 additional largefiles cached + 6 additional largefiles cached $ cd .. Rebasing between two repositories does not revert largefiles to old @@ -969,8 +967,6 @@ adding file changes added 1 changesets with 2 changes to 2 files (+1 heads) (run 'hg heads' to see heads, 'hg merge' to merge) - caching new largefiles - 0 largefiles cached $ hg rebase Invoking status precommit hook M sub/normal4 @@ -1323,8 +1319,6 @@ pulling from $TESTTMP/d (glob) searching for changes no changes found - caching new largefiles - 0 largefiles cached 0 additional largefiles cached Merging does not revert to old versions of largefiles and also check @@ -1362,8 +1356,6 @@ adding file changes added 2 changesets with 4 changes to 4 files (+1 heads) (run 'hg heads' to see heads, 'hg merge' to merge) - caching new largefiles - 2 largefiles cached $ hg merge merging sub/large4 largefile sub/large4 has a merge conflict @@ -1371,6 +1363,20 @@ 3 files updated, 1 files merged, 0 files removed, 0 files unresolved (branch merge, don't forget to commit) getting changed largefiles + error getting id b9ac37c6767a5dbc01e43afa32957d8d789be72a from url file:$TESTTMP/temp for file sub2/large6: can't get file locally (glob) + 0 largefiles updated, 0 removed + $ hg st + M normal3 + M sub/normal4 + ! sub2/large6 + $ hg up -Cqr. + $ hg merge --config paths.default=../e + merging sub/large4 + largefile sub/large4 has a merge conflict + keep (l)ocal or take (o)ther? l + 3 files updated, 1 files merged, 0 files removed, 0 files unresolved + (branch merge, don't forget to commit) + getting changed largefiles 1 largefiles updated, 0 removed $ hg commit -m "Merge repos e and f" Invoking status precommit hook From mads at kiilerich.com Mon Feb 25 21:23:56 2013 From: mads at kiilerich.com (Mads Kiilerich) Date: Tue, 26 Feb 2013 04:23:56 +0100 Subject: [PATCH stable?] largefiles: don't cache largefiles for all new pulled branchheads In-Reply-To: References: Message-ID: <512C2ACC.7070408@kiilerich.com> On 02/26/2013 04:21 AM, Mads Kiilerich wrote: > # HG changeset patch > # User Mads Kiilerich > # Date 1361848730 -3600 > # Branch stable > # Node ID edce3a16a9ececeeb4cc212d50dcb1cc81bf4dc6 > # Parent 89fd28cd4c011a974aa683a28e7302008f01e81e > largefiles: don't cache largefiles for all new pulled branchheads Na'Tosha's "largefiles: don't cache largefiles for pulled heads by default" is now in http://selenic.com/hg/rev/d69585a5c5c0 . The same issue is however getting more of a problem for us. I don't think it has been stated sufficiently explicit what is going on. When 2.5.1 is pulling from a repository with several named branches, then it will retrieve largefiles for all the branch heads. The more named branches a repository gets and the more activity there is on otherwise independent branches, the more of a problem it gets that it fetches largefiles for all named branches - no matter if they were pulled explicitly or pulled because they had been merged to something you pulled. The user will have to download more and more data that he didn't ask for and never will use. That goes directly against the idea of largefiles. It is "only" a performance/resource issue, it is not really a regression, and fixing it is a bit of a change of behaviour. But to us it has become an issue that we would like to see solved in stable. And to get back to d69585a5c5c0: I don't think there is any reason to introduce a command line option for the old behaviour. I would prefer to remove it and the supporting code again, as this patch shows. Opinions? /Mads > Fetching largefiles for all brancheads doesn't scale to setups with several > branches and huge volume of changed largefiles. > > The only case where it is relevant to fetch when pulling is when pulling from a > repository with only temporary access ... but in that case it is essential that > --all-largefiles is used anyway. If fetching largefiles from all revisions for > some reason is too much, then it is very likely that fetching largefiles from > all branchheads is too much too, and a better solution would be to use 'pull > -u'. > > In all other cases the largefiles will be fetched on demand anyway. > > And with or without this automatic caching of largefiles there will be cases > where a workaround must be used anyway - for instance by setting a default pull > path with '--config paths.default=...' . > > This is thus a slight change of behavior, but only in strategy and heuristic > for when it is most appropriate to fetch largefiles. There is no fundamental > change. > > diff --git a/hgext/largefiles/overrides.py b/hgext/largefiles/overrides.py > --- a/hgext/largefiles/overrides.py > +++ b/hgext/largefiles/overrides.py > @@ -722,20 +722,7 @@ > if not source: > source = 'default' > repo.lfpullsource = source > - oldheads = lfutil.getcurrentheads(repo) > result = orig(ui, repo, source, **opts) > - # If we do not have the new largefiles for any new heads we pulled, we > - # will run into a problem later if we try to merge or rebase with one of > - # these heads, so cache the largefiles now directly into the system > - # cache. > - ui.status(_("caching new largefiles\n")) > - numcached = 0 > - heads = lfutil.getcurrentheads(repo) > - newheads = set(heads).difference(set(oldheads)) > - for head in newheads: > - (cached, missing) = lfcommands.cachelfiles(ui, repo, head) > - numcached += len(cached) > - ui.status(_("%d largefiles cached\n") % numcached) > if opts.get('all_largefiles'): > revspostpull = len(repo) > revs = [] > diff --git a/tests/test-largefiles-cache.t b/tests/test-largefiles-cache.t > --- a/tests/test-largefiles-cache.t > +++ b/tests/test-largefiles-cache.t > @@ -40,8 +40,6 @@ > adding file changes > added 2 changesets with 1 changes to 1 files > (run 'hg update' to get a working copy) > - caching new largefiles > - 0 largefiles cached > > Update working directory to "tip", which requires largefile("large"), > but there is no cache file for it. So, hg must treat it as > @@ -83,8 +81,6 @@ > adding file changes > added 1 changesets with 1 changes to 1 files > (run 'hg update' to get a working copy) > - caching new largefiles > - 1 largefiles cached > > #if unix-permissions > > diff --git a/tests/test-largefiles.t b/tests/test-largefiles.t > --- a/tests/test-largefiles.t > +++ b/tests/test-largefiles.t > @@ -883,9 +883,7 @@ > adding file changes > added 6 changesets with 16 changes to 8 files > (run 'hg update' to get a working copy) > - caching new largefiles > - 3 largefiles cached > - 3 additional largefiles cached > + 6 additional largefiles cached > $ cd .. > > Rebasing between two repositories does not revert largefiles to old > @@ -969,8 +967,6 @@ > adding file changes > added 1 changesets with 2 changes to 2 files (+1 heads) > (run 'hg heads' to see heads, 'hg merge' to merge) > - caching new largefiles > - 0 largefiles cached > $ hg rebase > Invoking status precommit hook > M sub/normal4 > @@ -1323,8 +1319,6 @@ > pulling from $TESTTMP/d (glob) > searching for changes > no changes found > - caching new largefiles > - 0 largefiles cached > 0 additional largefiles cached > > Merging does not revert to old versions of largefiles and also check > @@ -1362,8 +1356,6 @@ > adding file changes > added 2 changesets with 4 changes to 4 files (+1 heads) > (run 'hg heads' to see heads, 'hg merge' to merge) > - caching new largefiles > - 2 largefiles cached > $ hg merge > merging sub/large4 > largefile sub/large4 has a merge conflict > @@ -1371,6 +1363,20 @@ > 3 files updated, 1 files merged, 0 files removed, 0 files unresolved > (branch merge, don't forget to commit) > getting changed largefiles > + error getting id b9ac37c6767a5dbc01e43afa32957d8d789be72a from url file:$TESTTMP/temp for file sub2/large6: can't get file locally (glob) > + 0 largefiles updated, 0 removed > + $ hg st > + M normal3 > + M sub/normal4 > + ! sub2/large6 > + $ hg up -Cqr. > + $ hg merge --config paths.default=../e > + merging sub/large4 > + largefile sub/large4 has a merge conflict > + keep (l)ocal or take (o)ther? l > + 3 files updated, 1 files merged, 0 files removed, 0 files unresolved > + (branch merge, don't forget to commit) > + getting changed largefiles > 1 largefiles updated, 0 removed > $ hg commit -m "Merge repos e and f" > Invoking status precommit hook From kbullock+mercurial at ringworld.org Mon Feb 25 23:14:03 2013 From: kbullock+mercurial at ringworld.org (Kevin Bullock) Date: Mon, 25 Feb 2013 23:14:03 -0600 Subject: [PATCH stable] templatefilters: add missing import of _ In-Reply-To: References: Message-ID: <9D0CA981-B706-456E-BD91-0BBFFC53C2C1@ringworld.org> On 25 Feb 2013, at 8:39 PM, Mads Kiilerich wrote: > # HG changeset patch > # User Mads Kiilerich > # Date 1361844560 -3600 > # Branch stable > # Node ID b1f0fd26bda704357708c73fdeb78f1b6f372238 > # Parent 61c8327ced503bf7a1996337af711e0f4a58d4c0 > templatefilters: add missing import of _ > > diff --git a/mercurial/templatefilters.py b/mercurial/templatefilters.py > --- a/mercurial/templatefilters.py > +++ b/mercurial/templatefilters.py > @@ -5,6 +5,7 @@ > # This software may be used and distributed according to the terms of the > # GNU General Public License version 2 or any later version. > > +from i18n import _ > import cgi, re, os, time, urllib > import encoding, node, util, error > import hbisect > diff --git a/tests/test-template-engine.t b/tests/test-template-engine.t > --- a/tests/test-template-engine.t > +++ b/tests/test-template-engine.t > @@ -44,4 +44,15 @@ > 0 97e5f848f0936960273bbf75be6388cd0350a32b -1 0000000000000000000000000000000000000000 > -1 0000000000000000000000000000000000000000 -1 0000000000000000000000000000000000000000 > > + $ hg tip --template '{fill(node, 7)}\n' > + hg: parse error: fill expects an integer width > + [255] > + $ hg tip --template '{fill(node, "7")}\n' > + ef4a3af > + ceb5370 > + e8500df > + 6f7b191 > + e48998e > + 059af > + > $ cd .. I'm confused what this test has to do with the code change. pacem in terris / ??? / ?????? / ????????? / ?? Kevin R. Bullock From kbullock+mercurial at ringworld.org Mon Feb 25 23:16:16 2013 From: kbullock+mercurial at ringworld.org (Kevin Bullock) Date: Mon, 25 Feb 2013 23:16:16 -0600 Subject: [PATCH 3 of 9 stable] tests: don't rely on broken behaviour in test-largefiles-cache.t In-Reply-To: References: <7f0cd251905074b0aec1.1361846481@mk-desktop> Message-ID: On 25 Feb 2013, at 8:41 PM, Mads Kiilerich wrote: > # HG changeset patch > # User Mads Kiilerich > # Date 1361846443 -3600 > # Branch stable > # Node ID c92e62e6b93838c00c749e85e4eab243e155dd58 > # Parent 27f081501f9e04320ac94654c61e766764ee159e > tests: don't rely on broken behaviour in test-largefiles-cache.t > > The test relied on the bug that 'pull largefiles from branchheads' didn't pull > any largefiles from tip revision when it seemed like no largefiles had been > checked out before. > > diff --git a/tests/test-largefiles-cache.t b/tests/test-largefiles-cache.t > --- a/tests/test-largefiles-cache.t > +++ b/tests/test-largefiles-cache.t > @@ -16,6 +16,9 @@ > $ echo large > large > $ hg add --large large > $ hg commit -m 'add largefile' > + $ hg rm large > + $ hg commit -m 'branchhead without largefile' > + $ hg up -qr 0 > $ cd .. > > Discard all cached largefiles in USERCACHE > @@ -24,7 +27,7 @@ > > Create mirror repo, and pull from source without largefile: > "pull" is used instead of "clone" for suppression of (1) updating to > -tip (= cahcing largefile from source repo), and (2) recording source > +tip (= caching largefile from source repo), and (2) recording source Looks like an unrelated spelling fix? pacem in terris / ??? / ?????? / ????????? / ?? Kevin R. Bullock From simohe at besonet.ch Tue Feb 26 02:42:41 2013 From: simohe at besonet.ch (Simon He.) Date: Tue, 26 Feb 2013 09:42:41 +0100 Subject: AW: [PATCH 2 of 2] tests: remove glob lines which unnecessary match / for \ on windows In-Reply-To: <1361830765.11033.73.camel@calx> References: <3312b3d481a6e61f9881.1361657451@deb64virt.virtual> <1361830765.11033.73.camel@calx> Message-ID: <001501ce13fd$3df45740$b9dd05c0$@besonet.ch> Having a check code recipe sounds good, but I have no idea how this could be done. I do not know of any rule when an "os path" and when a "hg path" is printed. And also not when ui.slash is considered (when writing an "os path") and when it is not. Sometimes it is unclear why some lines need no glob but similar ones do not. An example is mentioned in the introduction email. I only see one possibility to avoid similar patches in the hg history. To run any modified test on windows before it's patch is pushed. I fear that I am not the only developer who can not do this. So this would have to be done by a crew member (except when a developer mentions he has run the test on windows). Some related threads: locate command ignoring ui.slash: http://www.selenic.com/pipermail/mercurial-devel/2009-July/014187.html mads about glob matching and ui.slash: http://www.selenic.com/pipermail/mercurial-devel/2012-October/045168.html > -----Urspr?ngliche Nachricht----- > Von: Matt Mackall [mailto:mpm at selenic.com] > Gesendet: Montag, 25. Februar 2013 23:19 > An: Simon Heimberg > Cc: Mercurial-devel > Betreff: Re: [PATCH 2 of 2] tests: remove glob lines which unnecessary match / > for \ on windows > > On Sat, 2013-02-23 at 23:10 +0100, Simon Heimberg wrote: > > # HG changeset patch > > # User Simon Heimberg # Date 1361656497 -3600 # > > Branch stable # Node ID 3312b3d481a6e61f988125d4472b53c7a0b00211 > > # Parent 3660cfb8b145e88b77228a1676d5c37113d93595 > > tests: remove glob lines which unnecessary match / for \ on windows > > > > This lines were reported as unnecessary when running the tests on > > windows because the path was already printed with a slash and not a > backslash. > > I think I'm going to start insisting that such patches come with check-code > recipes. It's the only hope we have for not hitting these issues constantly. > > -- > Mathematics is the supreme nostalgia of our time. From mads at kiilerich.com Tue Feb 26 05:25:08 2013 From: mads at kiilerich.com (Mads Kiilerich) Date: Tue, 26 Feb 2013 12:25:08 +0100 Subject: [PATCH stable] templatefilters: add missing import of _ In-Reply-To: <9D0CA981-B706-456E-BD91-0BBFFC53C2C1@ringworld.org> References: <9D0CA981-B706-456E-BD91-0BBFFC53C2C1@ringworld.org> Message-ID: <512C9B94.3060007@kiilerich.com> On 02/26/2013 06:14 AM, Kevin Bullock wrote: > On 25 Feb 2013, at 8:39 PM, Mads Kiilerich wrote: > >> # HG changeset patch >> # User Mads Kiilerich >> # Date 1361844560 -3600 >> # Branch stable >> # Node ID b1f0fd26bda704357708c73fdeb78f1b6f372238 >> # Parent 61c8327ced503bf7a1996337af711e0f4a58d4c0 >> templatefilters: add missing import of _ >> >> diff --git a/mercurial/templatefilters.py b/mercurial/templatefilters.py >> --- a/mercurial/templatefilters.py >> +++ b/mercurial/templatefilters.py >> @@ -5,6 +5,7 @@ >> # This software may be used and distributed according to the terms of the >> # GNU General Public License version 2 or any later version. >> >> +from i18n import _ >> import cgi, re, os, time, urllib >> import encoding, node, util, error >> import hbisect >> diff --git a/tests/test-template-engine.t b/tests/test-template-engine.t >> --- a/tests/test-template-engine.t >> +++ b/tests/test-template-engine.t >> @@ -44,4 +44,15 @@ >> 0 97e5f848f0936960273bbf75be6388cd0350a32b -1 0000000000000000000000000000000000000000 >> -1 0000000000000000000000000000000000000000 -1 0000000000000000000000000000000000000000 >> >> + $ hg tip --template '{fill(node, 7)}\n' >> + hg: parse error: fill expects an integer width >> + [255] >> + $ hg tip --template '{fill(node, "7")}\n' >> + ef4a3af >> + ceb5370 >> + e8500df >> + 6f7b191 >> + e48998e >> + 059af >> + >> $ cd .. > I'm confused what this test has to do with the code change. The test is testing the code change. The original code was added without test coverage (and without documentation). The new tests gives _some_ test coverage of this code so this exact problem won't happen again. It is very surprising that the fill width can't be specified as an integer but has to be a string (especially given the error message), so it would be very misleading just to add a test that showed that now it knew how to fail. /Mads From hg at intevation.org Tue Feb 26 06:00:04 2013 From: hg at intevation.org (Mercurial Commits) Date: Tue, 26 Feb 2013 13:00:04 +0100 Subject: mercurial/crew@18720: 2 outgoing changesets Message-ID: <1361880004.791319.26332.nullmailer@hg.intevation.org> 2 outgoing changesets in mercurial/crew: http://hg.intevation.org/mercurial/crew/rev/0ade08dcb3c3 changeset: 18720:0ade08dcb3c3 tag: tip user: Simon Heimberg date: Sat Feb 23 22:54:57 2013 +0100 summary: tests: remove glob lines which unnecessary match / for \ on windows http://hg.intevation.org/mercurial/crew/rev/9ad13296c581 changeset: 18719:9ad13296c581 user: Simon Heimberg date: Sat Feb 23 22:07:38 2013 +0100 summary: tests: append glob to filename output when required for windows -- Repository URL: http://hg.intevation.org/mercurial/crew From kbullock+mercurial at ringworld.org Tue Feb 26 10:38:34 2013 From: kbullock+mercurial at ringworld.org (Kevin Bullock) Date: Tue, 26 Feb 2013 10:38:34 -0600 Subject: [PATCH stable] templatefilters: add missing import of _ In-Reply-To: <512C9B94.3060007@kiilerich.com> References: <9D0CA981-B706-456E-BD91-0BBFFC53C2C1@ringworld.org> <512C9B94.3060007@kiilerich.com> Message-ID: <6A43773A-07D0-4624-AE32-EC00E255BC98@ringworld.org> On Feb 26, 2013, at 5:25 AM, Mads Kiilerich wrote: > On 02/26/2013 06:14 AM, Kevin Bullock wrote: >> On 25 Feb 2013, at 8:39 PM, Mads Kiilerich wrote: >> >>> # HG changeset patch >>> # User Mads Kiilerich >>> # Date 1361844560 -3600 >>> # Branch stable >>> # Node ID b1f0fd26bda704357708c73fdeb78f1b6f372238 >>> # Parent 61c8327ced503bf7a1996337af711e0f4a58d4c0 >>> templatefilters: add missing import of _ >>> >>> diff --git a/mercurial/templatefilters.py b/mercurial/templatefilters.py >>> --- a/mercurial/templatefilters.py >>> +++ b/mercurial/templatefilters.py >>> @@ -5,6 +5,7 @@ >>> # This software may be used and distributed according to the terms of the >>> # GNU General Public License version 2 or any later version. >>> >>> +from i18n import _ >>> import cgi, re, os, time, urllib >>> import encoding, node, util, error >>> import hbisect >>> diff --git a/tests/test-template-engine.t b/tests/test-template-engine.t >>> --- a/tests/test-template-engine.t >>> +++ b/tests/test-template-engine.t >>> @@ -44,4 +44,15 @@ >>> 0 97e5f848f0936960273bbf75be6388cd0350a32b -1 0000000000000000000000000000000000000000 >>> -1 0000000000000000000000000000000000000000 -1 0000000000000000000000000000000000000000 >>> >>> + $ hg tip --template '{fill(node, 7)}\n' >>> + hg: parse error: fill expects an integer width >>> + [255] >>> + $ hg tip --template '{fill(node, "7")}\n' >>> + ef4a3af >>> + ceb5370 >>> + e8500df >>> + 6f7b191 >>> + e48998e >>> + 059af >>> + >>> $ cd .. >> I'm confused what this test has to do with the code change. > > The test is testing the code change. > > The original code was added without test coverage (and without documentation). Eh? How does adding a missing import of _ fix the fill() function? (This should be in the commit description.) pacem in terris / ??? / ?????? / ????????? / ?? Kevin R. Bullock From mpm at selenic.com Tue Feb 26 12:01:19 2013 From: mpm at selenic.com (Matt Mackall) Date: Tue, 26 Feb 2013 12:01:19 -0600 Subject: AW: [PATCH 2 of 2] tests: remove glob lines which unnecessary match / for \ on windows In-Reply-To: <001501ce13fd$3df45740$b9dd05c0$@besonet.ch> References: <3312b3d481a6e61f9881.1361657451@deb64virt.virtual> <1361830765.11033.73.camel@calx> <001501ce13fd$3df45740$b9dd05c0$@besonet.ch> Message-ID: <1361901679.11033.88.camel@calx> On Tue, 2013-02-26 at 09:42 +0100, Simon He. wrote: > Having a check code recipe sounds good, but I have no idea how this could be done. > I do not know of any rule when an "os path" and when a "hg path" is printed. $ grep 'pulling from .TESTTMP/' *.t test-blackbox.t: pulling from $TESTTMP/blackboxtest <- FAILED test-bookmarks-pushpull.t: pulling from $TESTTMP/a (glob) test-issue1502.t: pulling from $TESTTMP/foo (glob) test-issue1502.t: pulling from $TESTTMP/foo (glob) test-issue1802.t: pulling from $TESTTMP/unix-repo test-largefiles.t: pulling from $TESTTMP/a (glob) test-largefiles.t: pulling from $TESTTMP/b (glob) test-obsolete-checkheads.t: pulling from $TESTTMP/remote (glob) test-pull-r.t: pulling from $TESTTMP/repo2 (glob) test-rebase-pull.t: pulling from $TESTTMP/a (glob) test-rebase-pull.t: pulling from $TESTTMP/a (glob) test-rebase-pull.t: pulling from $TESTTMP/a (glob) test-rebase-pull.t: pulling from $TESTTMP/a (glob) test-rebase-pull.t: pulling from $TESTTMP/a (glob) test-rebase-pull.t: pulling from $TESTTMP/a (glob) test-subrepo-git.t: pulling from $TESTTMP/t (glob) test-subrepo.t: pulling from $TESTTMP/t (glob) This suggests the rule: "if it starts with ' pulling from $TESTTMP/', it better end with (glob)". The great bulk of the places where we use '\' on Windows can be covered by maybe a dozen patterns. -- Mathematics is the supreme nostalgia of our time. From mads at kiilerich.com Tue Feb 26 12:11:36 2013 From: mads at kiilerich.com (Mads Kiilerich) Date: Tue, 26 Feb 2013 19:11:36 +0100 Subject: [PATCH 3 of 9 stable] tests: don't rely on broken behaviour in test-largefiles-cache.t In-Reply-To: References: <7f0cd251905074b0aec1.1361846481@mk-desktop> Message-ID: <512CFAD8.6070705@kiilerich.com> On 02/26/2013 06:16 AM, Kevin Bullock wrote: > On 25 Feb 2013, at 8:41 PM, Mads Kiilerich wrote: > >> # HG changeset patch >> # User Mads Kiilerich >> # Date 1361846443 -3600 >> # Branch stable >> # Node ID c92e62e6b93838c00c749e85e4eab243e155dd58 >> # Parent 27f081501f9e04320ac94654c61e766764ee159e >> tests: don't rely on broken behaviour in test-largefiles-cache.t >> >> The test relied on the bug that 'pull largefiles from branchheads' didn't pull >> any largefiles from tip revision when it seemed like no largefiles had been >> checked out before. >> >> diff --git a/tests/test-largefiles-cache.t b/tests/test-largefiles-cache.t >> --- a/tests/test-largefiles-cache.t >> +++ b/tests/test-largefiles-cache.t >> @@ -16,6 +16,9 @@ >> $ echo large > large >> $ hg add --large large >> $ hg commit -m 'add largefile' >> + $ hg rm large >> + $ hg commit -m 'branchhead without largefile' >> + $ hg up -qr 0 >> $ cd .. >> >> Discard all cached largefiles in USERCACHE >> @@ -24,7 +27,7 @@ >> >> Create mirror repo, and pull from source without largefile: >> "pull" is used instead of "clone" for suppression of (1) updating to >> -tip (= cahcing largefile from source repo), and (2) recording source >> +tip (= caching largefile from source repo), and (2) recording source > Looks like an unrelated spelling fix? Absolutely correct. In the descriptive part of a test. The guidelines requiring no unrelated changes are good and do serve a purpose. But sometimes it serve no purpose to follow them literally. They are an attempt of formalizing and generalizing the intention. In this case I was doing trivial cleanup of the test file anyway. There is no way this could make a review harder or hide bugs or that anybody would care to apply or bisect one without the other. Fixing a typo in the passing in such a patch adds less overhead to the whole process than doing it in a separate patch. All time spent handling and discussing such a minor nice-to-have is a waste of time. Please, let's get the proportions right and focus on stuff that matters. /Mads From mads at kiilerich.com Tue Feb 26 12:11:40 2013 From: mads at kiilerich.com (Mads Kiilerich) Date: Tue, 26 Feb 2013 19:11:40 +0100 Subject: [PATCH stable] templatefilters: add missing import of _ In-Reply-To: <6A43773A-07D0-4624-AE32-EC00E255BC98@ringworld.org> References: <9D0CA981-B706-456E-BD91-0BBFFC53C2C1@ringworld.org> <512C9B94.3060007@kiilerich.com> <6A43773A-07D0-4624-AE32-EC00E255BC98@ringworld.org> Message-ID: <512CFADC.6050406@kiilerich.com> On 02/26/2013 05:38 PM, Kevin Bullock wrote: > On Feb 26, 2013, at 5:25 AM, Mads Kiilerich wrote: > >> On 02/26/2013 06:14 AM, Kevin Bullock wrote: >>> On 25 Feb 2013, at 8:39 PM, Mads Kiilerich wrote: >>> >>>> # HG changeset patch >>>> # User Mads Kiilerich >>>> # Date 1361844560 -3600 >>>> # Branch stable >>>> # Node ID b1f0fd26bda704357708c73fdeb78f1b6f372238 >>>> # Parent 61c8327ced503bf7a1996337af711e0f4a58d4c0 >>>> templatefilters: add missing import of _ >>>> >>>> diff --git a/mercurial/templatefilters.py b/mercurial/templatefilters.py >>>> --- a/mercurial/templatefilters.py >>>> +++ b/mercurial/templatefilters.py >>>> @@ -5,6 +5,7 @@ >>>> # This software may be used and distributed according to the terms of the >>>> # GNU General Public License version 2 or any later version. >>>> >>>> +from i18n import _ >>>> import cgi, re, os, time, urllib >>>> import encoding, node, util, error >>>> import hbisect >>>> diff --git a/tests/test-template-engine.t b/tests/test-template-engine.t >>>> --- a/tests/test-template-engine.t >>>> +++ b/tests/test-template-engine.t >>>> @@ -44,4 +44,15 @@ >>>> 0 97e5f848f0936960273bbf75be6388cd0350a32b -1 0000000000000000000000000000000000000000 >>>> -1 0000000000000000000000000000000000000000 -1 0000000000000000000000000000000000000000 >>>> >>>> + $ hg tip --template '{fill(node, 7)}\n' >>>> + hg: parse error: fill expects an integer width >>>> + [255] >>>> + $ hg tip --template '{fill(node, "7")}\n' >>>> + ef4a3af >>>> + ceb5370 >>>> + e8500df >>>> + 6f7b191 >>>> + e48998e >>>> + 059af >>>> + >>>> $ cd .. >>> I'm confused what this test has to do with the code change. >> The test is testing the code change. >> >> The original code was added without test coverage (and without documentation). > Eh? How does adding a missing import of _ fix the fill() function? (This should be in the commit description.) It is really so trivial that it doesn't deserve a description. When an import is added because it was missing then it is obviously because some code uses it. When a test is added then it is obviously because it exercises the code path that failed without the fix and proves that it no longer fails. Please, let's get the proportions right and save the long explanations to stuff that really needs an explanation. /Mads From kbullock+mercurial at ringworld.org Tue Feb 26 12:30:47 2013 From: kbullock+mercurial at ringworld.org (Kevin Bullock) Date: Tue, 26 Feb 2013 12:30:47 -0600 Subject: [PATCH stable] templatefilters: add missing import of _ In-Reply-To: <512CFADC.6050406@kiilerich.com> References: <9D0CA981-B706-456E-BD91-0BBFFC53C2C1@ringworld.org> <512C9B94.3060007@kiilerich.com> <6A43773A-07D0-4624-AE32-EC00E255BC98@ringworld.org> <512CFADC.6050406@kiilerich.com> Message-ID: <30731451-9F72-417B-9498-FA73FD260D5C@ringworld.org> On Feb 26, 2013, at 12:11 PM, Mads Kiilerich wrote: > On 02/26/2013 05:38 PM, Kevin Bullock wrote: >> On Feb 26, 2013, at 5:25 AM, Mads Kiilerich wrote: >> >>> On 02/26/2013 06:14 AM, Kevin Bullock wrote: >>>> On 25 Feb 2013, at 8:39 PM, Mads Kiilerich wrote: >>>> >>>>> # HG changeset patch >>>>> # User Mads Kiilerich >>>>> # Date 1361844560 -3600 >>>>> # Branch stable >>>>> # Node ID b1f0fd26bda704357708c73fdeb78f1b6f372238 >>>>> # Parent 61c8327ced503bf7a1996337af711e0f4a58d4c0 >>>>> templatefilters: add missing import of _ >>>>> >>>>> diff --git a/mercurial/templatefilters.py b/mercurial/templatefilters.py >>>>> --- a/mercurial/templatefilters.py >>>>> +++ b/mercurial/templatefilters.py >>>>> @@ -5,6 +5,7 @@ >>>>> # This software may be used and distributed according to the terms of the >>>>> # GNU General Public License version 2 or any later version. >>>>> >>>>> +from i18n import _ >>>>> import cgi, re, os, time, urllib >>>>> import encoding, node, util, error >>>>> import hbisect >>>>> diff --git a/tests/test-template-engine.t b/tests/test-template-engine.t >>>>> --- a/tests/test-template-engine.t >>>>> +++ b/tests/test-template-engine.t >>>>> @@ -44,4 +44,15 @@ >>>>> 0 97e5f848f0936960273bbf75be6388cd0350a32b -1 0000000000000000000000000000000000000000 >>>>> -1 0000000000000000000000000000000000000000 -1 0000000000000000000000000000000000000000 >>>>> >>>>> + $ hg tip --template '{fill(node, 7)}\n' >>>>> + hg: parse error: fill expects an integer width >>>>> + [255] >>>>> + $ hg tip --template '{fill(node, "7")}\n' >>>>> + ef4a3af >>>>> + ceb5370 >>>>> + e8500df >>>>> + 6f7b191 >>>>> + e48998e >>>>> + 059af >>>>> + >>>>> $ cd .. >>>> I'm confused what this test has to do with the code change. >>> The test is testing the code change. >>> >>> The original code was added without test coverage (and without documentation). >> Eh? How does adding a missing import of _ fix the fill() function? (This should be in the commit description.) > > It is really so trivial that it doesn't deserve a description. > > When an import is added because it was missing then it is obviously because some code uses it. > > When a test is added then it is obviously because it exercises the code path that failed without the fix and proves that it no longer fails. Not necessarily. It's possible (as I first thought) that some unrelated changes had gotten mixed into the same patch. It happens, and that's why we do code review on-list. If the added test is obviously related to the code path that the test exercises ("Whoops, we forgot to import the bookmarks module when trying to write bmstore!"), then maybe no description is needed. But these changes don't look related _at all_ at first blush. For the record, the offending line is at : raise error.ParseError(_("fill expects an integer width")) which was added in: changeset: 17638:e2711975be00 user: Matt Mackall date: Mon Sep 24 15:54:44 2012 -0500 summary: templatefilters: add parameterized fill function > Please, let's get the proportions right and save the long explanations to stuff that really needs an explanation. A one-sentence description -- or even a copy-and-paste of the traceback you hit -- would've avoided this entire thread. pacem in terris / ??? / ?????? / ????????? / ?? Kevin R. Bullock From mpm at selenic.com Tue Feb 26 13:30:04 2013 From: mpm at selenic.com (Matt Mackall) Date: Tue, 26 Feb 2013 13:30:04 -0600 Subject: [PATCH 3 of 9 stable] tests: don't rely on broken behaviour in test-largefiles-cache.t In-Reply-To: <512CFAD8.6070705@kiilerich.com> References: <7f0cd251905074b0aec1.1361846481@mk-desktop> <512CFAD8.6070705@kiilerich.com> Message-ID: <1361907004.11033.122.camel@calx> On Tue, 2013-02-26 at 19:11 +0100, Mads Kiilerich wrote: > On 02/26/2013 06:16 AM, Kevin Bullock wrote: > > On 25 Feb 2013, at 8:41 PM, Mads Kiilerich wrote: > > > >> # HG changeset patch > >> # User Mads Kiilerich > >> # Date 1361846443 -3600 > >> # Branch stable > >> # Node ID c92e62e6b93838c00c749e85e4eab243e155dd58 > >> # Parent 27f081501f9e04320ac94654c61e766764ee159e > >> tests: don't rely on broken behaviour in test-largefiles-cache.t > >> > >> The test relied on the bug that 'pull largefiles from branchheads' didn't pull > >> any largefiles from tip revision when it seemed like no largefiles had been > >> checked out before. > >> > >> diff --git a/tests/test-largefiles-cache.t b/tests/test-largefiles-cache.t > >> --- a/tests/test-largefiles-cache.t > >> +++ b/tests/test-largefiles-cache.t > >> @@ -16,6 +16,9 @@ > >> $ echo large > large > >> $ hg add --large large > >> $ hg commit -m 'add largefile' > >> + $ hg rm large > >> + $ hg commit -m 'branchhead without largefile' > >> + $ hg up -qr 0 > >> $ cd .. > >> > >> Discard all cached largefiles in USERCACHE > >> @@ -24,7 +27,7 @@ > >> > >> Create mirror repo, and pull from source without largefile: > >> "pull" is used instead of "clone" for suppression of (1) updating to > >> -tip (= cahcing largefile from source repo), and (2) recording source > >> +tip (= caching largefile from source repo), and (2) recording source > > Looks like an unrelated spelling fix? > > Absolutely correct. In the descriptive part of a test. > > The guidelines requiring no unrelated changes are good and do serve a > purpose. But sometimes it serve no purpose to follow them literally. Breaking the rules is a false efficiency as the probability of triggering an expensive rules discussion and/or resend is high. Further, the probability of triggering the expense does not drop in proportion to the value of the unrelated change, so the expected cost/benefit ratio goes to infinity as the value of the unrelated change goes to zero. So please do not break the rules, especially for nearly-zero-value changes like typos in test descriptions. Better to not make such changes at all than to spend an hour discussing them. -- Mathematics is the supreme nostalgia of our time. From mads at kiilerich.com Tue Feb 26 14:33:17 2013 From: mads at kiilerich.com (Mads Kiilerich) Date: Tue, 26 Feb 2013 21:33:17 +0100 Subject: [PATCH] tests: convert \ to / on test output lines containing $TESTTMP Message-ID: <2c246fef46d1f70b0882.1361910797@mk-desktop> # HG changeset patch # User Mads Kiilerich # Date 1361907870 -3600 # Node ID 2c246fef46d1f70b088284dafa00b0911920949f # Parent 0ade08dcb3c3d9a1418f38bf875d6c737750b19f tests: convert \ to / on test output lines containing $TESTTMP This reduces the need for adding '(glob)' on random lines in test output. diff --git a/contrib/check-code.py b/contrib/check-code.py --- a/contrib/check-code.py +++ b/contrib/check-code.py @@ -101,8 +101,6 @@ "explicit exit code checks unnecessary"), (uprefix + r'set -e', "don't use set -e"), (uprefix + r'\s', "don't indent commands, use > for continued lines"), - (r'^ saved backup bundle to \$TESTTMP.*\.hg$', - "use (glob) to match Windows paths too"), ], # warnings [ diff --git a/tests/run-tests.py b/tests/run-tests.py --- a/tests/run-tests.py +++ b/tests/run-tests.py @@ -570,6 +570,10 @@ if el == l: # perfect match (fast) return True if el: + if os.name == 'nt' and '$TESTTMP' in l: + l = l.replace('\\', '/') + if el == l: + return True if el.endswith(" (esc)\n"): el = el[:-7].decode('string-escape') + '\n' if el == l or os.name == 'nt' and el[:-1] + '\r\n' == l: diff --git a/tests/test-blackbox.t b/tests/test-blackbox.t --- a/tests/test-blackbox.t +++ b/tests/test-blackbox.t @@ -48,7 +48,7 @@ adding c $ cd ../blackboxtest2 $ hg pull - pulling from $TESTTMP/blackboxtest (glob) + pulling from $TESTTMP/blackboxtest searching for changes adding changesets adding manifests diff --git a/tests/test-bookmarks-pushpull.t b/tests/test-bookmarks-pushpull.t --- a/tests/test-bookmarks-pushpull.t +++ b/tests/test-bookmarks-pushpull.t @@ -139,7 +139,7 @@ * foobar 1:9b140be10808 $ hg pull --config paths.foo=../a foo - pulling from $TESTTMP/a (glob) + pulling from $TESTTMP/a searching for changes adding changesets adding manifests diff --git a/tests/test-clone.t b/tests/test-clone.t --- a/tests/test-clone.t +++ b/tests/test-clone.t @@ -92,7 +92,7 @@ $ hg clone -q -U --config 'paths.foobar=a#0' foobar f $ hg -R f showconfig paths.default - $TESTTMP/a#0 (glob) + $TESTTMP/a#0 Use --pull: diff --git a/tests/test-commit-amend.t b/tests/test-commit-amend.t --- a/tests/test-commit-amend.t +++ b/tests/test-commit-amend.t @@ -35,7 +35,7 @@ $ HGEDITOR="\"sh\" \"`pwd`/editor.sh\"" hg commit --amend -m 'amend base1' pretxncommit 43f1ba15f28a50abf0aae529cf8a16bfced7b149 43f1ba15f28a tip - saved backup bundle to $TESTTMP/.hg/strip-backup/489edb5b847d-amend-backup.hg (glob) + saved backup bundle to $TESTTMP/.hg/strip-backup/489edb5b847d-amend-backup.hg $ echo 'pretxncommit.foo = ' >> $HGRCPATH $ hg diff -c . diff -r ad120869acf0 -r 43f1ba15f28a a @@ -86,7 +86,7 @@ Add new file: $ hg ci --amend -m 'amend base1 new file' - saved backup bundle to $TESTTMP/.hg/strip-backup/43f1ba15f28a-amend-backup.hg (glob) + saved backup bundle to $TESTTMP/.hg/strip-backup/43f1ba15f28a-amend-backup.hg Remove file that was added in amended commit: (and test logfile option) @@ -95,7 +95,7 @@ $ hg rm b $ echo 'amend base1 remove new file' > ../logfile $ HGEDITOR="\"sh\" \"`pwd`/editor.sh\"" hg ci --amend --logfile ../logfile - saved backup bundle to $TESTTMP/.hg/strip-backup/b8e3cb2b3882-amend-backup.hg (glob) + saved backup bundle to $TESTTMP/.hg/strip-backup/b8e3cb2b3882-amend-backup.hg $ hg cat b b: no such file in rev 74609c7f506e @@ -109,7 +109,7 @@ a stripping amended changeset 74609c7f506e 1 changesets found - saved backup bundle to $TESTTMP/.hg/strip-backup/74609c7f506e-amend-backup.hg (glob) + saved backup bundle to $TESTTMP/.hg/strip-backup/74609c7f506e-amend-backup.hg 1 changesets found adding branch adding changesets @@ -146,10 +146,10 @@ Test -u/-d: $ hg ci --amend -u foo -d '1 0' - saved backup bundle to $TESTTMP/.hg/strip-backup/1cd866679df8-amend-backup.hg (glob) + saved backup bundle to $TESTTMP/.hg/strip-backup/1cd866679df8-amend-backup.hg $ echo a >> a $ hg ci --amend -u foo -d '1 0' - saved backup bundle to $TESTTMP/.hg/strip-backup/780e6f23e03d-amend-backup.hg (glob) + saved backup bundle to $TESTTMP/.hg/strip-backup/780e6f23e03d-amend-backup.hg $ hg log -r . changeset: 1:5f357c7560ab tag: tip @@ -180,7 +180,7 @@ a stripping amended changeset 5f357c7560ab 1 changesets found - saved backup bundle to $TESTTMP/.hg/strip-backup/5f357c7560ab-amend-backup.hg (glob) + saved backup bundle to $TESTTMP/.hg/strip-backup/5f357c7560ab-amend-backup.hg 1 changesets found adding branch adding changesets @@ -209,7 +209,7 @@ stripping intermediate changeset a0ea9b1a4c8c stripping amended changeset 7ab3bf440b54 2 changesets found - saved backup bundle to $TESTTMP/.hg/strip-backup/7ab3bf440b54-amend-backup.hg (glob) + saved backup bundle to $TESTTMP/.hg/strip-backup/7ab3bf440b54-amend-backup.hg 1 changesets found adding branch adding changesets @@ -232,13 +232,13 @@ $ hg book book1 $ hg book book2 $ hg ci --amend -m 'move bookmarks' - saved backup bundle to $TESTTMP/.hg/strip-backup/ea22a388757c-amend-backup.hg (glob) + saved backup bundle to $TESTTMP/.hg/strip-backup/ea22a388757c-amend-backup.hg $ hg book book1 1:6cec5aa930e2 * book2 1:6cec5aa930e2 $ echo a >> a $ hg ci --amend -m 'move bookmarks' - saved backup bundle to $TESTTMP/.hg/strip-backup/6cec5aa930e2-amend-backup.hg (glob) + saved backup bundle to $TESTTMP/.hg/strip-backup/6cec5aa930e2-amend-backup.hg $ hg book book1 1:48bb6e53a15f * book2 1:48bb6e53a15f @@ -275,7 +275,7 @@ marked working directory as branch default (branches are permanent and global, did you want a bookmark?) $ hg ci --amend -m 'back to default' - saved backup bundle to $TESTTMP/.hg/strip-backup/8ac881fbf49d-amend-backup.hg (glob) + saved backup bundle to $TESTTMP/.hg/strip-backup/8ac881fbf49d-amend-backup.hg $ hg branches default 2:ce12b0b57d46 @@ -291,7 +291,7 @@ $ echo b >> b $ hg ci -mb $ hg ci --amend --close-branch -m 'closing branch foo' - saved backup bundle to $TESTTMP/.hg/strip-backup/c962248fa264-amend-backup.hg (glob) + saved backup bundle to $TESTTMP/.hg/strip-backup/c962248fa264-amend-backup.hg Same thing, different code path: @@ -300,7 +300,7 @@ reopening closed branch head 4 $ echo b >> b $ hg ci --amend --close-branch - saved backup bundle to $TESTTMP/.hg/strip-backup/027371728205-amend-backup.hg (glob) + saved backup bundle to $TESTTMP/.hg/strip-backup/027371728205-amend-backup.hg $ hg branches default 2:ce12b0b57d46 @@ -324,7 +324,7 @@ $ hg ci -m 'b -> c' $ hg mv c d $ hg ci --amend -m 'b -> d' - saved backup bundle to $TESTTMP/.hg/strip-backup/b8c6eac7f12e-amend-backup.hg (glob) + saved backup bundle to $TESTTMP/.hg/strip-backup/b8c6eac7f12e-amend-backup.hg $ hg st --rev '.^' --copies d A d b @@ -332,7 +332,7 @@ $ hg ci -m 'e = d' $ hg cp e f $ hg ci --amend -m 'f = d' - saved backup bundle to $TESTTMP/.hg/strip-backup/7f9761d65613-amend-backup.hg (glob) + saved backup bundle to $TESTTMP/.hg/strip-backup/7f9761d65613-amend-backup.hg $ hg st --rev '.^' --copies f A f d @@ -343,7 +343,7 @@ $ hg cp a f $ mv f.orig f $ hg ci --amend -m replacef - saved backup bundle to $TESTTMP/.hg/strip-backup/9e8c5f7e3d95-amend-backup.hg (glob) + saved backup bundle to $TESTTMP/.hg/strip-backup/9e8c5f7e3d95-amend-backup.hg $ hg st --change . --copies $ hg log -r . --template "{file_copies}\n" @@ -355,7 +355,7 @@ adding g $ hg mv g h $ hg ci --amend - saved backup bundle to $TESTTMP/.hg/strip-backup/24aa8eacce2b-amend-backup.hg (glob) + saved backup bundle to $TESTTMP/.hg/strip-backup/24aa8eacce2b-amend-backup.hg $ hg st --change . --copies h A h $ hg log -r . --template "{file_copies}\n" @@ -375,11 +375,11 @@ $ echo a >> a $ hg ci -ma $ hg ci --amend -m "a'" - saved backup bundle to $TESTTMP/.hg/strip-backup/3837aa2a2fdb-amend-backup.hg (glob) + saved backup bundle to $TESTTMP/.hg/strip-backup/3837aa2a2fdb-amend-backup.hg $ hg log -r . --template "{branch}\n" a $ hg ci --amend -m "a''" - saved backup bundle to $TESTTMP/.hg/strip-backup/c05c06be7514-amend-backup.hg (glob) + saved backup bundle to $TESTTMP/.hg/strip-backup/c05c06be7514-amend-backup.hg $ hg log -r . --template "{branch}\n" a @@ -396,7 +396,7 @@ $ hg graft 12 grafting revision 12 $ hg ci --amend -m 'graft amend' - saved backup bundle to $TESTTMP/.hg/strip-backup/bd010aea3f39-amend-backup.hg (glob) + saved backup bundle to $TESTTMP/.hg/strip-backup/bd010aea3f39-amend-backup.hg $ hg log -r . --debug | grep extra extra: amend_source=bd010aea3f39f3fb2a2f884b9ccb0471cd77398e extra: branch=a diff --git a/tests/test-contrib.t b/tests/test-contrib.t --- a/tests/test-contrib.t +++ b/tests/test-contrib.t @@ -109,7 +109,7 @@ Test shrink-revlog: $ cd repo-a $ hg --config extensions.shrink="$CONTRIBDIR/shrink-revlog.py" shrink - shrinking $TESTTMP/repo-a/.hg/store/00manifest.i (glob) + shrinking $TESTTMP/repo-a/.hg/store/00manifest.i reading revs sorting revs writing revs @@ -117,8 +117,8 @@ new file size: 324 bytes ( 0.0 MiB) shrinkage: 0.0% (1.0x) note: old revlog saved in: - $TESTTMP/repo-a/.hg/store/00manifest.i.old (glob) - $TESTTMP/repo-a/.hg/store/00manifest.d.old (glob) + $TESTTMP/repo-a/.hg/store/00manifest.i.old + $TESTTMP/repo-a/.hg/store/00manifest.d.old (You can delete those files when you are satisfied that your repository is still sane. Running 'hg verify' is strongly recommended.) $ hg verify diff --git a/tests/test-convert-authormap.t b/tests/test-convert-authormap.t --- a/tests/test-convert-authormap.t +++ b/tests/test-convert-authormap.t @@ -27,7 +27,7 @@ sorting... converting... 0 foo - writing author map file $TESTTMP/new/.hg/authormap (glob) + writing author map file $TESTTMP/new/.hg/authormap $ cat new/.hg/authormap user name=Long User Name $ hg -Rnew log @@ -44,7 +44,7 @@ $ hg init new $ mv authormap.txt new/.hg/authormap $ hg convert orig new - ignoring bad line in author map file $TESTTMP/new/.hg/authormap: this line is ignored (glob) + ignoring bad line in author map file $TESTTMP/new/.hg/authormap: this line is ignored scanning source... sorting... converting... diff --git a/tests/test-convert-filemap.t b/tests/test-convert-filemap.t --- a/tests/test-convert-filemap.t +++ b/tests/test-convert-filemap.t @@ -568,7 +568,7 @@ $ cd namedbranch $ hg --config extensions.mq= strip tip 1 files updated, 0 files merged, 0 files removed, 0 files unresolved - saved backup bundle to $TESTTMP/namedbranch/.hg/strip-backup/73899bcbe45c-backup.hg (glob) + saved backup bundle to $TESTTMP/namedbranch/.hg/strip-backup/73899bcbe45c-backup.hg $ hg up foo 2 files updated, 0 files merged, 0 files removed, 0 files unresolved $ hg merge default diff --git a/tests/test-default-push.t b/tests/test-default-push.t --- a/tests/test-default-push.t +++ b/tests/test-default-push.t @@ -18,7 +18,7 @@ Push should push to 'default' when 'default-push' not set: $ hg --cwd b push - pushing to $TESTTMP/a (glob) + pushing to $TESTTMP/a searching for changes adding changesets adding manifests @@ -29,7 +29,7 @@ $ echo 'default-push = ../c' >> b/.hg/hgrc $ hg --cwd b push - pushing to $TESTTMP/c (glob) + pushing to $TESTTMP/c searching for changes adding changesets adding manifests diff --git a/tests/test-extension.t b/tests/test-extension.t --- a/tests/test-extension.t +++ b/tests/test-extension.t @@ -475,9 +475,9 @@ > cmdtable = None > EOF $ hg --config extensions.path=./path.py help foo > /dev/null - warning: error finding commands in $TESTTMP/hgext/forest.py (glob) + warning: error finding commands in $TESTTMP/hgext/forest.py hg: unknown command 'foo' - warning: error finding commands in $TESTTMP/hgext/forest.py (glob) + warning: error finding commands in $TESTTMP/hgext/forest.py [255] $ cat > throw.py < .hgignore $ hg status - abort: $TESTTMP/.hgignore: invalid pattern (relre): *.o (glob) + abort: $TESTTMP/.hgignore: invalid pattern (relre): *.o [255] $ echo ".*\.o" > .hgignore @@ -88,7 +88,7 @@ $ echo "syntax: invalid" > .hgignore $ hg status - $TESTTMP/.hgignore: ignoring invalid syntax 'invalid' (glob) + $TESTTMP/.hgignore: ignoring invalid syntax 'invalid' A dir/b.o ? .hgignore ? a.c diff --git a/tests/test-hgrc.t b/tests/test-hgrc.t --- a/tests/test-hgrc.t +++ b/tests/test-hgrc.t @@ -29,12 +29,12 @@ $ cd foobar $ cat .hg/hgrc [paths] - default = $TESTTMP/foo%bar (glob) + default = $TESTTMP/foo%bar $ hg paths - default = $TESTTMP/foo%bar (glob) + default = $TESTTMP/foo%bar $ hg showconfig - bundle.mainreporoot=$TESTTMP/foobar (glob) - paths.default=$TESTTMP/foo%bar (glob) + bundle.mainreporoot=$TESTTMP/foobar + paths.default=$TESTTMP/foo%bar $ cd .. issue1829: wrong indentation diff --git a/tests/test-histedit-bookmark-motion.t b/tests/test-histedit-bookmark-motion.t --- a/tests/test-histedit-bookmark-motion.t +++ b/tests/test-histedit-bookmark-motion.t @@ -90,8 +90,8 @@ histedit: moving bookmarks three from 055a42cdd887 to 59d9f330561f histedit: moving bookmarks two from 177f92b77385 to b346ab9a313d histedit: moving bookmarks will-move-backwards from d2ae7f538514 to cb9a9f314b8b - saved backup bundle to $TESTTMP/r/.hg/strip-backup/d2ae7f538514-backup.hg (glob) - saved backup bundle to $TESTTMP/r/.hg/strip-backup/96e494a2d553-backup.hg (glob) + saved backup bundle to $TESTTMP/r/.hg/strip-backup/d2ae7f538514-backup.hg + saved backup bundle to $TESTTMP/r/.hg/strip-backup/96e494a2d553-backup.hg $ hg log --graph @ changeset: 3:cacdfd884a93 | bookmark: five @@ -144,7 +144,7 @@ histedit: moving bookmarks five from cacdfd884a93 to c04e50810e4b histedit: moving bookmarks four from 59d9f330561f to c04e50810e4b histedit: moving bookmarks three from 59d9f330561f to c04e50810e4b - saved backup bundle to $TESTTMP/r/.hg/strip-backup/59d9f330561f-backup.hg (glob) + saved backup bundle to $TESTTMP/r/.hg/strip-backup/59d9f330561f-backup.hg We expect 'five' to stay at tip, since the tipmost bookmark is most likely the useful signal. diff --git a/tests/test-histedit-edit.t b/tests/test-histedit-edit.t --- a/tests/test-histedit-edit.t +++ b/tests/test-histedit-edit.t @@ -157,7 +157,7 @@ A f $ HGEDITOR='true' hg histedit --continue 0 files updated, 0 files merged, 0 files removed, 0 files unresolved - saved backup bundle to $TESTTMP/r/.hg/strip-backup/b5f70786f9b0-backup.hg (glob) + saved backup bundle to $TESTTMP/r/.hg/strip-backup/b5f70786f9b0-backup.hg $ hg status diff --git a/tests/test-histedit-fold.t b/tests/test-histedit-fold.t --- a/tests/test-histedit-fold.t +++ b/tests/test-histedit-fold.t @@ -278,7 +278,7 @@ HG: changed file 1 files updated, 0 files merged, 0 files removed, 0 files unresolved 0 files updated, 0 files merged, 0 files removed, 0 files unresolved - saved backup bundle to $TESTTMP/fold-with-dropped/.hg/strip-backup/617f94f13c0f-backup.hg (glob) + saved backup bundle to $TESTTMP/fold-with-dropped/.hg/strip-backup/617f94f13c0f-backup.hg $ hg log -G @ changeset: 1:10c647b2cdd5 | tag: tip diff --git a/tests/test-histedit-obsolete.t b/tests/test-histedit-obsolete.t --- a/tests/test-histedit-obsolete.t +++ b/tests/test-histedit-obsolete.t @@ -67,7 +67,7 @@ > pick 652413bf663e 5 f > EOF $ hg histedit 1 --commands commands.txt --verbose | grep histedit - saved backup bundle to $TESTTMP/base/.hg/strip-backup/96e494a2d553-backup.hg (glob) + saved backup bundle to $TESTTMP/base/.hg/strip-backup/96e494a2d553-backup.hg $ hg log --graph --hidden @ 8:cacdfd884a93 f | @@ -437,9 +437,9 @@ 0 files updated, 0 files merged, 2 files removed, 0 files unresolved 2 files updated, 0 files merged, 0 files removed, 0 files unresolved 0 files updated, 0 files merged, 0 files removed, 0 files unresolved - saved backup bundle to $TESTTMP/folding/.hg/strip-backup/58019c66f35f-backup.hg (glob) - saved backup bundle to $TESTTMP/folding/.hg/strip-backup/83d1858e070b-backup.hg (glob) - saved backup bundle to $TESTTMP/folding/.hg/strip-backup/859969f5ed7e-backup.hg (glob) + saved backup bundle to $TESTTMP/folding/.hg/strip-backup/58019c66f35f-backup.hg + saved backup bundle to $TESTTMP/folding/.hg/strip-backup/83d1858e070b-backup.hg + saved backup bundle to $TESTTMP/folding/.hg/strip-backup/859969f5ed7e-backup.hg $ hg log -G @ 19:f9daec13fb98 (secret) i | diff --git a/tests/test-hook.t b/tests/test-hook.t --- a/tests/test-hook.t +++ b/tests/test-hook.t @@ -630,7 +630,7 @@ $ echo aa >> from/a $ hg --cwd from ci -mb $ hg --cwd from push - pushing to $TESTTMP/to (glob) + pushing to $TESTTMP/to searching for changes adding changesets adding manifests diff --git a/tests/test-issue1502.t b/tests/test-issue1502.t --- a/tests/test-issue1502.t +++ b/tests/test-issue1502.t @@ -13,7 +13,7 @@ $ echo "bar" > foo1/a && hg -R foo1 commit -m "edit a in foo1" $ echo "hi" > foo/a && hg -R foo commit -m "edited a foo" $ hg -R foo1 pull -u - pulling from $TESTTMP/foo (glob) + pulling from $TESTTMP/foo searching for changes adding changesets adding manifests @@ -29,7 +29,7 @@ $ echo "there" >> foo/a && hg -R foo commit -m "edited a again" $ hg -R foo1 pull - pulling from $TESTTMP/foo (glob) + pulling from $TESTTMP/foo searching for changes adding changesets adding manifests diff --git a/tests/test-keyword.t b/tests/test-keyword.t --- a/tests/test-keyword.t +++ b/tests/test-keyword.t @@ -229,7 +229,7 @@ Message-Id: (glob) To: Test - changeset a2392c293916 in $TESTTMP/Test (glob) + changeset a2392c293916 in $TESTTMP/Test details: $TESTTMP/Test?cmd=changeset;node=a2392c293916 description: addsym @@ -252,7 +252,7 @@ Message-Id: (glob) To: Test - changeset ef63ca68695b in $TESTTMP/Test (glob) + changeset ef63ca68695b in $TESTTMP/Test details: $TESTTMP/Test?cmd=changeset;node=ef63ca68695b description: absym @@ -863,7 +863,7 @@ > default = ../Test > EOF $ hg incoming - comparing with $TESTTMP/Test (glob) + comparing with $TESTTMP/Test searching for changes changeset: 2:bb948857c743 tag: tip diff --git a/tests/test-largefiles-cache.t b/tests/test-largefiles-cache.t --- a/tests/test-largefiles-cache.t +++ b/tests/test-largefiles-cache.t @@ -44,7 +44,7 @@ $ hg update getting changed largefiles - error getting id 7f7097b041ccf68cc5561e9600da4655d21c6d18 from url file:$TESTTMP/mirror for file large: can't get file locally (glob) + error getting id 7f7097b041ccf68cc5561e9600da4655d21c6d18 from url file:$TESTTMP/mirror for file large: can't get file locally 0 largefiles updated, 0 removed 1 files updated, 0 files merged, 0 files removed, 0 files unresolved $ hg status @@ -61,7 +61,7 @@ $ hg update getting changed largefiles - error getting id 7f7097b041ccf68cc5561e9600da4655d21c6d18 from url file:$TESTTMP/mirror for file large: can't get file locally (glob) + error getting id 7f7097b041ccf68cc5561e9600da4655d21c6d18 from url file:$TESTTMP/mirror for file large: can't get file locally 0 largefiles updated, 0 removed 1 files updated, 0 files merged, 0 files removed, 0 files unresolved $ hg status diff --git a/tests/test-largefiles.t b/tests/test-largefiles.t --- a/tests/test-largefiles.t +++ b/tests/test-largefiles.t @@ -670,7 +670,7 @@ Test that outgoing --large works (with revsets too) $ hg outgoing --rev '.^' --large - comparing with $TESTTMP/a (glob) + comparing with $TESTTMP/a searching for changes changeset: 8:c02fd3b77ec4 user: test @@ -876,7 +876,7 @@ $ rm "${USERCACHE}"/* $ cd a-backup $ hg pull --all-largefiles --config paths.default-push=bogus/path - pulling from $TESTTMP/a (glob) + pulling from $TESTTMP/a searching for changes adding changesets adding manifests @@ -920,7 +920,7 @@ 'default' instead of 'default-push' when no source is specified (issue3584). The error messages go away if repo 'b' is created with --all-largefiles. $ hg pull --rebase --all-largefiles --config paths.default-push=bogus/path --config paths.default=../b - pulling from $TESTTMP/b (glob) + pulling from $TESTTMP/b searching for changes adding changesets adding manifests @@ -929,16 +929,16 @@ Invoking status precommit hook M sub/normal4 M sub2/large6 - saved backup bundle to $TESTTMP/d/.hg/strip-backup/f574fb32bb45-backup.hg (glob) - error getting id eb7338044dc27f9bc59b8dd5a246b065ead7a9c4 from url file:$TESTTMP/b for file large3: can't get file locally (glob) - error getting id eb7338044dc27f9bc59b8dd5a246b065ead7a9c4 from url file:$TESTTMP/b for file sub/large4: can't get file locally (glob) - error getting id eb7338044dc27f9bc59b8dd5a246b065ead7a9c4 from url file:$TESTTMP/b for file large1: can't get file locally (glob) - error getting id eb7338044dc27f9bc59b8dd5a246b065ead7a9c4 from url file:$TESTTMP/b for file sub/large2: can't get file locally (glob) - error getting id eb7338044dc27f9bc59b8dd5a246b065ead7a9c4 from url file:$TESTTMP/b for file sub/large2: can't get file locally (glob) - error getting id 5f78770c0e77ba4287ad6ef3071c9bf9c379742f from url file:$TESTTMP/b for file large1: can't get file locally (glob) - error getting id eb7338044dc27f9bc59b8dd5a246b065ead7a9c4 from url file:$TESTTMP/b for file sub/large2: can't get file locally (glob) - error getting id 4669e532d5b2c093a78eca010077e708a071bb64 from url file:$TESTTMP/b for file large1: can't get file locally (glob) - error getting id 1deebade43c8c498a3c8daddac0244dc55d1331d from url file:$TESTTMP/b for file sub/large2: can't get file locally (glob) + saved backup bundle to $TESTTMP/d/.hg/strip-backup/f574fb32bb45-backup.hg + error getting id eb7338044dc27f9bc59b8dd5a246b065ead7a9c4 from url file:$TESTTMP/b for file large3: can't get file locally + error getting id eb7338044dc27f9bc59b8dd5a246b065ead7a9c4 from url file:$TESTTMP/b for file sub/large4: can't get file locally + error getting id eb7338044dc27f9bc59b8dd5a246b065ead7a9c4 from url file:$TESTTMP/b for file large1: can't get file locally + error getting id eb7338044dc27f9bc59b8dd5a246b065ead7a9c4 from url file:$TESTTMP/b for file sub/large2: can't get file locally + error getting id eb7338044dc27f9bc59b8dd5a246b065ead7a9c4 from url file:$TESTTMP/b for file sub/large2: can't get file locally + error getting id 5f78770c0e77ba4287ad6ef3071c9bf9c379742f from url file:$TESTTMP/b for file large1: can't get file locally + error getting id eb7338044dc27f9bc59b8dd5a246b065ead7a9c4 from url file:$TESTTMP/b for file sub/large2: can't get file locally + error getting id 4669e532d5b2c093a78eca010077e708a071bb64 from url file:$TESTTMP/b for file large1: can't get file locally + error getting id 1deebade43c8c498a3c8daddac0244dc55d1331d from url file:$TESTTMP/b for file sub/large2: can't get file locally 0 additional largefiles cached 9 largefiles failed to download nothing to rebase @@ -976,7 +976,7 @@ Invoking status precommit hook M sub/normal4 M sub2/large6 - saved backup bundle to $TESTTMP/e/.hg/strip-backup/f574fb32bb45-backup.hg (glob) + saved backup bundle to $TESTTMP/e/.hg/strip-backup/f574fb32bb45-backup.hg $ hg log --template '{rev}:{node|short} {desc|firstline}\n' 9:598410d3eb9a modify normal file largefile in repo d 8:a381d2c8c80e modify normal file and largefile in repo b @@ -1186,7 +1186,7 @@ $ pwd $TESTTMP/e $ hg paths - default = $TESTTMP/d (glob) + default = $TESTTMP/d $ hg verify --large checking changesets @@ -1206,14 +1206,14 @@ checking files 10 files, 10 changesets, 28 total revisions searching 1 changesets for largefiles - changeset 9:598410d3eb9a: sub/large4 references missing $TESTTMP/d/.hg/largefiles/e166e74c7303192238d60af5a9c4ce9bef0b7928 (glob) + changeset 9:598410d3eb9a: sub/large4 references missing $TESTTMP/d/.hg/largefiles/e166e74c7303192238d60af5a9c4ce9bef0b7928 verified existence of 3 revisions of 3 largefiles [1] - introduce corruption and make sure that it is caught when checking content: $ echo '5 cents' > $TESTTMP/d/.hg/largefiles/e166e74c7303192238d60af5a9c4ce9bef0b7928 $ hg verify -q --large --lfc - changeset 9:598410d3eb9a: sub/large4 references corrupted $TESTTMP/d/.hg/largefiles/e166e74c7303192238d60af5a9c4ce9bef0b7928 (glob) + changeset 9:598410d3eb9a: sub/large4 references corrupted $TESTTMP/d/.hg/largefiles/e166e74c7303192238d60af5a9c4ce9bef0b7928 [1] - cleanup @@ -1222,13 +1222,13 @@ - verifying all revisions will fail because we didn't clone all largefiles to d: $ echo 'T-shirt' > $TESTTMP/d/.hg/largefiles/eb7338044dc27f9bc59b8dd5a246b065ead7a9c4 $ hg verify -q --lfa --lfc - changeset 0:30d30fe6a5be: large1 references missing $TESTTMP/d/.hg/largefiles/4669e532d5b2c093a78eca010077e708a071bb64 (glob) - changeset 0:30d30fe6a5be: sub/large2 references missing $TESTTMP/d/.hg/largefiles/1deebade43c8c498a3c8daddac0244dc55d1331d (glob) - changeset 1:ce8896473775: large1 references missing $TESTTMP/d/.hg/largefiles/5f78770c0e77ba4287ad6ef3071c9bf9c379742f (glob) - changeset 1:ce8896473775: sub/large2 references corrupted $TESTTMP/d/.hg/largefiles/eb7338044dc27f9bc59b8dd5a246b065ead7a9c4 (glob) - changeset 3:9e8fbc4bce62: large1 references corrupted $TESTTMP/d/.hg/largefiles/eb7338044dc27f9bc59b8dd5a246b065ead7a9c4 (glob) - changeset 4:74c02385b94c: large3 references corrupted $TESTTMP/d/.hg/largefiles/eb7338044dc27f9bc59b8dd5a246b065ead7a9c4 (glob) - changeset 4:74c02385b94c: sub/large4 references corrupted $TESTTMP/d/.hg/largefiles/eb7338044dc27f9bc59b8dd5a246b065ead7a9c4 (glob) + changeset 0:30d30fe6a5be: large1 references missing $TESTTMP/d/.hg/largefiles/4669e532d5b2c093a78eca010077e708a071bb64 + changeset 0:30d30fe6a5be: sub/large2 references missing $TESTTMP/d/.hg/largefiles/1deebade43c8c498a3c8daddac0244dc55d1331d + changeset 1:ce8896473775: large1 references missing $TESTTMP/d/.hg/largefiles/5f78770c0e77ba4287ad6ef3071c9bf9c379742f + changeset 1:ce8896473775: sub/large2 references corrupted $TESTTMP/d/.hg/largefiles/eb7338044dc27f9bc59b8dd5a246b065ead7a9c4 + changeset 3:9e8fbc4bce62: large1 references corrupted $TESTTMP/d/.hg/largefiles/eb7338044dc27f9bc59b8dd5a246b065ead7a9c4 + changeset 4:74c02385b94c: large3 references corrupted $TESTTMP/d/.hg/largefiles/eb7338044dc27f9bc59b8dd5a246b065ead7a9c4 + changeset 4:74c02385b94c: sub/large4 references corrupted $TESTTMP/d/.hg/largefiles/eb7338044dc27f9bc59b8dd5a246b065ead7a9c4 [1] - cleanup @@ -1574,7 +1574,7 @@ pushing to http://localhost:$HGPORT1/ searching for changes remote: largefiles: failed to put 4cdac4d8b084d0b599525cf732437fb337d422a8 into store: largefile contents do not match hash - abort: remotestore: could not put $TESTTMP/r7/.hg/largefiles/4cdac4d8b084d0b599525cf732437fb337d422a8 to remote store http://localhost:$HGPORT1/ (glob) + abort: remotestore: could not put $TESTTMP/r7/.hg/largefiles/4cdac4d8b084d0b599525cf732437fb337d422a8 to remote store http://localhost:$HGPORT1/ [255] $ mv 4cdac4d8b084d0b599525cf732437fb337d422a8 r7/.hg/largefiles/4cdac4d8b084d0b599525cf732437fb337d422a8 Push of file that exists on server but is corrupted - magic healing would be nice ... but too magic @@ -2036,7 +2036,7 @@ $ hg -q clone src clone2 $ hg -R clone2 paths | grep default - default = $TESTTMP/issue3651/src (glob) + default = $TESTTMP/issue3651/src $ hg -R clone2 summary --large parent: 0:fc0bd45326d3 tip @@ -2047,7 +2047,7 @@ searching for changes largefiles: (no files to upload) $ hg -R clone2 outgoing --large - comparing with $TESTTMP/issue3651/src (glob) + comparing with $TESTTMP/issue3651/src searching for changes no changes found searching for changes @@ -2070,7 +2070,7 @@ searching for changes largefiles: 1 to upload $ hg -R clone2 outgoing --large - comparing with $TESTTMP/issue3651/src (glob) + comparing with $TESTTMP/issue3651/src searching for changes changeset: 1:1acbe71ce432 tag: tip diff --git a/tests/test-lfconvert.t b/tests/test-lfconvert.t --- a/tests/test-lfconvert.t +++ b/tests/test-lfconvert.t @@ -125,7 +125,7 @@ $ hg commit -q -m"remove large, normal3" $ hg merge merging sub/maybelarge.dat and stuff/maybelarge.dat to stuff/maybelarge.dat - warning: $TESTTMP/bigfile-repo/stuff/maybelarge.dat looks like a binary file. (glob) + warning: $TESTTMP/bigfile-repo/stuff/maybelarge.dat looks like a binary file. merging stuff/maybelarge.dat incomplete! (edit conflicts, then use 'hg resolve --mark') merging sub/normal2 and stuff/normal2 to stuff/normal2 0 files updated, 1 files merged, 0 files removed, 1 files unresolved @@ -212,7 +212,7 @@ $ hg share -q -U bigfile-repo shared $ printf 'bogus' > shared/.hg/sharedpath $ hg lfconvert shared foo - abort: .hg/sharedpath points to nonexistent directory $TESTTMP/bogus! (glob) + abort: .hg/sharedpath points to nonexistent directory $TESTTMP/bogus! [255] $ hg lfconvert bigfile-repo largefiles-repo initializing destination largefiles-repo @@ -317,12 +317,12 @@ checking files 8 files, 7 changesets, 12 total revisions searching 7 changesets for largefiles - changeset 0:d4892ec57ce2: large references missing $TESTTMP/largefiles-repo-hg/.hg/largefiles/2e000fa7e85759c7f4c254d4d9c33ef481e459a7 (glob) - changeset 1:334e5237836d: sub/maybelarge.dat references missing $TESTTMP/largefiles-repo-hg/.hg/largefiles/34e163be8e43c5631d8b92e9c43ab0bf0fa62b9c (glob) - changeset 2:261ad3f3f037: stuff/maybelarge.dat references missing $TESTTMP/largefiles-repo-hg/.hg/largefiles/34e163be8e43c5631d8b92e9c43ab0bf0fa62b9c (glob) - changeset 3:55759520c76f: sub/maybelarge.dat references missing $TESTTMP/largefiles-repo-hg/.hg/largefiles/76236b6a2c6102826c61af4297dd738fb3b1de38 (glob) - changeset 5:9cc5aa7204f0: stuff/maybelarge.dat references missing $TESTTMP/largefiles-repo-hg/.hg/largefiles/76236b6a2c6102826c61af4297dd738fb3b1de38 (glob) - changeset 6:17126745edfd: anotherlarge references missing $TESTTMP/largefiles-repo-hg/.hg/largefiles/3b71f43ff30f4b15b5cd85dd9e95ebc7e84eb5a3 (glob) + changeset 0:d4892ec57ce2: large references missing $TESTTMP/largefiles-repo-hg/.hg/largefiles/2e000fa7e85759c7f4c254d4d9c33ef481e459a7 + changeset 1:334e5237836d: sub/maybelarge.dat references missing $TESTTMP/largefiles-repo-hg/.hg/largefiles/34e163be8e43c5631d8b92e9c43ab0bf0fa62b9c + changeset 2:261ad3f3f037: stuff/maybelarge.dat references missing $TESTTMP/largefiles-repo-hg/.hg/largefiles/34e163be8e43c5631d8b92e9c43ab0bf0fa62b9c + changeset 3:55759520c76f: sub/maybelarge.dat references missing $TESTTMP/largefiles-repo-hg/.hg/largefiles/76236b6a2c6102826c61af4297dd738fb3b1de38 + changeset 5:9cc5aa7204f0: stuff/maybelarge.dat references missing $TESTTMP/largefiles-repo-hg/.hg/largefiles/76236b6a2c6102826c61af4297dd738fb3b1de38 + changeset 6:17126745edfd: anotherlarge references missing $TESTTMP/largefiles-repo-hg/.hg/largefiles/3b71f43ff30f4b15b5cd85dd9e95ebc7e84eb5a3 verified existence of 6 revisions of 4 largefiles [1] $ hg -R largefiles-repo-hg showconfig paths @@ -343,7 +343,7 @@ $ rm largefiles-repo/.hg/largefiles/* $ hg lfconvert --to-normal issue3519 normalized3519 initializing destination normalized3519 - error getting id 2e000fa7e85759c7f4c254d4d9c33ef481e459a7 from url file:$TESTTMP/largefiles-repo for file large: can't get file locally (glob) + error getting id 2e000fa7e85759c7f4c254d4d9c33ef481e459a7 from url file:$TESTTMP/largefiles-repo for file large: can't get file locally abort: missing largefile 'large' from revision d4892ec57ce212905215fad1d9018f56b99202ad [255] diff --git a/tests/test-mq-merge.t b/tests/test-mq-merge.t --- a/tests/test-mq-merge.t +++ b/tests/test-mq-merge.t @@ -56,7 +56,7 @@ Save the patch queue so we can merge it later: $ hg qsave -c -e - copy $TESTTMP/t/.hg/patches to $TESTTMP/t/.hg/patches.1 (glob) + copy $TESTTMP/t/.hg/patches to $TESTTMP/t/.hg/patches.1 $ checkundo Update b and commit in an "update" changeset: @@ -76,7 +76,7 @@ b $ hg qpush -a -m - merging with queue at: $TESTTMP/t/.hg/patches.1 (glob) + merging with queue at: $TESTTMP/t/.hg/patches.1 applying rm_a now at: rm_a @@ -115,14 +115,14 @@ Create the reference queue: $ hg qsave -c -e -n refqueue - copy $TESTTMP/t2/.hg/patches to $TESTTMP/t2/.hg/refqueue (glob) + copy $TESTTMP/t2/.hg/patches to $TESTTMP/t2/.hg/refqueue $ hg up -C 1 1 files updated, 0 files merged, 1 files removed, 0 files unresolved Merge: $ HGMERGE=internal:other hg qpush -a -m -n refqueue - merging with queue at: $TESTTMP/t2/.hg/refqueue (glob) + merging with queue at: $TESTTMP/t2/.hg/refqueue applying patcha patching file a Hunk #1 succeeded at 2 with fuzz 1 (offset 0 lines). diff --git a/tests/test-mq-safety.t b/tests/test-mq-safety.t --- a/tests/test-mq-safety.t +++ b/tests/test-mq-safety.t @@ -69,7 +69,7 @@ abort: popping would remove a revision not managed by this patch queue [255] $ hg qpop -n patches - using patch queue: $TESTTMP/repo/.hg/patches (glob) + using patch queue: $TESTTMP/repo/.hg/patches abort: popping would remove a revision not managed by this patch queue [255] $ hg qrefresh diff --git a/tests/test-mq.t b/tests/test-mq.t --- a/tests/test-mq.t +++ b/tests/test-mq.t @@ -151,7 +151,7 @@ guards $ cat .hg/patches/series $ hg qinit -c - abort: repository $TESTTMP/d/.hg/patches already exists! (glob) + abort: repository $TESTTMP/d/.hg/patches already exists! [255] $ cd .. diff --git a/tests/test-notify-changegroup.t b/tests/test-notify-changegroup.t --- a/tests/test-notify-changegroup.t +++ b/tests/test-notify-changegroup.t @@ -56,11 +56,11 @@ Message-Id: <*> (glob) To: baz, foo at bar - changeset cb9a9f314b8b in $TESTTMP/a (glob) + changeset cb9a9f314b8b in $TESTTMP/a details: $TESTTMP/a?cmd=changeset;node=cb9a9f314b8b summary: a - changeset ba677d0156c1 in $TESTTMP/a (glob) + changeset ba677d0156c1 in $TESTTMP/a details: $TESTTMP/a?cmd=changeset;node=ba677d0156c1 summary: b @@ -107,11 +107,11 @@ Message-Id: <*> (glob) To: baz, foo at bar - changeset cb9a9f314b8b in $TESTTMP/a (glob) + changeset cb9a9f314b8b in $TESTTMP/a details: $TESTTMP/a?cmd=changeset;node=cb9a9f314b8b summary: a - changeset ba677d0156c1 in $TESTTMP/a (glob) + changeset ba677d0156c1 in $TESTTMP/a details: $TESTTMP/a?cmd=changeset;node=ba677d0156c1 summary: b @@ -184,19 +184,19 @@ Message-Id: <*> (glob) To: baz, foo at bar - changeset 84e487dddc58 in $TESTTMP/a (glob) + changeset 84e487dddc58 in $TESTTMP/a details: $TESTTMP/a?cmd=changeset;node=84e487dddc58 summary: newfile - changeset b29c7a2b6b0c in $TESTTMP/a (glob) + changeset b29c7a2b6b0c in $TESTTMP/a details: $TESTTMP/a?cmd=changeset;node=b29c7a2b6b0c summary: x - changeset 0957c7d64886 in $TESTTMP/a (glob) + changeset 0957c7d64886 in $TESTTMP/a details: $TESTTMP/a?cmd=changeset;node=0957c7d64886 summary: y - changeset 485b4e6b0249 in $TESTTMP/a (glob) + changeset 485b4e6b0249 in $TESTTMP/a details: $TESTTMP/a?cmd=changeset;node=485b4e6b0249 summary: merged diff --git a/tests/test-notify.t b/tests/test-notify.t --- a/tests/test-notify.t +++ b/tests/test-notify.t @@ -193,7 +193,7 @@ Message-Id: <*> (glob) To: baz, foo at bar - changeset 0647d048b600 in $TESTTMP/b (glob) + changeset 0647d048b600 in $TESTTMP/b details: $TESTTMP/b?cmd=changeset;node=0647d048b600 description: b diff --git a/tests/test-obsolete-checkheads.t b/tests/test-obsolete-checkheads.t --- a/tests/test-obsolete-checkheads.t +++ b/tests/test-obsolete-checkheads.t @@ -42,7 +42,7 @@ $ mkcommit old $ hg push - pushing to $TESTTMP/remote (glob) + pushing to $TESTTMP/remote searching for changes adding changesets adding manifests @@ -65,7 +65,7 @@ Push should not warn about creating new head $ hg push - pushing to $TESTTMP/remote (glob) + pushing to $TESTTMP/remote searching for changes adding changesets adding manifests @@ -81,7 +81,7 @@ $ cp -r ../backup1 ../remote $ hg -R ../remote phase --public c70b08862e08 $ hg pull -v - pulling from $TESTTMP/remote (glob) + pulling from $TESTTMP/remote searching for changes no changes found $ hg glog --hidden @@ -95,7 +95,7 @@ Abort: old will still be an head because it's public. $ hg push - pushing to $TESTTMP/remote (glob) + pushing to $TESTTMP/remote searching for changes abort: push creates new remote head 71e3228bffe1! (did you forget to merge? use push -f to force) @@ -155,7 +155,7 @@ Push should abort on new head $ hg push -r 'desc("other")' - pushing to $TESTTMP/remote (glob) + pushing to $TESTTMP/remote searching for changes abort: push creates new remote head d7d41ccbd4de! (did you forget to merge? use push -f to force) @@ -182,7 +182,7 @@ $ mkcommit new created new head $ hg push -f - pushing to $TESTTMP/remote (glob) + pushing to $TESTTMP/remote searching for changes adding changesets adding manifests @@ -217,7 +217,7 @@ one anyway. $ hg push - pushing to $TESTTMP/remote (glob) + pushing to $TESTTMP/remote searching for changes adding changesets adding manifests @@ -265,7 +265,7 @@ handled yet. $ hg push --traceback - pushing to $TESTTMP/remote (glob) + pushing to $TESTTMP/remote searching for changes adding changesets adding manifests diff --git a/tests/test-obsolete.t b/tests/test-obsolete.t --- a/tests/test-obsolete.t +++ b/tests/test-obsolete.t @@ -816,7 +816,7 @@ summary: A $ hg incoming - comparing with $TESTTMP/tmpe/repo-issue3805 (glob) + comparing with $TESTTMP/tmpe/repo-issue3805 searching for changes changeset: 2:3816541e5485 tag: tip @@ -826,7 +826,7 @@ summary: A $ hg incoming --bundle ../issue3805.hg - comparing with $TESTTMP/tmpe/repo-issue3805 (glob) + comparing with $TESTTMP/tmpe/repo-issue3805 searching for changes changeset: 2:3816541e5485 tag: tip @@ -836,7 +836,7 @@ summary: A $ hg outgoing - comparing with $TESTTMP/tmpe/repo-issue3805 (glob) + comparing with $TESTTMP/tmpe/repo-issue3805 searching for changes no changes found [1] diff --git a/tests/test-parents.t b/tests/test-parents.t --- a/tests/test-parents.t +++ b/tests/test-parents.t @@ -71,7 +71,7 @@ $ hg parents -r 2 ../a - abort: ../a not under root '$TESTTMP/repo' (glob) + abort: ../a not under root '$TESTTMP/repo' [255] diff --git a/tests/test-paths.t b/tests/test-paths.t --- a/tests/test-paths.t +++ b/tests/test-paths.t @@ -7,35 +7,35 @@ $ echo 'dupe = ../b' >> .hg/hgrc $ echo 'expand = $SOMETHING/bar' >> .hg/hgrc $ hg in dupe - comparing with $TESTTMP/b (glob) + comparing with $TESTTMP/b no changes found [1] $ cd .. $ hg -R a in dupe - comparing with $TESTTMP/b (glob) + comparing with $TESTTMP/b no changes found [1] $ cd a $ hg paths - dupe = $TESTTMP/b (glob) - expand = $TESTTMP/a/$SOMETHING/bar (glob) + dupe = $TESTTMP/b + expand = $TESTTMP/a/$SOMETHING/bar $ SOMETHING=foo hg paths - dupe = $TESTTMP/b (glob) - expand = $TESTTMP/a/foo/bar (glob) + dupe = $TESTTMP/b + expand = $TESTTMP/a/foo/bar #if msys $ SOMETHING=//foo hg paths - dupe = $TESTTMP/b (glob) + dupe = $TESTTMP/b expand = /foo/bar #else $ SOMETHING=/foo hg paths - dupe = $TESTTMP/b (glob) + dupe = $TESTTMP/b expand = /foo/bar #endif $ hg paths -q dupe expand $ hg paths dupe - $TESTTMP/b (glob) + $TESTTMP/b $ hg paths -q dupe $ hg paths unknown not found! diff --git a/tests/test-pull-r.t b/tests/test-pull-r.t --- a/tests/test-pull-r.t +++ b/tests/test-pull-r.t @@ -43,7 +43,7 @@ 2:effea6de0384 1:ed1b79f46b9a $ hg pull - pulling from $TESTTMP/repo2 (glob) + pulling from $TESTTMP/repo2 searching for changes adding changesets adding manifests diff --git a/tests/test-push-validation.t b/tests/test-push-validation.t --- a/tests/test-push-validation.t +++ b/tests/test-push-validation.t @@ -44,7 +44,7 @@ [1] $ hg push - pushing to $TESTTMP/test (glob) + pushing to $TESTTMP/test searching for changes adding changesets adding manifests @@ -79,7 +79,7 @@ [1] $ hg push - pushing to $TESTTMP/test (glob) + pushing to $TESTTMP/test searching for changes adding changesets adding manifests diff --git a/tests/test-rebase-bookmarks.t b/tests/test-rebase-bookmarks.t --- a/tests/test-rebase-bookmarks.t +++ b/tests/test-rebase-bookmarks.t @@ -146,7 +146,7 @@ $ echo 'c' > c $ hg resolve --mark c $ hg rebase --continue - saved backup bundle to $TESTTMP/a3/.hg/strip-backup/3d5fa227f4b5-backup.hg (glob) + saved backup bundle to $TESTTMP/a3/.hg/strip-backup/3d5fa227f4b5-backup.hg $ hg tglog @ 4: 'C' bookmarks: Y Z | diff --git a/tests/test-rebase-collapse.t b/tests/test-rebase-collapse.t --- a/tests/test-rebase-collapse.t +++ b/tests/test-rebase-collapse.t @@ -281,7 +281,7 @@ c65502d4178782309ce0574c5ae6ee9485a9bafa default $ hg strip 4 - saved backup bundle to $TESTTMP/b2/.hg/strip-backup/8a5212ebc852-backup.hg (glob) + saved backup bundle to $TESTTMP/b2/.hg/strip-backup/8a5212ebc852-backup.hg $ cat $TESTTMP/b2/.hg/cache/branchheads-served c65502d4178782309ce0574c5ae6ee9485a9bafa 4 diff --git a/tests/test-rebase-detach.t b/tests/test-rebase-detach.t --- a/tests/test-rebase-detach.t +++ b/tests/test-rebase-detach.t @@ -288,7 +288,7 @@ $ hg rebase -d 5 -s 7 - saved backup bundle to $TESTTMP/a5/.hg/strip-backup/13547172c9c0-backup.hg (glob) + saved backup bundle to $TESTTMP/a5/.hg/strip-backup/13547172c9c0-backup.hg $ hg tglog @ 8: 'D' | @@ -378,7 +378,7 @@ [255] $ hg resolve --all -t internal:local $ hg rebase -c - saved backup bundle to $TESTTMP/a7/.hg/strip-backup/6215fafa5447-backup.hg (glob) + saved backup bundle to $TESTTMP/a7/.hg/strip-backup/6215fafa5447-backup.hg $ hg log -G --template "{rev}:{phase} '{desc}' {branches}\n" @ 7:draft 'H' | diff --git a/tests/test-rebase-pull.t b/tests/test-rebase-pull.t --- a/tests/test-rebase-pull.t +++ b/tests/test-rebase-pull.t @@ -48,7 +48,7 @@ Now b has one revision to be pulled from a: $ hg pull --rebase - pulling from $TESTTMP/a (glob) + pulling from $TESTTMP/a searching for changes adding changesets adding manifests @@ -68,7 +68,7 @@ Re-run: $ hg pull --rebase - pulling from $TESTTMP/a (glob) + pulling from $TESTTMP/a searching for changes no changes found @@ -79,7 +79,7 @@ $ hg book norebase $ hg pull --rebase - pulling from $TESTTMP/a (glob) + pulling from $TESTTMP/a searching for changes adding changesets adding manifests @@ -96,7 +96,7 @@ pull --rebase --update should ignore --update: $ hg pull --rebase --update - pulling from $TESTTMP/a (glob) + pulling from $TESTTMP/a searching for changes no changes found @@ -105,7 +105,7 @@ $ hg up -q 1 $ hg pull --rebase - pulling from $TESTTMP/a (glob) + pulling from $TESTTMP/a searching for changes no changes found @@ -144,13 +144,13 @@ adding L1 created new head $ hg pull --rev tip --rebase - pulling from $TESTTMP/a (glob) + pulling from $TESTTMP/a searching for changes adding changesets adding manifests adding file changes added 2 changesets with 2 changes to 2 files - saved backup bundle to $TESTTMP/c/.hg/strip-backup/ff8d69a621f9-backup.hg (glob) + saved backup bundle to $TESTTMP/c/.hg/strip-backup/ff8d69a621f9-backup.hg $ hg tglog @ 5: 'L1' | diff --git a/tests/test-rebase-scenario-global.t b/tests/test-rebase-scenario-global.t --- a/tests/test-rebase-scenario-global.t +++ b/tests/test-rebase-scenario-global.t @@ -254,7 +254,7 @@ C onto A - rebase onto an ancestor: $ hg rebase -d 0 -s 2 - saved backup bundle to $TESTTMP/a7/.hg/strip-backup/5fddd98957c8-backup.hg (glob) + saved backup bundle to $TESTTMP/a7/.hg/strip-backup/5fddd98957c8-backup.hg $ hg tglog @ 7: 'D' | @@ -286,25 +286,25 @@ Check rebasing mutable changeset Source phase greater or equal to destination phase: new changeset get the phase of source: $ hg rebase -s9 -d0 - saved backup bundle to $TESTTMP/a7/.hg/strip-backup/2b23e52411f4-backup.hg (glob) + saved backup bundle to $TESTTMP/a7/.hg/strip-backup/2b23e52411f4-backup.hg $ hg log --template "{phase}\n" -r 9 draft $ hg rebase -s9 -d1 - saved backup bundle to $TESTTMP/a7/.hg/strip-backup/2cb10d0cfc6c-backup.hg (glob) + saved backup bundle to $TESTTMP/a7/.hg/strip-backup/2cb10d0cfc6c-backup.hg $ hg log --template "{phase}\n" -r 9 draft $ hg phase --force --secret 9 $ hg rebase -s9 -d0 - saved backup bundle to $TESTTMP/a7/.hg/strip-backup/c5b12b67163a-backup.hg (glob) + saved backup bundle to $TESTTMP/a7/.hg/strip-backup/c5b12b67163a-backup.hg $ hg log --template "{phase}\n" -r 9 secret $ hg rebase -s9 -d1 - saved backup bundle to $TESTTMP/a7/.hg/strip-backup/2a0524f868ac-backup.hg (glob) + saved backup bundle to $TESTTMP/a7/.hg/strip-backup/2a0524f868ac-backup.hg $ hg log --template "{phase}\n" -r 9 secret Source phase lower than destination phase: new changeset get the phase of destination: $ hg rebase -s8 -d9 - saved backup bundle to $TESTTMP/a7/.hg/strip-backup/6d4f22462821-backup.hg (glob) + saved backup bundle to $TESTTMP/a7/.hg/strip-backup/6d4f22462821-backup.hg $ hg log --template "{phase}\n" -r 'rev(9)' secret @@ -512,7 +512,7 @@ $ hg clone -q -u . ah ah5 $ cd ah5 $ hg rebase -r '6::' -d 2 - saved backup bundle to $TESTTMP/ah5/.hg/strip-backup/3d8a618087a7-backup.hg (glob) + saved backup bundle to $TESTTMP/ah5/.hg/strip-backup/3d8a618087a7-backup.hg $ hg tglog @ 8: 'I' | @@ -542,7 +542,7 @@ $ hg clone -q -u . ah ah6 $ cd ah6 $ hg rebase -r '(4+6)::' -d 1 - saved backup bundle to $TESTTMP/ah6/.hg/strip-backup/3d8a618087a7-backup.hg (glob) + saved backup bundle to $TESTTMP/ah6/.hg/strip-backup/3d8a618087a7-backup.hg $ hg tglog @ 8: 'I' | @@ -609,7 +609,7 @@ (actual test) $ hg rebase --dest 'desc(G)' --rev 'desc(K) + desc(I)' - saved backup bundle to $TESTTMP/a8/.hg/strip-backup/23a4ace37988-backup.hg (glob) + saved backup bundle to $TESTTMP/a8/.hg/strip-backup/23a4ace37988-backup.hg $ hg log --rev 'children(desc(G))' changeset: 9:adb617877056 parent: 6:eea13746799a diff --git a/tests/test-relink.t b/tests/test-relink.t --- a/tests/test-relink.t +++ b/tests/test-relink.t @@ -41,7 +41,7 @@ don't sit forever trying to double-lock the source repo $ hg relink . - relinking $TESTTMP/repo/.hg/store to $TESTTMP/repo/.hg/store (glob) + relinking $TESTTMP/repo/.hg/store to $TESTTMP/repo/.hg/store there is nothing to relink diff --git a/tests/test-revset-outgoing.t b/tests/test-revset-outgoing.t --- a/tests/test-revset-outgoing.t +++ b/tests/test-revset-outgoing.t @@ -40,7 +40,7 @@ $ cd b $ cat .hg/hgrc [paths] - default = $TESTTMP/a#stable (glob) + default = $TESTTMP/a#stable $ echo red >> a $ hg ci -qm3 @@ -61,7 +61,7 @@ $ hg tout - comparing with $TESTTMP/a (glob) + comparing with $TESTTMP/a searching for changes 2:1d4099801a4e: '3' stable @@ -80,11 +80,11 @@ $ cat .hg/hgrc [paths] - default = $TESTTMP/a#stable (glob) + default = $TESTTMP/a#stable green = ../a#default $ hg tout green - comparing with $TESTTMP/a (glob) + comparing with $TESTTMP/a searching for changes 3:f0461977a3db: '4' diff --git a/tests/test-share.t b/tests/test-share.t --- a/tests/test-share.t +++ b/tests/test-share.t @@ -27,14 +27,14 @@ Some sed versions appends newline, some don't, and some just fails $ cat .hg/sharedpath; echo - $TESTTMP/repo1/.hg (glob) + $TESTTMP/repo1/.hg trailing newline on .hg/sharedpath is ok $ hg tip -q 0:d3873e73d99e $ echo '' >> .hg/sharedpath $ cat .hg/sharedpath - $TESTTMP/repo1/.hg (glob) + $TESTTMP/repo1/.hg $ hg tip -q 0:d3873e73d99e diff --git a/tests/test-ssh.t b/tests/test-ssh.t --- a/tests/test-ssh.t +++ b/tests/test-ssh.t @@ -308,7 +308,7 @@ 73649e48688a $ hg id --ssh "sh ssh.sh" "ssh://user at dummy/a'repo" - remote: Illegal repository "$TESTTMP/a'repo" (glob) + remote: Illegal repository "$TESTTMP/a'repo" abort: no suitable response from remote hg! [255] diff --git a/tests/test-subrepo-deep-nested-change.t b/tests/test-subrepo-deep-nested-change.t --- a/tests/test-subrepo-deep-nested-change.t +++ b/tests/test-subrepo-deep-nested-change.t @@ -49,7 +49,7 @@ $ hg clone main cloned updating to branch default cloning subrepo sub1 from $TESTTMP/sub1 - cloning subrepo sub1/sub2 from $TESTTMP/sub2 (glob) + cloning subrepo sub1/sub2 from $TESTTMP/sub2 3 files updated, 0 files merged, 0 files removed, 0 files unresolved Checking cloned repo ids diff --git a/tests/test-subrepo-git.t b/tests/test-subrepo-git.t --- a/tests/test-subrepo-git.t +++ b/tests/test-subrepo-git.t @@ -135,7 +135,7 @@ user b push changes $ hg push 2>/dev/null - pushing to $TESTTMP/t (glob) + pushing to $TESTTMP/t pushing branch testing of subrepo s searching for changes adding changesets @@ -147,7 +147,7 @@ $ cd ../ta $ hg pull - pulling from $TESTTMP/t (glob) + pulling from $TESTTMP/t searching for changes adding changesets adding manifests @@ -175,7 +175,7 @@ source ../gitroot revision f47b465e1bce645dbf37232a00574aa1546ca8d3 $ hg push 2>/dev/null - pushing to $TESTTMP/t (glob) + pushing to $TESTTMP/t pushing branch testing of subrepo s searching for changes adding changesets @@ -207,7 +207,7 @@ $ echo aa >> a $ hg commit -m aa $ hg push - pushing to $TESTTMP/t (glob) + pushing to $TESTTMP/t searching for changes adding changesets adding manifests diff --git a/tests/test-subrepo-paths.t b/tests/test-subrepo-paths.t --- a/tests/test-subrepo-paths.t +++ b/tests/test-subrepo-paths.t @@ -55,7 +55,7 @@ > .* = \1 > EOF $ hg debugsub - abort: bad subrepository pattern in $TESTTMP/outer/.hg/hgrc:2: invalid group reference (glob) + abort: bad subrepository pattern in $TESTTMP/outer/.hg/hgrc:2: invalid group reference [255] $ cd .. diff --git a/tests/test-subrepo-recursion.t b/tests/test-subrepo-recursion.t --- a/tests/test-subrepo-recursion.t +++ b/tests/test-subrepo-recursion.t @@ -363,7 +363,7 @@ archiving (foo/bar) [================================>] 1/1\r (no-eol) (glob) (esc) \r (no-eol) (esc) cloning subrepo foo from $TESTTMP/repo/foo - cloning subrepo foo/bar from $TESTTMP/repo/foo/bar (glob) + cloning subrepo foo/bar from $TESTTMP/repo/foo/bar The newly cloned subrepos contain no working copy: @@ -386,7 +386,7 @@ $ echo f > foo/f $ hg archive --subrepos -r tip archive cloning subrepo foo from $TESTTMP/empty/foo - abort: destination '$TESTTMP/almost-empty/foo' is not empty (in subrepo foo) (glob) + abort: destination '$TESTTMP/almost-empty/foo' is not empty (in subrepo foo) [255] Clone and test outgoing: @@ -395,11 +395,11 @@ $ hg clone repo repo2 updating to branch default cloning subrepo foo from $TESTTMP/repo/foo - cloning subrepo foo/bar from $TESTTMP/repo/foo/bar (glob) + cloning subrepo foo/bar from $TESTTMP/repo/foo/bar 3 files updated, 0 files merged, 0 files removed, 0 files unresolved $ cd repo2 $ hg outgoing -S - comparing with $TESTTMP/repo (glob) + comparing with $TESTTMP/repo searching for changes no changes found comparing with $TESTTMP/repo/foo @@ -425,7 +425,7 @@ $ hg commit --subrepos -m 3-4-2 committing subrepository foo $ hg outgoing -S - comparing with $TESTTMP/repo (glob) + comparing with $TESTTMP/repo searching for changes changeset: 3:2655b8ecc4ee tag: tip @@ -455,7 +455,7 @@ Test incoming: $ hg incoming -S - comparing with $TESTTMP/repo2 (glob) + comparing with $TESTTMP/repo2 searching for changes changeset: 3:2655b8ecc4ee tag: tip diff --git a/tests/test-subrepo.t b/tests/test-subrepo.t --- a/tests/test-subrepo.t +++ b/tests/test-subrepo.t @@ -270,7 +270,7 @@ $ hg clone t tc updating to branch default cloning subrepo s from $TESTTMP/t/s - cloning subrepo s/ss from $TESTTMP/t/s/ss (glob) + cloning subrepo s/ss from $TESTTMP/t/s/ss cloning subrepo t from $TESTTMP/t/t 3 files updated, 0 files merged, 0 files removed, 0 files unresolved $ cd tc @@ -288,8 +288,8 @@ $ hg ci -m11 committing subrepository t $ hg push - pushing to $TESTTMP/t (glob) - pushing subrepo s/ss to $TESTTMP/t/s/ss (glob) + pushing to $TESTTMP/t + pushing subrepo s/ss to $TESTTMP/t/s/ss searching for changes no changes found pushing subrepo s to $TESTTMP/t/s @@ -313,8 +313,8 @@ $ hg ci -m12 committing subrepository s $ hg push - pushing to $TESTTMP/t (glob) - pushing subrepo s/ss to $TESTTMP/t/s/ss (glob) + pushing to $TESTTMP/t + pushing subrepo s/ss to $TESTTMP/t/s/ss searching for changes no changes found pushing subrepo s to $TESTTMP/t/s @@ -323,8 +323,8 @@ (did you forget to merge? use push -f to force) [255] $ hg push -f - pushing to $TESTTMP/t (glob) - pushing subrepo s/ss to $TESTTMP/t/s/ss (glob) + pushing to $TESTTMP/t + pushing subrepo s/ss to $TESTTMP/t/s/ss searching for changes no changes found pushing subrepo s to $TESTTMP/t/s @@ -355,7 +355,7 @@ $ cd ../tc $ hg pull - pulling from $TESTTMP/t (glob) + pulling from $TESTTMP/t searching for changes adding changesets adding manifests @@ -670,7 +670,7 @@ $ hg -R issue1852a push `pwd`/issue1852c pushing to $TESTTMP/issue1852c - pushing subrepo sub/repo to $TESTTMP/issue1852c/sub/repo (glob) + pushing subrepo sub/repo to $TESTTMP/issue1852c/sub/repo searching for changes no changes found searching for changes @@ -1077,7 +1077,7 @@ > default=../issue3781-dest/ > EOF $ hg push - pushing to $TESTTMP/issue3781-dest (glob) + pushing to $TESTTMP/issue3781-dest pushing subrepo s to $TESTTMP/issue3781-dest/s searching for changes no changes found diff --git a/tests/test-url-rev.t b/tests/test-url-rev.t --- a/tests/test-url-rev.t +++ b/tests/test-url-rev.t @@ -42,7 +42,7 @@ $ cat clone/.hg/hgrc [paths] - default = $TESTTMP/repo#foo (glob) + default = $TESTTMP/repo#foo Changing original repo: diff --git a/tests/test-walk.t b/tests/test-walk.t --- a/tests/test-walk.t +++ b/tests/test-walk.t @@ -181,10 +181,10 @@ f mammals/Procyonidae/raccoon mammals/Procyonidae/raccoon f mammals/skunk mammals/skunk $ hg debugwalk .. - abort: .. not under root '$TESTTMP/t' (glob) + abort: .. not under root '$TESTTMP/t' [255] $ hg debugwalk beans/../.. - abort: beans/../.. not under root '$TESTTMP/t' (glob) + abort: beans/../.. not under root '$TESTTMP/t' [255] $ hg debugwalk .hg abort: path contains illegal component: .hg @@ -209,7 +209,7 @@ f beans/pinto beans/pinto f beans/turtle beans/turtle $ hg debugwalk `pwd`/.. - abort: $TESTTMP/t/.. not under root '$TESTTMP/t' (glob) + abort: $TESTTMP/t/.. not under root '$TESTTMP/t' [255] Test patterns: diff --git a/tests/test-win32text.t b/tests/test-win32text.t --- a/tests/test-win32text.t +++ b/tests/test-win32text.t @@ -385,7 +385,7 @@ WARNING: f4.bat already has CRLF line endings and does not need EOL conversion by the win32text plugin. Before your next commit, please reconsider your encode/decode settings in - Mercurial.ini or $TESTTMP/t/.hg/hgrc. (glob) + Mercurial.ini or $TESTTMP/t/.hg/hgrc. 3 files updated, 0 files merged, 0 files removed, 0 files unresolved $ cat bin hello\x00\r (esc) From mads at kiilerich.com Tue Feb 26 14:34:54 2013 From: mads at kiilerich.com (Mads Kiilerich) Date: Tue, 26 Feb 2013 21:34:54 +0100 Subject: [PATCH] tests: work around msys bash mangling of paths in test-mq.t Message-ID: <89602c1c69202073a978.1361910894@mk-desktop> # HG changeset patch # User Mads Kiilerich # Date 1361909090 -3600 # Node ID 89602c1c69202073a978eab5ce22f7a307c274ad # Parent 2c246fef46d1f70b088284dafa00b0911920949f tests: work around msys bash mangling of paths in test-mq.t diff --git a/tests/test-mq.t b/tests/test-mq.t --- a/tests/test-mq.t +++ b/tests/test-mq.t @@ -1567,12 +1567,13 @@ > wsgicgi.launch(app) > HGWEB $ . "$TESTDIR/cgienv" +#if msys + $ PATH_INFO=//tags; export PATH_INFO +#else $ PATH_INFO=/tags; export PATH_INFO +#endif $ QUERY_STRING='style=raw' - $ python hgweb.cgi | grep -v ETag: - Status: 200 Script output follows\r (esc) - Content-Type: text/plain; charset=ascii\r (esc) - \r (esc) + $ python hgweb.cgi | grep ^tip tip [0-9a-f]{40} (re) $ cd .. From wagner.bruna+mercurial at gmail.com Tue Feb 26 16:42:08 2013 From: wagner.bruna+mercurial at gmail.com (Wagner Bruna) Date: Tue, 26 Feb 2013 19:42:08 -0300 Subject: [PATCH RESEND] hgweb: add group authorization In-Reply-To: References: <51138D89.2060904@kiilerich.com> Message-ID: <512D3A40.4000102@gmail.com> Em 07-02-2013 15:36, Markus Zapke-Gr?ndemann escreveu: > # HG changeset patch > # User Markus Zapke-Gr?ndemann > # Date 1360231888 -3600 > # Node ID d2dbfdee987a51efb6f4ad69e3b116aa22553326 > # Parent 2fefd1170bf269e26bb304553009f38e0117c342 > hgweb: add group authorization. (sorry for taking so long to reply, I was kind of internet-impaired these days) Very useful feature IMHO. I have a few suggestions below: > diff --git a/mercurial/help/config.txt b/mercurial/help/config.txt > --- a/mercurial/help/config.txt > +++ b/mercurial/help/config.txt > @@ -1286,8 +1286,12 @@ The full set of options is: > push is not allowed. If the special value ``*``, any remote user can > push, including unauthenticated users. Otherwise, the remote user > must have been authenticated, and the authenticated user name must > - be present in this list. The contents of the allow_push list are > - examined after the deny_push list. > + be present in this list. It is also possible to use groups in this > + list. A group name is prefixed by an ``@``. Groups can either be > + groups defined in the ``groups_section`` or Unix groups. If a group > + from the ``groups_section`` has the same name as an Unix group it > + is used instead. The contents of the allow_push list are examined > + after the deny_push list. > > ``allow_read`` > If the user has not already been denied repository access due to > @@ -1297,8 +1301,12 @@ The full set of options is: > denied for the user. If the list is empty or not set, then access > is permitted to all users by default. Setting allow_read to the > special value ``*`` is equivalent to it not being set (i.e. access > - is permitted to all users). The contents of the allow_read list are > - examined after the deny_read list. > + is permitted to all users). It is also possible to use groups in > + this list. A group name is prefixed by an ``@``. Groups can either > + be groups defined in the ``groups_section`` or Unix groups. If a > + group from the ``groups_section`` has the same name as an Unix group > + it is used instead. The contents of the allow_read list are examined > + after the deny_read list. > > ``allowzip`` > (DEPRECATED) Whether to allow .zip downloading of repository > @@ -1366,8 +1374,13 @@ The full set of options is: > Whether to deny pushing to the repository. If empty or not set, > push is not denied. If the special value ``*``, all remote users are > denied push. Otherwise, unauthenticated users are all denied, and > - any authenticated user name present in this list is also denied. The > - contents of the deny_push list are examined before the allow_push list. > + any authenticated user name present in this list is also denied. It > + is also possible to use groups in this list. A group name is > + prefixed by an ``@``. Groups can either be groups defined in the > + ``groups_section`` or Unix groups. If a group from the > + ``groups_section`` has the same name as an Unix group it is used > + instead. The contents of the deny_push list are examined before the > + allow_push list. > > ``deny_read`` > Whether to deny reading/viewing of the repository. If this list is > @@ -1380,9 +1393,12 @@ The full set of options is: > deny_read and allow_read are empty or not set, then access is > permitted to all users by default. If the repository is being > served via hgwebdir, denied users will not be able to see it in > - the list of repositories. The contents of the deny_read list have > - priority over (are examined before) the contents of the allow_read > - list. > + the list of repositories. It is also possible to use groups in this > + list. A group name is prefixed by an ``@``. Groups can either be > + groups defined in the ``groups_section`` or Unix groups. If a group > + from the ``groups_section`` has the same name as an Unix group it is > + used instead. The contents of the deny_read list have priority over > + (are examined before) the contents of the allow_read list. > > ``descend`` > hgwebdir indexes will not descend into subdirectories. Only repositories > @@ -1400,6 +1416,30 @@ The full set of options is: > ``errorlog`` > Where to output the error log. Default is stderr. > > +``groups_section`` > + Name of hgrc section used to define groups for authorization. > + Default is ``web.groups``. Use the section to define the groups used > + by authorization. > + > + Example:: > + > + [web] > + allow_read = @devs > + > + [web.groups] Minor nit: the dot could cause some confusion with the section.key notation, so I'd call it simply "webgroups" (or even "usergroups"). > + devs = alice, bob, clara, david > + > + Groups can contain other groups:: > + > + [web] > + allow_read = @devs, @testers > + allow_push = @devs > + > + [web.groups] > + devs = alice, bob, clara, david > + ci = hudson > + testers = @ci, lisa, mario What about a different notation, similar to the [auth] section, supporting per-group attributes: [webgroups] devs.type = hgconfig devs.members = alice, bob, clara, david # this would pull members from the same named unix group... anotherteam.type = unix # ...or perhaps explicitly: # anotherteam.group = anotherteamunixgroup # the '@' marker would be fully optional then: @ci.members = hudson # @ci.type = hgconfig would be the default here Together with a bit more flexibility in the _ismember function below (that could be implemented in a follow-up patch), additional group providers could then be easily added through extensions (ldap comes to mind). Regards, Wagner > + > ``guessmime`` > Control MIME types for raw download of file content. > Set to True to let hgweb guess the content type from the file > diff --git a/mercurial/hgweb/common.py b/mercurial/hgweb/common.py > --- a/mercurial/hgweb/common.py > +++ b/mercurial/hgweb/common.py > @@ -8,6 +8,8 @@ > > import errno, mimetypes, os > > +from mercurial import util > + > HTTP_OK = 200 > HTTP_NOT_MODIFIED = 304 > HTTP_BAD_REQUEST = 400 > @@ -18,6 +20,53 @@ HTTP_METHOD_NOT_ALLOWED = 405 > HTTP_SERVER_ERROR = 500 > > > +def _get_users(ui, group, seen=None): > + """Return the users of the group as list.""" > + # update list of groups seen so far for detecting recursions > + if not seen: > + seen = [] > + seen.append(group) > + # check which section to use to lookup groups > + section = ui.config('web', 'groups_section', 'web.groups') > + # first, try to use group definition from groups_section > + users = [] > + hgrcusers = ui.configlist(section, group) > + if hgrcusers: > + for item in hgrcusers: > + if not item.startswith('@'): > + users.append(item) > + continue > + if item[1:] in seen: > + raise ErrorResponse(HTTP_UNAUTHORIZED, > + 'recursion detected for group "%s" in group "%s"' % > + (item[1:], group)) > + users += _get_users(ui, item[1:], seen) > + if not users: > + # if no users found in group definition, get users from OS-level group > + try: > + users = util.groupmembers(group) > + except KeyError: > + raise ErrorResponse(HTTP_UNAUTHORIZED, > + 'group "%s" is undefined' % group) > + return users > + > + > +def _is_member(ui, user, group): > + """Check recursively if a user is member of a group. > + > + If the group equals * all users are members. > + """ > + if group == ['*'] or user in group: > + return True > + for item in group: > + if not item.startswith('@'): > + continue > + users = _get_users(ui, item[1:]) > + if user in users: > + return True > + return False > + > + > def checkauthz(hgweb, req, op): > '''Check permission for operation based on request data (including > authentication info). Return if op allowed, else raise an ErrorResponse > @@ -25,18 +74,19 @@ def checkauthz(hgweb, req, op): > > user = req.env.get('REMOTE_USER') > > + # check read permission > deny_read = hgweb.configlist('web', 'deny_read') > - if deny_read and (not user or deny_read == ['*'] or user in deny_read): > + if deny_read and (not user or _is_member(hgweb.repo.ui, user, deny_read)): > raise ErrorResponse(HTTP_UNAUTHORIZED, 'read not authorized') > > allow_read = hgweb.configlist('web', 'allow_read') > - result = (not allow_read) or (allow_read == ['*']) > - if not (result or user in allow_read): > + if not (not allow_read or _is_member(hgweb.repo.ui, user, allow_read)): > raise ErrorResponse(HTTP_UNAUTHORIZED, 'read not authorized') > > + # check pull permission > if op == 'pull' and not hgweb.allowpull: > raise ErrorResponse(HTTP_UNAUTHORIZED, 'pull not authorized') > - elif op == 'pull' or op is None: # op is None for interface requests > + elif op == 'pull' or op is None: # op is None for interface requests > return > > # enforce that you can only push using POST requests > @@ -50,12 +100,13 @@ def checkauthz(hgweb, req, op): > if hgweb.configbool('web', 'push_ssl', True) and scheme != 'https': > raise ErrorResponse(HTTP_FORBIDDEN, 'ssl required') > > + # check push permission > deny = hgweb.configlist('web', 'deny_push') > - if deny and (not user or deny == ['*'] or user in deny): > + if deny and (not user or _is_member(hgweb.repo.ui, user, deny)): > raise ErrorResponse(HTTP_UNAUTHORIZED, 'push not authorized') > > allow = hgweb.configlist('web', 'allow_push') > - result = allow and (allow == ['*'] or user in allow) > + result = allow and _is_member(hgweb.repo.ui, user, allow) > if not result: > raise ErrorResponse(HTTP_UNAUTHORIZED, 'push not authorized') > > diff --git a/mercurial/hgweb/hgwebdir_mod.py b/mercurial/hgweb/hgwebdir_mod.py > --- a/mercurial/hgweb/hgwebdir_mod.py > +++ b/mercurial/hgweb/hgwebdir_mod.py > @@ -10,8 +10,8 @@ import os, re, time > from mercurial.i18n import _ > from mercurial import ui, hg, scmutil, util, templater > from mercurial import error, encoding > -from common import ErrorResponse, get_mtime, staticfile, paritygen, \ > - get_contact, HTTP_OK, HTTP_NOT_FOUND, HTTP_SERVER_ERROR > +from common import _is_member, ErrorResponse, get_mtime, staticfile, \ > + paritygen, get_contact, HTTP_OK, HTTP_NOT_FOUND, HTTP_SERVER_ERROR > from hgweb_mod import hgweb, makebreadcrumb > from request import wsgirequest > import webutil > @@ -164,12 +164,12 @@ class hgwebdir(object): > user = req.env.get('REMOTE_USER') > > deny_read = ui.configlist('web', 'deny_read', untrusted=True) > - if deny_read and (not user or deny_read == ['*'] or user in deny_read): > + if deny_read and (not user or _is_member(ui, user, deny_read)): > return False > > allow_read = ui.configlist('web', 'allow_read', untrusted=True) > # by default, allow reading if no allow_read option has been set > - if (not allow_read) or (allow_read == ['*']) or (user in allow_read): > + if (not allow_read) or _is_member(ui, user, allow_read): > return True > > return False > diff --git a/tests/test-hgweb-authz.t b/tests/test-hgweb-authz.t > new file mode 100644 > --- /dev/null > +++ b/tests/test-hgweb-authz.t > @@ -0,0 +1,111 @@ > +This test exercises the authorization functionality with a dummy script > + > + $ cat < dummywsgi > + > import os > + > import sys > + > > + > from mercurial.hgweb import hgweb > + > > + > app = hgweb(os.path.join(os.environ['TESTTMP'], 'hgweb.config')) > + > environ = { > + > 'SCRIPT_NAME': '', > + > 'REQUEST_METHOD': 'GET', > + > 'PATH_INFO': sys.argv[1], > + > 'SERVER_PROTOCOL': 'HTTP/1.0', > + > 'QUERY_STRING': '', > + > 'CONTENT_LENGTH': '0', > + > 'SERVER_NAME': 'localhost', > + > 'SERVER_PORT': '80', > + > 'REPO_NAME': sys.argv[1], > + > 'HTTP_HOST': 'localhost:80', > + > 'REMOTE_USER': sys.argv[2], > + > 'wsgi.input': sys.stdin, > + > 'wsgi.url_scheme': 'http', > + > 'wsgi.multithread': False, > + > 'wsgi.version': (1, 0), > + > 'wsgi.run_once': False, > + > 'wsgi.errors': sys.stderr, > + > 'wsgi.multiprocess': False, > + > } > + > > + > def start_response(status, headers, exc_info=None): > + > def dummy_response(data): > + > pass > + > sys.stdout.write(status + '\n') > + > return dummy_response > + > > + > app(environ, start_response) > + > EOF > + > +creating test repository > + > + $ hg init r1 > + $ cd r1 > + $ echo c1 > f1 > + $ echo c2 > f2 > + $ hg ci -A -m "init" f1 f2 > + > +writing hgweb.config > + > + $ cd .. > + $ cat < hgweb.config > + > [paths] > + > r1 = `pwd`/r1 > + > EOF > + > +group authorization test > + > + $ cat < r1/.hg/hgrc > + > [web] > + > allow_read = @developers, cathrin > + > > + > [web.groups] > + > developers = alice, bob > + > EOF > + > + $ python ./dummywsgi r1 alice > + 200 Script output follows > + $ python ./dummywsgi r1 bob > + 200 Script output follows > + $ python ./dummywsgi r1 cathrin > + 200 Script output follows > + $ python ./dummywsgi r1 nosuchuser > + 401 read not authorized > + > +groups can contain other groups > + > + $ cat < r1/.hg/hgrc > + > [web] > + > allow_read = @developers, @testers > + > > + > [web.groups] > + > developers = alice, bob > + > ci = hudson > + > testers = @ci, lisa, mario > + > EOF > + > + $ python ./dummywsgi r1 hudson > + 200 Script output follows > + > +using an unknown groups fails > + > + $ cat < r1/.hg/hgrc > + > [web] > + > allow_read = @quux > + > EOF > + > + $ python ./dummywsgi r1 alice > + 401 group "quux" is undefined > + > +using a recursive groups setup is not allowed > + > + $ cat < r1/.hg/hgrc > + > [web] > + > allow_read = @developers > + > > + > [web.groups] > + > developers = alice, bob, @developers > + > EOF > + > + $ python ./dummywsgi r1 alice > + 401 recursion detected for group "developers" in group "developers" From sterkrig at myopera.com Wed Feb 27 00:10:42 2013 From: sterkrig at myopera.com (Nikolaj Sjujskij) Date: Wed, 27 Feb 2013 10:10:42 +0400 Subject: Convert extension and splicemap feature In-Reply-To: References: Message-ID: Den 2013-02-25 19:54:13 skrev Constantine Dokolas : > I have a subversion repository to convert and splicemaps don't work (I > have > to use splicemaps because of all the non-standard branch paths). The > reason > is that there are paths with spaces all over our repository and splicemap > lines are split on spaces and commas. I'd like the mercurial developers > to > consider adding support for URL encoding (i.e. decode "%20"s in the > splicemap file) in the convert extension. I think that should be filed in bugzilla: http://bz.selenic.com/ Probably won't be too hard to implement. From hg at intevation.org Wed Feb 27 06:00:05 2013 From: hg at intevation.org (Mercurial Commits) Date: Wed, 27 Feb 2013 13:00:05 +0100 Subject: mercurial/crew@18720: 2 outgoing changesets Message-ID: <1361966405.855430.7857.nullmailer@hg.intevation.org> 2 outgoing changesets in mercurial/crew: http://hg.intevation.org/mercurial/crew/rev/0ade08dcb3c3 changeset: 18720:0ade08dcb3c3 tag: tip user: Simon Heimberg date: Sat Feb 23 22:54:57 2013 +0100 summary: tests: remove glob lines which unnecessary match / for \ on windows http://hg.intevation.org/mercurial/crew/rev/9ad13296c581 changeset: 18719:9ad13296c581 user: Simon Heimberg date: Sat Feb 23 22:07:38 2013 +0100 summary: tests: append glob to filename output when required for windows -- Repository URL: http://hg.intevation.org/mercurial/crew From kbullock+mercurial at ringworld.org Wed Feb 27 10:14:18 2013 From: kbullock+mercurial at ringworld.org (Kevin Bullock) Date: Wed, 27 Feb 2013 10:14:18 -0600 Subject: Convert extension and splicemap feature In-Reply-To: References: Message-ID: On Feb 27, 2013, at 12:10 AM, Nikolaj Sjujskij wrote: > Den 2013-02-25 19:54:13 skrev Constantine Dokolas : > >> I have a subversion repository to convert and splicemaps don't work (I have >> to use splicemaps because of all the non-standard branch paths). The reason >> is that there are paths with spaces all over our repository and splicemap >> lines are split on spaces and commas. I'd like the mercurial developers to >> consider adding support for URL encoding (i.e. decode "%20"s in the >> splicemap file) in the convert extension. > I think that should be filed in bugzilla: http://bz.selenic.com/ > Probably won't be too hard to implement. Please do file it in the tracker. I'll say, though, that I'd rather have it interpret quotes than URL-encoded characters. URL encoding is overkill for encoding exactly two special characters. pacem in terris / ??? / ?????? / ????????? / ?? Kevin R. Bullock From markuszapke at gmx.net Wed Feb 27 10:59:34 2013 From: markuszapke at gmx.net (=?UTF-8?B?TWFya3VzIFphcGtlLUdyw7xuZGVtYW5u?=) Date: Wed, 27 Feb 2013 17:59:34 +0100 Subject: [PATCH RESEND] hgweb: add group authorization In-Reply-To: <512D3A40.4000102@gmail.com> References: <51138D89.2060904@kiilerich.com> <512D3A40.4000102@gmail.com> Message-ID: <512E3B76.8050909@gmx.net> Wagner Bruna schrieb: > Em 07-02-2013 15:36, Markus Zapke-Gr?ndemann escreveu: >> # HG changeset patch >> # User Markus Zapke-Gr?ndemann >> # Date 1360231888 -3600 >> # Node ID d2dbfdee987a51efb6f4ad69e3b116aa22553326 >> # Parent 2fefd1170bf269e26bb304553009f38e0117c342 >> hgweb: add group authorization. > > (sorry for taking so long to reply, I was kind of internet-impaired these days) > > Very useful feature IMHO. I have a few suggestions below: > >> diff --git a/mercurial/help/config.txt b/mercurial/help/config.txt >> --- a/mercurial/help/config.txt >> +++ b/mercurial/help/config.txt >> @@ -1286,8 +1286,12 @@ The full set of options is: >> push is not allowed. If the special value ``*``, any remote user can >> push, including unauthenticated users. Otherwise, the remote user >> must have been authenticated, and the authenticated user name must >> - be present in this list. The contents of the allow_push list are >> - examined after the deny_push list. >> + be present in this list. It is also possible to use groups in this >> + list. A group name is prefixed by an ``@``. Groups can either be >> + groups defined in the ``groups_section`` or Unix groups. If a group >> + from the ``groups_section`` has the same name as an Unix group it >> + is used instead. The contents of the allow_push list are examined >> + after the deny_push list. >> >> ``allow_read`` >> If the user has not already been denied repository access due to >> @@ -1297,8 +1301,12 @@ The full set of options is: >> denied for the user. If the list is empty or not set, then access >> is permitted to all users by default. Setting allow_read to the >> special value ``*`` is equivalent to it not being set (i.e. access >> - is permitted to all users). The contents of the allow_read list are >> - examined after the deny_read list. >> + is permitted to all users). It is also possible to use groups in >> + this list. A group name is prefixed by an ``@``. Groups can either >> + be groups defined in the ``groups_section`` or Unix groups. If a >> + group from the ``groups_section`` has the same name as an Unix group >> + it is used instead. The contents of the allow_read list are examined >> + after the deny_read list. >> >> ``allowzip`` >> (DEPRECATED) Whether to allow .zip downloading of repository >> @@ -1366,8 +1374,13 @@ The full set of options is: >> Whether to deny pushing to the repository. If empty or not set, >> push is not denied. If the special value ``*``, all remote users are >> denied push. Otherwise, unauthenticated users are all denied, and >> - any authenticated user name present in this list is also denied. The >> - contents of the deny_push list are examined before the allow_push list. >> + any authenticated user name present in this list is also denied. It >> + is also possible to use groups in this list. A group name is >> + prefixed by an ``@``. Groups can either be groups defined in the >> + ``groups_section`` or Unix groups. If a group from the >> + ``groups_section`` has the same name as an Unix group it is used >> + instead. The contents of the deny_push list are examined before the >> + allow_push list. >> >> ``deny_read`` >> Whether to deny reading/viewing of the repository. If this list is >> @@ -1380,9 +1393,12 @@ The full set of options is: >> deny_read and allow_read are empty or not set, then access is >> permitted to all users by default. If the repository is being >> served via hgwebdir, denied users will not be able to see it in >> - the list of repositories. The contents of the deny_read list have >> - priority over (are examined before) the contents of the allow_read >> - list. >> + the list of repositories. It is also possible to use groups in this >> + list. A group name is prefixed by an ``@``. Groups can either be >> + groups defined in the ``groups_section`` or Unix groups. If a group >> + from the ``groups_section`` has the same name as an Unix group it is >> + used instead. The contents of the deny_read list have priority over >> + (are examined before) the contents of the allow_read list. >> >> ``descend`` >> hgwebdir indexes will not descend into subdirectories. Only repositories >> @@ -1400,6 +1416,30 @@ The full set of options is: >> ``errorlog`` >> Where to output the error log. Default is stderr. >> >> +``groups_section`` >> + Name of hgrc section used to define groups for authorization. >> + Default is ``web.groups``. Use the section to define the groups used >> + by authorization. >> + >> + Example:: >> + >> + [web] >> + allow_read = @devs >> + >> + [web.groups] > > Minor nit: the dot could cause some confusion with the section.key notation, > so I'd call it simply "webgroups" (or even "usergroups"). I've used the same notation used by the acl extension. It uses acl.allow and acl.deny for example. IMO this is a good design. One can see that this is a subsection of the web section. >> + devs = alice, bob, clara, david >> + >> + Groups can contain other groups:: >> + >> + [web] >> + allow_read = @devs, @testers >> + allow_push = @devs >> + >> + [web.groups] >> + devs = alice, bob, clara, david >> + ci = hudson >> + testers = @ci, lisa, mario > > What about a different notation, similar to the [auth] section, supporting > per-group attributes: > > > [webgroups] > > devs.type = hgconfig > devs.members = alice, bob, clara, david > > # this would pull members from the same named unix group... > anotherteam.type = unix > # ...or perhaps explicitly: > # anotherteam.group = anotherteamunixgroup > > # the '@' marker would be fully optional then: > @ci.members = hudson > # @ci.type = hgconfig would be the default here I don't see the advantage of the explicit declaration in your solution. The current implementation is simpler and therefore easier to understand. If it would be possible to "overwrite" Unix groups with groups created in hgrc this could cause some confusion. The @ marker is again taken from the acl extension which is using it also for groups. > Together with a bit more flexibility in the _ismember function below (that > could be implemented in a follow-up patch), additional group providers could > then be easily added through extensions (ldap comes to mind). The integration of LDAP or many other services can be easily done on Unix-based systems using PAM. I think it's easier to rely on PAM then implementing everything again in hgweb. Regards Markus From angel.ezquerra at gmail.com Wed Feb 27 11:06:31 2013 From: angel.ezquerra at gmail.com (Angel Ezquerra) Date: Wed, 27 Feb 2013 18:06:31 +0100 Subject: [PATCH 0 of 3 V6] hgweb: teach archive how to handle file patterns Message-ID: Compared to the previous version this version adds an extra patch which modifies the templates so that this new feature is exposed through the web interface. It also (tries to) address Mads' comments. Also note that the title of this series does not really fit the actual contents of the series anymore because this only teaches hgweb to download directories, not patterns. I kept the title to make it easier for patchwork to detect this new version of the series. From angel.ezquerra at gmail.com Wed Feb 27 11:06:32 2013 From: angel.ezquerra at gmail.com (Angel Ezquerra) Date: Wed, 27 Feb 2013 18:06:32 +0100 Subject: [PATCH 1 of 3 V6] test-archive: gracefully handle HTTPErrors on get-with-headers In-Reply-To: References: Message-ID: # HG changeset patch # User Angel Ezquerra # Date 1360141605 -3600 # Node ID a1aab0b30144b6d9b383e8021d24eecd5861c84e # Parent c8c3887a24c1ee30b0afbdb6812e64bb64b400e6 test-archive: gracefully handle HTTPErrors on get-with-headers This avoids pritting out a traceback when a get-with-headers call causes hgweb to respond with an HTTPError code. diff --git a/tests/test-archive.t b/tests/test-archive.t --- a/tests/test-archive.t +++ b/tests/test-archive.t @@ -69,10 +69,18 @@ > msvcrt.setmode(sys.stdout.fileno(), os.O_BINARY) > except ImportError: > pass - > node, archive = sys.argv[1:] - > f = urllib2.urlopen('http://127.0.0.1:%s/?cmd=archive;node=%s;type=%s' - > % (os.environ['HGPORT'], node, archive)) - > sys.stdout.write(f.read()) + > if len(sys.argv) <= 3: + > node, archive = sys.argv[1:] + > requeststr = 'cmd=archive;node=%s;type=%s' % (node, archive) + > else: + > node, archive, file = sys.argv[1:] + > requeststr = 'cmd=archive;node=%s;type=%s;file=%s' % (node, archive, file) + > try: + > f = urllib2.urlopen('http://127.0.0.1:%s/?%s' + > % (os.environ['HGPORT'], requeststr)) + > sys.stdout.write(f.read()) + > except urllib2.HTTPError, e: + > sys.stderr.write(str(e) + '\n') > EOF $ python getarchive.py "$TIP" gz | gunzip | tar tf - 2>/dev/null test-archive-2c0277f05ed4/.hg_archival.txt From angel.ezquerra at gmail.com Wed Feb 27 11:06:33 2013 From: angel.ezquerra at gmail.com (Angel Ezquerra) Date: Wed, 27 Feb 2013 18:06:33 +0100 Subject: [PATCH 2 of 3 V6] hgweb: teach archive how to download a specific directory or file In-Reply-To: References: Message-ID: # HG changeset patch # User Angel Ezquerra # Date 1360493525 -3600 # Node ID b9fda7cbf2c239cecd667159391befb440edba80 # Parent a1aab0b30144b6d9b383e8021d24eecd5861c84e hgweb: teach archive how to download a specific directory or file The archive web command now takes into account the "file" request entry, if one is provided. The provided "file" is processed as a "path" corresponding to a directory or file that will be downloaded. With this change hgweb can to process requests such as: http://mercurial.selenic.com/hg/archive/tip.zip/mercurial/templates This will download all files on the mercurial/templates directory as a zip file. It is not possible to specify file patterns. Those will be rejected with a 403 reply fromthe server. Note that this is a first step to add support for downloading directories from the web interface. Currently the only way to use this feature is by manually constructing the URL that you want to download. We will have to modify the archiveentry map entry on the different templates so that it adds the current folder path to the archive links. diff --git a/mercurial/hgweb/webcommands.py b/mercurial/hgweb/webcommands.py --- a/mercurial/hgweb/webcommands.py +++ b/mercurial/hgweb/webcommands.py @@ -816,6 +816,17 @@ if cnode == key or key == 'tip': arch_version = short(cnode) name = "%s-%s" % (reponame, arch_version) + + ctx = webutil.changectx(web.repo, req) + pats = [] + file = req.form.get('file', None) + if file: + file = file[0] + if ':' in file: + msg = 'Archive pattern not allowed: %s' % file + raise ErrorResponse(HTTP_FORBIDDEN, msg) + pats = ['path:' + file] + mimetype, artype, extension, encoding = web.archive_specs[type_] headers = [ ('Content-Disposition', 'attachment; filename=%s%s' % (name, extension)) @@ -825,9 +836,9 @@ req.headers.extend(headers) req.respond(HTTP_OK, mimetype) - ctx = webutil.changectx(web.repo, req) + matchfn = scmutil.match(ctx, pats, default='path') archival.archive(web.repo, req, cnode, artype, prefix=name, - matchfn=scmutil.match(ctx, []), + matchfn=matchfn, subrepos=web.configbool("web", "archivesubrepos")) return [] diff --git a/tests/test-archive.t b/tests/test-archive.t --- a/tests/test-archive.t +++ b/tests/test-archive.t @@ -100,6 +100,13 @@ testing: test-archive-2c0277f05ed4/baz/bletch OK testing: test-archive-2c0277f05ed4/foo OK No errors detected in compressed data of archive.zip. + $ python getarchive.py "$TIP" gz baz | gunzip | tar tf - 2>/dev/null + test-archive-2c0277f05ed4/baz/bletch + +test that we reject unsafe patterns + + $ python getarchive.py "$TIP" gz relre:baz + HTTP Error 403: Archive pattern not allowed: relre:baz $ "$TESTDIR/killdaemons.py" $DAEMON_PIDS From angel.ezquerra at gmail.com Wed Feb 27 11:06:34 2013 From: angel.ezquerra at gmail.com (Angel Ezquerra) Date: Wed, 27 Feb 2013 18:06:34 +0100 Subject: [PATCH 3 of 3 V6] hgweb: change manifest archive links to only archive the current directory In-Reply-To: References: Message-ID: <94d2291b295ab3c335c4.1361984794@Angel-PC.localdomain> # HG changeset patch # User Angel Ezquerra # Date 1361910035 -3600 # Node ID 94d2291b295ab3c335c4d215a401004d8290340c # Parent b9fda7cbf2c239cecd667159391befb440edba80 hgweb: change manifest archive links to only archive the current directory When the web server shows the manifest for a single, non top directory, append the path to the directory to the archive links. This makes the web server generate archive files that only include the current directory (and its subdirectories). Note that archive links in other pages (e.g. changeset) or at the top of the manifest are unchanged. Directory archive links have an extra "/" at the end which does not impact the result of the archive operation. Keeping it there made the implementation of this feature simpler. diff --git a/mercurial/templates/coal/map b/mercurial/templates/coal/map --- a/mercurial/templates/coal/map +++ b/mercurial/templates/coal/map @@ -217,7 +217,7 @@ index = ../paper/index.tmpl archiveentry = '
  • - {type|escape} + {type|escape}
  • ' notfound = ../paper/notfound.tmpl error = ../paper/error.tmpl diff --git a/mercurial/templates/gitweb/map b/mercurial/templates/gitweb/map --- a/mercurial/templates/gitweb/map +++ b/mercurial/templates/gitweb/map @@ -282,7 +282,7 @@ file | diff | annotate {rename%filelogrename} ' -archiveentry = ' | {type|escape} ' +archiveentry = ' | {type|escape} ' indexentry = ' diff --git a/mercurial/templates/monoblue/map b/mercurial/templates/monoblue/map --- a/mercurial/templates/monoblue/map +++ b/mercurial/templates/monoblue/map @@ -238,7 +238,7 @@ {rename%filelogrename} ' -archiveentry = '
  • {type|escape}
  • ' +archiveentry = '
  • {type|escape}
  • ' indexentry = ' {name|escape} diff --git a/mercurial/templates/paper/map b/mercurial/templates/paper/map --- a/mercurial/templates/paper/map +++ b/mercurial/templates/paper/map @@ -225,7 +225,7 @@ index = index.tmpl archiveentry = '
  • - {type|escape} + {type|escape}
  • ' notfound = notfound.tmpl error = error.tmpl From cdokolas at gmail.com Wed Feb 27 07:06:28 2013 From: cdokolas at gmail.com (Constantine Dokolas) Date: Wed, 27 Feb 2013 15:06:28 +0200 Subject: Convert extension and splicemap feature In-Reply-To: References: Message-ID: Done! -- There is a computer disease that anybody who works with computers knows about. It's a very serious disease and it interferes completely with the work. The trouble with computers is that you 'play' with them! - Richard P. Feynman On Wed, Feb 27, 2013 at 8:10 AM, Nikolaj Sjujskij wrote: > Den 2013-02-25 19:54:13 skrev Constantine Dokolas : > > > I have a subversion repository to convert and splicemaps don't work (I >> have >> to use splicemaps because of all the non-standard branch paths). The >> reason >> is that there are paths with spaces all over our repository and splicemap >> lines are split on spaces and commas. I'd like the mercurial developers to >> consider adding support for URL encoding (i.e. decode "%20"s in the >> splicemap file) in the convert extension. >> > I think that should be filed in bugzilla: http://bz.selenic.com/ > Probably won't be too hard to implement. > -------------- next part -------------- An HTML attachment was scrubbed... URL: From mercurial-bugs at selenic.com Wed Feb 27 07:06:02 2013 From: mercurial-bugs at selenic.com (mercurial-bugs at selenic.com) Date: Wed, 27 Feb 2013 13:06:02 +0000 Subject: [Bug 3844] New: Support URL encoding in splicemap file Message-ID: http://bz.selenic.com/show_bug.cgi?id=3844 Priority: normal Bug ID: 3844 CC: mercurial-devel at selenic.com Assignee: bugzilla at selenic.com Summary: Support URL encoding in splicemap file Severity: feature Classification: Unclassified OS: Windows Reporter: cdokolas at gmail.com Hardware: PC Status: UNCONFIRMED Version: 2.4.2 Component: convert Product: Mercurial I have a subversion repository to convert and splicemaps don't work (I have to use splicemaps because of all the non-standard branch paths). The reason is that there are paths with spaces all over our repository and splicemap lines are split on spaces and commas. I'd like the mercurial developers to consider adding support for URL encoding (i.e. decode "%20"s in the splicemap file) in the convert extension. I don't remember much about cases other than the splicemap file, but you may wish to look into additional places where this feature would be helpful. -- You are receiving this mail because: You are on the CC list for the bug. From cdokolas at gmail.com Wed Feb 27 13:32:08 2013 From: cdokolas at gmail.com (Constantine Dokolas) Date: Wed, 27 Feb 2013 21:32:08 +0200 Subject: Convert extension and splicemap feature In-Reply-To: References: Message-ID: It's up to the developers to change the design to something that better fits the project. I won't gripe if it's done your way, if it fulfills the need. -- There is a computer disease that anybody who works with computers knows about. It's a very serious disease and it interferes completely with the work. The trouble with computers is that you 'play' with them! - Richard P. Feynman On Wed, Feb 27, 2013 at 6:14 PM, Kevin Bullock < kbullock+mercurial at ringworld.org> wrote: > On Feb 27, 2013, at 12:10 AM, Nikolaj Sjujskij wrote: > > > Den 2013-02-25 19:54:13 skrev Constantine Dokolas : > > > >> I have a subversion repository to convert and splicemaps don't work (I > have > >> to use splicemaps because of all the non-standard branch paths). The > reason > >> is that there are paths with spaces all over our repository and > splicemap > >> lines are split on spaces and commas. I'd like the mercurial developers > to > >> consider adding support for URL encoding (i.e. decode "%20"s in the > >> splicemap file) in the convert extension. > > I think that should be filed in bugzilla: http://bz.selenic.com/ > > Probably won't be too hard to implement. > > Please do file it in the tracker. I'll say, though, that I'd rather have > it interpret quotes than URL-encoded characters. URL encoding is overkill > for encoding exactly two special characters. > > pacem in terris / ??? / ?????? / ????????? / ?? > Kevin R. Bullock > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From mercurial-bugs at selenic.com Wed Feb 27 16:20:50 2013 From: mercurial-bugs at selenic.com (mercurial-bugs at selenic.com) Date: Wed, 27 Feb 2013 22:20:50 +0000 Subject: [Bug 3845] New: broken error message on non-existing revision with dash in the name Message-ID: http://bz.selenic.com/show_bug.cgi?id=3845 Priority: normal Bug ID: 3845 CC: mercurial-devel at selenic.com Assignee: bugzilla at selenic.com Summary: broken error message on non-existing revision with dash in the name Severity: bug Classification: Unclassified OS: Linux Reporter: leo at energysavvy.com Hardware: PC Status: UNCONFIRMED Version: 2.5.1 Component: Mercurial Product: Mercurial Mercurial displays an incorrect error message when trying to update to a non-existing revision with a dash in its name: vm ~: hg update foo abort: unknown revision 'foo'! vm ~: hg update foo-bar abort: unknown revision 'foo'! Expected behavior: vm ~: hg update foo abort: unknown revision 'foo'! vm ~: hg update foo-bar abort: unknown revision 'foo-bar'! -- You are receiving this mail because: You are on the CC list for the bug. From martin at geisler.net Wed Feb 27 16:24:24 2013 From: martin at geisler.net (Martin Geisler) Date: Wed, 27 Feb 2013 23:24:24 +0100 Subject: [PATCH RFC] update: add an option to allow to merge local changes when crossing branches In-Reply-To: <12190966-640B-4627-8927-C72E0308B0B9@ringworld.org> (sfid-20130223_172004_412903_A73C4724) (Kevin Bullock's message of "Sat, 23 Feb 2013 09:07:07 -0600") References: <567106adefd309717d8f.1361528527@fc8> <512771A6.8080209@grauw.nl> <7E8EBF7C-C984-4E02-A327-01A854C291B9@ringworld.org> <8738wokryh.fsf@hbox.dyndns.org> <1033C124-F628-48EE-8B5E-F091571EDFF7@ringworld.org> <87y5efjmsc.fsf@hbox.dyndns.org> <12190966-640B-4627-8927-C72E0308B0B9@ringworld.org> Message-ID: <87a9qpgztz.fsf@hbox.dyndns.org> Kevin Bullock writes: > On 23 Feb 2013, at 5:24 AM, Martin Geisler wrote: > >> Kevin Bullock writes: >> >>> On 22 Feb 2013, at 2:35 PM, Martin Geisler wrote: >>> >>>> I don't know why you say the risk of conflicts is greater here than >>>> with any other update/merge? >>> >>> Simply because you're merging a larger set of changes, as you get to >>> below. >> >> As you say, a merge because of a dirty working copy will use >> >> * working copy parent (base) >> * dirty working copy (local) >> * update target (other) >> >> That ought to be an easy merge regardless of the update target since >> the difference between base and local is "small". >> >> I say "small" because I expect the diff present in the dirty working >> copy to be one commit. That is much smaller than most branch merges >> where the distance from local/other to base is 10, 100 or more >> commits. > > I was assuming that a cross-branch update would use: > > * common ancestor of target and WC (base) > * dirty working copy (local) > * update target on other branch (other) > > Is this not what the patch does? I don't know this code well, but I think you're suggesting the wrong ancestor: using the common ancestor of target and WC for a three-way merge will make you merge the entire *branch* from "base" into "other". You only want to merge the changes since the working copy parent, and the working copy. For that you need the base to be the working copy parent. This is really a matter of committing the working copy, grafting the commit to the target revision and uncommitting it again. I once made an ASCII art graph of how I believe graft works: http://stackoverflow.com/a/9605306/110204 I hope someone will correct me if I'm confused here :) -- Martin Geisler -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 835 bytes Desc: not available URL: From martin at geisler.net Wed Feb 27 16:32:59 2013 From: martin at geisler.net (Martin Geisler) Date: Wed, 27 Feb 2013 23:32:59 +0100 Subject: [PATCH RFC] update: add an option to allow to merge local changes when crossing branches In-Reply-To: (sfid-20130223_202004_977425_9B352EDB) (Angel Ezquerra's message of "Sat, 23 Feb 2013 19:24:02 +0100") References: <567106adefd309717d8f.1361528527@fc8> <512771A6.8080209@grauw.nl> <7E8EBF7C-C984-4E02-A327-01A854C291B9@ringworld.org> <8738wokryh.fsf@hbox.dyndns.org> <1033C124-F628-48EE-8B5E-F091571EDFF7@ringworld.org> <87y5efjmsc.fsf@hbox.dyndns.org> Message-ID: <87621dgzfo.fsf@hbox.dyndns.org> Angel Ezquerra writes: > On Sat, Feb 23, 2013 at 12:24 PM, Martin Geisler wrote: >> Kevin Bullock writes: >> >>> The theoretical problem is the same, but the _usability_ problem is >>> very different, both because of a likely larger set of conflicts >>> (merge early and often!), and because you'd have to do something >>> different to get back to your original state (and we'd likely have >>> to track more state outside of history). >> >> The risk of losing changes is certainly greater when they only live >> inside .hg/merge instead of in permanent history -- 100% agreed. >> >> My starting point was only that every single time I've had the >> "sorry, I wont help you update across branches" message I "fixed" it >> by updating twice and could continue with my work. > > I also do this somethings although in other cases I either shelve my > changes or commit and rebase. > It seems that having to update back to an ancestor doubles the changes > of making an error while merging? Yeah, there will be situations where you get to resolve conflicts when updating to the ancestor and get the resolve the same conflicts again when updating to your target revision. If there two merges were done as a single merge, then you might get fewer conflicts: Think of a case where you modify file A.txt in the working copy. File A.txt exists in both the working copy parent and in your target revision, but it doesn't exist in the common ancestor: two merges will cause a conflict that you don't get if you merge directly. I'm not sure if the reversion situation can occur. -- Martin Geisler -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 835 bytes Desc: not available URL: From mads at kiilerich.com Thu Feb 28 17:54:01 2013 From: mads at kiilerich.com (Mads Kiilerich) Date: Fri, 01 Mar 2013 00:54:01 +0100 Subject: [PATCH] tests: work around msys bash mangling of paths in test-mq.t In-Reply-To: References: <89602c1c69202073a978.1361910894@mk-desktop> Message-ID: <512FEE19.1040307@kiilerich.com> On 02/28/2013 10:54 PM, Bryan O'Sullivan wrote: > On Tue, Feb 26, 2013 at 12:34 PM, Mads Kiilerich > wrote: > > tests: work around msys bash mangling of paths in test-mq.t > > > Ugh. Necessary evil, I guess. It will not be necessary with something like http://patchwork.serpentine.com/patch/914/ . But yes, poor msys cannot know if /foo refer to a virtual file system path that has to be translated to driveletter+path format before being passed to a native windows app. /Mads -------------- next part -------------- An HTML attachment was scrubbed... URL: From hg at intevation.org Thu Feb 28 06:00:05 2013 From: hg at intevation.org (Mercurial Commits) Date: Thu, 28 Feb 2013 13:00:05 +0100 Subject: mercurial/crew@18720: 2 outgoing changesets Message-ID: <1362052805.208947.21211.nullmailer@hg.intevation.org> 2 outgoing changesets in mercurial/crew: http://hg.intevation.org/mercurial/crew/rev/0ade08dcb3c3 changeset: 18720:0ade08dcb3c3 tag: tip user: Simon Heimberg date: Sat Feb 23 22:54:57 2013 +0100 summary: tests: remove glob lines which unnecessary match / for \ on windows http://hg.intevation.org/mercurial/crew/rev/9ad13296c581 changeset: 18719:9ad13296c581 user: Simon Heimberg date: Sat Feb 23 22:07:38 2013 +0100 summary: tests: append glob to filename output when required for windows -- Repository URL: http://hg.intevation.org/mercurial/crew From mads at kiilerich.com Thu Feb 28 08:14:40 2013 From: mads at kiilerich.com (Mads Kiilerich) Date: Thu, 28 Feb 2013 15:14:40 +0100 Subject: [PATCH stable] templatefilters: add missing import of _ In-Reply-To: References: Message-ID: <512F6650.8050107@kiilerich.com> On 02/26/2013 03:39 AM, Mads Kiilerich wrote: > # HG changeset patch > # User Mads Kiilerich > # Date 1361844560 -3600 > # Branch stable > # Node ID b1f0fd26bda704357708c73fdeb78f1b6f372238 > # Parent 61c8327ced503bf7a1996337af711e0f4a58d4c0 > templatefilters: add missing import of _ fix pushed to crew stable /Mads From angel.ezquerra at gmail.com Thu Feb 28 11:02:00 2013 From: angel.ezquerra at gmail.com (Angel Ezquerra) Date: Thu, 28 Feb 2013 18:02:00 +0100 Subject: [PATCH 1 of 3] pull: add --subrepos flag In-Reply-To: <5129CD64.3050904@yahoo.com> References: <5125A8BA.8020106@yahoo.com> <5129CD64.3050904@yahoo.com> Message-ID: On Sun, Feb 24, 2013 at 9:20 AM, Matt Harbison wrote: > Angel Ezquerra wrote: >> >> On Thu, Feb 21, 2013 at 5:55 AM, Matt Harbison >> wrote: >>> >>> Angel Ezquerra wrote: >>>> >>>> On Wed, Feb 20, 2013 at 6:57 AM, Matt >>>> Harbison wrote: >>>>> >>>>> On Sun, 17 Feb 2013 13:19:16 +0100, Angel Ezquerra wrote: >>>>> >>>>>> # HG changeset patch # User Angel >>>>>> Ezquerra # Date 1360519226 -3600 # Node >>>>>> ID abbd26cca35280fb8f784b3f2c02eef71696c47b # Parent >>>>>> 55b9b294b7544a6a144f627f71f4b770907d5a98 pull: add --subrepos >>>>>> flag >>>>>> >>>>>> The purpose of this new flag is to ensure that you are able to >>>>>> update to any incoming revision without requiring any network >>>>>> access. The idea is to make sure that the repository is >>>>>> self-contained after doing hg pull --subrepos, as long as it >>>>>> already was self-contained before the pull). >>>>>> >>>>>> When the --subrepos flag is enabled, pull will also pull (or >>>>>> clone) all subrepos that are present on the current revision and >>>>>> those that are referenced by any of the incoming revisions. >>>>> >>>>> I haven't gotten a chance to really play with this yet, so I'm >>>>> going more off the comments here- I apologize if these answers >>>>> should be obvious, but I'm not familiar enough with some of the >>>>> code. >>>>> >>>>> - Is there an easy way to tell if the repo is/was self contained? >>>>> (Maybe incoming -S?) >>>> >>>> >>>> No there is not. I don't think incoming -S would do the trick since >>>> that would just tell you if there are _new_ incoming revisions on >>>> some of the _current_ subrepos. A repo is "self-contained" if it is >>>> possible to update to any of its revisions withing requiring a pull >>>> of one or more of its subrepos. >>>> >>>> I don't know of any existing mercurial command that would be able to >>>> give you that information. >>>> >>>>> - Is the 'self-contained' bit to limit overhead on each pull, or is >>>>> there another reason this can't ensure the result is self >>>>> contained? 'Push' and 'outgoing -S' recognize (almost) everything >>>>> going in the other direction, so it might be nice to have the same >>>>> capability with a form of pull. (I may have found a push bug that >>>>> I haven't gotten back to yet.) >>>> >>>> >>>> I'm not sure I understand what you mean. >>> >>> >>> Consider this (contrived) case: >>> >>> 1) push a repo and subrepo to remote (remote is now self contained) >>> 2) strip or rollback the remote subrepo >>> 3) a top level local repo push will repopulate the remote subrepo >>> >>> Now reverse it: >>> >>> 1) pull a repo and subrepo from remote (local is self contained) >>> 2) strip or rollback the local subrepo >>> 3) nothing is incoming top level, so the subrepo isn't repopulated (if >>> you've updated to a working dir without that subrepo). >>> >>> I'm not sure if there's a less contrived case, or if this matters too >>> much. I guess I was just wondering aloud about the symmetry between >>> push and pull -S (this is certainly much better than it was). >> >> >> I don't think this is a very big deal because "pull --subrepos" also >> performs a pull on all the repositories that are found on the current >> revision. I think this would fix your contrived case. > >> >> >> The only corner case that would not be properly handled by this would >> be the case in which pull --subrepos cloned a _new_ subrepo that is >> not found on the current revision (i.e. that is introduced on one of >> the cloned revisions) and then you striped some revisions from that >> "future subrepo". In that case would would still be able to get the >> missing revisions as you would do today, i.e. by updating to the >> offending revision. You could also use the onsub extension (which is >> shipped with TortoiseHg). >> >> BTW, the more I use the onsub extension the more I am convinced that >> it should be distributed with mercurial, and even that the onsub >> command itself should become a built-in command. > > > I'd be fine with that. I haven't used it, but from what I've read, it seems > like a useful crutch to do things that aren't currently possible because > they aren't well defined, like tagging all repos or opening a branch. But > ideally there wouldn't be a need for it with commands that accept a -S. The > principle of least surprise says those commands can handle subrepos already. The cool thing about the onsub command is that it lets you operate on subrepos without operating on the parent repo, which often is what you want. Using the -S option on mercurial commands does not work the same because it (usually) will also perform an action on the parent repo. >> That being said, if we did want to also handle this very small corner >> case there are at least a couple of possible solutions: >> >> 1. make the --subrepos flag take a revset that would tell it which >> revisions to look for subrepos to pull. > > > Why not use the -r option? But really, I think in this case 'pull -S' == > 'pull -S -r all()', so I'm not sure if that helps. I think it could help a little. We must just make sure that 'pull -S -r .' does what I would expect, which is to just pull all current subrepos. >> 2. make --subrepos also look for subrepos on the descendants of the >> current revision. >> >> #1 would be nice _if_ we could also skip the revset to get the >> behavior that the current patch proposes. However I don't think that >> is possible to have a flag that can optionally take a parameter. > > Agreed. A special case parameter isn't nice. I guess if this really became an issue we could think about an --all-subrepos options, as in large files, but I don't really think it will be necessary. Also perhaps using pull -r 0:tip would work. I'll have to check. >> #2... maybe that is too much overhead for such a small corner case? > > Not sure.. That's why I was asking if there's large repos to benchmark on > :-). The other thing I'm wondering is, since we seem to have various caches, > maybe caching subrepo info would speed things up? I have no idea what form > this would take, or even how the existing caches are invalidated, detect > corruption, etc. The construct I've got in my push patches is: > > f = repo.wjoin('.hgsubstate') > revs = repo.revs('(adds(%s) or modifies(%s)) and ::(%ln)', f, f, revs) > > I'm not sure if this helps cut down overhead- you do have to traverse the > whole repo, but you don't have to process the .hgsubstate file for revisions > where the subrepos don't change. (Though you referenced having the latest > path for the repo, and that can change without affecting .hgsubstate, so > this may not be useful anyway.) I think the code could easily check if the parent repo refers to a revision that is missing on the subrepo and then only pull those subrepos that were missing revisions (or new subrepos). However this would make it hard to just pull all subrepos, which you need to do when you want to move a subrepo forward (i.e. select a newer revision on a subrepo). My ideal pull behavior would be for pull without --subrepos to actually perform this check and pull the minimum amount of revisions needed to make the current parent repo revision consistent. Adding --subrepos would pull all current and new subrepos (as this patch proposes), regardless of whether they have changed. That being said, I am not proposing (yet) to change the current pull (without --subrepos) behavior. I first want to add the --subrepos flag and make it do something useful. >> Additionally, I wonder if it would make sense to change the current >> pull behavior a little, by checking if any of the subrepos that are >> present on the _current_ parent revision point to a revision that does >> not exist, and if that is the case fulling from them _up to that >> revision_? I think the parent pull time is an excellent time to do >> this kind of stuff since you already know that you have an internet >> connection... > > > Can you show a short test case or pseudo test case of this? I'm not sure > what you're suggesting here. Wouldn't the existing pull bring in all of the > changes to the tip of each subrepo now? Why back off on that without a -r > option? Umm, what I had in mind was the following scenario: 1. You pull a repo that has some subrepos. 2. You update to tip, which pulls all subrepos. 3. You enter into one of the subrepos 4. You strip some revisions on that subrepo. How do you get those missing revisions back? However I've been thinking about this and it is not really necessary. You can just do "hg update --clean -r ." and that will pull from all subrepos that are missing revisions, which is what I wanted. So, never mind... Just forget about that :-) >>> I realize you can't do such a thing without crawling most of the >>> history. Are there large public repositories that use subrepos? I'm >>> wondering what the performance hit would be. (It's easy for me to think >>> something is a good idea when I only have small repos and wouldn't >>> notice the hit.) >> >> >> We have repositories with thousands of files and more than 20 >> subrepos. I don't know if you would consider that big... > > > Not sure. I'm assuming that the number of commits is the governing factor > when walking the history? But that's almost certainly going to be larger > than the toy repos I make, or even the real ones I use at work (still less > than 1000 in the subrepo, and probably less than 200 on the parent). Just > looking for something to run benchmarks on. I think fully pulling all subrepos when you explicitly ask to by using the --subrepos flag would be acceptable in any case. >>> FWIW, largefiles works the same way- if you don't clone or pull with >>> --all-largefiles, there's no single command to go back and get the files >>> for all revisions that are not incoming. That leaves the user wondering >>> if they really can disconnect from the central repo. >> >> >> That is true. It would be nice to be able to do that. However there is >> a difference between largefiles and subrepos. Largefiles tries to only >> get the files that you need, when you need them _by design_. Subrepos >> is not meant (IMHO) to do that (or at least it is not necessary for >> subrepos to fulfill its main purpose, which is to track "submodules"). > > > I agree with you about subrepos, but the --all-largefiles flag is a new(ish) > feature that lets you override that original largefiles design, so you can > disconnect from the central repo. (So a very similar motivation for this.) > I was going to put in a command to download missing largefiles, but never > got around to it. But I don't think a new command would be an option for > subrepos if we don't get this right, because it really is just a pull. If > we can change the pull command in the future if there's a need to handle > this, then it may not be that big of a deal now. And I suspect the only > hinderance to adding it later will be if there's a big performance drop. If this became a problem we could think about adding some other flag in the future, or perhaps integrating the onsub extension into core? >>>> I don't think you (we?) must give too much importance to this >>>> "self-contained" concept. It is just a way for me to explain the >>>> purpose of the patch, and specially to explain why we must look for >>>> subrepos on all the new incoming revisions, and why we cannot just >>>> limit ourselves to pulling the subrepos on the current revisions >>>> (short answer: because new subrepos may appear on the new, incoming >>>> revisions). >>>> >>>> My patch explicitly says that hg pull -S will only make your subrepo >>>> self-contained if it was already self-contained before. This is in >>>> order to avoid having to look for subrepos on all the repo history, >>>> rather than just looking for subrepos on the incoming revision (and >>>> the current one). >>>> >>>>> - The full subrepo gets pulled, even revs not committed to the >>>>> parent? I think that's a good thing, because regularly get burned >>>>> when I 'pull -u' the tree to another machine and then go to apply >>>>> the rest of a patch queue to the subrepo. >>>> >>>> >>>> Yes. It is perhaps not optimal but I think it is simpler. In >>>> addition if different parent repo revisions point to different >>>> revisions on a subrepo there is no way for us to tell which of those >>>> subrepo revisions is the one that is closes to tip, or which ones >>>> are ancestors of the other ones, etc. As a result we would need to >>>> perform as many pulls on a given repo as the number of different >>>> revisions of that subrepo that were referenced on the parent repo. >>>> That is complex and slow, so it is much simpler and possibly faster >>>> (in some cases at least) to just pull all revisions from each >>>> subrepo. >>> >>> >>> OK, I misread the code- I thought each subrepo was getting a pull at >>> each revision, which I figured would be slow. I attached a test patch >>> below- there's nothing special about it, but it helped me with my pull >>> and outgoing changes (some comments probably still reflect this), so I >>> changed that to pull and incoming to test your patch. >>> >>> - I think I see a double pull of a subrepo (search for "hg pull -S -r >>> 3"). >> >> >> You are right. There is a problem with the current version of the >> patch. It will clone the same repo multiple times if the same subrepo >> refers to different revisions. I will resend with a fix. > >> >> >> BTW, where do you think the tests for this new feature should go? >> Should it go into one of the test-pull*.t files or in one of the >> test-subrepo*.t files? Do you think the test that you propose in that >> patch would be enough to test this new feature? Maybe it could be made >> a bit simpler? >> > > I assumed it would go in test-subrepo*t, so anyone hacking on subrepos > doesn't have to find it in an obscure test, but I can see the same argument > from someone working on pull(). Probably what tips it to subrepo*t though > is that there is some existing subrepo infrastructure that doesn't exist in > test-pull*t. Yes, I think you are right. It should probably go into test-subrepo-recursion.t. > I'm not sure that it's comprehensive, and there's probably some duplication. > I put it together to e.g. test 'push -r 2' then 'push -r 4', and make sure > the grandchild repo code path got exercised. Since you aren't doing > anything with -r, there may be duplicate pull tests. The incoming tests > probably aren't relevant either, though I think they should agree on what > they are doing eventually. > > Those tests also didn't exercise the subrepo pull path (the dests were > empty, so clone was used). I marked various potential issues in there with > 'XXX'. > One thing I did specifically was to skew the rev values between the parent > and child, so parent rev 1 doesn't lock in subrepo rev 1. This makes it > easier to test with the -r option (which I realize you aren't doing now, but > might be a nice to have in the future). I think I will take some inspiration from your test and write a new one specific to my proposed patch. >>> - I wonder if the code in this patch can be leveraged to make incoming >>> print all of the stuff 'pull -S' will grab in the future. >> >> >> In theory that would be certainly possible. At least we could run the >> same "look for subrepos to pull" code and show the list of subrepos >> that would be pulled and then run incoming on them. The main problem >> is that incoming already has a --subrepos flag, which does something >> slightly different... I'm not sure that could be changed... > > > I think it just recurses into the subrepo and does an incoming on it. If it > does something else, it's too subtle for me to have noticed. > > I've probably stated bits and pieces of this over the course of a week or > so, but just to explicitly put it all together, I think in an ideal world we > would have new pull/incoming, and push/outgoing agree with the same options, > and each group is the reverse of the other. It may be fantasy, but: > > incoming pull operation > current behavior, parent repo only > xxx [1] -u current behavior, pull subrepo on update > -S -S (this patch) pull parent + all subrepos to > tip > -S -r -S -r (future) pull parent to rev, revs of > subrepos > used up to that rev I think your -S -r idea is worth thinking about. This could mean that if where revs that you already had in your parent repo you would still pull from the corresponding subrepos, right? > [1] It doesn't seem sensible to add -u to incoming for this, so leaving no > equivalent form is probably best. > > outgoing push operation > [2] current, parent only and all respectively > -S [3] current, push parent + all subrepos to tip > -S -r -r (future) push parent to rev, revs of > subrepos > used up to that rev The problem with this is that if a subrepo changes more than once in a range there is not cheap way to only send those revisions (and their descendants) AFAIK. What I mean is that if subrepo S changes from revision A to B and then from B to C on two different parent revisions, you cannot just do push -r C on the subrepo, because B and C may be on different branches and not have an ancestor-descendant relationship. In that case you only have two choices. Either you push twice ("push -r A" then "push -r C" or you push all). > [2] It seems buggy to me that the no arg forms disagree, since outgoing's > help says "These are the changesets that would be pushed if a push was > requested." But that ship has probably already sailed. Unfortunately I think that is true. > [3] There is no form of push that takes -S Since I have another patch series (waiting for review!) that makes push only push "cleanstore" subrepos, it may make sense to add a "push -S" flag to force pushing all subrepos regardless of the cleanstore state. > So the last two lines in each table align in functionality and (roughly) in > arguments. > > > >>>>> I'll try to experiment with this some in the next few days. I ran >>>>> into issues with what I'm working on (push, outgoing) with deeply >>>>> nested subrepos, and also when a parent locks in an earlier subrepo >>>>> version. I wonder if deeply nested subrepos will be a problem here >>>>> since hgsubrepo.pull() doesn't walk its subrepos and pull them. >>>> >>>> >>>> I must confess that I have not tried that too much. We should >>>> definitely do this recursively. That being said I hope to get some >>>> feedback on the current version that I sent to the list first. >>> >>> >>> Sorry, I got crossed up on that too. hgsubrepo.pull() ends up calling >>> _repo.pull(), so it does recurse. >> >> >> You are right. That's nice! :-) >> >>> The test below indicates that clone won't >>> recurse- it reminds that an update is needed. (Maybe clone needs a -S >>> too >>> as part of these changes? If you aren't walking the history, I >>> don't see a way around that because nothing is incoming after a clone, >>> so you won't see subrepos of a cloned subrepo.) >> >> >> I guess that would make sense in another patch. >> >>> The other thing worth a test is largefiles- the --all-largefiles >>> option isn't passed to subrepos, so as it stands, 'pull -S' won't let >>> you really disconnect, because largefiles in subrepos won't be cached. >>> That >>> can be fixed later. >> >> >> I agree. We do not really use largefiles (yet) so we have not come >> across this (yet) but I'm sure this is something we would like to >> improve as well. >> >> One last thing, did you have time to have a look at the code of the >> patch series itself? I plan to send an slighly changed version of the >> patch series that will only change the first patch to fix the issue >> you found (the fix is minimal so the code should be almost the same). >> Do you have any comments? > > > I did, but I'm not as well versed in this area of code- that's why I've kept > the conversation fairly high level. I was able to follow your commit > message and it looks like the code does what it says. Just curious- is > specifying None as the revision the right thing to do in pull()? AFAICT, > None gives you the working directory... so does that change the results > based on what the subrepo is currently updated to? I use '.' on the latest version of the patch. Anyway, I think I will resend the series with an added test. We can think about the other possible improvements later. I really hope I can get this in before the next release! Cheers, Angel From bos at serpentine.com Thu Feb 28 15:53:46 2013 From: bos at serpentine.com (Bryan O'Sullivan) Date: Thu, 28 Feb 2013 13:53:46 -0800 Subject: [PATCH] tests: convert \ to / on test output lines containing $TESTTMP In-Reply-To: <2c246fef46d1f70b0882.1361910797@mk-desktop> References: <2c246fef46d1f70b0882.1361910797@mk-desktop> Message-ID: On Tue, Feb 26, 2013 at 12:33 PM, Mads Kiilerich wrote: > tests: convert \ to / on test output lines containing $TESTTMP > Looks good, thanks. -------------- next part -------------- An HTML attachment was scrubbed... URL: From bos at serpentine.com Thu Feb 28 15:54:27 2013 From: bos at serpentine.com (Bryan O'Sullivan) Date: Thu, 28 Feb 2013 13:54:27 -0800 Subject: [PATCH] tests: work around msys bash mangling of paths in test-mq.t In-Reply-To: <89602c1c69202073a978.1361910894@mk-desktop> References: <89602c1c69202073a978.1361910894@mk-desktop> Message-ID: On Tue, Feb 26, 2013 at 12:34 PM, Mads Kiilerich wrote: > tests: work around msys bash mangling of paths in test-mq.t > Ugh. Necessary evil, I guess. -------------- next part -------------- An HTML attachment was scrubbed... URL: From mpm at selenic.com Thu Feb 28 20:20:37 2013 From: mpm at selenic.com (Matt Mackall) Date: Thu, 28 Feb 2013 20:20:37 -0600 Subject: Server trouble Message-ID: <20130301022036.GA21687@waste.org> Up until Sunday the main mercurial server had been running without trouble for 549 days. Then it encountered an i/o error on the xen root partition that could only be addressed with a reboot. I took advantage of the downtime to do a long overdue kernel upgrade. Unfortunately, the new kernel only lasted a few days before deciding to randomly disable the primary network interface twice in 24 hours. Worse yet, this coincided with me leaving the country on a two week vacation. So it took most of a day to get someone on-site and on the phone with me to fix things. I'm pretty sure that I've now got a cron job that will detect and fix the problem until I can do a proper fix, but we might be in for a rough couple of weeks. -- Mathematics is the supreme nostalgia of our time. From hgbuildbot at kublai.com Thu Feb 28 08:50:13 2013 From: hgbuildbot at kublai.com (hgbuildbot at kublai.com) Date: Thu, 28 Feb 2013 06:50:13 -0800 Subject: buildbot failure in Mercurial on python-hglib Message-ID: <20130228145014.3CF062981A@hgbuildbot.cs.ubc.ca> The Buildbot has detected a new failure on builder python-hglib while building hg. Full details are available at: http://hgbuildbot.kublai.com/builders/python-hglib/builds/819 Buildbot URL: http://hgbuildbot.kublai.com/ Buildslave for this Build: l6 Build Reason: scheduler Build Source Stamp: [branch stable] a5d33446e46c11737c59106ba91fba88deabf3c3 Blamelist: Mads Kiilerich BUILD FAILED: failed sincerely, -The Buildbot From durham at fb.com Thu Feb 28 20:33:42 2013 From: durham at fb.com (Durham Goode) Date: Thu, 28 Feb 2013 18:33:42 -0800 Subject: [PATCH] blackbox: fix exception when logging commands with format characters Message-ID: <6980c9cc2eb4ee69a530.1362105222@dev350.prn1.facebook.com> # HG changeset patch # User Durham Goode # Date 1362075146 28800 # Thu Feb 28 10:12:26 2013 -0800 # Node ID 6980c9cc2eb4ee69a530c6c55b44955fb16c53e7 # Parent 0e272121ea4e33027061f8fb9700074ae8f6c63d blackbox: fix exception when logging commands with format characters When running commands like 'hg export -o mypatch-%N.patch', the blackbox would throw an exception because it tried to format %N. This change prevents it from trying to format the command string. diff --git a/mercurial/dispatch.py b/mercurial/dispatch.py --- a/mercurial/dispatch.py +++ b/mercurial/dispatch.py @@ -737,7 +737,7 @@ ui.warn(_("warning: --repository ignored\n")) msg = ' '.join(' ' in a and repr(a) or a for a in fullargs) - ui.log("command", msg + "\n") + ui.log("command", '%s\n', msg) d = lambda: util.checksignature(func)(ui, *args, **cmdoptions) starttime = time.time() ret = None From hg at intevation.org Thu Feb 28 21:05:09 2013 From: hg at intevation.org (Mercurial Commits) Date: Fri, 01 Mar 2013 04:05:09 +0100 Subject: mercurial@18736: 18 new changesets (10 stable) Message-ID: <1362107109.478182.17917.nullmailer@hg.intevation.org> 18 new changesets (10 stable) in mercurial: http://selenic.com/repo/hg//rev/9ad13296c581 changeset: 18719:9ad13296c581 user: Simon Heimberg date: Sat Feb 23 22:07:38 2013 +0100 summary: tests: append glob to filename output when required for windows http://selenic.com/repo/hg//rev/0ade08dcb3c3 changeset: 18720:0ade08dcb3c3 user: Simon Heimberg date: Sat Feb 23 22:54:57 2013 +0100 summary: tests: remove glob lines which unnecessary match / for \ on windows http://selenic.com/repo/hg//rev/2dc7f63181b9 changeset: 18721:2dc7f63181b9 branch: stable parent: 18701:61c8327ced50 user: Mads Kiilerich date: Thu Feb 28 13:44:22 2013 +0100 summary: largefiles: fix off-by-one error on pull --all-largefiles http://selenic.com/repo/hg//rev/f0aa8bbffe60 changeset: 18722:f0aa8bbffe60 branch: stable user: Mads Kiilerich date: Thu Feb 28 13:44:24 2013 +0100 summary: largefiles: fix download of largefiles from an empty list of changesets http://selenic.com/repo/hg//rev/e56f7cd8c67b changeset: 18723:e56f7cd8c67b branch: stable user: Mads Kiilerich date: Thu Feb 28 13:44:59 2013 +0100 summary: tests: don't rely on broken behaviour in test-largefiles-cache.t http://selenic.com/repo/hg//rev/894a5897a9dd changeset: 18724:894a5897a9dd branch: stable user: Mads Kiilerich date: Thu Feb 28 13:45:18 2013 +0100 summary: largefiles: getstandinmatcher should not depend on existence of directories http://selenic.com/repo/hg//rev/0ac00315875f changeset: 18725:0ac00315875f branch: stable user: Mads Kiilerich date: Thu Feb 28 13:45:18 2013 +0100 summary: largefiles: don't assume that .hg/largefiles/ still exists http://selenic.com/repo/hg//rev/431b246cfb12 changeset: 18726:431b246cfb12 branch: stable user: Mads Kiilerich date: Thu Feb 28 13:45:18 2013 +0100 summary: largefiles: missing largefiles should not be committed as removed http://selenic.com/repo/hg//rev/4846f2115927 changeset: 18727:4846f2115927 branch: stable user: Mads Kiilerich date: Thu Feb 28 13:45:18 2013 +0100 summary: largefiles: don't let update leave wrong largefiles in wd if fetch fails http://selenic.com/repo/hg//rev/1e636f7b1cfe changeset: 18728:1e636f7b1cfe branch: stable user: Mads Kiilerich date: Thu Feb 28 13:45:18 2013 +0100 summary: largefiles: simplify cachelfiles - don't spend a lot of time checking hashes http://selenic.com/repo/hg//rev/4e53ac3f466a changeset: 18729:4e53ac3f466a branch: stable user: Mads Kiilerich date: Thu Feb 28 13:45:18 2013 +0100 summary: largefiles: updatelfiles should use working dir standins, not standins from p1 http://selenic.com/repo/hg//rev/a5d33446e46c changeset: 18730:a5d33446e46c branch: stable user: Mads Kiilerich date: Thu Feb 28 13:55:00 2013 +0100 summary: templatefilters: add missing import of _ http://selenic.com/repo/hg//rev/c2d079387b2c changeset: 18731:c2d079387b2c parent: 18720:0ade08dcb3c3 parent: 18730:a5d33446e46c user: Mads Kiilerich date: Thu Feb 28 14:51:59 2013 +0100 summary: merge with stable http://selenic.com/repo/hg//rev/1793251e75c8 changeset: 18732:1793251e75c8 user: Mads Kiilerich date: Thu Feb 28 14:05:15 2013 +0100 summary: largefiles: remove wrong comment on standin matcher and code for creating dirs http://selenic.com/repo/hg//rev/1663fe10f693 changeset: 18733:1663fe10f693 user: Mads Kiilerich date: Tue Feb 26 21:04:50 2013 +0100 summary: tests: work around msys bash mangling of paths in test-mq.t http://selenic.com/repo/hg//rev/b72697653306 changeset: 18734:b72697653306 user: Thomas Arendsen Hein date: Thu Feb 28 21:34:44 2013 +0100 summary: help: new SHA-1 fingerprint of hg.intevation.org in hostfingerprints example http://selenic.com/repo/hg//rev/716cad930691 changeset: 18735:716cad930691 user: Bryan O'Sullivan date: Thu Feb 28 12:51:18 2013 -0800 summary: util: generalize bytecount to unitcountfn http://selenic.com/repo/hg//rev/af9ddea2cb99 changeset: 18736:af9ddea2cb99 tag: tip user: Bryan O'Sullivan date: Thu Feb 28 13:11:42 2013 -0800 summary: util: add a timed function for use during development -- Repository URL: http://selenic.com/repo/hg/ From gilles.moris at free.fr Thu Feb 28 09:24:32 2013 From: gilles.moris at free.fr (Gilles Moris) Date: Thu, 28 Feb 2013 16:24:32 +0100 Subject: [PATCH RFC] update: add an option to allow to merge local changes when crossing branches In-Reply-To: <87a9qpgztz.fsf@hbox.dyndns.org> References: <567106adefd309717d8f.1361528527@fc8> <12190966-640B-4627-8927-C72E0308B0B9@ringworld.org> <87a9qpgztz.fsf@hbox.dyndns.org> Message-ID: <201302281624.33214.gilles.moris@free.fr> On Wednesday 27 February 2013 11:24:24 pm Martin Geisler wrote: > Kevin Bullock writes: > > On 23 Feb 2013, at 5:24 AM, Martin Geisler wrote: > >> Kevin Bullock writes: > >>> On 22 Feb 2013, at 2:35 PM, Martin Geisler wrote: > >>>> I don't know why you say the risk of conflicts is greater here than > >>>> with any other update/merge? > >>> > >>> Simply because you're merging a larger set of changes, as you get to > >>> below. > >> > >> As you say, a merge because of a dirty working copy will use > >> > >> * working copy parent (base) > >> * dirty working copy (local) > >> * update target (other) > >> > >> That ought to be an easy merge regardless of the update target since > >> the difference between base and local is "small". > >> > >> I say "small" because I expect the diff present in the dirty working > >> copy to be one commit. That is much smaller than most branch merges > >> where the distance from local/other to base is 10, 100 or more > >> commits. > > > > I was assuming that a cross-branch update would use: > > > > * common ancestor of target and WC (base) > > * dirty working copy (local) > > * update target on other branch (other) > > > > Is this not what the patch does? > > I don't know this code well, but I think you're suggesting the wrong > ancestor: using the common ancestor of target and WC for a three-way > merge will make you merge the entire *branch* from "base" into "other". > > You only want to merge the changes since the working copy parent, and > the working copy. For that you need the base to be the working copy > parent. > > This is really a matter of committing the working copy, grafting the > commit to the target revision and uncommitting it again. I once made an > ASCII art graph of how I believe graft works: > > http://stackoverflow.com/a/9605306/110204 > > I hope someone will correct me if I'm confused here :) Martin, Yes you are right, all the patch does is pa = p1, where pa provides the ancestor to the merge engine and p1 is the parent of the working copy. It just extends what the linear case already does. I think one of the tricky point is that there is currently no easy way to revert from a working copy merge, even in the linear case. Either we document your trick, or we try to provide a more intuitive way. I am going to look how to tackle that one. Once we have that, we may rediscuss whether we can allow merge of the working copy by default when crossing branches. Regards. Gilles. From mads at kiilerich.com Thu Feb 28 08:15:10 2013 From: mads at kiilerich.com (Mads Kiilerich) Date: Thu, 28 Feb 2013 15:15:10 +0100 Subject: [PATCH] tests: work around msys bash mangling of paths in test-mq.t In-Reply-To: <89602c1c69202073a978.1361910894@mk-desktop> References: <89602c1c69202073a978.1361910894@mk-desktop> Message-ID: <512F666E.7010609@kiilerich.com> On 02/26/2013 09:34 PM, Mads Kiilerich wrote: > # HG changeset patch > # User Mads Kiilerich > # Date 1361909090 -3600 > # Node ID 89602c1c69202073a978eab5ce22f7a307c274ad > # Parent 2c246fef46d1f70b088284dafa00b0911920949f > tests: work around msys bash mangling of paths in test-mq.t > crewed /Mads From mads at kiilerich.com Thu Feb 28 08:16:00 2013 From: mads at kiilerich.com (Mads Kiilerich) Date: Thu, 28 Feb 2013 15:16:00 +0100 Subject: [PATCH 1 of 9 stable] largefiles: fix off-by-one error on pull --all-largefiles In-Reply-To: <7f0cd251905074b0aec1.1361846481@mk-desktop> References: <7f0cd251905074b0aec1.1361846481@mk-desktop> Message-ID: <512F66A0.3070103@kiilerich.com> series pushed to crew stable /Mads From hg at intevation.org Thu Feb 28 22:00:09 2013 From: hg at intevation.org (Mercurial Commits) Date: Fri, 01 Mar 2013 05:00:09 +0100 Subject: mercurial@18742: 6 new changesets (3 stable) Message-ID: <1362110409.525671.19675.nullmailer@hg.intevation.org> 6 new changesets (3 stable) in mercurial: http://selenic.com/repo/hg//rev/56f8522c3591 changeset: 18737:56f8522c3591 parent: 18667:f12804d3ff80 user: Matt Mackall date: Sun Feb 17 14:34:53 2013 -0600 summary: httppeer: improve protocol check http://selenic.com/repo/hg//rev/b376e8f91c16 changeset: 18738:b376e8f91c16 user: Matt Mackall date: Sun Feb 17 14:41:31 2013 -0600 summary: httppeer: avoid large dumps when we don't see an hgweb repo http://selenic.com/repo/hg//rev/5b7175377bab changeset: 18739:5b7175377bab branch: stable tag: 2.5.2 parent: 18730:a5d33446e46c user: Matt Mackall date: Thu Feb 28 21:29:31 2013 -0600 summary: setparents: drop copies from dropped p2 (issue3843) http://selenic.com/repo/hg//rev/6f002b142f9b changeset: 18740:6f002b142f9b branch: stable user: Matt Mackall date: Thu Feb 28 21:53:04 2013 -0600 summary: Added tag 2.5.2 for changeset 5b7175377bab http://selenic.com/repo/hg//rev/605c7c94fd70 changeset: 18741:605c7c94fd70 branch: stable user: Matt Mackall date: Thu Feb 28 21:53:13 2013 -0600 summary: Added signature for changeset 5b7175377bab http://selenic.com/repo/hg//rev/a07be8953733 changeset: 18742:a07be8953733 tag: tip parent: 18736:af9ddea2cb99 parent: 18738:b376e8f91c16 user: Matt Mackall date: Thu Feb 28 21:58:37 2013 -0600 summary: merge with crew -- Repository URL: http://selenic.com/repo/hg/ From hgbuildbot at kublai.com Thu Feb 28 22:24:04 2013 From: hgbuildbot at kublai.com (hgbuildbot at kublai.com) Date: Thu, 28 Feb 2013 20:24:04 -0800 Subject: buildbot success in Mercurial on hg tests (stable) Message-ID: <20130301042406.56D0C25A5E@hgbuildbot.cs.ubc.ca> The Buildbot has detected a restored build on builder hg tests (stable) while building hg. Full details are available at: http://hgbuildbot.kublai.com/builders/hg%20tests%20%28stable%29/builds/307 Buildbot URL: http://hgbuildbot.kublai.com/ Buildslave for this Build: p64.osuosl.test Build Reason: scheduler Build Source Stamp: [branch stable] 605c7c94fd70dcdb2ed695e8420e6ddae10a3a5b Blamelist: Matt Mackall Build succeeded! sincerely, -The Buildbot From hgbuildbot at kublai.com Thu Feb 28 22:38:38 2013 From: hgbuildbot at kublai.com (hgbuildbot at kublai.com) Date: Thu, 28 Feb 2013 20:38:38 -0800 Subject: buildbot success in Mercurial on python-hglib Message-ID: <20130301043839.2704725F72@hgbuildbot.cs.ubc.ca> The Buildbot has detected a restored build on builder python-hglib while building hg. Full details are available at: http://hgbuildbot.kublai.com/builders/python-hglib/builds/823 Buildbot URL: http://hgbuildbot.kublai.com/ Buildslave for this Build: l6 Build Reason: scheduler Build Source Stamp: [branch stable] 605c7c94fd70dcdb2ed695e8420e6ddae10a3a5b Blamelist: Matt Mackall Build succeeded! sincerely, -The Buildbot From durham at fb.com Thu Feb 28 12:15:30 2013 From: durham at fb.com (Durham Goode) Date: Thu, 28 Feb 2013 10:15:30 -0800 Subject: [PATCH] blackbox: fix exception when logging commands with format characters Message-ID: # HG changeset patch # User Durham Goode # Date 1362075146 28800 # Thu Feb 28 10:12:26 2013 -0800 # Node ID adbb2ebc035ecae18b8eaa1777363314d522728d # Parent 4bfd54a664a497c3a51623c2dc8edba7bbd836a5 blackbox: fix exception when logging commands with format characters When running commands like 'hg export -o mypatch-%N.patch', the blackbox would throw an exception because it tried to format %N. This change prevents it from trying to format the command string. diff --git a/mercurial/dispatch.py b/mercurial/dispatch.py --- a/mercurial/dispatch.py +++ b/mercurial/dispatch.py @@ -737,7 +737,7 @@ ui.warn(_("warning: --repository ignored\n")) msg = ' '.join(' ' in a and repr(a) or a for a in fullargs) - ui.log("command", msg + "\n") + ui.log("command", '%s\n', msg) d = lambda: util.checksignature(func)(ui, *args, **cmdoptions) starttime = time.time() ret = None From durham at fb.com Thu Feb 28 23:02:11 2013 From: durham at fb.com (Durham Goode) Date: Fri, 1 Mar 2013 05:02:11 +0000 Subject: [PATCH] blackbox: fix exception when logging commands with format characters In-Reply-To: References: Message-ID: <2B10A89294DA6740AC6155F56842F9CE081C9C46@PRN-MBX02-2.TheFacebook.com> This patch is the exact same as the other patch email that got sent out. I sent it again when I thought it was lost due to the server outage. ________________________________________ From: mercurial-devel-bounces at selenic.com [mercurial-devel-bounces at selenic.com] on behalf of Durham Goode [durham at fb.com] Sent: Thursday, February 28, 2013 10:15 AM To: mercurial-devel at selenic.com Subject: [PATCH] blackbox: fix exception when logging commands with format characters # HG changeset patch # User Durham Goode # Date 1362075146 28800 # Thu Feb 28 10:12:26 2013 -0800 # Node ID adbb2ebc035ecae18b8eaa1777363314d522728d # Parent 4bfd54a664a497c3a51623c2dc8edba7bbd836a5 blackbox: fix exception when logging commands with format characters When running commands like 'hg export -o mypatch-%N.patch', the blackbox would throw an exception because it tried to format %N. This change prevents it from trying to format the command string. diff --git a/mercurial/dispatch.py b/mercurial/dispatch.py --- a/mercurial/dispatch.py +++ b/mercurial/dispatch.py @@ -737,7 +737,7 @@ ui.warn(_("warning: --repository ignored\n")) msg = ' '.join(' ' in a and repr(a) or a for a in fullargs) - ui.log("command", msg + "\n") + ui.log("command", '%s\n', msg) d = lambda: util.checksignature(func)(ui, *args, **cmdoptions) starttime = time.time() ret = None _______________________________________________ Mercurial-devel mailing list Mercurial-devel at selenic.com http://selenic.com/mailman/listinfo/mercurial-devel From marc.strapetz at syntevo.com Thu Feb 28 04:57:47 2013 From: marc.strapetz at syntevo.com (Marc Strapetz) Date: Thu, 28 Feb 2013 11:57:47 +0100 Subject: blame confusion Message-ID: <512F382B.2000801@syntevo.com> When it comes to blaming merge revisions, I do not understand Mercurial's behavior (version 2.4.2). I've created a file with contents: 1 2 3 at r0 and immediately forked 'branch'. In 'branch', the file is modified to: 1 2x (at r1) 3y (at r7) In 'default', many lines have been added to the beginning of the file, and finally similar lines to "1","2","3" again: 1 (at r5) 2x (at r6) 3y (at r6) . . . 1 2 3 Finally, 'branch' is merged to 'default' at r8, resulting in: 1 2x 3y . . . 1 2x 3y So, the last lines have been merged properly, as expected. However a "hg blame" gives something like: 0: 1 <-- should be r5 1: 2x <-- should be r6 7: 3y <-- should be r6 . . . 0: 1 8: 2x <-- yes, merged at r8, however here I'd expect to see "1" 8: 3y <-- the same, here I'd expect to see "7" Is this annotation expected? If so, what is the logic behind this annotation? I can supply a test repository for this scenario. -Marc