[EGIT PATCH 4/7 v3] Handle peeling of loose refs.
From: Robin Rosenberg <hidden>
Date: 2016-06-15 22:45:39
Subsystem:
the rest · Maintainer:
Linus Torvalds
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 <redacted> --- org.spearce.jgit/src/org/spearce/jgit/lib/Ref.java | 35 ++++++++++++++----- .../src/org/spearce/jgit/lib/RefDatabase.java | 32 ++++++++++++++++-- .../src/org/spearce/jgit/lib/Repository.java | 13 +++++++ .../spearce/jgit/transport/BasePackConnection.java | 2 +- .../spearce/jgit/transport/TransportAmazonS3.java | 2 +- .../org/spearce/jgit/transport/TransportHttp.java | 2 +- .../org/spearce/jgit/transport/TransportSftp.java | 2 +- .../jgit/transport/WalkRemoteObjectDatabase.java | 2 +- 8 files changed, 73 insertions(+), 17 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..0e98f46 100644
--- a/org.spearce.jgit/src/org/spearce/jgit/lib/Ref.java
+++ b/org.spearce.jgit/src/org/spearce/jgit/lib/Ref.java@@ -126,6 +126,8 @@ public boolean isPacked() { private final String origName; + private final boolean peeled; + /** * Create a new ref pairing. *
@@ -140,10 +142,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, null, false); } /**
@@ -158,7 +157,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, null, false); } /**
@@ -175,15 +174,18 @@ 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 not yet peeled (in which case the next parameter should be null) + * @param peeled + * true if peel represents a the peeled value of the object */ public Ref(final Storage st, final String origName, final String refName, final ObjectId id, - final ObjectId peel) { + final ObjectId peel, final boolean peeled) { storage = st; this.origName = origName; name = refName; objectId = id; peeledObjectId = peel; + this.peeled = peeled; } /**
@@ -199,10 +201,12 @@ public Ref(final Storage st, final String origName, final String refName, final * @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. + * @param peeled + * true if peel represents a the peeled value of the object */ public Ref(final Storage st, final String refName, final ObjectId id, - final ObjectId peel) { - this(st, refName, refName, id, peel); + final ObjectId peel, boolean peeled) { + this(st, refName, refName, id, peel, peeled); } /**
@@ -238,10 +242,19 @@ public ObjectId getObjectId() { * refer to an annotated tag. */ public ObjectId getPeeledObjectId() { + if (!peeled) + return null; return peeledObjectId; } /** + * @return whether the Ref represents a peeled tag + */ + public boolean isPeeled() { + return peeled; + } + + /** * How was this ref obtained? * <p> * The current storage model of a Ref may influence how the ref must be
@@ -259,4 +272,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..494aecb 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, false); // 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; + ObjectId peeled = null; + try { + Object target = db.mapObject(ref.getObjectId(), ref.getName()); + while (target instanceof Tag) { + final Tag tag = (Tag)target; + peeled = tag.getObjId(); + if (Constants.TYPE_TAG.equals(tag.getType())) + target = db.mapObject(tag.getObjId(), ref.getName()); + else + break; + } + } catch (IOException e) { + // Ignore a read error. Â Callers will also get the same error + // if they try to use the result of getPeeledObjectId. + } + return new Ref(ref.getStorage(), ref.getName(), ref.getObjectId(), peeled, true); + + } + private File fileForRef(final String name) { if (name.startsWith(REFS_SLASH)) return new File(refsDir, name.substring(REFS_SLASH.length()));
@@ -350,7 +373,7 @@ private Ref readRefBasic(final String origName, final String name, final int dep if (r == null) return new Ref(Ref.Storage.LOOSE, origName, target, null); if (!origName.equals(r.getName())) - r = new Ref(Ref.Storage.LOOSE_PACKED, origName, r.getName(), r.getObjectId(), r.getPeeledObjectId()); + r = new Ref(Ref.Storage.LOOSE_PACKED, origName, r.getName(), r.getObjectId(), r.getPeeledObjectId(), true); return r; }
@@ -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;
@@ -397,7 +423,7 @@ private void refreshPackedRefs() { final ObjectId id = ObjectId.fromString(p.substring(1)); last = new Ref(Ref.Storage.PACKED, last.getName(), last - .getName(), last.getObjectId(), id); + .getName(), last.getObjectId(), id, true); newPackedRefs.put(last.getName(), last); continue; }
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() {
diff --git a/org.spearce.jgit/src/org/spearce/jgit/transport/BasePackConnection.java b/org.spearce.jgit/src/org/spearce/jgit/transport/BasePackConnection.java
index e5fc040..e9df30e 100644
--- a/org.spearce.jgit/src/org/spearce/jgit/transport/BasePackConnection.java
+++ b/org.spearce.jgit/src/org/spearce/jgit/transport/BasePackConnection.java@@ -176,7 +176,7 @@ private void readAdvertisedRefsImpl() throws IOException { throw duplicateAdvertisement(name + "^{}"); avail.put(name, new Ref(Ref.Storage.NETWORK, name, prior - .getObjectId(), id)); + .getObjectId(), id, true)); } else { final Ref prior; prior = avail.put(name, new Ref(Ref.Storage.NETWORK, name, id));
diff --git a/org.spearce.jgit/src/org/spearce/jgit/transport/TransportAmazonS3.java b/org.spearce.jgit/src/org/spearce/jgit/transport/TransportAmazonS3.java
index f9df36d..9f1b516 100644
--- a/org.spearce.jgit/src/org/spearce/jgit/transport/TransportAmazonS3.java
+++ b/org.spearce.jgit/src/org/spearce/jgit/transport/TransportAmazonS3.java@@ -300,7 +300,7 @@ private Ref readRef(final TreeMap<String, Ref> avail, final String rn) if (r == null) return null; r = new Ref(r.getStorage(), rn, r.getObjectId(), r - .getPeeledObjectId()); + .getPeeledObjectId(), r.isPeeled()); avail.put(r.getName(), r); return r; }
diff --git a/org.spearce.jgit/src/org/spearce/jgit/transport/TransportHttp.java b/org.spearce.jgit/src/org/spearce/jgit/transport/TransportHttp.java
index 1357e58..fe4a437 100644
--- a/org.spearce.jgit/src/org/spearce/jgit/transport/TransportHttp.java
+++ b/org.spearce.jgit/src/org/spearce/jgit/transport/TransportHttp.java@@ -237,7 +237,7 @@ FileStream open(final String path) throws IOException { throw duplicateAdvertisement(name + "^{}"); avail.put(name, new Ref(Ref.Storage.NETWORK, name, prior - .getObjectId(), id)); + .getObjectId(), id, true)); } else { final Ref prior = avail.put(name, new Ref( Ref.Storage.NETWORK, name, id));
diff --git a/org.spearce.jgit/src/org/spearce/jgit/transport/TransportSftp.java b/org.spearce.jgit/src/org/spearce/jgit/transport/TransportSftp.java
index 78f4ad8..544e77c 100644
--- a/org.spearce.jgit/src/org/spearce/jgit/transport/TransportSftp.java
+++ b/org.spearce.jgit/src/org/spearce/jgit/transport/TransportSftp.java@@ -428,7 +428,7 @@ private Ref readRef(final TreeMap<String, Ref> avail, r = avail.get(p); if (r != null) { r = new Ref(loose(r), name, r.getObjectId(), r - .getPeeledObjectId()); + .getPeeledObjectId(), true); avail.put(name, r); } return r;
diff --git a/org.spearce.jgit/src/org/spearce/jgit/transport/WalkRemoteObjectDatabase.java b/org.spearce.jgit/src/org/spearce/jgit/transport/WalkRemoteObjectDatabase.java
index 54dd581..a4f8961 100644
--- a/org.spearce.jgit/src/org/spearce/jgit/transport/WalkRemoteObjectDatabase.java
+++ b/org.spearce.jgit/src/org/spearce/jgit/transport/WalkRemoteObjectDatabase.java@@ -438,7 +438,7 @@ private void readPackedRefsImpl(final Map<String, Ref> avail, throw new TransportException("Peeled line before ref."); final ObjectId id = ObjectId.fromString(line + 1); last = new Ref(Ref.Storage.PACKED, last.getName(), last - .getObjectId(), id); + .getObjectId(), id, true); avail.put(last.getName(), last); continue; }
--
1.6.0.3.640.g6331a.dirty