diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCache.java b/org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCache.java index d7f975b00..db1cfd554 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCache.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCache.java @@ -737,12 +737,14 @@ public class DirCache { final LockFile tmp = myLock; requireLocked(tmp); myLock = null; - if (!tmp.commit()) + if (!tmp.commit()) { return false; + } snapshot = tmp.getCommitSnapshot(); if (indexChangedListener != null - && !Arrays.equals(readIndexChecksum, writeIndexChecksum)) - indexChangedListener.onIndexChanged(new IndexChangedEvent()); + && !Arrays.equals(readIndexChecksum, writeIndexChecksum)) { + indexChangedListener.onIndexChanged(new IndexChangedEvent(true)); + } return true; } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/events/IndexChangedEvent.java b/org.eclipse.jgit/src/org/eclipse/jgit/events/IndexChangedEvent.java index 647ec8a20..dcce86a33 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/events/IndexChangedEvent.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/events/IndexChangedEvent.java @@ -47,6 +47,28 @@ package org.eclipse.jgit.events; * Describes a change to one or more paths in the index file. */ public class IndexChangedEvent extends RepositoryEvent { + private boolean internal; + + /** + * Notify that the index changed + * + * @param internal + * {@code true} if the index was changed by the same + * JGit process + * @since 5.0 + */ + public IndexChangedEvent(boolean internal) { + this.internal = internal; + } + + /** + * @return {@code true} if the index was changed by the same JGit process + * @since 5.0 + */ + public boolean isInternal() { + return internal; + } + /** {@inheritDoc} */ @Override public Class getListenerType() { diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsRepository.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsRepository.java index 197681658..5169e929e 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsRepository.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsRepository.java @@ -133,7 +133,7 @@ public abstract class DfsRepository extends Repository { /** {@inheritDoc} */ @Override - public void notifyIndexChanged() { + public void notifyIndexChanged(boolean internal) { // Do not send notifications. // There is no index, as there is no working tree. } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/FileRepository.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/FileRepository.java index 9b82210e6..9bbf7466b 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/FileRepository.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/FileRepository.java @@ -58,6 +58,7 @@ import java.util.HashSet; import java.util.Locale; import java.util.Objects; import java.util.Set; +import java.util.concurrent.atomic.AtomicReference; import org.eclipse.jgit.annotations.Nullable; import org.eclipse.jgit.api.errors.JGitInternalException; @@ -125,7 +126,8 @@ public class FileRepository extends Repository { private final FileBasedConfig repoConfig; private final RefDatabase refs; private final ObjectDirectory objectDatabase; - private FileSnapshot snapshot; + + private AtomicReference snapshot = new AtomicReference<>(); /** * Construct a representation of a Git repository. @@ -241,7 +243,7 @@ public class FileRepository extends Repository { } if (!isBare()) - snapshot = FileSnapshot.save(getIndexFile()); + snapshot.getAndSet(FileSnapshot.save(getIndexFile())); } private void loadSystemConfig() throws IOException { @@ -544,21 +546,23 @@ public class FileRepository extends Repository { /** Detect index changes. */ private void detectIndexChanges() { - if (isBare()) + if (isBare()) { return; + } File indexFile = getIndexFile(); - if (snapshot == null) - snapshot = FileSnapshot.save(indexFile); - else if (snapshot.isModified(indexFile)) - notifyIndexChanged(); + if (snapshot.get() == null) { + snapshot.getAndSet(FileSnapshot.save(indexFile)); + } else if (snapshot.get().isModified(indexFile)) { + notifyIndexChanged(false); + } } /** {@inheritDoc} */ @Override - public void notifyIndexChanged() { - snapshot = FileSnapshot.save(getIndexFile()); - fireEvent(new IndexChangedEvent()); + public void notifyIndexChanged(boolean internal) { + snapshot.getAndSet(FileSnapshot.save(getIndexFile())); + fireEvent(new IndexChangedEvent(internal)); } /** {@inheritDoc} */ diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/Repository.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/Repository.java index 3d85ee4e4..9b5085189 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/Repository.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/Repository.java @@ -1267,7 +1267,7 @@ public abstract class Repository implements AutoCloseable { IndexChangedListener l = new IndexChangedListener() { @Override public void onIndexChanged(IndexChangedEvent event) { - notifyIndexChanged(); + notifyIndexChanged(true); } }; return DirCache.lock(this, l); @@ -1560,16 +1560,22 @@ public abstract class Repository implements AutoCloseable { } /** - * Force a scan for changed refs. + * Force a scan for changed refs. Fires an IndexChangedEvent(false) if + * changes are detected. * * @throws java.io.IOException */ public abstract void scanForRepoChanges() throws IOException; /** - * Notify that the index changed + * Notify that the index changed by firing an IndexChangedEvent. + * + * @param internal + * {@code true} if the index was changed by the same + * JGit process + * @since 5.0 */ - public abstract void notifyIndexChanged(); + public abstract void notifyIndexChanged(boolean internal); /** * Get a shortened more user friendly ref name