Skip to content

Commit

Permalink
Pass marked revision to decorateRevisionToBuild()
Browse files Browse the repository at this point in the history
  • Loading branch information
wannessels committed Oct 17, 2014
1 parent c2082bd commit 80a396f
Show file tree
Hide file tree
Showing 4 changed files with 39 additions and 6 deletions.
2 changes: 1 addition & 1 deletion src/main/java/hudson/plugins/git/GitSCM.java
Expand Up @@ -831,7 +831,7 @@ public EnvVars getEnvironment() {
Revision rev = marked;
// Modify the revision based on extensions
for (GitSCMExtension ext : extensions) {
rev = ext.decorateRevisionToBuild(this,build,git,listener,rev);
rev = ext.decorateRevisionToBuild(this,build,git,listener,marked,rev);
}
Build revToBuild = new Build(marked, rev, build.getNumber(), null);
buildData.saveBuild(revToBuild);
Expand Down
Expand Up @@ -76,7 +76,7 @@ public FilePath getWorkingDirectory(GitSCM scm, AbstractProject<?, ?> context, F
* the chosen revision and returning it) or manipulate the state of the working tree (such as
* running git-clean.)
*
* <h3>{@link #decorateRevisionToBuild(GitSCM, AbstractBuild, GitClient, BuildListener, Revision)} vs {@link BuildChooser}</h3>
* <h3>{@link #decorateRevisionToBuild(GitSCM, AbstractBuild, GitClient, BuildListener, Revision, Revision)} vs {@link BuildChooser}</h3>
* <p>
* {@link BuildChooser} and this method are similar in the sense that they both participate in the process
* of determining what commits to build. So when a plugin wants to control the commit to be built, you have
Expand All @@ -87,18 +87,20 @@ public FilePath getWorkingDirectory(GitSCM scm, AbstractProject<?, ?> context, F
* control what commit to build. For example the gerrit-trigger plugin looks at
* a specific build parameter, then retrieves that commit from Gerrit and builds that.
*
* {@link #decorateRevisionToBuild(GitSCM, AbstractBuild, GitClient, BuildListener, Revision)} is suitable
* {@link #decorateRevisionToBuild(GitSCM, AbstractBuild, GitClient, BuildListener, Revision, Revision)} is suitable
* when you accept arbitrary revision as an input and then create some derivative commits and then build that
* result. The primary example is for speculative merge with another branch (people use this to answer
* the question of "what happens if I were to integrate this feature branch back to the master branch?")
*
* @param marked
* The revision that started this build. (e.g. pre-merge)
* @param rev
* The revision selected for this build.
* @return
* The revision selected for this build. Unless you are decorating the given {@code rev}, return the value
* given in the {@code rev} parameter.
*/
public Revision decorateRevisionToBuild(GitSCM scm, AbstractBuild<?,?> build, GitClient git, BuildListener listener, Revision rev) throws IOException, InterruptedException, GitException {
public Revision decorateRevisionToBuild(GitSCM scm, AbstractBuild<?,?> build, GitClient git, BuildListener listener, Revision marked, Revision rev) throws IOException, InterruptedException, GitException {
return rev;
}

Expand Down
Expand Up @@ -49,7 +49,7 @@ public UserMergeOptions getOptions() {
}

@Override
public Revision decorateRevisionToBuild(GitSCM scm, AbstractBuild<?, ?> build, GitClient git, BuildListener listener, Revision rev) throws IOException, InterruptedException {
public Revision decorateRevisionToBuild(GitSCM scm, AbstractBuild<?, ?> build, GitClient git, BuildListener listener, Revision marked, Revision rev) throws IOException, InterruptedException {
String remoteBranchRef = GitSCM.getParameterString(options.getRef(), build.getEnvironment(listener));

// if the branch we are merging is already at the commit being built, the entire merge becomes no-op
Expand Down Expand Up @@ -85,7 +85,7 @@ public Revision decorateRevisionToBuild(GitSCM scm, AbstractBuild<?, ?> build, G
// record the fact that we've tried building 'rev' and it failed, or else
// BuildChooser in future builds will pick up this same 'rev' again and we'll see the exact same merge failure
// all over again.
scm.getBuildData(build).saveBuild(new Build(rev, build.getNumber(), FAILURE));
scm.getBuildData(build).saveBuild(new Build(marked,rev, build.getNumber(), FAILURE));
throw new AbortException("Branch not suitable for integration as it does not merge cleanly");
}

Expand Down
31 changes: 31 additions & 0 deletions src/test/java/hudson/plugins/git/GitSCMTest.java
Expand Up @@ -1000,6 +1000,37 @@ public void testMergeFailed() throws Exception {
assertBuildStatus(Result.FAILURE, build2);
assertFalse("scm polling should not detect any more changes after build", project.poll(listener).hasChanges());
}

@Bug(25191)
public void testMultipleMergeFailed() throws Exception {
FreeStyleProject project = setupSimpleProject("master");

GitSCM scm = new GitSCM(
createRemoteRepositories(),
Collections.singletonList(new BranchSpec("master")),
false, Collections.<SubmoduleConfig>emptyList(),
null, null,
Collections.<GitSCMExtension>emptyList());
project.setScm(scm);
scm.getExtensions().add(new PreBuildMerge(new UserMergeOptions("origin", "integration1", "")));
scm.getExtensions().add(new PreBuildMerge(new UserMergeOptions("origin", "integration2", "")));

commit("dummyFile", johnDoe, "Initial Commit");
testRepo.git.branch("integration1");
testRepo.git.branch("integration2");
build(project, Result.SUCCESS);

final String commitFile = "commitFile";
testRepo.git.checkoutBranch("integration1","master");
commit(commitFile,"abc", johnDoe, "merge conflict with integration2");

testRepo.git.checkoutBranch("integration2","master");
commit(commitFile,"cde", johnDoe, "merge conflict with integration1");

final FreeStyleBuild build = build(project, Result.FAILURE);

assertFalse("scm polling should not detect any more changes after build", project.poll(listener).hasChanges());
}

public void testMergeFailedWithSlave() throws Exception {
FreeStyleProject project = setupSimpleProject("master");
Expand Down

0 comments on commit 80a396f

Please sign in to comment.