diff options
author | Matthias Sohn <matthias.sohn@sap.com> | 2018-12-25 23:58:53 +0100 |
---|---|---|
committer | Matthias Sohn <matthias.sohn@sap.com> | 2018-12-25 23:58:53 +0100 |
commit | 25deb304600242e4bffda53b9e41d46bcb301414 (patch) | |
tree | 0eb236acb820d1c537dbfcb7cf91839f1257a7f2 /org.eclipse.jgit | |
parent | f4fc6404baac5a6a5db34f71e62fb62fd8f1b8ef (diff) | |
parent | 8eecb4f8b746bc01f09df02870e89d4bc4e118b9 (diff) | |
download | jgit-25deb304600242e4bffda53b9e41d46bcb301414.tar.gz jgit-25deb304600242e4bffda53b9e41d46bcb301414.zip |
Merge branch 'stable-5.0' into stable-5.1
* stable-5.0:
Call AdvertiseRefsHook for protocol v2
Prepare 4.11.7-SNAPSHOT builds
JGit v4.11.6.201812241910-r
Prepare 4.9.9-SNAPSHOT builds
JGit v4.9.8.201812241815-r
UploadPack: Test filtering by AdvertiseRefsHook in stateless transports
Prepare 4.7.8-SNAPSHOT builds
JGit v4.7.7.201812240805-r
Fix feature versions imported by feature org.eclipse.jgit.pgm
Prepare 4.5.6-SNAPSHOT builds
JGit v4.5.5.201812240535-r
Call AdvertiseRefsHook before validating wants
Change-Id: Icdc212bf5be2485d0f8028acf6c62fb8531d0e3c
Signed-off-by: Jonathan Nieder <jrn@google.com>
Signed-off-by: Matthias Sohn <matthias.sohn@sap.com>
Diffstat (limited to 'org.eclipse.jgit')
-rw-r--r-- | org.eclipse.jgit/src/org/eclipse/jgit/transport/UploadPack.java | 79 |
1 files changed, 54 insertions, 25 deletions
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/UploadPack.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/UploadPack.java index cd7290edcd..c753bcdc7a 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/UploadPack.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/UploadPack.java @@ -43,8 +43,9 @@ package org.eclipse.jgit.transport; +import static java.util.function.Function.identity; +import static java.util.stream.Collectors.toMap; import static org.eclipse.jgit.lib.Constants.R_TAGS; -import static org.eclipse.jgit.lib.RefDatabase.ALL; import static org.eclipse.jgit.transport.GitProtocolConstants.CAPABILITY_REF_IN_WANT; import static org.eclipse.jgit.transport.GitProtocolConstants.COMMAND_FETCH; import static org.eclipse.jgit.transport.GitProtocolConstants.COMMAND_LS_REFS; @@ -262,7 +263,10 @@ public class UploadPack { private OutputStream msgOut = NullOutputStream.INSTANCE; - /** The refs we advertised as existing at the start of the connection. */ + /** + * Refs eligible for advertising to the client, set using + * {@link #setAdvertisedRefs}. + */ private Map<String, Ref> refs; /** Hook used while processing Git protocol v2 requests. */ @@ -271,6 +275,9 @@ public class UploadPack { /** Hook used while advertising the refs to the client. */ private AdvertiseRefsHook advertiseRefsHook = AdvertiseRefsHook.DEFAULT; + /** Whether the {@link #advertiseRefsHook} has been invoked. */ + private boolean advertiseRefsHookCalled; + /** Filter used while advertising the refs to the client. */ private RefFilter refFilter = RefFilter.DEFAULT; @@ -793,11 +800,52 @@ public class UploadPack { } private Map<String, Ref> getAdvertisedOrDefaultRefs() throws IOException { - if (refs == null) - setAdvertisedRefs(db.getRefDatabase().getRefs(ALL)); + if (refs != null) { + return refs; + } + + advertiseRefsHook.advertiseRefs(this); + advertiseRefsHookCalled = true; + if (refs == null) { + // Fall back to all refs. + setAdvertisedRefs( + db.getRefDatabase().getRefs().stream() + .collect(toMap(Ref::getName, identity()))); + } return refs; } + private Map<String, Ref> getFilteredRefs(Collection<String> refPrefixes) + throws IOException { + if (refPrefixes.isEmpty()) { + return getAdvertisedOrDefaultRefs(); + } + if (refs == null && !advertiseRefsHookCalled) { + advertiseRefsHook.advertiseRefs(this); + advertiseRefsHookCalled = true; + } + if (refs == null) { + // Fast path: the advertised refs hook did not set advertised refs. + Map<String, Ref> rs = new HashMap<>(); + for (String p : refPrefixes) { + for (Ref r : db.getRefDatabase().getRefsByPrefix(p)) { + rs.put(r.getName(), r); + } + } + if (refFilter != RefFilter.DEFAULT) { + return refFilter.filter(rs); + } + return transferConfig.getRefFilter().filter(rs); + } + + // Slow path: filter the refs provided by the advertised refs hook. + // refFilter has already been applied to refs. + return refs.values().stream() + .filter(ref -> refPrefixes.stream() + .anyMatch(ref.getName()::startsWith)) + .collect(toMap(Ref::getName, identity())); + } + private void service() throws IOException { boolean sendPack = false; // If it's a non-bidi request, we need to read the entire request before @@ -923,17 +971,7 @@ public class UploadPack { if (req.getPeel()) { adv.setDerefTags(true); } - Map<String, Ref> refsToSend; - if (req.getRefPrefixes().isEmpty()) { - refsToSend = getAdvertisedOrDefaultRefs(); - } else { - refsToSend = new HashMap<>(); - for (String refPrefix : req.getRefPrefixes()) { - for (Ref ref : db.getRefDatabase().getRefsByPrefix(refPrefix)) { - refsToSend.put(ref.getName(), ref); - } - } - } + Map<String, Ref> refsToSend = getFilteredRefs(req.getRefPrefixes()); if (req.getSymrefs()) { findSymrefs(adv, refsToSend); } @@ -1281,15 +1319,7 @@ public class UploadPack { return; } - try { - advertiseRefsHook.advertiseRefs(this); - } catch (ServiceMayNotContinueException fail) { - if (fail.getMessage() != null) { - adv.writeOne("ERR " + fail.getMessage()); //$NON-NLS-1$ - fail.setOutput(); - } - throw fail; - } + Map<String, Ref> advertisedOrDefaultRefs = getAdvertisedOrDefaultRefs(); if (serviceName != null) { adv.writeOne("# service=" + serviceName + '\n'); //$NON-NLS-1$ @@ -1321,7 +1351,6 @@ public class UploadPack { adv.advertiseCapability(OPTION_FILTER); } adv.setDerefTags(true); - Map<String, Ref> advertisedOrDefaultRefs = getAdvertisedOrDefaultRefs(); findSymrefs(adv, advertisedOrDefaultRefs); advertised = adv.send(advertisedOrDefaultRefs); if (adv.isEmpty()) |