Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
  • Loading branch information
stephenc committed Mar 22, 2017
1 parent f97f860 commit 266413c
Show file tree
Hide file tree
Showing 3 changed files with 64 additions and 23 deletions.
2 changes: 1 addition & 1 deletion pom.xml
Expand Up @@ -147,7 +147,7 @@
<dependency>
<groupId>org.jenkins-ci.plugins</groupId>
<artifactId>git-client</artifactId>
<version>2.3.0</version>
<version>2.3.1-20170322.101950-1</version>
</dependency>
<dependency>
<groupId>org.jenkins-ci.plugins</groupId>
Expand Down
53 changes: 45 additions & 8 deletions src/main/java/jenkins/plugins/git/AbstractGitSCMSource.java
Expand Up @@ -54,9 +54,11 @@
import hudson.plugins.git.util.BuildChooserContext;
import hudson.plugins.git.util.BuildChooserDescriptor;
import hudson.plugins.git.util.BuildData;
import hudson.remoting.VirtualChannel;
import hudson.scm.SCM;
import hudson.security.ACL;
import java.util.Map;
import java.util.TreeSet;
import jenkins.model.Jenkins;
import jenkins.scm.api.SCMFile;
import jenkins.scm.api.SCMHead;
Expand Down Expand Up @@ -104,6 +106,7 @@
import java.util.logging.Logger;
import java.util.regex.Pattern;
import org.eclipse.jgit.transport.URIish;
import org.jenkinsci.plugins.gitclient.RepositoryCallback;

/**
* @author Stephen Connolly
Expand Down Expand Up @@ -387,22 +390,56 @@ protected List<Action> retrieveActions(@CheckForNull SCMSourceEvent event, @NonN
return doRetrieve(new Retriever<List<Action>>() {
@Override
public List<Action> run(GitClient client, String remoteName) throws IOException, InterruptedException {
final Repository repository = client.getRepository();
Ref headRef = repository.getRef(Constants.HEAD);
if (headRef instanceof SymbolicRef) {
String target = headRef.getTarget().getName();
if (target.startsWith(Constants.R_HEADS)){
Map<String, String> symrefs = client.getRemoteSymbolicReferences(getRemote(), null);
if (symrefs.containsKey(Constants.HEAD)) {
// Hurrah! The Server is Git 1.8.5 or newer and our client has symref reporting
String target = symrefs.get(Constants.HEAD);
if (target.startsWith(Constants.R_HEADS)) {
// shorten standard names
target = target.substring(Constants.R_HEADS.length());
}
List<Action> result = new ArrayList<Action>();
List<Action> result = new ArrayList<>();
if (StringUtils.isNotBlank(target)) {
result.add(new GitRemoteHeadRefAction(getRemote(), target));
}
return result;
} else {
return Collections.emptyList();
}
// Ok, now we do it the old-school way... see what ref has the same hash as HEAD
// I think we will still need to keep this code path even if JGit implements
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=514052 as there is always the potential that
// the remote server is Git 1.8.4 or earlier
Map<String, ObjectId> remoteReferences = client.getRemoteReferences(getRemote(), null, false, false);
if (remoteReferences.containsKey(Constants.HEAD)) {
ObjectId head = remoteReferences.get(Constants.HEAD);
Set<String> names = new TreeSet<>();
for (Map.Entry<String, ObjectId> entry: remoteReferences.entrySet()) {
if (entry.getKey().equals(Constants.HEAD)) continue;
if (head.equals(entry.getValue())) {
names.add(entry.getKey());
}
}
// if there is one and only one match, that's the winner
if (names.size() == 1) {
String target = names.iterator().next();
if (target.startsWith(Constants.R_HEADS)) {
// shorten standard names
target = target.substring(Constants.R_HEADS.length());
}
List<Action> result = new ArrayList<>();
if (StringUtils.isNotBlank(target)) {
result.add(new GitRemoteHeadRefAction(getRemote(), target));
}
return result;
}
// if there are multiple matches, prefer `master`
if (names.contains(Constants.R_HEADS + Constants.MASTER)) {
List<Action> result = new ArrayList<Action>();
result.add(new GitRemoteHeadRefAction(getRemote(), Constants.MASTER));
return result;
}
}
// Give up, there's no way to get the primary branch
return new ArrayList<>();
}
}, listener, false);
}
Expand Down
32 changes: 18 additions & 14 deletions src/test/java/jenkins/plugins/git/AbstractGitSCMSourceTest.java
Expand Up @@ -45,6 +45,7 @@ public class AbstractGitSCMSourceTest {
public JenkinsRule r = new JenkinsRule();
@Rule
public GitSampleRepoRule sampleRepo = new GitSampleRepoRule();
@Rule
public GitSampleRepoRule sampleRepo2 = new GitSampleRepoRule();

// TODO AbstractGitSCMSourceRetrieveHeadsTest *sounds* like it would be the right place, but it does not in fact retrieve any heads!
Expand Down Expand Up @@ -76,23 +77,16 @@ public static abstract class ActionableSCMSourceOwner extends Actionable impleme
public void retrievePrimaryHead() throws Exception {
sampleRepo.init();
sampleRepo.write("file.txt", "");
sampleRepo.git("status");
sampleRepo.git("add", "file.txt");
sampleRepo.git("status");
sampleRepo.git("commit", "--all", "--message=add-empty-file");
sampleRepo.git("status");
sampleRepo.git("checkout", "-b", "new-primary");
sampleRepo.git("status");
sampleRepo.write("file.txt", "content");
sampleRepo.git("status");
sampleRepo.git("add", "file.txt");
sampleRepo.git("status");
sampleRepo.git("commit", "--all", "--message=add-file");
sampleRepo.git("status");
sampleRepo.git("checkout", "-b", "dev", "master");
sampleRepo.git("status");
sampleRepo.git("checkout", "new-primary");
sampleRepo.git("status");
sampleRepo.git("checkout", "master");
sampleRepo.git("checkout", "-b", "dev");
sampleRepo.git("symbolic-ref", "HEAD", "refs/heads/new-primary");

SCMSource source = new GitSCMSource(null, sampleRepo.toString(), "", "*", "", true);
ActionableSCMSourceOwner owner = Mockito.mock(ActionableSCMSourceOwner.class);
when(owner.getSCMSource(source.getId())).thenReturn(source);
Expand All @@ -104,10 +98,20 @@ public void retrievePrimaryHead() throws Exception {
headByName.put(h.getName(), h);
}
assertThat(headByName.keySet(), containsInAnyOrder("master", "dev", "new-primary"));
for (Action a : source.fetchActions(null, listener)) {
owner.addAction(a);
List<Action> actions = source.fetchActions(null, listener);
GitRemoteHeadRefAction refAction = null;
for (Action a: actions) {
if (a instanceof GitRemoteHeadRefAction) {
refAction = (GitRemoteHeadRefAction) a;
break;
}
}
List<Action> actions = source.fetchActions(headByName.get("new-primary"), null, listener);
assertThat(refAction, notNullValue());
assertThat(refAction.getName(), is("new-primary"));
when(owner.getAction(GitRemoteHeadRefAction.class)).thenReturn(refAction);
when(owner.getActions(GitRemoteHeadRefAction.class)).thenReturn(Collections.singletonList(refAction));
actions = source.fetchActions(headByName.get("new-primary"), null, listener);

PrimaryInstanceMetadataAction primary = null;
for (Action a: actions) {
if (a instanceof PrimaryInstanceMetadataAction) {
Expand Down

0 comments on commit 266413c

Please sign in to comment.