D441: revset: optimize "draft() & ::x" pattern
quark updated this revision to Diff 1059. REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D441?vs=1058&id=1059 REVISION DETAIL https://phab.mercurial-scm.org/D441 AFFECTED FILES mercurial/dagop.py mercurial/revset.py mercurial/revsetlang.py tests/test-revset.t CHANGE DETAILS diff --git a/tests/test-revset.t b/tests/test-revset.t --- a/tests/test-revset.t +++ b/tests/test-revset.t @@ -4511,3 +4511,173 @@ $ hg log -r 'successors(B+A)-contentdivergent()-obsolete()' -T '{desc}\n' Z + +Test `draft() & ::x` optimization + + $ hg init $TESTTMP/repo2 + $ cd $TESTTMP/repo2 + $ hg debugdrawdag <<'EOS' + > P5 S1 + >| | + > S2 | D3 + > \|/ + > P4 + >| + > P3 D2 + >| | + > P2 D1 + >|/ + > P1 + >| + > P0 + > EOS + $ hg phase --public -r P4+P5 + $ hg phase --force --secret -r S1+S2 + $ hg log -G -T '{rev} {desc} {phase}' -r 'sort(all(), topo, topo.firstbranch=P5)' + o 8 P5 public + | + | o 10 S1 secret + | | + | o 7 D3 draft + |/ + | o 9 S2 secret + |/ + o 6 P4 public + | + o 5 P3 public + | + o 3 P2 public + | + | o 4 D2 draft + | | + | o 2 D1 draft + |/ + o 1 P1 public + | + o 0 P0 public + + $ hg debugrevspec --verify -p analyzed -p optimized 'draft() & ::(((S1+D1+P5)-D3)+S2)' + * analyzed: + (and +(func + ('symbol', 'draft') + None + define) +(func + ('symbol', 'ancestors') + (or +(list + (and +(or + (list +('symbol', 'S1') +('symbol', 'D1') +('symbol', 'P5')) + define) +(not + ('symbol', 'D3') + follow) +define) + ('symbol', 'S2')) +define) + follow) +define) + * optimized: + (func +('symbol', '_phaseandancestors') +(list + ('string', 'draft') + (or +(list + (difference +(func + ('symbol', '_list') + ('string', 'S1\x00D1\x00P5') + define) +('symbol', 'D3') +define) + ('symbol', 'S2')) +define)) +define) + $ hg debugrevspec --verify -p analyzed -p optimized 'secret() & ::9' + * analyzed: + (and +(func + ('symbol', 'secret') + None + define) +(func + ('symbol', 'ancestors') + ('symbol', '9') + follow) +define) + * optimized: + (func +('symbol', '_phaseandancestors') +(list + ('string', 'secret') + ('symbol', '9')) +define) + $ hg debugrevspec --verify -p analyzed -p optimized '(not public()) & ::(tag())' + * analyzed: + (and +(not + (func +('symbol', 'public') +None +any) + define) +(func + ('symbol', 'ancestors') + (func +('symbol', 'tag') +None +define) + follow) +define) + * optimized: + (func +('symbol', '_phaseandancestors') +(list + ('string', '_notpublic') + (func +('symbol', 'tag') +None +define)) +define) + $ hg debugrevspec --verify -p optimized '(not public()) & ancestors(S1+D2+P5, 1)' + * optimized: + (and +(func + ('symbol', '_notpublic') + None + any) +(func + ('symbol', 'ancestors') + (list +(func + ('symbol', '_list') + ('string', 'S1\x00D2\x00P5') + define) +('symbol', '1')) + follow) +define) + $ hg debugrevspec --verify -p optimized '(not public()) & ancestors(S1+D2+P5, depth=1)' + * optimized: + (and +(func + ('symbol', '_notpublic') + None + any) +(func + ('symbol', 'ancestors') + (list +(func + ('symbol', '_list') + ('string', 'S1\x00D2\x00P5') + define) +(keyvalue + ('symbol', 'depth') + ('symbol', '1'))) + follow) +define) diff --git a/mercurial/revsetlang.py b/mercurial/revsetlang.py --- a/mercurial/revsetlang.py +++ b/mercurial/revsetlang.py @@ -313,6 +313,49 @@ if _isposargs(ta, 1) and _isposargs(tb, 1): return ('list', ta, tb) +def _matchtree(tree, pattern): +"""like re.match, return matched patterns or None if not matched + +A fixed string matches a fixed string. A lambda matches and captures things +if it returns True. A tuple will trigger a recursive match on its elements. +Return a list of captured subtrees. + +>>> t = lambda x: True +>>> _matchtree(parse('A'), ('symbol', 'A')) +[] +>>> _matchtree(parse('A'), ('symbol', ('A',))) +>>> _matchtree(parse('A'), ('symbol', 'A', 'B')) +>>> _matchtree(parse('A'), ('func', 'A')) +>>> _matchtree(parse('A'), ('symbol')) +>>> _matchtree(parse('A'), 'A') +>>> _matchtree(parse('A'), t) +[('symbol', 'A')] +>>> _matchtree(parse('A'), (t, lambda x: x == 'A')) +['symbol', 'A'] +>>> _ma
D441: revset: optimize "draft() & ::x" pattern
martinvonz added a comment. I'll review in more detail later, but just a quick comment for now INLINE COMMENTS > revset.py:1554 > +def keepfunc(rev): > +return getphase(repo, rev) in selectedphases > + Isn't "getphase(repo,rev) >= keepphase" more natural? You'd then replace phasenamemap by something like minphase = { '_notpublic': draft, 'draft': draft, 'secret': secret, } REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D441 To: quark, #hg-reviewers Cc: martinvonz, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D441: revset: optimize "draft() & ::x" pattern
quark updated this revision to Diff 1058. REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D441?vs=1057&id=1058 REVISION DETAIL https://phab.mercurial-scm.org/D441 AFFECTED FILES mercurial/dagop.py mercurial/revset.py mercurial/revsetlang.py tests/test-revset.t CHANGE DETAILS diff --git a/tests/test-revset.t b/tests/test-revset.t --- a/tests/test-revset.t +++ b/tests/test-revset.t @@ -4511,3 +4511,165 @@ $ hg log -r 'successors(B+A)-contentdivergent()-obsolete()' -T '{desc}\n' Z + +Test `draft() & ::x` optimization + + $ hg init $TESTTMP/repo2 + $ cd $TESTTMP/repo2 + $ hg debugdrawdag <<'EOS' + > P5 S1 + >| | + > S2 | D3 + > \|/ + > P4 + >| + > P3 D2 + >| | + > P2 D1 + >|/ + > P1 + >| + > P0 + > EOS + $ hg phase --public -r P4+P5 + $ hg phase --force --secret -r S1+S2 + $ hg log -G -T '{rev} {desc} {phase}' -r 'sort(all(), topo, topo.firstbranch=P5)' + o 8 P5 public + | + | o 10 S1 secret + | | + | o 7 D3 draft + |/ + | o 9 S2 secret + |/ + o 6 P4 public + | + o 5 P3 public + | + o 3 P2 public + | + | o 4 D2 draft + | | + | o 2 D1 draft + |/ + o 1 P1 public + | + o 0 P0 public + + $ hg debugrevspec --verify -p analyzed -p optimized 'draft() & ::((S1+D1+P5)-D3)' + * analyzed: + (and +(func + ('symbol', 'draft') + None + define) +(func + ('symbol', 'ancestors') + (and +(or + (list +('symbol', 'S1') +('symbol', 'D1') +('symbol', 'P5')) + define) +(not + ('symbol', 'D3') + follow) +define) + follow) +define) + * optimized: + (func +('symbol', '_phaseandancestors') +(list + ('string', 'draft') + (difference +(func + ('symbol', '_list') + ('string', 'S1\x00D1\x00P5') + define) +('symbol', 'D3') +define)) +define) + $ hg debugrevspec --verify -p analyzed -p optimized 'secret() & ::(7::)' + * analyzed: + (and +(func + ('symbol', 'secret') + None + define) +(func + ('symbol', 'ancestors') + (func +('symbol', 'descendants') +('symbol', '7') +define) + follow) +define) + * optimized: + (func +('symbol', '_phaseandancestors') +(list + ('string', 'secret') + (func +('symbol', 'descendants') +('symbol', '7') +define)) +define) + $ hg debugrevspec --verify -p analyzed -p optimized '(not public()) & ::(S1)' + * analyzed: + (and +(not + (func +('symbol', 'public') +None +any) + define) +(func + ('symbol', 'ancestors') + ('symbol', 'S1') + follow) +define) + * optimized: + (func +('symbol', '_phaseandancestors') +(list + ('string', '_notpublic') + ('symbol', 'S1')) +define) + $ hg debugrevspec --verify -p optimized '(not public()) & ancestors(S1+D2+P5, 1)' + * optimized: + (and +(func + ('symbol', '_notpublic') + None + any) +(func + ('symbol', 'ancestors') + (list +(func + ('symbol', '_list') + ('string', 'S1\x00D2\x00P5') + define) +('symbol', '1')) + follow) +define) + $ hg debugrevspec --verify -p optimized '(not public()) & ancestors(S1+D2+P5, depth=1)' + * optimized: + (and +(func + ('symbol', '_notpublic') + None + any) +(func + ('symbol', 'ancestors') + (list +(func + ('symbol', '_list') + ('string', 'S1\x00D2\x00P5') + define) +(keyvalue + ('symbol', 'depth') + ('symbol', '1'))) + follow) +define) diff --git a/mercurial/revsetlang.py b/mercurial/revsetlang.py --- a/mercurial/revsetlang.py +++ b/mercurial/revsetlang.py @@ -313,6 +313,49 @@ if _isposargs(ta, 1) and _isposargs(tb, 1): return ('list', ta, tb) +def _matchtree(tree, pattern): +"""like re.match, return matched patterns or None if not matched + +A fixed string matches a fixed string. A lambda matches and captures things +if it returns True. A tuple will trigger a recursive match on its elements. +Return a list of captured subtrees. + +>>> t = lambda x: True +>>> _matchtree(parse('A'), ('symbol', 'A')) +[] +>>> _matchtree(parse('A'), ('symbol', ('A',))) +>>> _matchtree(parse('A'), ('symbol', 'A', 'B')) +>>> _matchtree(parse('A'), ('func', 'A')) +>>> _matchtree(parse('A'), ('symbol')) +>>> _matchtree(parse('A'), 'A') +>>> _matchtree(parse('A'), t) +[('symbol', 'A')] +>>> _matchtree(parse('A'), (t, lambda x: x == 'A')) +['symbol', 'A'] +>>> _matchtree(parse('A'), (t, lambda x: x == 'B')) +>>> _matchtree(parse('A+B'), ('or', ('list', t, ('symbol', t +[('symbol', 'A'), 'B'] +""" +matchedlist = [] +if
D441: revset: optimize "draft() & ::x" pattern
quark updated this revision to Diff 1057. REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D441?vs=1056&id=1057 REVISION DETAIL https://phab.mercurial-scm.org/D441 AFFECTED FILES mercurial/dagop.py mercurial/revset.py mercurial/revsetlang.py tests/test-revset.t CHANGE DETAILS diff --git a/tests/test-revset.t b/tests/test-revset.t --- a/tests/test-revset.t +++ b/tests/test-revset.t @@ -4511,3 +4511,165 @@ $ hg log -r 'successors(B+A)-contentdivergent()-obsolete()' -T '{desc}\n' Z + +Test `draft() & ::x` optimization + + $ hg init $TESTTMP/repo2 + $ cd $TESTTMP/repo2 + $ hg debugdrawdag <<'EOS' + > P5 S1 + >| | + > S2 | D3 + > \|/ + > P4 + >| + > P3 D2 + >| | + > P2 D1 + >|/ + > P1 + >| + > P0 + > EOS + $ hg phase --public -r P4+P5 + $ hg phase --force --secret -r S1+S2 + $ hg log -G -T '{rev} {desc} {phase}' -r 'sort(all(), topo, topo.firstbranch=P5)' + o 8 P5 public + | + | o 10 S1 secret + | | + | o 7 D3 draft + |/ + | o 9 S2 secret + |/ + o 6 P4 public + | + o 5 P3 public + | + o 3 P2 public + | + | o 4 D2 draft + | | + | o 2 D1 draft + |/ + o 1 P1 public + | + o 0 P0 public + + $ hg debugrevspec --verify -p analyzed -p optimized 'draft() & ::((S1+D1+P5)-D3)' + * analyzed: + (and +(func + ('symbol', 'draft') + None + define) +(func + ('symbol', 'ancestors') + (and +(or + (list +('symbol', 'S1') +('symbol', 'D1') +('symbol', 'P5')) + define) +(not + ('symbol', 'D3') + follow) +define) + follow) +define) + * optimized: + (func +('symbol', '_phaseandancestors') +(list + ('string', 'draft') + (difference +(func + ('symbol', '_list') + ('string', 'S1\x00D1\x00P5') + define) +('symbol', 'D3') +define)) +define) + $ hg debugrevspec --verify -p analyzed -p optimized 'secret() & ::(7::)' + * analyzed: + (and +(func + ('symbol', 'secret') + None + define) +(func + ('symbol', 'ancestors') + (func +('symbol', 'descendants') +('symbol', '7') +define) + follow) +define) + * optimized: + (func +('symbol', '_phaseandancestors') +(list + ('string', 'secret') + (func +('symbol', 'descendants') +('symbol', '7') +define)) +define) + $ hg debugrevspec --verify -p analyzed -p optimized '(not public()) & ::(S1)' + * analyzed: + (and +(not + (func +('symbol', 'public') +None +any) + define) +(func + ('symbol', 'ancestors') + ('symbol', 'S1') + follow) +define) + * optimized: + (func +('symbol', '_phaseandancestors') +(list + ('string', '_notpublic') + ('symbol', 'S1')) +define) + $ hg debugrevspec --verify -p optimized '(not public()) & ancestors(S1+D2+P5, 1)' + * optimized: + (and +(func + ('symbol', '_notpublic') + None + any) +(func + ('symbol', 'ancestors') + (list +(func + ('symbol', '_list') + ('string', 'S1\x00D2\x00P5') + define) +('symbol', '1')) + follow) +define) + $ hg debugrevspec --verify -p optimized '(not public()) & ancestors(S1+D2+P5, depth=1)' + * optimized: + (and +(func + ('symbol', '_notpublic') + None + any) +(func + ('symbol', 'ancestors') + (list +(func + ('symbol', '_list') + ('string', 'S1\x00D2\x00P5') + define) +(keyvalue + ('symbol', 'depth') + ('symbol', '1'))) + follow) +define) diff --git a/mercurial/revsetlang.py b/mercurial/revsetlang.py --- a/mercurial/revsetlang.py +++ b/mercurial/revsetlang.py @@ -313,6 +313,32 @@ if _isposargs(ta, 1) and _isposargs(tb, 1): return ('list', ta, tb) +def _matchtree(tree, pattern): +"""like re.match, return matched patterns or None if not matched + +A fixed string matches a fixed string. A lambda matches and captures things +if it returns True. A tuple will trigger a recursive match on its elements. +""" +matchedlist = [] +if util.safehasattr(pattern, '__call__'): +matched = pattern(tree) +if matched: +return [tree] +else: +return None +else: +if isinstance(tree, tuple): +if not isinstance(pattern, tuple) or len(tree) != len(pattern): +return None +for i, t in enumerate(tree): +matched = _matchtree(t, pattern[i]) +if matched is None: +return None +matchedlist.extend(matched) +elif tree != pattern: +return None +return matchedlist + def _fixops(x): """Rewrite raw parsed tr
D441: revset: optimize "draft() & ::x" pattern
quark created this revision. Herald added a subscriber: mercurial-devel. Herald added a reviewer: hg-reviewers. REVISION SUMMARY The `draft() & ::x` type query could be common for selecting one or more draft feature branches being worked on. Before this patch, `::x` may travel though the changelog DAG for a long distance until it gets a smaller revision number than `min(draft())`, which means the smallest revision in `draft()` basically decides the time needed to calculate the revset. It could be slow on long changelog with distant drafts. This patch adds a fast path for this situation, and will stop traveling the changelog DAG once `::x` hits a non-draft revision. The fast path also works for `secret()` and `not public()`. To measure the performance difference, I used drawdag to create a repo that emulates distant drafts: DRAFT4 | DRAFT3 # draft / PUBLIC # public | PUBLIC9998 | . DRAFT2 .| . DRAFT1 # draft | / PUBLIC0001 # public And measured the performance using the repo: 1. before $ hg perfrevset 'draft() & ::(DRAFT2+DRAFT4)' ! wall 0.017132 comb 0.01 user 0.01 sys 0.00 (best of 156) $ hg perfrevset 'draft() & ::(all())' ! wall 0.024221 comb 0.03 user 0.03 sys 0.00 (best of 113) 2. after $ hg perfrevset 'draft() & ::(DRAFT2+DRAFT4)' ! wall 0.000243 comb 0.00 user 0.00 sys 0.00 (best of 9303) $ hg perfrevset 'draft() & ::(all())' ! wall 0.004319 comb 0.00 user 0.00 sys 0.00 (best of 655) REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D441 AFFECTED FILES mercurial/dagop.py mercurial/revset.py mercurial/revsetlang.py tests/test-revset.t CHANGE DETAILS diff --git a/tests/test-revset.t b/tests/test-revset.t --- a/tests/test-revset.t +++ b/tests/test-revset.t @@ -4511,3 +4511,177 @@ $ hg log -r 'successors(B+A)-contentdivergent()-obsolete()' -T '{desc}\n' Z + +Test `draft() & ::x` optimization + + $ hg init $TESTTMP/repo2 + $ cd $TESTTMP/repo2 + $ hg debugdrawdag <<'EOS' + > P5 S1 + >| | + > S2 | D3 + > \|/ + > P4 + >| + > P3 D2 + >| | + > P2 D1 + >|/ + > P1 + >| + > P0 + > EOS + $ hg phase --public -r P4+P5 + $ hg phase --force --secret -r S1+S2 + $ hg log -G -T '{rev} {desc} {phase}' -r 'sort(all(), topo, topo.firstbranch=P5)' + o 8 P5 public + | + | o 10 S1 secret + | | + | o 7 D3 draft + |/ + | o 9 S2 secret + |/ + o 6 P4 public + | + o 5 P3 public + | + o 3 P2 public + | + | o 4 D2 draft + | | + | o 2 D1 draft + |/ + o 1 P1 public + | + o 0 P0 public + + $ hg debugrevspec --verify -p analyzed -p optimized 'draft() & ::((S1+D1+P5)-D3)' + * analyzed: + (and +(func + ('symbol', 'draft') + None + define) +(func + ('symbol', 'ancestors') + (and +(or + (list +('symbol', 'S1') +('symbol', 'D1') +('symbol', 'P5')) + define) +(not + ('symbol', 'D3') + follow) +define) + follow) +define) + * optimized: + (func +('symbol', '_phaseandancestors') +(list + ('string', 'draft') + (difference +(func + ('symbol', '_list') + ('string', 'S1\x00D1\x00P5') + define) +('symbol', 'D3') +define)) +define) + $ hg debugrevspec --verify -p analyzed -p optimized 'secret() & ::(S2+S1+D2+P5)' + * analyzed: + (and +(func + ('symbol', 'secret') + None + define) +(func + ('symbol', 'ancestors') + (or +(list + ('symbol', 'S2') + ('symbol', 'S1') + ('symbol', 'D2') + ('symbol', 'P5')) +define) + follow) +define) + * optimized: + (func +('symbol', '_phaseandancestors') +(list + ('string', 'secret') + (func +('symbol', '_list') +('string', 'S2\x00S1\x00D2\x00P5') +define)) +define) + $ hg debugrevspec --verify -p analyzed -p optimized '(not public()) & ::(S2+S1+D2+P5)' + * analyzed: + (and +(not + (func +('symbol', 'public') +None +any) + define) +(func + ('symbol', 'ancestors') + (or +(list + ('symbol', 'S2') + ('symbol', 'S1') + ('symbol', 'D2') + ('symbol', 'P5')) +define) + follow) +define) + * optimized: + (func +('symbol', '_phaseandancestors') +(list + ('string', '_notpublic') + (func +('symbol', '_list') +('string', 'S2\x00S1\x00D2\x00P5') +define)) +define) + $ hg debugrevspec --verify -p optimized '(not public()) & ancestors(S1+D2+P5, 1)' + * optimized: + (and +(func + ('symbol', '_notpublic') + None + any) +(func + ('
D440: exchange: don't attempt phase exchange if phase-heads was in bundle
martinvonz created this revision. Herald added a subscriber: mercurial-devel. Herald added a reviewer: hg-reviewers. REVISION SUMMARY The Mercurial core server doesn't yet include phase-heads parts in the bundle, but our Google-internal server wants to do that. Unfortunately, the usual exchange still happens even if phase-heads part is included (including the short-circuited one for old/publishing servers). That means that even if our server (again, the Google-internal one, but also future Mercurial core servers) includes a phase-heads part to indicate that some heads should be drafts, that would still get overwritten by the phase updating that happens after. So let's fix that by marking the phase step done if we receive at least one phase-heads part in the bundle. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D440 AFFECTED FILES mercurial/bundle2.py mercurial/exchange.py CHANGE DETAILS diff --git a/mercurial/exchange.py b/mercurial/exchange.py --- a/mercurial/exchange.py +++ b/mercurial/exchange.py @@ -1389,6 +1389,10 @@ if pullop.fetch: pullop.cgresult = bundle2.combinechangegroupresults(op) +# If the bundle had a phase-heads part, then phase exchange is already done +if op.records['phase-heads']: +pullop.stepsdone.add('phases') + # processing phases change for namespace, value in op.records['listkeys']: if namespace == 'phases': diff --git a/mercurial/bundle2.py b/mercurial/bundle2.py --- a/mercurial/bundle2.py +++ b/mercurial/bundle2.py @@ -1815,6 +1815,7 @@ """apply phases from bundle part to repo""" headsbyphase = _readphaseheads(inpart) phases.updatephases(op.repo.unfiltered(), op.gettransaction(), headsbyphase) +op.records.add('phase-heads', {}) @parthandler('reply:pushkey', ('return', 'in-reply-to')) def handlepushkeyreply(op, inpart): To: martinvonz, #hg-reviewers Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Re: Fwd: Dropping Support for Python 2.6
(Adding Mercurial-devel mailing list, as I'm not sure if anyone is actually using mercurial-infrastructure@) On 08-08-17 09:21, Mathias De Maré wrote: On 04-05-17 16:36, Anton Shestakov wrote: On Tue, 2 May 2017 20:30:07 +0200 Pierre-Yves David wrote: So, we are already operating a repository at: https://www.mercurial-scm.org/release/ And we already have all the necessary bits in our current make file to create and update it such repository. As pointed in the previous section, these repositories have users, since they complains when it broke. The builder use to run on some of my hardware in the USA, the thing when down for some time when I moved back to France (since the hardward spent months in cardbox). It went back online a bit last year but the build broken again a handful of month ago. I did not had time to fix it for good since then. I've been running this in pure good will for a couple of year but I'm not a user of it. I would also be happy to free the hardware for other usage. So I'm not planning to fix this short terms. Other member of the community (Anton for one, in CC) have expressed interested in resurrecting the builder. Maybe it is time to officially hand the thing to whoever wants to do it. Well, it would be good to resurrect it indeed, even if because not building RPMs anymore is clearly a step backwards. We have a wiki page for people who want to help with running tests on different platforms: https://www.mercurial-scm.org/wiki/Buildbot, maybe having some clear instructions on how to set up an RPM builder would inspire someone. I wouldn't mind setting it up on my makeshift home server (an old netbook with Atom CPU), the problem with that is that I don't use RPM-based distros and don't know much about them, and dogfooding is kinda important (e.g. people would need to ping me every time something goes wrong, and probably include a recipe of how to fix it). Incidentally, can't it be done on the current m-s.o infrastructure and not by volunteers? I would be willing to set this up on the existing infrastructure, if I can get access to it. The CentOS builds all work now (once my CentOS 5 patches are in), and we are dogfooding these (not yet on a regular basis, but I hope to change that). Normally, any recent Linux with Docker should be enough to build these. I would very much like to see these builds appear in https://www.mercurial-scm.org/downloads . If it's not possible to do this on the existing infrastructure, I can try to set up a buildbot worker on a server in our company (but since it contacts 'the world', it may take some time to get that accepted). Greetings, Mathias ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D426: obsutil: correct deprecation warning message
ryanmce abandoned this revision. ryanmce added a comment. I don't pull from committed usually. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D426 To: ryanmce, #hg-reviewers Cc: lothiraldan, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D379: simplemerge: use context paths for default labels instead of file paths
phillco added a comment. Blocked on https://phab.mercurial-scm.org/D378. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D379 To: phillco, #hg-reviewers Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D379: simplemerge: use context paths for default labels instead of file paths
phillco updated this revision to Diff 1039. REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D379?vs=860&id=1039 REVISION DETAIL https://phab.mercurial-scm.org/D379 AFFECTED FILES mercurial/simplemerge.py CHANGE DETAILS diff --git a/mercurial/simplemerge.py b/mercurial/simplemerge.py --- a/mercurial/simplemerge.py +++ b/mercurial/simplemerge.py @@ -461,8 +461,8 @@ mode = opts.get('mode','merge') name_a, name_b, name_base = None, None, None if mode != 'union': -name_a, name_b, name_base = _picklabels([localfile, - otherfile, None], +name_a, name_b, name_base = _picklabels([localctx.path(), + otherctx.path(), None], opts.get('label', [])) try: To: phillco, #hg-reviewers Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D383: simplemerge: simplify code now that we always write to a context
phillco updated this revision to Diff 1043. REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D383?vs=864&id=1043 REVISION DETAIL https://phab.mercurial-scm.org/D383 AFFECTED FILES mercurial/simplemerge.py CHANGE DETAILS diff --git a/mercurial/simplemerge.py b/mercurial/simplemerge.py --- a/mercurial/simplemerge.py +++ b/mercurial/simplemerge.py @@ -436,17 +436,6 @@ # repository usually sees) might be more useful. return _verifytext(ctx.decodeddata(), ctx.path(), ui, opts) -class ctxwriter(object): -def __init__(self, ctx): -self.ctx = ctx -self.text = "" - -def write(self, text): -self.text += text - -def close(self): -self.ctx.write(self.text, self.ctx.flags()) - mode = opts.get('mode','merge') name_a, name_b, name_base = None, None, None if mode != 'union': @@ -461,11 +450,6 @@ except error.Abort: return 1 -if opts.get('print'): -out = ui.fout -else: -out = ctxwriter(localctx) - m3 = Merge3Text(basetext, localtext, othertext) extrakwargs = { "localorother": opts.get("localorother", None), @@ -479,12 +463,17 @@ extrakwargs['base_marker'] = '|||' extrakwargs['name_base'] = name_base extrakwargs['minimize'] = False + +mergedtext = "" for line in m3.merge_lines(name_a=name_a, name_b=name_b, **pycompat.strkwargs(extrakwargs)): -out.write(line) +if opts.get('print'): +ui.fout.write(line) +else: +mergedtext += line if not opts.get('print'): -out.close() +localctx.write(mergedtext, localctx.flags()) if m3.conflicts and not mode == 'union': return 1 To: phillco, #hg-reviewers Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D381: simplemerge: stop accepting, and passing, file parameters
phillco updated this revision to Diff 1041. REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D381?vs=862&id=1041 REVISION DETAIL https://phab.mercurial-scm.org/D381 AFFECTED FILES contrib/simplemerge mercurial/filemerge.py mercurial/simplemerge.py CHANGE DETAILS diff --git a/mercurial/simplemerge.py b/mercurial/simplemerge.py --- a/mercurial/simplemerge.py +++ b/mercurial/simplemerge.py @@ -419,8 +419,8 @@ return [name_a, name_b, name_base] -def simplemerge(ui, localfile, basefile, otherfile, -localctx=None, basectx=None, otherctx=None, repo=None, **opts): +def simplemerge(ui, localctx=None, basectx=None, otherctx=None, repo=None, +**opts): """Performs the simplemerge algorithm. {local|base|other}ctx are optional. If passed, they (local/base/other) will diff --git a/mercurial/filemerge.py b/mercurial/filemerge.py --- a/mercurial/filemerge.py +++ b/mercurial/filemerge.py @@ -353,7 +353,7 @@ labels = _defaultconflictlabels if len(labels) < 3: labels.append('base') -r = simplemerge.simplemerge(ui, a, b, c, fcd, fca, fco, +r = simplemerge.simplemerge(ui, fcd, fca, fco, quiet=True, label=labels, repo=repo) if not r: ui.debug(" premerge successful\n") @@ -384,7 +384,7 @@ ui = repo.ui -r = simplemerge.simplemerge(ui, a, b, c, fcd, fca, fco, +r = simplemerge.simplemerge(ui, fcd, fca, fco, label=labels, mode=mode, repo=repo) return True, r, False @@ -437,7 +437,7 @@ assert localorother is not None tool, toolpath, binary, symlink = toolconf a, b, c, back = files -r = simplemerge.simplemerge(repo.ui, a, b, c, fcd, fca, fco, +r = simplemerge.simplemerge(repo.ui, fcd, fca, fco, label=labels, localorother=localorother, repo=repo) return True, r diff --git a/contrib/simplemerge b/contrib/simplemerge --- a/contrib/simplemerge +++ b/contrib/simplemerge @@ -77,9 +77,6 @@ raise ParseError(_('wrong number of arguments')) local, base, other = args sys.exit(simplemerge.simplemerge(ui.ui.load(), - local, - base, - other, filebackedctx(local), filebackedctx(base), filebackedctx(other), To: phillco, #hg-reviewers Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D382: simplemerge: make context parameters non-optional
phillco updated this revision to Diff 1042. REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D382?vs=863&id=1042 REVISION DETAIL https://phab.mercurial-scm.org/D382 AFFECTED FILES mercurial/simplemerge.py CHANGE DETAILS diff --git a/mercurial/simplemerge.py b/mercurial/simplemerge.py --- a/mercurial/simplemerge.py +++ b/mercurial/simplemerge.py @@ -419,13 +419,10 @@ return [name_a, name_b, name_base] -def simplemerge(ui, localctx=None, basectx=None, otherctx=None, repo=None, -**opts): +def simplemerge(ui, localctx, basectx, otherctx, repo=None, **opts): """Performs the simplemerge algorithm. -{local|base|other}ctx are optional. If passed, they (local/base/other) will -be read from and the merge result written to (local). You should pass -explicit labels in this mode since the default is to use the file paths. +The merged result is written into `localctx`. """ def readctx(ctx): if not ctx: To: phillco, #hg-reviewers Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D380: simplemerge: stop reading from, and writing to, files
phillco updated this revision to Diff 1040. REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D380?vs=861&id=1040 REVISION DETAIL https://phab.mercurial-scm.org/D380 AFFECTED FILES mercurial/simplemerge.py CHANGE DETAILS diff --git a/mercurial/simplemerge.py b/mercurial/simplemerge.py --- a/mercurial/simplemerge.py +++ b/mercurial/simplemerge.py @@ -18,15 +18,12 @@ from __future__ import absolute_import -import os - from .i18n import _ from . import ( error, mdiff, pycompat, util, -vfs as vfsmod, ) class CantReprocessAndShowBase(Exception): @@ -428,13 +425,8 @@ {local|base|other}ctx are optional. If passed, they (local/base/other) will be read from and the merge result written to (local). You should pass -explicit labels in this mode since the default is to use the file paths.""" -def readfile(filename): -f = open(filename, "rb") -text = f.read() -f.close() -return _verifytext(text, filename, ui, opts) - +explicit labels in this mode since the default is to use the file paths. +""" def readctx(ctx): if not ctx: return None @@ -466,20 +458,16 @@ opts.get('label', [])) try: -localtext = readctx(localctx) if localctx else readfile(localfile) -basetext = readctx(basectx) if basectx else readfile(basefile) -othertext = readctx(otherctx) if otherctx else readfile(otherfile) +localtext = readctx(localctx) +basetext = readctx(basectx) +othertext = readctx(otherctx) except error.Abort: return 1 if opts.get('print'): out = ui.fout -elif localctx: +else: out = ctxwriter(localctx) -else: -localfile = os.path.realpath(localfile) -opener = vfsmod.vfs(os.path.dirname(localfile)) -out = opener(os.path.basename(localfile), "w", atomictemp=True) m3 = Merge3Text(basetext, localtext, othertext) extrakwargs = { To: phillco, #hg-reviewers Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D377: simplemerge: add `filtereddata=False` to simplemerge()
phillco abandoned this revision. phillco added a comment. Abandoned in favor of https://phab.mercurial-scm.org/D434's approach. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D377 To: phillco, #hg-reviewers Cc: durin42, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D434: context: add `decodeddata()` to basefilectx
phillco created this revision. Herald added a subscriber: mercurial-devel. Herald added a reviewer: hg-reviewers. REVISION SUMMARY This will be used as an abstraction by simplemerge to get the data it used to read off the filesystem. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D434 AFFECTED FILES mercurial/context.py CHANGE DETAILS diff --git a/mercurial/context.py b/mercurial/context.py --- a/mercurial/context.py +++ b/mercurial/context.py @@ -1056,6 +1056,13 @@ c = visit.pop(max(visit)) yield c +def decodeddata(self): +"""Returns `data()` after running repository decoding filters. + +This is often equivalent to how the data would be expressed on disk. +""" +return self._repo.wwritedata(self.path(), self.data()) + def _annotatepair(parents, childfctx, child, skipchild, diffopts): r''' Given parent and child fctxes and annotate data for parents, for all lines To: phillco, #hg-reviewers Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D378: contrib: make simplemerge script pass context-like objects
phillco updated this revision to Diff 1038. REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D378?vs=859&id=1038 REVISION DETAIL https://phab.mercurial-scm.org/D378 AFFECTED FILES contrib/simplemerge CHANGE DETAILS diff --git a/contrib/simplemerge b/contrib/simplemerge --- a/contrib/simplemerge +++ b/contrib/simplemerge @@ -41,6 +41,26 @@ for first, second in out_opts: sys.stdout.write(' %-*s %s\n' % (opts_len, first, second)) +class filebackedctx(object): +"""simplemerge requires context-like objects""" +def __init__(self, path): +self._path = path + +def decodeddata(self): +with open(self._path, "rb") as f: +return f.read() + +def flags(self): +return '' + +def path(self): +return self._path + +def write(self, data, flags): +assert not flags +with open(self._path, "w") as f: +f.write(data) + try: for fp in (sys.stdin, sys.stdout, sys.stderr): util.setbinary(fp) @@ -55,7 +75,16 @@ sys.exit(0) if len(args) != 3: raise ParseError(_('wrong number of arguments')) -sys.exit(simplemerge.simplemerge(ui.ui.load(), *args, **opts)) +local, base, other = args +sys.exit(simplemerge.simplemerge(ui.ui.load(), + local, + base, + other, + filebackedctx(local), + filebackedctx(base), + filebackedctx(other), + filtereddata=True, + **opts)) except ParseError as e: sys.stdout.write("%s: %s\n" % (sys.argv[0], e)) showhelp() To: phillco, #hg-reviewers Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D435: simplemerge: use `ctx.decoddeddata()` instead of `repo.wreaddata`
phillco created this revision. Herald added a subscriber: mercurial-devel. Herald added a reviewer: hg-reviewers. REVISION SUMMARY This eliminates the need for the `repo` object. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D435 AFFECTED FILES mercurial/simplemerge.py CHANGE DETAILS diff --git a/mercurial/simplemerge.py b/mercurial/simplemerge.py --- a/mercurial/simplemerge.py +++ b/mercurial/simplemerge.py @@ -438,15 +438,14 @@ def readctx(ctx): if not ctx: return None -if not repo: -raise error.ProgrammingError('simplemerge: repo must be passed if ' - 'using contexts') -# `wwritedata` is used to get the post-filter data from `ctx` (i.e., -# what would have been in the working copy). Since merges were run in -# the working copy, and thus used post-filter data, we do the same to -# maintain behavior. -return repo.wwritedata(ctx.path(), - _verifytext(ctx.data(), ctx.path(), ui, opts)) +# Merges were always run in the working copy before, which means +# they used decoded data, if the user defined any repository +# filters. +# +# Maintain that behavior today for BC, though perhaps in the future +# it'd be worth considering whether merging encoded data (what the +# repository usually sees) might be more useful. +return _verifytext(ctx.decodeddata(), ctx.path(), ui, opts) class ctxwriter(object): def __init__(self, ctx): To: phillco, #hg-reviewers Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
[Bug 5662] New: file copied onto existing file becomes just modified on commit
https://bz.mercurial-scm.org/show_bug.cgi?id=5662 Bug ID: 5662 Summary: file copied onto existing file becomes just modified on commit Product: Mercurial Version: 4.3-rc Hardware: PC OS: Linux Status: UNCONFIRMED Severity: feature Priority: wish Component: Mercurial Assignee: bugzi...@mercurial-scm.org Reporter: martinv...@google.com CC: mercurial-devel@mercurial-scm.org $ echo a > a $ echo b > b $ hg ci -Am initial $ hg cp -f a b $ hg st -C M b a $ hg ci -m 'copy a onto b' $ hg st -C --change . M b -- You are receiving this mail because: You are on the CC list for the bug. ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D351: demandimport: disable if chg is being used
quark added a comment. How about using `sys.argv[0]` to test if chg is being used? Instead of running `hg serve --cmdserver chgunix ...`, chg client executes `chgserve ...`. And the hg script could notice that by checking `sys.argv[0]` and does some special handling (expand it to `hg serve --cmdserver chgunix` for now, but we might want to use a different entry point in the future). REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D351 To: quark, #hg-reviewers, phillco Cc: phillco, sid0, yuja, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D421: hg: move part of top-level logic to dispatch.run
quark added inline comments. INLINE COMMENTS > yuja wrote in hg:30 > This makes the import of `dispatch` non-lazy, right? I thought demandimport was per module, non-recursive. It's obviously recursive. Will change. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D421 To: quark, #hg-reviewers, yuja Cc: yuja, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Re: [PATCH 4 of 8] template: add minimal obsfate template function
On Wed, 2017-08-09 at 22:42 +0900, Yuya Nishihara wrote: > On Tue, 08 Aug 2017 18:48:08 +0200, Boris Feld wrote: > > On Wed, 2017-08-09 at 00:19 +0900, Yuya Nishihara wrote: > > > On Mon, 07 Aug 2017 16:56:23 +0200, Boris Feld wrote: > > > > +@templatekeyword("succsandmarkers") > > > > +def showsuccsandmarkers(repo, ctx, **args): > > > > +"""Returns a list of dict for each final successor of ctx. > > > > + > > > > +The dict contains successors node id in "successors" keys > > > > and > > > > the list of > > > > +obs-markers from ctx to the set of successors in "markers" > > > > +""" > > > > + > > > > +values = obsutil.successorsandmarkers(repo, ctx) > > > > + > > > > +if values is None: > > > > +values = [] > > > > + > > > > +return showlist('succsandmarkers', values, args) > > > > > > I think returning a list of successor nodes is more natural. > > > > > > Can we theoretically gather the relevant markers from successor > > > nodes? > > > If the "markers" field serves just as a cache, it could be stored > > > in > > > revcache[] and passed to obsfate() under the hood. > > > > The current algorithm for computing the successors sets of a > > changeset > > is this one: > > > > Walk the obs-marker graph starting at a given revision. Follow > > successors of each revisions walked until revisions has no more > > successors, they are stable and they are the tip-most successor of > > the > > initial revision. > > > > Having the sets of successors doesn't helps because a successor > > could > > be successor for more than one obsolete revision (fold for > > example). > > Thanks for clarifying that. So markers are tied to each successorset? > > successorssets(rev) -> [(succs0, markers0), (succs1, markers1), > ...] Yes markers are tied to each successorset. > > In which case, {successorsset} could populate markers by makemap(), > > successorssets % "{successorset} {obsmarkers}" > > no idea how this should be rendered, > but > let's revisit it later. I tried modifying successorssets to smuggle the markers via makemap but it has one limitation. In the case of pruned commits, we would have an empty successorsset but at least one marker (the marker for pruning). Adding markers via makemap would make the following condition: if(succsandmarkers, ...) false for pruned markers. I propose to keep succsandmarkers but hex all node ids so we would never see binary information. > > and perhaps obsfate could take the pair explicitly or implicitly. > > successorsets % "{obsfate(successorset, obsmarkers)}" # a function > successorsets % "{obsfate}" # a keyword available only in > successorsets > > obsfate could be even split to verb/users/mindate/maxdate. > > successorsets % "{obsverb} {obsusers} ..." > > these keyword functions may be populated by > makemap(), too. I tried splitting obsfate into several functions and it looks nicer. I prefer functions instead of keywords because keywords feels too magic, do we have already some keywords that are similar (not taking context as inputs) in core? I have a rough series splitting obsfate(succsandmarkers) into obsfateverb(successorset, markers), obsfateusers(successorset, markers), ... Should I finish it and send a V2? > > > The list of markers between a revisions and its successors could be > > cached, I'm not sure how to use revcache for that. Did you meant > > returning a hybrid object like this one, with a non-null revcache > > parameter: https://www.mercurial-scm.org/repo/hg/file/tip/mercurial > > /tem > > platekw.py#l641? > > Something like showlatesttag() or showfile*() was in mind, but > "revcache" > seems not the right tool as the markers aren't bound to the current > rev. ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D426: obsutil: correct deprecation warning message
lothiraldan added a comment. Thx @ryanmce, the fix (https://phab.mercurial-scm.org/D413) should already been pushed to hg-commited, could you try pulling and see if you have it? REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D426 To: ryanmce, #hg-reviewers Cc: lothiraldan, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D426: obsutil: correct deprecation warning message
ryanmce created this revision. Herald added a subscriber: mercurial-devel. Herald added a reviewer: hg-reviewers. REPOSITORY rHG Mercurial BRANCH default REVISION DETAIL https://phab.mercurial-scm.org/D426 AFFECTED FILES mercurial/obsutil.py CHANGE DETAILS diff --git a/mercurial/obsutil.py b/mercurial/obsutil.py --- a/mercurial/obsutil.py +++ b/mercurial/obsutil.py @@ -31,7 +31,7 @@ def precnode(self): msg = ("'marker.precnode' is deprecated, " - "use 'marker.precnode'") + "use 'marker.prednode'") util.nouideprecwarn(msg, '4.4') return self.prednode() To: ryanmce, #hg-reviewers Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D360: log: add a "graphwidth" template variable
This revision was automatically updated to reflect the committed changes. Closed by commit rHG6f6c87888b22: log: add a "graphwidth" template variable (authored by hooper). CHANGED PRIOR TO COMMIT https://phab.mercurial-scm.org/D360?vs=1009&id=1026#toc REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D360?vs=1009&id=1026 REVISION DETAIL https://phab.mercurial-scm.org/D360 AFFECTED FILES mercurial/cmdutil.py mercurial/graphmod.py mercurial/templatekw.py tests/test-command-template.t CHANGE DETAILS diff --git a/tests/test-command-template.t b/tests/test-command-template.t --- a/tests/test-command-template.t +++ b/tests/test-command-template.t @@ -4319,3 +4319,155 @@ custom $ cd .. + +Test 'graphwidth' in 'hg log' on various topologies. The key here is that the +printed graphwidths 3, 5, 7, etc. should all line up in their respective +columns. We don't care about other aspects of the graph rendering here. + + $ hg init graphwidth + $ cd graphwidth + + $ wrappabletext="a a a a a a a a a a a a" + + $ printf "first\n" > file + $ hg add file + $ hg commit -m "$wrappabletext" + + $ printf "first\nsecond\n" > file + $ hg commit -m "$wrappabletext" + + $ hg checkout 0 + 1 files updated, 0 files merged, 0 files removed, 0 files unresolved + $ printf "third\nfirst\n" > file + $ hg commit -m "$wrappabletext" + created new head + + $ hg merge + merging file + 0 files updated, 1 files merged, 0 files removed, 0 files unresolved + (branch merge, don't forget to commit) + + $ hg log --graph -T "{graphwidth}" + @ 3 + | + | @ 5 + |/ + o 3 + + $ hg commit -m "$wrappabletext" + + $ hg log --graph -T "{graphwidth}" + @5 + |\ + | o 5 + | | + o | 5 + |/ + o 3 + + + $ hg checkout 0 + 1 files updated, 0 files merged, 0 files removed, 0 files unresolved + $ printf "third\nfirst\nsecond\n" > file + $ hg commit -m "$wrappabletext" + created new head + + $ hg log --graph -T "{graphwidth}" + @ 3 + | + | o7 + | |\ + +---o 7 + | | + | o 5 + |/ + o 3 + + + $ hg log --graph -T "{graphwidth}" -r 3 + o5 + |\ + ~ ~ + + $ hg log --graph -T "{graphwidth}" -r 1 + o 3 + | + ~ + + $ hg merge + 1 files updated, 0 files merged, 0 files removed, 0 files unresolved + (branch merge, don't forget to commit) + $ hg commit -m "$wrappabletext" + + $ printf "seventh\n" >> file + $ hg commit -m "$wrappabletext" + + $ hg log --graph -T "{graphwidth}" + @ 3 + | + o5 + |\ + | o 5 + | | + o |7 + |\ \ + | o | 7 + | |/ + o / 5 + |/ + o 3 + + +The point of graphwidth is to allow wrapping that accounts for the space taken +by the graph. + + $ COLUMNS=10 hg log --graph -T "{fill(desc, termwidth - graphwidth)}" + @ a a a a + | a a a a + | a a a a + oa a a + |\ a a a + | | a a a + | | a a a + | o a a a + | | a a a + | | a a a + | | a a a + o |a a + |\ \ a a + | | | a a + | | | a a + | | | a a + | | | a a + | o | a a + | |/ a a + | |a a + | |a a + | |a a + | |a a + o | a a a + |/ a a a + |a a a + |a a a + o a a a a + a a a a + a a a a + +Something tricky happens when there are elided nodes; the next drawn row of +edges can be more than one column wider, but the graph width only increases by +one column. The remaining columns are added in between the nodes. + + $ hg log --graph -T "{graphwidth}" -r "0|2|4|5" + o5 + |\ + | \ + | :\ + o : : 7 + :/ / + : o 5 + :/ + o 3 + + + $ cd .. + diff --git a/mercurial/templatekw.py b/mercurial/templatekw.py --- a/mercurial/templatekw.py +++ b/mercurial/templatekw.py @@ -469,6 +469,13 @@ else: return 'o' +@templatekeyword('graphwidth') +def showgraphwidth(repo, ctx, templ, **args): +"""Integer. The width of the graph drawn by 'log --graph' or zero.""" +# The value args['graphwidth'] will be this function, so we use an internal +# name to pass the value through props into this function. +return args.get('_graphwidth', 0) + @templatekeyword('index') def showindex(**args): """Integer. The current iteration of the loop. (0 indexed)""" diff --git a/mercurial/graphmod.py b/mercurial/graphmod.py --- a/mercurial/graphmod.py +++ b/mercurial/graphmod.py @@ -172,7 +172,7 @@ yield (cur, type, data, (col, color), edges) seen = next -def asciiedges(type, char, lines, state, rev, parents): +def asciiedges(type, char, state, rev, parents): """adds edge info to changelog DAG walk suitable for ascii()""" seen = state['seen'] if rev not in seen: @@ -192,6 +192,7 @@ state['edges'][parent] = state['styles'].get(ptype, '|') ncols = len(seen) +width = 1 + ncols * 2 nextseen = seen[:] nextseen[nodeidx:nodeidx + 1] = newparents edges = [(nodeidx, nextseen.index(p)) for p in knownparents] @@ -205,9 +206,9 @@ edges.append((nodeidx, nodeidx)) ed
D351: demandimport: disable if chg is being used
yuja added a comment. Can you update the comment in chgserver.py in new series? It says "CHGINTERNALMARK is temporarily set by chg client to detect if chg will start another chg." REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D351 To: quark, #hg-reviewers, phillco Cc: phillco, sid0, yuja, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D360: log: add a "graphwidth" template variable
yuja accepted this revision. yuja added a comment. This revision is now accepted and ready to land. Slightly adjusted the commit message for new version, and queued, thanks. INLINE COMMENTS > hooper wrote in cmdutil.py:2557 > There can be many of them. E.g. in the hg repo it looks like a couple > hundred with "hg log --graph -r 'tag()'". It just seems easy enough to hedge > against it being expensive, though you might argue premature optimization. Okay, I guess using a list would be slightly faster in common scenario, but I have no strong opinion about this. > graphmod.py:212 > char = '\\' > lines = [] > nodeidx += 1 Removed this `lines` in flight. > graphmod.py:227 > state['edges'].pop(rev, None) > -yield (type, char, lines, (nodeidx, edges, ncols, nmorecols)) > +yield (type, char, width, (nodeidx, edges, ncols, nmorecols)) > Perhaps the `width` can be computed from the `coldata` afterwards, but that wouldn't make much difference. `width = indentation_level * 2 + 1` # graphmod.ascii() indentation_level = max(ncols, ncols + coldiff) for (line, logstr) in zip(lines, text): ln = "%-*s %s" % (2 * indentation_level, "".join(line), logstr) REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D360 To: hooper, #hg-reviewers, yuja Cc: yuja, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D352: chgserver: special handle __version__ in mtimehash (issue5653)
yuja added a comment. I'll drop this per your comment on the issue5653. Thanks for investigating it further. https://bz.mercurial-scm.org/show_bug.cgi?id=5653#c4 REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D352 To: quark, #hg-reviewers Cc: yuja, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D421: hg: move part of top-level logic to dispatch.run
yuja requested changes to this revision. yuja added inline comments. This revision now requires changes to proceed. INLINE COMMENTS > hg:30 > try: > -if sys.version_info[0] < 3 or sys.version_info >= (3, 6): > -import hgdemandimport; hgdemandimport.enable() > +import mercurial.dispatch > except ImportError: This makes the import of `dispatch` non-lazy, right? REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D421 To: quark, #hg-reviewers, yuja Cc: yuja, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Re: [PATCH 1 of 2 STABLE V2] tests: test behavior of IOError during transactions (issue5658)
On Tue, 15 Aug 2017 13:55:01 -0700, Gregory Szorc wrote: > # HG changeset patch > # User Gregory Szorc > # Date 1502741560 25200 > # Mon Aug 14 13:12:40 2017 -0700 > # Branch stable > # Node ID 0d5b565629f0491a7673fcfdd9c02cbc1a4b > # Parent 7686cbb0ba4138c56d038d8d82ccc052bf9b60d7 > tests: test behavior of IOError during transactions (issue5658) Queued for stable, thanks! ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel