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

[EGIT PATCH 4/7] Handle peeling of loose refs.

From
Robin Rosenberg <robin.rosenberg@dewire.com>
Date
Nov 7, 2008, 22:07 UTC
Message-ID
<1226095664-13759-5-git-send-email-robin.rosenberg@dewire.com>
In-Reply-To
<1226095664-13759-4-git-send-email-robin.rosenberg@dewire.com>

For packed refs we got peeling automatically from packed-refs, but for loose tags we have to follow the tags and get the leaf object in order to comply with the documentation.

Signed-off-by: Robin Rosenberg <robin.rosenberg@dewire.com>
---
 org.spearce.jgit/src/org/spearce/jgit/lib/Ref.java |   22 +++++++++++----
 .../src/org/spearce/jgit/lib/RefDatabase.java      |   28 +++++++++++++++++++-
 .../src/org/spearce/jgit/lib/Repository.java       |   13 +++++++++
 3 files changed, 56 insertions(+), 7 deletions(-)
diff --git a/org.spearce.jgit/src/org/spearce/jgit/lib/Ref.java b/org.spearce.jgit/src/org/spearce/jgit/lib/Ref.java
index 2f102af..1a6cc4c 100644
--- a/org.spearce.jgit/src/org/spearce/jgit/lib/Ref.java
+++ b/org.spearce.jgit/src/org/spearce/jgit/lib/Ref.java
@@ -140,10 +140,7 @@ public boolean isPacked() {
 	 *            does not exist yet.
 	 */
 	public Ref(final Storage st, final String origName, final String refName, final ObjectId id) {
-		storage = st;
-		this.origName = origName;
-		name = refName;
-		objectId = id;
+		this(st, origName, refName, id, ObjectId.zeroId());
 	}
 
 	/**
@@ -158,7 +155,7 @@ public Ref(final Storage st, final String origName, final String refName, final 
 	 *            does not exist yet.
 	 */
 	public Ref(final Storage st, final String refName, final ObjectId id) {
-		this(st, refName, refName, id);
+		this(st, refName, refName, id, ObjectId.zeroId());
 	}
 
 	/**
@@ -175,7 +172,7 @@ public Ref(final Storage st, final String refName, final ObjectId id) {
 	 *            does not exist yet.
 	 * @param peel
 	 *            peeled value of the ref's tag. May be null if this is not a
-	 *            tag or the peeled value is not known.
+	 *            tag or the zero id if the peeled value is not known.
 	 */
 	public Ref(final Storage st, final String origName, final String refName, final ObjectId id,
 			final ObjectId peel) {
@@ -238,10 +235,19 @@ public ObjectId getObjectId() {
 	 *         refer to an annotated tag.
 	 */
 	public ObjectId getPeeledObjectId() {
+		if (peeledObjectId == ObjectId.zeroId())
+			return null;
 		return peeledObjectId;
 	}
 
 	/**
+	 * @return whether the Ref represents a peeled tag
+	 */
+	public boolean isPeeled() {
+		return peeledObjectId != null && peeledObjectId != ObjectId.zeroId();
+	}
+
+	/**
 	 * How was this ref obtained?
 	 * <p>
 	 * The current storage model of a Ref may influence how the ref must be
@@ -259,4 +265,8 @@ public String toString() {
 			o = "(" + origName + ")";
 		return "Ref[" + o + name + "=" + ObjectId.toString(getObjectId()) + "]";
 	}
+
+	void setPeeledObjectId(final ObjectId id) {
+		peeledObjectId = id;
+	}
 }
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 5a1b85f..0d73191 100644
--- a/org.spearce.jgit/src/org/spearce/jgit/lib/RefDatabase.java
+++ b/org.spearce.jgit/src/org/spearce/jgit/lib/RefDatabase.java
@@ -271,7 +271,8 @@ private void readOneLooseRef(final Map<String, Ref> avail,
 					return;
 				}
 
-				ref = new Ref(Ref.Storage.LOOSE, origName, refName, id);
+				ref = new Ref(Ref.Storage.LOOSE, origName, refName, id, null); // unpeeled
+
 				looseRefs.put(ref.getName(), ref);
 				looseRefsMTime.put(ref.getName(), ent.lastModified());
 				avail.put(ref.getName(), ref);
@@ -288,6 +289,28 @@ private void readOneLooseRef(final Map<String, Ref> avail,
 		}
 	}
 
+	Ref peel(final Ref ref) {
+		if (ref.isPeeled())
+			return ref;
+		try {
+			Object tt = db.mapObject(ref.getObjectId(), ref.getName());
+			if (tt != null && tt instanceof Tag) {
+				Tag t = (Tag)tt;
+				while (t != null && t.getType().equals(Constants.TYPE_TAG))
+					t = db.mapTag(t.getTag(), t.getObjId());
+				if (t != null)
+					ref.setPeeledObjectId(t.getObjId());
+				else
+					ref.setPeeledObjectId(null);
+			} else
+				ref.setPeeledObjectId(ref.getObjectId());
+		} catch (IOException e) {
+			// Serious error. Caller knows a ref should never be null
+			ref.setPeeledObjectId(null);
+		}
+		return ref;
+	}
+
 	private File fileForRef(final String name) {
 		if (name.startsWith(REFS_SLASH))
 			return new File(refsDir, name.substring(REFS_SLASH.length()));
@@ -364,6 +387,9 @@ private Ref readRefBasic(final String origName, final String name, final int dep
 		}
 
 		ref = new Ref(Ref.Storage.LOOSE, origName, name, id);
+
+		looseRefs.put(origName, ref);
+		ref = new Ref(Ref.Storage.LOOSE, origName, id);
 		looseRefs.put(name, ref);
 		looseRefsMTime.put(name, mtime);
 		return ref;
diff --git a/org.spearce.jgit/src/org/spearce/jgit/lib/Repository.java b/org.spearce.jgit/src/org/spearce/jgit/lib/Repository.java
index 26748e2..4d6e6fd 100644
--- a/org.spearce.jgit/src/org/spearce/jgit/lib/Repository.java
+++ b/org.spearce.jgit/src/org/spearce/jgit/lib/Repository.java
@@ -939,6 +939,19 @@ public String getBranch() throws IOException {
 	}
 
 	/**
+	 * Peel a possibly unpeeled ref and updates it. If the ref cannot be peeled
+	 * the peeled id is set to {@link ObjectId#zeroId()}
+	 * 
+	 * @param ref
+	 *            The ref to peel
+	 * @return The same, an updated ref with peeled info or a new instance with
+	 *         more information
+	 */
+	public Ref peel(final Ref ref) {
+		return refs.peel(ref);
+	}
+
+	/**
 	 * @return true if HEAD points to a StGit patch.
 	 */
 	public boolean isStGitMode() {
-- 
1.6.0.3.578.g6a50
Previous: Robin RosenbergNext: Robin Rosenberg
Message 5 of 22 in “Tag decoration v2”
  1. 0/7 Tag decoration v2Robin Rosenberg, Nov 7, 2008
  2. 1/7 Test the origName part of the key vs the ref itselfRobin Rosenberg, Nov 7, 2008
  3. 2/7 Add constant for "refs/"Robin Rosenberg, Nov 7, 2008
  4. 3/7 Keep original ref name when reading refsRobin Rosenberg, Nov 7, 2008
  5. 4/7 Handle peeling of loose refs.Robin Rosenberg, Nov 7, 2008
  6. 5/7 Add a method to get refs by object IdRobin Rosenberg, Nov 7, 2008
  7. 6/7 Add tags to the graphical history display.Robin Rosenberg, Nov 7, 2008
  8. 7/7 Add decorate option to log programRobin Rosenberg, Nov 7, 2008
  9. Shawn O. PearceNov 11, 2008
  10. Robin RosenbergNov 14, 2008
  11. Shawn O. PearceNov 11, 2008
  12. 1/7 Add constant for "refs/"Robin Rosenberg, Nov 14, 2008
  13. 2/7 Keep original ref name when reading refsRobin Rosenberg, Nov 14, 2008
  14. 3/7 Test the origName part of the key vs the ref itselfRobin Rosenberg, Nov 14, 2008
  15. 4/7 Handle peeling of loose refs.Robin Rosenberg, Nov 14, 2008
  16. 5/7 Add a method to get refs by object IdRobin Rosenberg, Nov 14, 2008
  17. Shawn O. PearceNov 16, 2008
  18. Shawn O. PearceNov 11, 2008
  19. Shawn O. PearceNov 11, 2008
  20. Robin RosenbergNov 14, 2008
  21. Shawn O. PearceNov 11, 2008
  22. Robin RosenbergNov 13, 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.