src/main/java/com/semanticcms/autogit/servlet/AutoGitContextListener.java
private void resync() throws IOException {
		Path gtl;
		synchronized(gitToplevelLock) {
			gtl = gitToplevel;
		}
		WatchService w;
		synchronized(watcherLock) {
			w = watcher;
		}
		if(gtl != null && w != null) {
			synchronized(registered) {
				Set<Path> extraKeys = new HashSet<>(registered.keySet());
				resync(w, gtl, extraKeys);
				for(Path extraKey : extraKeys) {
					if(DEBUG) log("Canceling watch key: " + extraKey);
					registered.remove(extraKey).cancel();
				}
			}
		}
	}
private void resync() throws IOException {
		Path gtl;
		synchronized(gitToplevelLock) {
			gtl = gitToplevel;
		}
		WatchService w;
		synchronized(watcherLock) {
			w = watcher;
		}
		if(gtl != null && w != null) {
			synchronized(registered) {
				Set<Path> extraKeys = new HashSet<>(registered.keySet());
				resync(w, gtl, extraKeys);
				for(Path extraKey : extraKeys) {
					if(DEBUG) log("Canceling watch key: " + extraKey);
					registered.remove(extraKey).cancel();
				}
			}
		}
	}
Resyncs the entire directory recursively, registering and canceling any
discrepancies found.