The HEAD ref cannot be pushed to by a client, if it is a detached HEAD the client shouldn't be permitted to change it, if it is a symref to another ref then the client should update the destination ref and not the symref. Instead offer the HEAD ref as a ".have" line, which is an invalid ref that the client can't update but still lets the client know we have its target object reachable. Signed-off-by: Shawn O. Pearce <spearce@xxxxxxxxxxx> --- .../org/spearce/jgit/transport/ReceivePack.java | 5 ++++- .../org/spearce/jgit/transport/RefAdvertiser.java | 15 +++++++++++++++ 2 files changed, 19 insertions(+), 1 deletions(-) diff --git a/org.spearce.jgit/src/org/spearce/jgit/transport/ReceivePack.java b/org.spearce.jgit/src/org/spearce/jgit/transport/ReceivePack.java index fd8aa86..1c490af 100644 --- a/org.spearce.jgit/src/org/spearce/jgit/transport/ReceivePack.java +++ b/org.spearce.jgit/src/org/spearce/jgit/transport/ReceivePack.java @@ -509,8 +509,11 @@ private void sendAdvertisedRefs() throws IOException { adv.advertiseCapability(CAPABILITY_REPORT_STATUS); if (allowOfsDelta) adv.advertiseCapability(CAPABILITY_OFS_DELTA); - refs = db.getAllRefs(); + refs = new HashMap<String, Ref>(db.getAllRefs()); + final Ref head = refs.remove(Constants.HEAD); adv.send(refs.values()); + if (head != null && head.getName() == head.getOrigName()) + adv.advertiseHave(head.getObjectId()); if (adv.isEmpty()) adv.advertiseId(ObjectId.zeroId(), "capabilities^{}"); pckOut.end(); diff --git a/org.spearce.jgit/src/org/spearce/jgit/transport/RefAdvertiser.java b/org.spearce.jgit/src/org/spearce/jgit/transport/RefAdvertiser.java index 245891d..91700da 100644 --- a/org.spearce.jgit/src/org/spearce/jgit/transport/RefAdvertiser.java +++ b/org.spearce.jgit/src/org/spearce/jgit/transport/RefAdvertiser.java @@ -95,6 +95,15 @@ void send(final Collection<Ref> refs) throws IOException { } } + void advertiseHave(AnyObjectId id) throws IOException { + RevObject obj = parseAnyOrNull(id); + if (obj != null) { + advertiseAnyOnce(obj, ".have"); + if (obj instanceof RevTag) + advertiseAnyOnce(((RevTag) obj).getObject(), ".have"); + } + } + boolean isEmpty() { return first; } @@ -109,6 +118,12 @@ private RevObject parseAnyOrNull(final AnyObjectId id) { } } + private void advertiseAnyOnce(final RevObject obj, final String refName) + throws IOException { + if (!obj.has(ADVERTISED)) + advertiseAny(obj, refName); + } + private void advertiseAny(final RevObject obj, final String refName) throws IOException { obj.add(ADVERTISED); -- 1.6.4.rc0.117.g28cb -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html