Skip to content

Commit

Permalink
[JENKINS-48061] Partial fix for the easy case of non-head revision in…
Browse files Browse the repository at this point in the history
… history of branch
  • Loading branch information
stephenc committed Dec 6, 2017
1 parent f5ca22d commit 5cfdeaa
Show file tree
Hide file tree
Showing 2 changed files with 92 additions and 3 deletions.
13 changes: 10 additions & 3 deletions src/main/java/jenkins/plugins/git/AbstractGitSCMSource.java
Expand Up @@ -815,13 +815,20 @@ public SCMRevision run(GitClient client, String remoteName) throws IOException,
try {
objectId = client.revParse(revision);
hash = objectId.name();
List<Branch> branches = client.getBranchesContaining(hash, false);
if (branches.isEmpty()) {
String candidatePrefix = Constants.R_REMOTES.substring(Constants.R_REFS.length())
+ context.remoteName() + "/";
String name = null;
for (Branch b: client.getBranchesContaining(hash, true)) {
if (b.getName().startsWith(candidatePrefix)) {
name = b.getName().substring(candidatePrefix.length());
break;
}
}
if (name == null) {
listener.getLogger().printf("Could not find a branch containing commit %s%n",
hash);
return null;
}
String name = branches.get(0).getName();
listener.getLogger()
.printf("Selected match: %s revision %s%n", name, hash);
return new SCMRevisionImpl(new SCMHead(name), hash);
Expand Down
82 changes: 82 additions & 0 deletions src/test/java/jenkins/plugins/git/AbstractGitSCMSourceTest.java
Expand Up @@ -34,6 +34,7 @@
import jenkins.scm.api.SCMSourceOwner;
import jenkins.scm.api.metadata.PrimaryInstanceMetadataAction;
import jenkins.scm.api.trait.SCMSourceTrait;
import org.junit.Ignore;
import org.junit.Rule;
import org.junit.Test;
import org.jvnet.hudson.test.Issue;
Expand Down Expand Up @@ -427,6 +428,87 @@ public void retrieveRevision() throws Exception {
assertThat(source.fetchRevisions(listener), hasItems("master", "dev", "v1"));
// we do not care to return commit hashes or other references
}

@Issue("JENKINS-48061")
@Test
public void retrieveRevision_nonHead() throws Exception {
sampleRepo.init();
sampleRepo.write("file", "v1");
sampleRepo.git("commit", "--all", "--message=v1");
sampleRepo.git("tag", "v1");
String v1 = sampleRepo.head();
sampleRepo.write("file", "v2");
sampleRepo.git("commit", "--all", "--message=v2"); // master
sampleRepo.git("checkout", "-b", "dev");
sampleRepo.write("file", "v3");
sampleRepo.git("commit", "--all", "--message=v3"); // dev
String v3 = sampleRepo.head();
sampleRepo.write("file", "v4");
sampleRepo.git("commit", "--all", "--message=v4"); // dev
// SCM.checkout does not permit a null build argument, unfortunately.
Run<?,?> run = r.buildAndAssertSuccess(r.createFreeStyleProject());
GitSCMSource source = new GitSCMSource(sampleRepo.toString());
source.setTraits(Arrays.asList(new BranchDiscoveryTrait(), new TagDiscoveryTrait()));
StreamTaskListener listener = StreamTaskListener.fromStderr();
// Test retrieval of non head revision:
assertEquals("v3", fileAt(v3, run, source, listener));
}

@Issue("JENKINS-48061")
@Test
@Ignore("Cannot fix until JENKINS-48385 merged") // TODO unignore once JENKINS-48385
public void retrieveRevision_nonAdvertised() throws Exception {
sampleRepo.init();
sampleRepo.write("file", "v1");
sampleRepo.git("commit", "--all", "--message=v1");
sampleRepo.git("tag", "v1");
String v1 = sampleRepo.head();
sampleRepo.write("file", "v2");
sampleRepo.git("commit", "--all", "--message=v2"); // master
sampleRepo.git("checkout", "-b", "dev");
sampleRepo.write("file", "v3");
sampleRepo.git("commit", "--all", "--message=v3"); // dev
String v3 = sampleRepo.head();
sampleRepo.git("reset", "--hard", "HEAD^"); // dev, the v3 ref is eligible for GC but still fetchable
sampleRepo.write("file", "v4");
sampleRepo.git("commit", "--all", "--message=v4"); // dev
// SCM.checkout does not permit a null build argument, unfortunately.
Run<?,?> run = r.buildAndAssertSuccess(r.createFreeStyleProject());
GitSCMSource source = new GitSCMSource(sampleRepo.toString());
source.setTraits(Arrays.asList(new BranchDiscoveryTrait(), new TagDiscoveryTrait()));
StreamTaskListener listener = StreamTaskListener.fromStderr();
// Test retrieval of non head revision:
assertEquals("v3", fileAt(v3, run, source, listener));
}

@Issue("JENKINS-48061")
@Test
@Ignore("Cannot fix until JENKINS-48385 merged") // TODO unignore once JENKINS-48385
public void retrieveRevision_customRef() throws Exception {
sampleRepo.init();
sampleRepo.write("file", "v1");
sampleRepo.git("commit", "--all", "--message=v1");
sampleRepo.git("tag", "v1");
String v1 = sampleRepo.head();
sampleRepo.write("file", "v2");
sampleRepo.git("commit", "--all", "--message=v2"); // master
sampleRepo.git("checkout", "-b", "dev");
sampleRepo.write("file", "v3");
sampleRepo.git("commit", "--all", "--message=v3"); // dev
String v3 = sampleRepo.head();
sampleRepo.git("update-ref", "refs/custom/foo", v3); // now this is an advertised ref so cannot be GC'd
sampleRepo.git("reset", "--hard", "HEAD^"); // dev
sampleRepo.write("file", "v4");
sampleRepo.git("commit", "--all", "--message=v4"); // dev
// SCM.checkout does not permit a null build argument, unfortunately.
Run<?,?> run = r.buildAndAssertSuccess(r.createFreeStyleProject());
GitSCMSource source = new GitSCMSource(sampleRepo.toString());
source.setTraits(Arrays.asList(new BranchDiscoveryTrait(), new TagDiscoveryTrait()));
StreamTaskListener listener = StreamTaskListener.fromStderr();
// Test retrieval of non head revision:
assertEquals("v3", fileAt(v3, run, source, listener));
}

private String fileAt(String revision, Run<?,?> run, SCMSource source, TaskListener listener) throws Exception {
SCMRevision rev = source.fetch(revision, listener);
if (rev == null) {
Expand Down

0 comments on commit 5cfdeaa

Please sign in to comment.