git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[EGIT PATCH 2/9] Cached modification times for symbolic refs too

From
Robin Rosenberg <robin.rosenberg@dewire.com>
Date
Jul 10, 2008, 22:40 UTC
Message-ID
<1215729651-26781-3-git-send-email-robin.rosenberg@dewire.com>
In-Reply-To
<1215729651-26781-2-git-send-email-robin.rosenberg@dewire.com>

We want to detect changes to symbolic refs like HEAD. When HEAD is redirected to another branch, that's a change even if if the branch head itself did not change.

Signed-off-by: Robin Rosenberg <robin.rosenberg@dewire.com>
---
 .../src/org/spearce/jgit/lib/RefDatabase.java      |   48 +++++++++++---------
 1 files changed, 27 insertions(+), 21 deletions(-)
diff --git a/org.spearce.jgit/src/org/spearce/jgit/lib/RefDatabase.java b/org.spearce.jgit/src/org/spearce/jgit/lib/RefDatabase.java
index 4be33b8..17a74e5 100644
--- a/org.spearce.jgit/src/org/spearce/jgit/lib/RefDatabase.java
+++ b/org.spearce.jgit/src/org/spearce/jgit/lib/RefDatabase.java
@@ -71,7 +71,8 @@ class RefDatabase {
 
 	private final File refsDir;
 
-	private Map<String, CachedRef> looseRefs;
+	private Map<String, Ref> looseRefs;
+	private Map<String, Long> looseRefsMTime;
 
 	private final File packedRefsFile;
 
@@ -94,7 +95,8 @@ class RefDatabase {
 	}
 
 	void clearCache() {
-		looseRefs = new HashMap<String, CachedRef>();
+		looseRefs = new HashMap<String, Ref>();
+		looseRefsMTime = new HashMap<String, Long>();
 		packedRefs = new HashMap<String, Ref>();
 		packedRefsLastModified = 0;
 		packedRefsLength = 0;
@@ -135,7 +137,8 @@ class RefDatabase {
 	}
 
 	void stored(final String name, final ObjectId id, final long time) {
-		looseRefs.put(name, new CachedRef(Ref.Storage.LOOSE, name, id, time));
+		looseRefs.put(name, new Ref(Ref.Storage.LOOSE, name, id));
+		looseRefsMTime.put(name, time);
 		setModified();
 		db.fireRefsMaybeChanged();
 	}
@@ -203,7 +206,11 @@ class RefDatabase {
 		final HashMap<String, Ref> avail = new HashMap<String, Ref>();
 		readPackedRefs(avail);
 		readLooseRefs(avail, REFS_SLASH, refsDir);
-		readOneLooseRef(avail, Constants.HEAD, new File(gitDir, Constants.HEAD));
+		try {
+			avail.put(Constants.HEAD, readRefBasic(Constants.HEAD, 0));
+		} catch (IOException e) {
+			// ignore here
+		}
 		db.fireRefsMaybeChanged();
 		return avail;
 	}
@@ -231,13 +238,15 @@ class RefDatabase {
 			final String refName, final File ent) {
 		// Unchanged and cached? Don't read it again.
 		//
-		CachedRef ref = looseRefs.get(refName);
+		Ref ref = looseRefs.get(refName);
 		if (ref != null) {
-			if (ref.lastModified == ent.lastModified()) {
+			Long cachedlastModified = looseRefsMTime.get(refName);
+			if (cachedlastModified != null && cachedlastModified == ent.lastModified()) {
 				avail.put(ref.getName(), ref);
 				return;
 			}
 			looseRefs.remove(refName);
+			looseRefsMTime.remove(refName);
 		}
 
 		// Recurse into the directory.
@@ -269,9 +278,9 @@ class RefDatabase {
 					return;
 				}
 
-				ref = new CachedRef(Ref.Storage.LOOSE, refName, id, ent
-						.lastModified());
+				ref = new Ref(Ref.Storage.LOOSE, refName, id);
 				looseRefs.put(ref.getName(), ref);
+				looseRefsMTime.put(ref.getName(), ent.lastModified());
 				avail.put(ref.getName(), ref);
 			} finally {
 				in.close();
@@ -297,13 +306,15 @@ class RefDatabase {
 		// Prefer loose ref to packed ref as the loose
 		// file can be more up-to-date than a packed one.
 		//
-		CachedRef ref = looseRefs.get(name);
+		Ref ref = looseRefs.get(name);
 		final File loose = fileForRef(name);
 		final long mtime = loose.lastModified();
 		if (ref != null) {
-			if (ref.lastModified == mtime)
+			Long cachedlastModified = looseRefsMTime.get(name);
+			if (cachedlastModified != null && cachedlastModified == mtime)
 				return ref;
 			looseRefs.remove(name);
+			looseRefsMTime.remove(name);
 		}
 
 		if (mtime == 0) {
@@ -331,6 +342,10 @@ class RefDatabase {
 
 			final String target = line.substring("ref: ".length());
 			final Ref r = readRefBasic(target, depth + 1);
+			Long cachedMtime = looseRefsMTime.get(name);
+			if (cachedMtime != null && cachedMtime != mtime)
+				setModified();
+			looseRefsMTime.put(name, mtime);
 			return r != null ? r : new Ref(Ref.Storage.LOOSE, target, null);
 		}
 
@@ -343,8 +358,9 @@ class RefDatabase {
 			throw new IOException("Not a ref: " + name + ": " + line);
 		}
 
-		ref = new CachedRef(Ref.Storage.LOOSE, name, id, mtime);
+		ref = new Ref(Ref.Storage.LOOSE, name, id);
 		looseRefs.put(name, ref);
+		looseRefsMTime.put(name, mtime);
 		return ref;
 	}
 
@@ -421,14 +437,4 @@ class RefDatabase {
 				fileLocation), CHAR_ENC));
 	}
 
-	private static class CachedRef extends Ref {
-		final long lastModified;
-
-		CachedRef(final Storage st, final String refName, final ObjectId id,
-				final long mtime) {
-			super(st, refName, id);
-			lastModified = mtime;
-		}
-	}
-
 }
-- 
1.5.6.2.220.g44701
Previous: Robin RosenbergNext: Robin Rosenberg
Message 3 of 19 in “Repository change listeners”
  1. 0/9 Repository change listenersRobin Rosenberg, Jul 10, 2008
  2. 1/9 Create a listener structure for changes to refs and indexRobin Rosenberg, Jul 10, 2008
  3. 2/9 Cached modification times for symbolic refs tooRobin Rosenberg, Jul 10, 2008
  4. 3/9 Connect the history page to the refs update subscription mechanismRobin Rosenberg, Jul 10, 2008
  5. 4/9 Add a method to listen to changes in any repositoryRobin Rosenberg, Jul 10, 2008
  6. 5/9 Add a job to periodically scan for repository changesRobin Rosenberg, Jul 10, 2008
  7. 6/9 Change GitHistoryPage to listen on any repository.Robin Rosenberg, Jul 10, 2008
  8. 7/9 Add a job to refresh projects when the index changes.Robin Rosenberg, Jul 10, 2008
  9. 8/9 Make git dectected changes depend on the automatic refresh settingRobin Rosenberg, Jul 10, 2008
  10. 9/9 Attach the resource decorator to the repository change event mechanismRobin Rosenberg, Jul 10, 2008
  11. Shawn O. PearceJul 11, 2008
  12. 7/7 Add a job to refresh projects when the index changes.Robin Rosenberg, Jul 11, 2008
  13. Shawn O. PearceJul 11, 2008
  14. 4/4 Add a method to listen to changes in any repositoryRobin Rosenberg, Jul 11, 2008
  15. jgit (was: [PATCH 4/4] Add a method...)Andreas Ericsson, Jul 11, 2008
  16. Robin RosenbergJul 11, 2008
  17. Shawn O. PearceJul 11, 2008
  18. Create a listener structure for changes to refs and indexRobin Rosenberg, Jul 11, 2008
  19. Shawn O. PearceJul 11, 2008

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.