Skip to content
Permalink
Browse files

[JENKINS-40834] Bingo! A nasty hack gets us the symref info for JGit …

…pending their implementation of same
  • Loading branch information...
stephenc committed Mar 22, 2017
1 parent 64f4303 commit 2cb2fc176d47bf1dc0d8017e9bfd567d4fa453e5
Showing with 47 additions and 0 deletions.
  1. +47 −0 src/main/java/org/jenkinsci/plugins/gitclient/JGitAPIImpl.java
@@ -30,7 +30,9 @@
import java.io.PrintWriter;
import java.io.StringWriter;
import java.io.Writer;
import java.lang.reflect.Field;
import java.net.URISyntaxException;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
@@ -62,6 +64,7 @@
import org.eclipse.jgit.api.ShowNoteCommand;
import org.eclipse.jgit.api.errors.CheckoutConflictException;
import org.eclipse.jgit.api.errors.GitAPIException;
import org.eclipse.jgit.api.errors.InvalidRemoteException;
import org.eclipse.jgit.api.errors.JGitInternalException;
import org.eclipse.jgit.diff.DiffEntry;
import org.eclipse.jgit.diff.DiffEntry.ChangeType;
@@ -71,6 +74,7 @@
import org.eclipse.jgit.errors.NotSupportedException;
import org.eclipse.jgit.errors.TransportException;
import org.eclipse.jgit.fnmatch.FileNameMatcher;
import org.eclipse.jgit.internal.JGitText;
import org.eclipse.jgit.internal.storage.file.FileRepository;
import org.eclipse.jgit.lib.Config;
import org.eclipse.jgit.lib.Constants;
@@ -98,6 +102,7 @@
import org.eclipse.jgit.revwalk.filter.MaxCountRevFilter;
import org.eclipse.jgit.revwalk.filter.RevFilter;
import org.eclipse.jgit.submodule.SubmoduleWalk;
import org.eclipse.jgit.transport.BasePackFetchConnection;
import org.eclipse.jgit.transport.CredentialsProvider;
import org.eclipse.jgit.transport.FetchConnection;
import org.eclipse.jgit.transport.HttpTransport;
@@ -801,10 +806,52 @@ public void deleteRef(String refName) throws GitException, InterruptedException
return references;
}
try (Repository repo = openDummyRepository()) {
try {
// HACK HACK HACK
// The symref info is advertised as a capability starting from git 1.8.5
// So all we need to do is ask JGit to fetch the refs and then (because JGit adds all capabilities
// into a Set) we iterate the resulting set to find any that matching symref=$symref:$realref
// of course JGit does not expose a way to iterate the capabilities, so instead we have to hack
// and peek inside
// TODO if JGit implement https://bugs.eclipse.org/bugs/show_bug.cgi?id=514052 we should switch to that
Class<?> basePackConnection = BasePackFetchConnection.class.getSuperclass();
Field remoteCapablities = basePackConnection.getDeclaredField("remoteCapablities");
remoteCapablities.setAccessible(true);
try (Transport transport = Transport.open(repo, url)) {
transport.setCredentialsProvider(getProvider());
try (FetchConnection fc = transport.openFetch()) {
fc.getRefs();
if (fc instanceof BasePackFetchConnection) {
Object o = remoteCapablities.get(fc);
if (o instanceof Set) {
boolean hackWorked = false;
for (String capability: (Set<String>)o) {
if (capability.startsWith("symref=")) {
hackWorked = true;
int index = capability.indexOf(":", 7);
if (index != -1) {
references.put(capability.substring(7, index), capability.substring(index+1));
}
}
}
if (hackWorked) {
return references;
}
}
}
}
} catch (URISyntaxException | NotSupportedException | TransportException e) {
// ignore this is a total hack
}
} catch (IllegalAccessException | NoSuchFieldException e) {
// ignore, we just have to try it the Git 1.8.4 way
}

LsRemoteCommand lsRemote = new LsRemoteCommand(repo);
lsRemote.setRemote(url);
lsRemote.setCredentialsProvider(getProvider());
Map<String, Ref> refs = lsRemote.callAsMap();

Ref target = refs.get(Constants.HEAD);
if (target == null) {
return references;

0 comments on commit 2cb2fc1

Please sign in to comment.
You can’t perform that action at this time.