Patch Set 1:

Interesting idea, doing a shared immutable DirCache.

That might be difficult since the API exposes the DirCacheEntry, and you can edit a DirCacheEntry's fields via setter methods.  An immutable DirCache would have to expose immutable DirCacheEntry instances too.  :-(

I think its just easier to break the API and declare that the "easy to get, easy to use DirCache on Repository is shared... and you are responsible for thread safety".  But changing semantics like that might make sense to actually break the API, so applications need to at least go to each call site and consider use of the shared one, or create a new one.

But what do we call this new method?

  DirCache readDirCache(DirCacheSharingType type);

  enum DirCacheSharingType {
   /** A shared instance is returned, and should not be modified. */
    SHARED,

    /** A new instance is allocated for the caller. */
    PRIVATE
  }

  DirCache readDirCache() {
    return readDirCache(DirCacheSharingType.PRIVATE);
  }

That might actually work.  Then applications that really want that shared copy can update their call sites to use the new SHARED constant.

A PRIVATE DirCache can be created quickly by cloning the SHARED DirCache if the SHAREd one is up-to-date.  That would allow a PRIVATE one to still be constructed without doing a lot of disk IO and parsing, so even old applications would still get some benefit.