Some comments ...
On Tue, Aug 11, 2009 at 04:54, Imran M Yousuf<imyo...@gmail.com> wrote:
> @@ -67,19 +76,28 @@ private Excludes() {
> }
>
> private static final String FILENAME_GITIGNORE = ".gitignore"; // NOI18N
> - private static HashMap<String, List<PathPattern>> ignorePatterns;
> + private final static HashMap<String, List<PathPattern>> ignorePatterns = new HashMap<String, List<PathPattern>>();
> + private final static Set<File> monitoredFiles = new HashSet<File>();
> + private final static Timer timer = new Timer();
> + private final static int DELAY = 5000;
>
> private static List<PathPattern> getIgnorePatterns(File file) {
> - if (ignorePatterns == null) {
> - ignorePatterns = new HashMap<String, List<PathPattern>>();
> - }
> - String key = file.getAbsolutePath();
> + final String key = file.getAbsolutePath();
> List<PathPattern> patterns = ignorePatterns.get(key);
> - if (patterns == null) {
> + if (patterns == null && file.exists() && !file.isDirectory()) {
> patterns = readIgnorePatterns(file);
> if (!patterns.isEmpty()) {
> ignorePatterns.put(key, patterns);
> }
Shouldn't access to ignorePatterns here also be synchronized? Maybe we
should just use a thread-safe Map instead.
> + if(!monitoredFiles.contains(file)) {
> + synchronized(monitoredFiles) {
> + monitoredFiles.add(file);
> + }
I don't understand the purpose of monitoredFiles. You never remove
entries from it. To me it would be simpler if the ignorePatterns map
serve the dual purpose of tracking both cached and monitored files?
> + monitorFileChange(file, key);
> + }
> + }
> + else if (patterns == null) {
> + patterns = Collections.emptyList();
> }
> return patterns;
> }
> @@ -162,6 +180,52 @@ public static boolean isIgnored(File file,
> boolean checkSharability) {
> return false;
> }
>
> + private static void monitorFileChange(final File file, final String key) {
> + final FileObject fileObject = FileUtil.toFileObject(file);
> + TimerTask task = new TimerTask() {
> +
> + private Date lastModified = fileObject.lastModified();
> +
> + @Override
> + public void run() {
> + if (!lastModified.equals(fileObject.lastModified())) {
> + fileObject.refresh();
> + lastModified = fileObject.lastModified();
> + }
> + }
> + };
> + timer.schedule(task, DELAY, DELAY);
Do you think it wold be worth it to have just one timer task to
iterate over the cached ignore files?
> + fileObject.addFileChangeListener(new FileChangeAdapter() {
> +
> + private void evictPatterns() {
> + synchronized (ignorePatterns) {
> + ignorePatterns.remove(key);
> + }
> + }
> +
> + @Override
> + public void fileChanged(FileEvent fe) {
> + evictPatterns();
> + }
> +
> + @Override
> + public void fileAttributeChanged(FileAttributeEvent fe) {
> + System.out.println("A");
Some debug left overs ...
> + evictPatterns();
> + }
> +
> + @Override
> + public void fileDeleted(FileEvent fe) {
> + evictPatterns();
> + }
> +
> + @Override
> + public void fileRenamed(FileRenameEvent fe) {
> + evictPatterns();
> + }
> + });
> + }
> +
> private static String stripWorkDir(File wd, File f) {
> int skip = f.getPath().length() > wd.getPath().length() ? 1 : 0;
> String relName = f.getPath().substring(wd.getPath().length() + skip);
> --
> 1.6.2.1
BTW, last year I filed a bug for JGit about supporting file
monitoring. It has some interesting comments by Robin about the
reloading done internally in JGit.
- http://code.google.com/p/egit/issues/detail?id=40
--
Jonas Fonseca
Can you please help me out on how I could clear the cache? BTW I
resubmitted the patch.
I was thinking of something like this - whenever a pattern is added
something should be added to the cache and whenever a pattern is
removed it should be done so from the cache as well. Whenever a new
file is added to the index from NetBeans or file system it should be
checked whether it should be excluded or not and added to the cache if
required and when a file is deleted so should it be done from cache as
well; all in all a simple read-write through cache strategy.
- Imran
I am not completely sure I follow you. If "cache" refers to the
exclude pattern cache, then yes, we want to pick up changes of
.gitignore and .git/info/exclude files and mirror it.
From what I understand, you want to also refresh or update the status
information cache used for showing the status view and annotating the
files in the file explorers. So when an .gitignore file has changed,
say in directory src/org/example/, all files under that directory
(which the .gitignore file has an effect on), needs to be refreshed as
well.
The way to do this is to call StatusCache's refreshCached() method of
GitUtils's forceStatusRefresh() ... on a background thread, which I
guess the pattern cache update code is already running on.
Regarding file deletion, deletion of .gitignore files is similar to
changes of .gitignore files, the module's VCSIntercepter will pick up
deletions of tracked files done via the IDE and will refresh the
status cache accordingly.
Don't know if that answers your question.
--
Jonas Fonseca