These variables are mainly for use in the window title. Not all variables make sense across SCM drivers, hence why it is now completely up to the driver, what variables it provides.
Ideally we would be able to remove arbitrary callbacks rather than the last one added, but for this we would need to introduce some sort of handle (the callback itself is a block so not suitable as handle). The push/pop API for callbacks is sufficient for our use-case though.
This is so that tests can use the exact same executable to create the repository, as is used to obtain status (svn repositories created with newer executables are often not backwards compatible).
This was previously public so that we could write tests for it, but since the test runner is linked with the object files, it can access symbols that has visibility set to hidden.
Normally we enable these on application launch when we receive an ‘application did become active’ notification, for tests though, this notification is lacking, but we do want it enabled for tests, and while we could do a constructor in the tests to enable it, it seems better to just enable it by default.
One issue is that if TextMate is launched “in the background” then it will still do SCM status gathering. Though long-term I may actually want to always have it enabled, even when TextMate is not active.
This ensures that when an scm::ng::info_ptr object has been disposed by the user, the associated callback will not be called (as no-one else will keep it retained).
When requesting SCM info for a path, we now always return the cached info for the first parent of the path, but if the first parent of the path is not the direct parent, we do a more thorough search (which involve disk access) in a background thread.
The latter is required because we may have nested repositories. E.g. asking for SCM info for /path/to/project/submodule/file will initially return the root project’s cached SCM info (if the submodule info hasn’t yet been added to the cache) but will then later invoke the callback with the submodule’s SCM info.
This is to be used when the application is in the background. Rather than completely disable updates, it might perhaps be better simply to increase the delay used to throttle updates.
Also change SCM implementation so that it doesn’t use objects with automatic storage, as the objects may be accessed from threads, which may run after objects with automatic storage has been destroyed.
This won’t perform any disk access on main thread. The previous API would check for the SCM-metadata directories on the main thread and also obtain the initial status and branch during creation.
This is both convenience, since we setup the TM_SCM variables in several places, but will also allow to register for changed variables (and thus, fetch branch name in a thread).
The problem with hg is that running ‘hg status’ may trigger fsevents, which would normally have us call ‘hg status’ again. To avoid this, we check if there actually are changes compared to the last time we ran the SCM driver. This has some overhead, as we need to scan the disk to produce the fingerprint.
Additionally the throttling has been improved. Previously we would delay a status fetch if it had been less than 3 seconds since the last request, but during this “penalty wait” more requests could still be submitted (in case of disk activity) and would be queued for later execution — now such requests are dropped.
We didn’t actually use the file itself, only its parent directory, and there are several places we want SCM info for an untitled file’s project directory, so removing the need for a file simplifies things.
The problem is that we used to treat an empty status map as meaning we hadn’t yet requested status for this repository, however, now that we no longer need status for all files, we would have an empty status map for clean (svn) repositories, leading to needlessly requesting status updates all the time (and on main thread).
This can be used to make decisions about whether or not we should assign a virtual status to directories, prune them from a status display, or similar.
Subversion itself is roughly 30% faster if we do not ask for status of all files, the XML processing though is magnitudes faster, since it will only have to deal with a few records (in the general case) rather than a record per file (xsltproc seems to do around ~10,000 files per second on my Mac Pro, though I have no idea if it scales linearly).
The scm::status::versioned status has now been removed.
The upshot of this is that SCM drivers can leave out files that are “clean” from their status map, and TextMate will assume they have status “none” (clean). This cuts down on the amount of data that needs to be sent (and/or processed) by the SCM drivers.
For a repository with 7,767 files it takes 3.5 seconds for Python to convert a full file listing from XML to the simpler line-based format. Using xsltproc the same takes 0.74 seconds.
According to issue #340 TextMate “freeze for up to about 5 - 10 minutes” when doing svn status. Not sure how much this change helps on that, no doubt it’s an improvement.