Skip to main content

Notice: This Wiki is now read only and edits are no longer possible. Please see: for the plan.

Jump to: navigation, search

CVS Hacks

This page contains descriptions of some of the things we did to make the CVS plug-ins work well.


The ability to Synchronize between the local workspace and a CVS server is one of the most popular feature of the CVS plug-in. As of Eclipse 3.3, there are two types of CVS Synchronization, which we refer to as the "old-style" and "model-based" synchronizations. I'll first describe the old-style Synchronization since it came first.

The old-style synchronization uses the "cvs -n update" command to query the state of the server without affecting the state of the workspace (i.e. the CVS sandbox). However, this command only indicates what resources have changed but does not indicate what the new revision is. It also doesn't traverse into new directories. To address the first shortcoming, the synchronize operation accumulates a list of all files that have changed remotely and runs the "cvs status" command to determine what the current revisions are. To address the second issue, the operation must rerun the update command on each new directory.

Because the "cvs -n update" does not traverse into directories, the command must be rerun for each new directory discovered at each level. This can add significant overhead if the new directory structure is deep. A serious performance issue involved empty directories. Some projects have a lot of empty directories. Synchronizing on these projects has serious performance problems. To fix this, we key track of all empty folders in the ISynchronizer. This fixed the performance problems but has the side effect that you cannot ignore a directory that exists remotely. This differs from the behavior of other CVS clients (see bugs 79869 and 78695).

The model-based synchronization basically performs a standard "cvs update" into a virtual sandbox. This allows logical models to efficiently query the contents of any files that have changed. The advantage is that the operation is more standard the the old-style synchronization. The disadvantage is that the performance is not as good. See bug 152581 for a comparison of the performance of the two types of synchronizations.

CVS Label Decorations

The section contains a few items related to the CVS decorator

Decorator Enablement

When a user starts working with CVS, we wanted to have the CVS decorator on by default. However, we couldn;t just turn the decorator on by default in the plugin.xml as this would cause the CVS plug-ins to be loaded when Eclipse first started even if the user never intended to use CVS. To work around this, we wrote code in the CVS/UI plug-in startup that would enable the decorators the first time the plug-in started. After that time, the setting was never altered by the CVS/UI plug-in (i.e. if the user subsequently disabled the decorator, it would stay disabled even across restarts). One side effect of this is that choosing Restore Defaults in the preference page disables the CVS decorator.

Dirty State Determination

A dirty bit cache is used to cache the dirty sate of folders so that recomputation of the folder dirty state is only performed when the dirty state of a descendant of a folder changes. The cache operates by placing a bit in the session properties for each resource that indicates whether the resource is dirty, clean or needs to be recomputed. The session property key is SyncInfoCache.IS_DIRTY. It also uses the ISynchronizer to persist the bit for folders to improve dirty state computation on restart. The key used for the ISynchronizer is SessionPropertySyncInfoCache.FOLDER_DIRTY_STATE_KEY.

  1. On startup when a folder dirty state is queried, look in the synchronizer cache and, if the state is there, us it and put is in the session cache
  2. When a state changes, set the flag to recompute.
  3. when the state is queried, use the cached state unless it is "recompute" in which case the state needs to be recalculated.
  4. On shutdown, transfer the folder dirty state to the synchronizer cache since the session cache is not persisted across restarts.

Back to the top