Store in IndexChangedEvent if it was caused by JGit itself

This allows to differentiate if index was changed by an external git
command or by JGit itself.

Change-Id: Iae692ba7d9bf01a288b3fb2dc2d07aec9891c712
Signed-off-by: Matthias Sohn <matthias.sohn@sap.com>
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 d7f975b..db1cfd5 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 boolean commit() {
 		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 647ec8a..dcce86a 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 @@
  * Describes a change to one or more paths in the index file.
  */
 public class IndexChangedEvent extends RepositoryEvent<IndexChangedListener> {
+	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<IndexChangedListener> 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 1976816..5169e92 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 void scanForRepoChanges() throws IOException {
 
 	/** {@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 9b82210..9bbf746 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.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<FileSnapshot> snapshot = new AtomicReference<>();
 
 	/**
 	 * Construct a representation of a Git repository.
@@ -241,7 +243,7 @@ public void onConfigChanged(ConfigChangedEvent event) {
 		}
 
 		if (!isBare())
-			snapshot = FileSnapshot.save(getIndexFile());
+			snapshot.getAndSet(FileSnapshot.save(getIndexFile()));
 	}
 
 	private void loadSystemConfig() throws IOException {
@@ -544,21 +546,23 @@ public void scanForRepoChanges() throws IOException {
 
 	/** 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 3d85ee4..9b50851 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 DirCache lockDirCache() throws NoWorkTreeException,
 		IndexChangedListener l = new IndexChangedListener() {
 			@Override
 			public void onIndexChanged(IndexChangedEvent event) {
-				notifyIndexChanged();
+				notifyIndexChanged(true);
 			}
 		};
 		return DirCache.lock(this, l);
@@ -1560,16 +1560,22 @@ public File getWorkTree() throws NoWorkTreeException {
 	}
 
 	/**
-	 * 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