Skip to content
Snippets Groups Projects
  1. Feb 01, 2018
  2. Jan 31, 2018
  3. Jan 28, 2018
    • Matt Harbison's avatar
      revset: evaluate filesets against each revision for 'file()' (issue5778) · f6ca1e11
      Matt Harbison authored
      After f2aeff8a87b6, the fileset was evaluated to a set of files against the
      working directory, and then those files were applied against each revision.  The
      result was nonsense.  For example, `hg log -r 'file("set:exec()")'` on the
      Mercurial repo listed revision 0 because it has the `hg` script, which is
      currently +x.  But that bit wasn't applied until revision 280 (which
      'contains()' properly indicates).
      
      This technique was borrowed from checkstatus(), which services adds(),
      modifies(), and removes(), so it seems safe enough.  The 'r:' case is explicitly
      assigned to wdirrev, freeing up rev=None to mean "re-evaluate at each revision".
      The distinction is important to avoid behavior changes with `hg log set:...`
      (test-largefiles-misc.t and test-fileset-generated.t drop current log output
      without this).  I'm not sure what the right behavior for that is (1fd352aa08fc
      explicitly enabled this behavior for graphlog), but the day before the release
      isn't the time to experiment.
      f6ca1e11
  4. Feb 01, 2018
  5. Jan 31, 2018
  6. Jan 29, 2018
  7. Jan 30, 2018
  8. Jan 31, 2018
    • Jun Wu's avatar
      lazymanifest: avoid reading uninitialized memory · 113a30b8
      Jun Wu authored
      I got errors running tests with clang UBSAN [1] enabled. One of them is:
      
      ```
      --- test-dirstate.t
      +++ test-dirstate.t.err
      @@ -85,9 +85,115 @@
         $ echo "[extensions]" >> .hg/hgrc
         $ echo "dirstateex=../dirstateexception.py" >> .hg/hgrc
         $ hg up 0
      -  abort: simulated error while recording dirstateupdates
      -  [255]
      +  mercurial/cext/manifest.c:781:13: runtime error: load of value 190, which is not a valid value for type 'bool'
      +      #0 0x7f668a8cf748 in lazymanifest_diff mercurial/cext/manifest.c:781
      +      #1 0x7f6692fc1dc4 in call_function Python-2.7.11/Python/ceval.c:4350
      +      .......
      +  SUMMARY: UndefinedBehaviorSanitizer: invalid-bool-load mercurial/cext/manifest.c:781:13 in
      +  [1]
         $ hg log -r . -T '{rev}\n'
         1
         $ hg status
      -  ? a
      ```
      
      While the code is not technically wrong, but switching the condition would
      make clang UBSAN happy. So let's do it.
      
      The uninitialized memory could come from, for example, `lazymanifest_copy`
      allocates `self->maxlines` items but only writes the first `self->lines`
      items.
      
      [1]: https://clang.llvm.org/docs/UndefinedBehaviorSanitizer.html
      
      Test Plan:
      Run `test-dirstate.t` with UBSAN and it no longer reports the issue.
      
      Differential Revision: https://phab.mercurial-scm.org/D1948
      113a30b8
  9. Jan 26, 2018
  10. Jan 29, 2018
  11. Jan 30, 2018
    • Matt Harbison's avatar
      lfs: don't require the .hglfs file to be tracked to control the policy · 4425790f
      Matt Harbison authored
      The .hgignore file doesn't need to be tracked, nor does the git equivalent of
      this file.  I'm still a little concerned about the effects of forgetting to
      commit this file.  But the fact that conversions maintain the hashes if only the
      normal vs external storage changes, should make this less risky.
      4425790f
  12. Jan 28, 2018
  13. Jan 26, 2018
  14. Jan 24, 2018
  15. Jan 23, 2018
  16. Jan 25, 2018
  17. Jan 24, 2018
  18. Jan 22, 2018
  19. Jan 21, 2018
    • Gregory Szorc's avatar
      bundle2: increase payload part chunk size to 32kb · 4fb2bb61
      Gregory Szorc authored
      Bundle2 payload parts are framed chunks. Esentially, we obtain
      data in equal size chunks of size `preferedchunksize` and emit those
      to a generator. That generator is fed into a compressor (which can
      be the no-op compressor, which just re-emits the generator). And
      the output from the compressor likely goes to a file descriptor
      or socket.
      
      What this means is that small chunk sizes create more Python objects
      and Python function calls than larger chunk sizes. And as we know,
      Python object and function call overhead in performance sensitive
      code matters (at least with CPython).
      
      This commit increases the bundle2 part payload chunk size from 4k
      to 32k. Practically speaking, this means that the chunks we feed
      into a compressor (implemented in C code) or feed directly into a
      file handle or socket write() are larger. It's possible the chunks
      might be larger than what the receiver can handle in one logical
      operation. But at that point, we're in C code, which is much more
      efficient at dealing with splitting up the chunk and making multiple
      function calls than Python is.
      
      A downside to larger chunks is that the receiver has to wait for that
      much data to arrive (either raw or from a decompressor) before it
      can process the chunk. But 32kb still feels like a small buffer to
      have to wait for. And in many cases, the client will convert from
      8 read(4096) to 1 read(32768). That's happening in Python land. So
      we cut down on the number of Python objects and function calls,
      making the client faster as well. I don't think there are any
      significant concerns to increasing the payload chunk size to 32kb.
      
      The impact of this change on performance significant. Using `curl`
      to obtain a stream clone bundle2 payload from a server on localhost
      serving the mozilla-unified repository:
      
      before: 20.78 user; 7.71 system;  80.5 MB/s
      after:  13.90 user; 3.51 system; 132 MB/s
      legacy:  9.72 user; 8.16 system; 132 MB/s
      
      bundle2 stream clone generation is still more resource intensive than
      legacy stream clone (that's likely because of the use of a
      util.chunkbuffer). But the throughput is the same. We might
      be in territory we're this is effectively a benchmark of the
      networking stack or Python's syscall throughput.
      
      From the client perspective, `hg clone -U --stream`:
      
      before: 33.50 user; 7.95 system; 53.3 MB/s
      after:  22.82 user; 7.33 system; 72.7 MB/s
      legacy: 29.96 user; 7.94 system; 58.0 MB/s
      
      And for `hg clone --stream` with a working directory update of
      ~230k files:
      
      after:  119.55 user; 26.47 system; 0:57.08 wall
      legacy: 126.98 user; 26.94 system; 1:05.56 wall
      
      So, it appears that bundle2's stream clone is now definitively faster
      than legacy stream clone!
      
      Differential Revision: https://phab.mercurial-scm.org/D1932
      4fb2bb61
  20. Jan 22, 2018
    • Gregory Szorc's avatar
      bundle2: always advertise client support for stream parts · 1d118f9f
      Gregory Szorc authored
      Previously, enabling of stream clone over bundle2 was a server-side
      only change. And clients would only advertise bundle2 support for
      stream clones if an experimental config option was set.
      
      This situation wasn't forward compatible because in the future
      (when the feature is enabled on servers by default), an old client
      would send a request to the server but it wouldn't send its own
      bundle2 capability support for stream parts. Servers would have to
      infer that clients not sending this capability were old Mercurial
      clients that only sent the capability if the feature was
      explicitly enabled. Implicit and inferred behavior makes implementing
      servers hard. It's much better to be explicit about client features.
      
      We should either make the config option for bundle2 stream clones
      disable the feature client-side as well (so a server doesn't see
      a request from a client not advertising stream support). Or we
      should always advertise stream support if a client is willing
      to accept stream parts.
      
      Since I anticipating stabilizing stream clone support in bundle2
      quickly, I think it's safe to always advertise client support
      in the bundle2 capabilities. So this commit changes things to
      do that.
      
      Because capabilities now vary between client and server, we had
      to create variations of the variable substitutions for those
      strings.
      
      Differential Revision: https://phab.mercurial-scm.org/D1931
      1d118f9f
    • Gregory Szorc's avatar
      exchange: don't send stream data when server.uncompressed is set · 9adae6a2
      Gregory Szorc authored
      Previously, bundle2 stream support would send out data even though
      the streaming clone feature was disabled. This commit changes
      the part handler to respect the server config.
      
      Differential Revision: https://phab.mercurial-scm.org/D1930
      9adae6a2
    • Gregory Szorc's avatar
      bundle2: don't advertise stream bundle2 capability when feature disabled · c1b9eb15
      Gregory Szorc authored
      The server.uncompressed config option can be used to disable streaming
      clones. While the top-level capability to advertise streaming clone
      support isn't advertised when this option is set, we were still sending
      the bundle2-level capabilities advertising support for stream parts.
      It makes sense to not advertise that support when streaming clones
      are globally disabled.
      
      If the structure of the new code seems a bit odd, it is because we'll
      have to further tweak the behavior in commit(s) ahead.
      
      Differential Revision: https://phab.mercurial-scm.org/D1929
      c1b9eb15
    • Gregory Szorc's avatar
      tests: add more testing around server.uncompressed · 8ed5f760
      Gregory Szorc authored
      We already have testing for server.uncompressed in test-http*.t.
      However, it doesn't cover the new bundle2 use case. And, we don't
      have comprehensive testing of advertised capabilities.
      
      We add tests to test-clone-uncompressed.t that demonstrate
      behavior for both legacy and bundle2 configurations.
      
      If you look closely, the bundle2 capabilities are advertising
      stream support when it isn't enabled. That's a bug.
      
      In addition, while the client is smart enough to not request
      a stream clone when the server doesn't have the feature enabled,
      the getbundle wire protocol command is still sending stream
      clone data. This doesn't match the behavior of the legacy
      stream_out wire protocol command. That's also a bug. Tests
      have been added.
      
      While I was here, I also changed how the PID is recorded in
      $DAEMON_PIDS. If we kill a process, the PID formerly in
      $DAEMON_PIDS no longer exists. So we should replace that file
      instead of appending to it.
      
      Differential Revision: https://phab.mercurial-scm.org/D1928
      8ed5f760
    • Gregory Szorc's avatar
      bundle2: move version of stream clone into part name · b116a66b
      Gregory Szorc authored
      I don't like having version numbers as part parameters. It means
      that parts can theoretically vary wildly in their generation and
      processing semantics. I think that a named part should have consistent
      behavior over time. In other words, if you need to introduce new
      functionality or behavior, that should be expressed by inventing
      a new bundle2 part, not adding functionality to an existing part.
      
      This commit applies this advice to the just-introduced stream clone
      via bundle2 feature.
      
      The "version" part parameter is removed. The name of the bundle2 part
      is now "stream2" instead of "stream" with "version=v2".
      
      Differential Revision: https://phab.mercurial-scm.org/D1927
      b116a66b
    • Gregory Szorc's avatar
      exchange: send bundle2 stream clones uncompressed · a84dbc87
      Gregory Szorc authored
      Stream clones don't compress well. And compression undermines
      a point of stream clones which is to trade significant CPU
      reductions by increasing size.
      
      Building upon our introduction of metadata to communicate bundle
      information back to callers of exchange.getbundlechunks(), we add
      an attribute to the bundler that communicates whether the bundle is
      best left uncompressed. We return this attribute as part of the bundle
      metadata. And the wire protocol honors it when determining whether
      to compress the wire protocol response.
      
      The added test demonstrates that the raw result from the wire
      protocol is not compressed. It also demonstrates that the server
      will serve stream responses when the feature isn't enabled. We'll
      address that in another commit.
      
      The effect of this change is that server-side CPU usage for bundle2
      stream clones is significantly reduced by removing zstd compression.
      For the mozilla-unified repository:
      
      before: 37.69 user 8.01 system
      after:  27.38 user 7.34 system
      
      Assuming things are CPU bound, that ~10s reduction would translate to
      faster clones on the client. zstd can decompress at >1 GB/s. So the
      overhead from decompression on the client is small in the grand scheme
      of things. But if zlib compression were being used, the overhead would
      be much greater.
      
      Differential Revision: https://phab.mercurial-scm.org/D1926
      a84dbc87
    • Gregory Szorc's avatar
      tests: update test to work with Git 2.16 · 8144f1b0
      Gregory Szorc authored
      It looks like Git 2.16 removed the "..." from some strings.
      Glob over those characters in the test output.
      
      Differential Revision: https://phab.mercurial-scm.org/D1935
      8144f1b0
  21. Jan 20, 2018
    • Gregory Szorc's avatar
      exchange: return bundle info from getbundlechunks() (API) · ba15580e
      Gregory Szorc authored
      We generally want a mechanism to pass information about the
      generated bundle back to callers (in addition to the byte stream).
      Ideally we would return a bundler from this function and have the
      caller code to an interface. But the bundling APIs are not great
      and getbundlechunks() is the best API we have for obtaining bundle
      contents in a unified manner.
      
      We change getbundlechunks() to return a dict that we can use to
      communicate metadata.
      
      We populate that dict with the bundle version number to demonstrate
      some value.
      
      .. api::
      
         exchange.getbundlechunks() now returns a 2-tuple instead of just
         an iterator.
      
      Differential Revision: https://phab.mercurial-scm.org/D1925
      ba15580e
    • Gregory Szorc's avatar
      exchange: make stream bundle part deterministic · 08cc94dd
      Gregory Szorc authored
      repo.requirements is a set. We need to sort it so the part
      content is deterministic.
      
      Differential Revision: https://phab.mercurial-scm.org/D1924
      08cc94dd
    • Gregory Szorc's avatar
      bundle2: specify what capabilities will be used for · c97639ad
      Gregory Szorc authored
      We currently assume there is a symmetric relationship of bundle2
      capabilities between client and server. However, this may not always be
      the case.
      
      We need a bundle2 capability to advertise bundle2 streaming clone support
      on servers to differentiate it from the existing, legacy streaming clone
      support.
      
      However, servers may wish to disable streaming clone support. If bundle2
      capabilities were the same between client and server, a client (which
      may also be a server) that has disabled streaming clone support would
      not be able to perform a streaming clone itself!
      
      This commit introduces a "role" argument to bundle2.getrepocaps() that
      explicitly defines the role being performed. This will allow us (and
      extensions) to alter bundle2 capabilities depending on the operation
      being performed.
      
      Differential Revision: https://phab.mercurial-scm.org/D1923
      c97639ad
    • Gregory Szorc's avatar
      wireproto: don't compress errors from getbundle() · 9d249f3d
      Gregory Szorc authored
      Errors should be small. There's no real need to compress them.
      Truth be told, there's no good reason to not compress them either.
      But leaving them uncompressed makes it easier to test failures
      by looking at the raw HTTP response. This makes it easier for us
      to write tests. It may make it easier for people writing their
      own clients.
      
      Differential Revision: https://phab.mercurial-scm.org/D1922
      9d249f3d
  22. Jan 21, 2018
  23. Jan 20, 2018
Loading