Skip to content
Snippets Groups Projects
  1. Jan 24, 2019
    • Boris Feld's avatar
      revlog: make sure we never use sparserevlog without general delta (issue6056) · 189e06b2
      Boris Feld authored
      We are getting user report where the delta code tries to use `sparse-revlog`
      logic on repository where `generaldelta` is disabled. This can't work so we
      ensure the two booleans have a consistent value.
      
      Creating this kind of repository is not expected to be possible the current bug
      report point at a clonebundle related bug that is still to be properly isolated
      (Yuya Nishihara seems to a have done it).
      
      Corrupting a repository to reproduce the issue is possible. A test using this
      method is included in this fix.
      189e06b2
  2. Jan 30, 2019
  3. Jan 23, 2019
  4. Jan 24, 2019
  5. Nov 28, 2018
    • Yuya Nishihara's avatar
      ui: optimize buffered write with no label · ff927ecb
      Yuya Nishihara authored
      This was spotted while making fastannotate faster again after ditching its
      own formatter. Since I'm going to inline _write() into ui.write(), I decided
      to include this patch in this series.
      
      Here, the cost of '(self.label(a, label) for a in args)' was significant
      in hot loops.
      ff927ecb
  6. Jan 23, 2019
    • Boris Feld's avatar
      partialdiscovery: avoid `undecided` related computation sooner than necessary · 76873548
      Boris Feld authored
      Changeset 1d30be90c9dc move the update of the `undecided` set within the
      `partialdiscovery` object in order to clarify the API.
      
      The update to the `undecided` set was unconditional in 1d30be90c9dc and the first
      access to the `self.undecided` property triggered the initial computation of
      the set of undecided revisions. As a result, the set was computed much
      earlier, at a time where less information is available, immediately followed
      by an update of this set to remove common revisions.
      
      To fix this regression, we ignore the `undecided` related logic in
      `addcommons` when that `undecided` set has not been computed yet. Code that
      actually needs to know the `undecided` set will trigger its computation later.
      The change has no effects on semantic because the initial computation
      `undecided` set takes all knowns `common` into account.
      
      Example performance running `hg debugdiscovery` from a pypy repo missing 10
      changesets:
      
      870a89c6909d: 52.3ms (regression parent)
      1d30be90c9dc: 72.0ms (regression)
      5a5f504a7175: 64.8ms (this fix parent)
      this fix:     52.6ms
      76873548
  7. Jan 21, 2019
    • Yuya Nishihara's avatar
      revlog: fix resolution of revlog version 0 · c953c2a9
      Yuya Nishihara authored
      This partially backs out cecf3f8bccd3, "revlog: always process opener options."
      
      My understanding is that if there's no "revlog1" nor "revlog2" in .hg/requires,
      the repository should stick to the v0 format. The reasoning is briefly
      described in 31a5973fcf96, "revlog: get rid of defversion."
      
      Maybe we can drop support for missing opener options, but I didn't do that
      in this patch.
      c953c2a9
  8. Jan 20, 2019
  9. Jan 19, 2019
    • Martin von Zweigbergk's avatar
      narrow: fix crash when restoring backup in legacy repo · 88a7c211
      Martin von Zweigbergk authored
      Using --addremove when committing in an old repo (before we started
      keeping .hg/narrowspec.dirstate) results in a crash. The test
      case modified in this patch would crash like this:
      
        abort: $ENOENT$
      
      The issue is that when the dirstateguard is aborted, it tries to
      restore the backup of .hg/narrowspec.dirstate. However, since we were
      in an old repo, that file did not get created when the dirstateguard
      was created. Note that the dirstateguard is not used unless
      --addremove is passed.
      
      This patch fixes the bug by making restorewcbackup() not fail if the
      backup doesn't exist. I also made clearwcbackup() safe, just in case.
      
      Differential Revision: https://phab.mercurial-scm.org/D5634
      88a7c211
  10. Jan 18, 2019
  11. Jan 19, 2019
  12. Jan 18, 2019
  13. Jan 10, 2019
    • Boris Feld's avatar
      update: fix edge-case with update.atomic-file and read-only files · 593f6359
      Boris Feld authored
      We used to create the tempfile with the original file mode. That means
      creating a read-only tempfile when the original file is read-only, which crash
      if we need to write on the tempfile.
      
      The file in the working directory ends up being writable with and without the
      atomic update config, so the behavior is the same.
      593f6359
  14. Jan 17, 2019
  15. Jan 13, 2019
  16. Sep 26, 2018
  17. Jan 10, 2019
  18. Jan 04, 2019
    • Valentin Gatien-Baron's avatar
      match: support rooted globs in hgignore · 4fab8a7d
      Valentin Gatien-Baron authored
      In a .hgignore, "glob:foo" always means "**/foo". This cannot be
      avoided because there is no syntax like "^" in regexes to say you
      don't want the implied "**/" (of course one can use regexes, but glob
      syntax is nice).
      
      When you have a long list of fairly specific globs like
      path/to/some/thing, this has two consequences:
      1. unintended files may be ignored (not too common though)
      2. matching performance can suffer significantly
        Here is vanilla hg status timing on a private repository:
      
        Using syntax:glob everywhere
        real	0m2.199s
        user	0m1.545s
        sys	0m0.619s
      
        When rooting the appropriate globs
        real	0m1.434s
        user	0m0.847s
        sys	0m0.565s
      
        (tangentially, none of this shows up in --profile's output. It
         seems that C code doesn't play well with profiling)
      
      The code already supports this but there is no syntax to make use of
      it, so it seems reasonable to create such syntax. I create a new
      hgignore syntax "rootglob".
      
      Differential Revision: https://phab.mercurial-scm.org/D5493
      4fab8a7d
  19. Nov 07, 2018
  20. Jan 04, 2019
    • Boris Feld's avatar
      discovery: compute newly discovered missing in a more efficient way · f4277a35
      Boris Feld authored
      Calling "descendants" is expensive, instead, we bound the walk inside the know set
      of undecided revision.
      
      This help with discovery performance:
      
      # without the revset '%ld' improvement
      $ hg perfdiscovery -R pypy-left pypy-right
      before: wall 0.675631 comb 0.680000 user 0.670000 sys 0.010000 (median of 15)
      after:  wall 0.520145 comb 0.530000 user 0.510000 sys 0.020000 (median of 19)
      
      There is another series in flight that greatly improves performances of "%ld"
      substitution in `repo.revs` call. If this changeset is applied above it, we
      see a similar performance boost.
      
      # with the revset '%ld' improvement
      $ hg perfdiscovery -R pypy-left pypy-right
      before: wall 0.477848 comb 0.480000 user 0.480000 sys 0.000000 (median of 22)
      after:  wall 0.404163 comb 0.400000 user 0.400000 sys 0.000000 (median of 24)
      f4277a35
  21. Jan 17, 2019
  22. Jan 14, 2019
    • Boris Feld's avatar
      revsetbenchmark: add more example for roots usages · 41f14e8f
      Boris Feld authored
      We test the `roots` revset in setting similar to our test for `heads`.
      
      Note that the algorithm used for roots can give result without consuming the
      full input set. This provides a significant speedup when testing or accessing
      a single value. We can't just replace it with simple, full algorithm like we
      did for `heads`. See performance number below:
      
      0) roots((tip~100::) - (tip~100::tip))
      1) roots((0::) - (0::tip))
      2) roots(tip~100:)
      3) roots(:42)
      4) roots(not public())
      5) roots((0:tip)::)
      6) roots(0::tip)
      7) 42:68 and roots(42:tip)
      8) roots(0:tip)
      9) roots((:42) + (tip~42:))
      10) roots(all())
      11) roots(-10000:-1)
      12) (-5000:-1000) and roots(-10000:-1)
      13) roots(matching(tip, "author"))
      14) roots(matching(tip, "author")) and -10000:-1
      15) (-10000:-1) and roots(matching(tip, "author"))
      
          plain    min      max      first    last     reverse  rev..rst rev..ast sort     sor..rst sor..ast
      00) 0.000789 0.000801 0.000801 0.000819 0.000784 0.000774 0.000793 0.000816 0.000815 0.000831 0.000799
      01) 0.097610 0.002717 0.096706 0.002615 0.059189 0.089033 0.059862 0.002644 0.098058 0.002640 0.058992
      02) 0.000709 0.000117 0.000382 0.000136 0.000384 0.000724 0.000412 0.000133 0.000733 0.000159 0.000416
      03) 0.000075 0.000064 0.000093 0.000080 0.000097 0.000089 0.000123 0.000079 0.000105 0.000102 0.000126
      04) 0.000055 0.000071 0.000070 0.000087 0.000075 0.000066 0.000100 0.000085 0.000082 0.000110 0.000102
      05) 0.088043 0.001084 0.087816 0.001097 0.048049 0.072454 0.047673 0.001089 0.088491 0.001163 0.047824
      06) 0.058761 0.001727 0.059324 0.001850 0.058562 0.059198 0.058998 0.001743 0.058556 0.001874 0.059420
      07) 0.000131 0.000121 0.000145 0.000138 0.000150 0.000142 0.000178 0.000135 0.000160 0.000163 0.000179
      08) 0.058003 0.000077 0.032327 0.000093 0.031966 0.056812 0.031753 0.000092 0.057113 0.000116 0.031933
      09) 0.000503 0.000145 0.000469 0.000161 0.000476 0.000564 0.000502 0.000160 0.000537 0.000187 0.000500
      10) 0.056654 0.000058 0.033104 0.000073 0.032157 0.056598 0.031877 0.000071 0.056433 0.000094 0.031819
      11) 0.005842 0.000081 0.001907 0.000101 0.001883 0.005868 0.001915 0.000099 0.005836 0.000122 0.001896
      12) 0.003237 0.000634 0.001784 0.000655 0.001803 0.003245 0.001837 0.000649 0.003231 0.000680 0.001858
      41f14e8f
    • Boris Feld's avatar
      dagop: minor python optimization to `headrevs` · 61f9ef23
      Boris Feld authored
      Less lookup and less function call never hurt. This provides a small speedup
      on various run of the 'heads()' revset. This also buys back some of the slow
      down we observed in the previous changesets for single value lookup.
      
      Performance number:
      0) before dagop.headrevs usage
      1) after dagop.headrevs usage
      2) after this change
      
      revset: heads(all())
         plain         min           max           first         last          reverse       rev..rst      rev..ast      sort          sor..rst      sor..ast
      0) 0.036503      0.032564      0.030024      0.032378      0.030887      0.036367      0.031713      0.032205      0.036467      0.032286      0.030300
      1) 0.036668      0.035347 108% 0.035611 118% 0.035358 109% 0.035726 115% 0.036411      0.035261 111% 0.036096 112% 0.036052      0.035095 108% 0.035792 118%
      2) 0.034254  93% 0.034482      0.035003      0.034353      0.033754  94% 0.034689      0.034361      0.035059      0.034636      0.034662      0.035465
      
      revset: heads(-10000:-1)
         plain         min           max           first         last          reverse       rev..rst      rev..ast      sort          sor..rst      sor..ast
      0) 0.003936      0.003218      0.003227      0.003302      0.003328      0.003848      0.003305      0.003252      0.003839      0.003306      0.003279
      1) 0.003870      0.003785 117% 0.003821 118% 0.003780 114% 0.003769 113% 0.003776      0.003792 114% 0.003805 117% 0.003810      0.003798 114% 0.003840 117%
      2) 0.003666  94% 0.003577  94% 0.003632      0.003644      0.003614      0.003638      0.003652      0.003632      0.003661      0.003660      0.003658
      
      revset: (-5000:-1000) and heads(-10000:-1)
         plain         min           max           first         last          reverse       rev..rst      rev..ast      sort          sor..rst      sor..ast
      0) 0.004244      0.003368      0.003313      0.003367      0.003327      0.004325      0.003401      0.003379      0.004310      0.003359      0.003396
      1) 0.003969  93% 0.003862 114% 0.003834 115% 0.003810 113% 0.003822 114% 0.003940  91% 0.003908 114% 0.003814 112% 0.003986  92% 0.003954 117% 0.003816 112%
      2) 0.003728  93% 0.003638  94% 0.003659      0.003685      0.003628  94% 0.003716  94% 0.003653  93% 0.003655      0.003748  94% 0.003740  94% 0.003686
      
      revset: heads(matching(tip, "author"))
         plain         min           max           first         last          reverse       rev..rst      rev..ast      sort          sor..rst      sor..ast
      0) 7.574666      7.545950      7.570743      7.578697      7.525725      7.509929      7.443854      7.488442      7.452880      7.445411      7.689107
      1) 7.549390      7.389162      7.529790      7.536297      7.450467      7.555347      7.404586      7.514948      7.542794      7.524787      7.536918
      2) 7.568294      7.479326      7.578624      7.380375      7.440102      7.454218      7.515189      7.556511      7.524585      7.537566      7.507418
      
      revset: heads(matching(tip, "author")) and -10000:-1
         plain         min           max           first         last          reverse       rev..rst      rev..ast      sort          sor..rst      sor..ast
      0) 7.512533      7.605877      7.382894      7.462109      7.420086      7.575034      7.448452      7.549374      7.457880      7.450308      7.515019
      1) 7.548677      7.551832      7.629598      7.494857      7.550554      7.521838      7.451794      error         7.321781      7.546885      7.557523
      2) 7.451985      7.541044      7.506563      7.470928      7.512618      7.474988      7.498887      7.547930      7.560276      7.618599      7.465442
      
      revset: (-10000:-1) and heads(matching(tip, "author"))
         plain         min           max           first         last          reverse       rev..rst      rev..ast      sort          sor..rst      sor..ast
      0) 7.465419      7.570089      7.439594      7.521221      7.498716      7.492922      7.479108      7.552397      7.407888      error         7.468264
      1) 7.539866      7.548045      7.491761      7.517170      7.469824      7.501990      7.579102      7.502568      7.578102      7.555754      7.567622
      2) 7.370463      7.514712      7.497024      7.679428      7.638138      7.490775      7.472273      7.652587      7.584139      7.511893      7.466384
      61f9ef23
    • Boris Feld's avatar
      revset: use changelog's `headrevs` method to compute heads · 5affe158
      Boris Feld authored
      Instead of implementing our own algorithm, we reuse a more generic one. This
      previous algorithm did not leave much room for laziness so we do not really
      regress in that regards. A small impact is visible for first/last value in
      some of the simpler cases. The time needed to compute all values improves
      overall. Small optimization in the dagop.headrevs function will help to buy
      this back in the next changesets.
      
      There is room to introduce actual laziness in this algorithm, but this is out
      of scope for this series.
      
      This has no visible effect on expensive cases:
      
      revset: heads(matching(tip, "author"))
         plain         min           max           first         last          reverse       rev..rst      rev..ast      sort          sor..rst      sor..ast
      0) 7.574666      7.545950      7.570743      7.578697      7.525725      7.509929      7.443854      7.488442      7.452880      7.445411      7.689107
      1) 7.549390      7.389162      7.529790      7.536297      7.450467      7.555347      7.404586      7.514948      7.542794      7.524787      7.536918
      
      revset: heads(matching(tip, "author")) and -10000:-1
         plain         min           max           first         last          reverse       rev..rst      rev..ast      sort          sor..rst      sor..ast
      0) 7.512533      7.605877      7.382894      7.462109      7.420086      7.575034      7.448452      7.549374      7.457880      7.450308      7.515019
      1) 7.548677      7.551832      7.629598      7.494857      7.550554      7.521838      7.451794      error         7.321781      7.546885      7.557523
      
      revset: (-10000:-1) and heads(matching(tip, "author"))
         plain         min           max           first         last          reverse       rev..rst      rev..ast      sort          sor..rst      sor..ast
      0) 7.465419      7.570089      7.439594      7.521221      7.498716      7.492922      7.479108      7.552397      7.407888      error         7.468264
      1) 7.539866      7.548045      7.491761      7.517170      7.469824      7.501990      7.579102      7.502568      7.578102      7.555754      7.567622
      
      In simpler cases, we see a 10-15% impact when retrieving a single value, the
      full computation time is equivalent or improved:
      
      revset: (-5000:-1000) and heads(-10000:-1)
         plain         min           max           first         last          reverse       rev..rst      rev..ast      sort          sor..rst      sor..ast
      0) 0.004244      0.003368      0.003313      0.003367      0.003327      0.004325      0.003401      0.003379      0.004310      0.003359      0.003396
      1) 0.003969  93% 0.003862 114% 0.003834 115% 0.003810 113% 0.003822 114% 0.003940  91% 0.003908 114% 0.003814 112% 0.003986  92% 0.003954 117% 0.003816 112%
      
      revset: heads(all())
         plain         min           max           first         last          reverse       rev..rst      rev..ast      sort          sor..rst      sor..ast
      0) 0.036503      0.032564      0.030024      0.032378      0.030887      0.036367      0.031713      0.032205      0.036467      0.032286      0.030300
      1) 0.036668      0.035347 108% 0.035611 118% 0.035358 109% 0.035726 115% 0.036411      0.035261 111% 0.036096 112% 0.036052      0.035095 108% 0.035792 118%
      
      revset: heads(-10000:-1)
         plain         min           max           first         last          reverse       rev..rst      rev..ast      sort          sor..rst      sor..ast
      0) 0.003936      0.003218      0.003227      0.003302      0.003328      0.003848      0.003305      0.003252      0.003839      0.003306      0.003279
      1) 0.003870      0.003785 117% 0.003821 118% 0.003780 114% 0.003769 113% 0.003776      0.003792 114% 0.003805 117% 0.003810      0.003798 114% 0.003840 117%
      5affe158
    • Boris Feld's avatar
      revlog: accept a revs argument in `headrevs` · 1421d048
      Boris Feld authored
      Computing the heads of an arbitrary set of revision is useful, we make it
      possible to do so through the `headrevs` method of the revlog.
      
      Right now, this is just calling dagop's implementation. However, we expect to
      plug a native implementation soon.
      1421d048
    • Boris Feld's avatar
      revset: inline parents computation to reuse the input argument · 4c6fdc7e
      Boris Feld authored
      Before this change, using `heads(xxx)` would compute `xxx` multiple time. Once
      to select the possible candidates, and once to compute the parent set.
      
      The code used to compute parents is a direct copy past from the `parents`
      revset. We expect to replace it quickly in a later changeset. So we did not
      bother with extracting a function.
      
      In case where the input set is expensive to compute this provides a
      significant performance boost.
      
      (output are from contrib/revsetbenchmarks.py)
      
      revset: heads(matching(tip, "author"))
         plain         min           max           first         last          reverse       rev..rst      rev..ast      sort          sor..rst      sor..ast
      0) 15.06746      14.92766      7.335694      15.03092      7.635580      15.04133      7.454806      15.27565      14.97796      14.87607      7.480900
      1) 7.529300  49% 7.592152  50% 7.480548      7.544528  50% 7.421248      7.522279  50% 7.484876      7.613154  49% 7.599553  50% 7.561410  50% 7.508990
      
      In other cases, with a faster input set, we still see a (smaller) performance
      boost.
      
      revset: heads(all())
         plain         min           max           first         last          reverse       rev..rst      rev..ast      sort          sor..rst      sor..ast
      0) 0.038994      0.035981      0.033345      0.035751      0.033569      0.039833      0.033653      0.035428      0.039483      0.035750      0.033657
      1) 0.036359  93% 0.032613  90% 0.031479  94% 0.032790  91% 0.030681  91% 0.036456  91% 0.031128  92% 0.032461  91% 0.036276  91% 0.032721  91% 0.031024  92%
      
      revset: heads(-10000:-1)
         plain         min           max           first         last          reverse       rev..rst      rev..ast      sort          sor..rst      sor..ast
      0) 0.004184      0.003576      0.003593      0.003628      0.003569      0.004277      0.003590      0.003719      0.004194      0.003659      0.003690
      1) 0.003850  92% 0.003267  91% 0.003256  90% 0.003261  89% 0.003204  89% 0.003855  90% 0.003294  91% 0.003164  85% 0.003848  91% 0.003302  90% 0.003296  89%
      
      revset: (-5000:-1000) and heads(-10000:-1)
         plain         min           max           first         last          reverse       rev..rst      rev..ast      sort          sor..rst      sor..ast
      0) 0.004730      0.003429      0.003359      0.003391      0.003369      0.004787      0.003418      0.003469      0.004772      0.003445      0.003454
      1) 0.004277  90% 0.003430      0.003423      0.003353      0.003340      0.004250  88% 0.003387      0.003385      0.004325  90% 0.003413      0.003373
      
      revset: heads(matching(tip, "author")) and -10000:-1
         plain         min           max           first         last          reverse       rev..rst      rev..ast      sort          sor..rst      sor..ast
      0) 8.250275      8.231453      7.508579      8.230028      7.529777      8.358590      7.531636      8.301830      8.137196      8.421402      7.540355
      1) 7.474707  90% 7.587345  92% 7.486192      7.548340  91% 7.485288      7.659108  91% 7.485307      7.628890  91% 7.523479  92% 7.558384  89% 7.467524
      
      revset: (-10000:-1) and heads(matching(tip, "author"))
         plain         min           max           first         last          reverse       rev..rst      rev..ast      sort          sor..rst      sor..ast
      0) 8.341504      8.315248      7.489414      8.320746      7.548816      8.244137      7.514663      8.281701      8.218862      8.412644      7.456793
      1) 7.553704  90% 7.570679  91% 7.391438      7.724237  92% 7.527400      7.570637  91% 7.580622      7.450912  89% 7.556154  91% 7.514726  89% 7.494328
      4c6fdc7e
  23. Jan 13, 2019
Loading