Skip to content
  • Jeff King's avatar
    git: add --no-optional-locks option · 27344d6a
    Jeff King authored and Junio C Hamano's avatar Junio C Hamano committed
    
    
    Some tools like IDEs or fancy editors may periodically run
    commands like "git status" in the background to keep track
    of the state of the repository. Some of these commands may
    refresh the index and write out the result in an
    opportunistic way: if they can get the index lock, then they
    update the on-disk index with any updates they find. And if
    not, then their in-core refresh is lost and just has to be
    recomputed by the next caller.
    
    But taking the index lock may conflict with other operations
    in the repository. Especially ones that the user is doing
    themselves, which _aren't_ opportunistic. In other words,
    "git status" knows how to back off when somebody else is
    holding the lock, but other commands don't know that status
    would be happy to drop the lock if somebody else wanted it.
    
    There are a couple possible solutions:
    
      1. Have some kind of "pseudo-lock" that allows other
         commands to tell status that they want the lock.
    
         This is likely to be complicated and error-prone to
         implement (and maybe even impossible with just
         dotlocks to work from, as it requires some
         inter-process communication).
    
      2. Avoid background runs of commands like "git status"
         that want to do opportunistic updates, preferring
         instead plumbing like diff-files, etc.
    
         This is awkward for a couple of reasons. One is that
         "status --porcelain" reports a lot more about the
         repository state than is available from individual
         plumbing commands. And two is that we actually _do_
         want to see the refreshed index. We just don't want to
         take a lock or write out the result. Whereas commands
         like diff-files expect us to refresh the index
         separately and write it to disk so that they can depend
         on the result. But that write is exactly what we're
         trying to avoid.
    
      3. Ask "status" not to lock or write the index.
    
         This is easy to implement. The big downside is that any
         work done in refreshing the index for such a call is
         lost when the process exits. So a background process
         may end up re-hashing a changed file multiple times
         until the user runs a command that does an index
         refresh themselves.
    
    This patch implements the option 3. The idea (and the test)
    is largely stolen from a Git for Windows patch by Johannes
    Schindelin, 67e5ce7f63 (status: offer *not* to lock the
    index and update it, 2016-08-12). The twist here is that
    instead of making this an option to "git status", it becomes
    a "git" option and matching environment variable.
    
    The reason there is two-fold:
    
      1. An environment variable is carried through to
         sub-processes. And whether an invocation is a
         background process or not should apply to the whole
         process tree. So you could do "git --no-optional-locks
         foo", and if "foo" is a script or alias that calls
         "status", you'll still get the effect.
    
      2. There may be other programs that want the same
         treatment.
    
         I've punted here on finding more callers to convert,
         since "status" is the obvious one to call as a repeated
         background job. But "git diff"'s opportunistic refresh
         of the index may be a good candidate.
    
    The test is taken from 67e5ce7f63, and it's worth repeating
    Johannes's explanation:
    
      Note that the regression test added in this commit does
      not *really* verify that no index.lock file was written;
      that test is not possible in a portable way. Instead, we
      verify that .git/index is rewritten *only* when `git
      status` is run without `--no-optional-locks`.
    
    Signed-off-by: default avatarJeff King <peff@peff.net>
    Signed-off-by: default avatarJunio C Hamano <gitster@pobox.com>
    27344d6a