Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
[JENKINS-12402] Support fast-forward mode configuration
  • Loading branch information
martinda authored and MarkEWaite committed Feb 8, 2015
1 parent 12427c0 commit 3d67ef2
Show file tree
Hide file tree
Showing 10 changed files with 384 additions and 36 deletions.
1 change: 1 addition & 0 deletions src/main/java/hudson/plugins/git/GitSCM.java
Expand Up @@ -1379,6 +1379,7 @@ public static PreBuildMergeOptions createMergeOptions(UserMergeOptions mergeOpti
mergeOptions.setMergeRemote(mergeRemote);
mergeOptions.setMergeTarget(mergeOptionsBean.getMergeTarget());
mergeOptions.setMergeStrategy(mergeOptionsBean.getMergeStrategy());
mergeOptions.setFastForwardMode(mergeOptionsBean.getFastForwardMode());
}

return mergeOptions;
Expand Down
59 changes: 57 additions & 2 deletions src/main/java/hudson/plugins/git/UserMergeOptions.java
Expand Up @@ -21,16 +21,27 @@ public class UserMergeOptions extends AbstractDescribableImpl<UserMergeOptions>
private String mergeRemote;
private String mergeTarget;
private String mergeStrategy;
private MergeCommand.GitPluginFastForwardMode fastForwardMode;

@DataBoundConstructor
/**
* @deprecated use the new constructor that allows to set the fast forward mode.
*/
@Deprecated
public UserMergeOptions(String mergeRemote, String mergeTarget, String mergeStrategy) {
this(mergeRemote, mergeTarget, mergeStrategy, MergeCommand.GitPluginFastForwardMode.FF);
}

@DataBoundConstructor
public UserMergeOptions(String mergeRemote, String mergeTarget, String mergeStrategy,
MergeCommand.GitPluginFastForwardMode fastForwardMode) {
this.mergeRemote = mergeRemote;
this.mergeTarget = mergeTarget;
this.mergeStrategy = mergeStrategy;
this.fastForwardMode = fastForwardMode;
}

public UserMergeOptions(PreBuildMergeOptions pbm) {
this(pbm.getRemoteBranchName(),pbm.getMergeTarget(),pbm.getMergeStrategy().toString());
this(pbm.getRemoteBranchName(), pbm.getMergeTarget(), pbm.getMergeStrategy().toString(), pbm.getFastForwardMode());
}

/**
Expand Down Expand Up @@ -59,8 +70,52 @@ public MergeCommand.Strategy getMergeStrategy() {
return MergeCommand.Strategy.DEFAULT;
}

public MergeCommand.GitPluginFastForwardMode getFastForwardMode() {
for (MergeCommand.GitPluginFastForwardMode ffMode : MergeCommand.GitPluginFastForwardMode.values())
if (ffMode.equals(fastForwardMode))
return ffMode;
return MergeCommand.GitPluginFastForwardMode.FF;
}

@Override
public String toString() {
return "UserMergeOptions{" +
"mergeRemote='" + mergeRemote + '\'' +
", mergeTarget='" + mergeTarget + '\'' +
", mergeStrategy='" + mergeStrategy + '\'' +
", fastForwardMode='" + fastForwardMode + '\'' +
'}';
}

@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;

UserMergeOptions that = (UserMergeOptions) o;

if (fastForwardMode != null ? !fastForwardMode.equals(that.fastForwardMode) : that.fastForwardMode != null)
return false;
if (mergeRemote != null ? !mergeRemote.equals(that.mergeRemote) : that.mergeRemote != null) return false;
if (mergeStrategy != null ? !mergeStrategy.equals(that.mergeStrategy) : that.mergeStrategy != null)
return false;
if (mergeTarget != null ? !mergeTarget.equals(that.mergeTarget) : that.mergeTarget != null) return false;

return true;
}

@Override
public int hashCode() {
int result = mergeRemote != null ? mergeRemote.hashCode() : 0;
result = 31 * result + (mergeTarget != null ? mergeTarget.hashCode() : 0);
result = 31 * result + (mergeStrategy != null ? mergeStrategy.hashCode() : 0);
result = 31 * result + (fastForwardMode != null ? fastForwardMode.hashCode() : 0);
return result;
}

@Extension
public static class DescriptorImpl extends Descriptor<UserMergeOptions> {

@Override
public String getDisplayName() {
return "";
Expand Down
Expand Up @@ -58,7 +58,7 @@ public Revision decorateRevisionToBuild(GitSCM scm, Run<?, ?> build, GitClient g
return rev;

// Only merge if there's a branch to merge that isn't us..
listener.getLogger().println("Merging " + rev + " onto " + remoteBranchRef + " using " + scm.getUserMergeOptions().getMergeStrategy().toString() + " strategy");
listener.getLogger().println("Merging " + rev + " to " + remoteBranchRef + ", " + scm.getUserMergeOptions().toString());

// checkout origin/blah
ObjectId target = git.revParse(remoteBranchRef);
Expand Down Expand Up @@ -100,6 +100,7 @@ public Revision decorateRevisionToBuild(GitSCM scm, Run<?, ?> build, GitClient g
public void decorateMergeCommand(GitSCM scm, Run<?, ?> build, GitClient git, TaskListener listener, MergeCommand cmd) throws IOException, InterruptedException, GitException {
if (scm.getUserMergeOptions().getMergeStrategy() != null)
cmd.setStrategy(scm.getUserMergeOptions().getMergeStrategy());
cmd.setGitPluginFastForwardMode(scm.getUserMergeOptions().getFastForwardMode());
}

@Override
Expand Down
14 changes: 14 additions & 0 deletions src/main/java/hudson/plugins/git/opt/PreBuildMergeOptions.java
Expand Up @@ -31,6 +31,8 @@ public class PreBuildMergeOptions implements Serializable {
*/
public String mergeStrategy = MergeCommand.Strategy.DEFAULT.toString();

public MergeCommand.GitPluginFastForwardMode fastForwardMode = MergeCommand.GitPluginFastForwardMode.FF;

public RemoteConfig getMergeRemote() {
return mergeRemote;
}
Expand Down Expand Up @@ -60,6 +62,18 @@ public void setMergeStrategy(MergeCommand.Strategy mergeStrategy) {
this.mergeStrategy = mergeStrategy.toString();
}

@Exported
public MergeCommand.GitPluginFastForwardMode getFastForwardMode() {
for (MergeCommand.GitPluginFastForwardMode ffMode : MergeCommand.GitPluginFastForwardMode.values())
if (ffMode == fastForwardMode)
return ffMode;
return MergeCommand.GitPluginFastForwardMode.FF;
}

public void setFastForwardMode(MergeCommand.GitPluginFastForwardMode fastForwardMode) {
this.fastForwardMode = fastForwardMode;
}

@Exported
public String getRemoteBranchName() {
return (mergeRemote == null) ? null : mergeRemote.getName() + "/" + mergeTarget;
Expand Down
Expand Up @@ -10,7 +10,12 @@
<f:entry title="${%Branch to merge to}" field="mergeTarget">
<f:textbox id="git.mergeTarget" clazz="required"/>
</f:entry>
<f:entry title="Merge strategy:" field="mergeStrategy">
<f:entry title="Merge strategy" field="mergeStrategy">
<f:select />
</f:entry>
</j:jelly>
<f:entry title="Fast-forward mode" field="fastForwardMode">
<f:enum>
${it.toString()}
</f:enum>
</f:entry>
</j:jelly>
@@ -0,0 +1,5 @@
<div>
Merge fast-forward mode selection.</br>
The default, --ff, gracefully falls back to a merge commit when required.</br>
For more information, see the <a href="http://git-scm.com/docs/git-merge">Git Merge Documentation</a>
</div>
39 changes: 25 additions & 14 deletions src/test/java/hudson/plugins/git/AbstractGitTestCase.java
Expand Up @@ -4,6 +4,7 @@
import hudson.EnvVars;
import hudson.FilePath;
import hudson.Functions;
import hudson.Launcher;
import hudson.matrix.MatrixBuild;
import hudson.matrix.MatrixProject;
import hudson.model.FreeStyleBuild;
Expand Down Expand Up @@ -31,6 +32,7 @@

import java.io.File;
import java.io.IOException;
import java.io.ByteArrayOutputStream;
import java.util.Collections;
import java.util.List;

Expand All @@ -50,17 +52,17 @@
* @author ishaaq
*/
public abstract class AbstractGitTestCase extends HudsonTestCase {
protected TaskListener listener;

protected TestGitRepo testRepo;
// aliases of testRepo properties
protected PersonIdent johnDoe;
protected PersonIdent janeDoe;
protected File workDir; // aliases "gitDir"
protected FilePath workspace; // aliases "gitDirPath"
protected GitClient git;
protected TaskListener listener;

protected TestGitRepo testRepo;

// aliases of testRepo properties
protected PersonIdent johnDoe;
protected PersonIdent janeDoe;
protected File workDir; // aliases "gitDir"
protected FilePath workspace; // aliases "gitDirPath"
protected GitClient git;

@Override
protected void setUp() throws Exception {
super.setUp();
Expand Down Expand Up @@ -89,18 +91,18 @@ protected void tearDown() throws Exception {

protected void commit(final String fileName, final PersonIdent committer, final String message)
throws GitException, InterruptedException {
testRepo.commit(fileName, committer, message);
testRepo.commit(fileName, committer, message);
}

protected void commit(final String fileName, final String fileContent, final PersonIdent committer, final String message)

throws GitException, InterruptedException {
testRepo.commit(fileName, fileContent, committer, message);
testRepo.commit(fileName, fileContent, committer, message);
}

protected void commit(final String fileName, final PersonIdent author, final PersonIdent committer,
final String message) throws GitException, InterruptedException {
testRepo.commit(fileName, author, committer, message);
testRepo.commit(fileName, author, committer, message);
}

protected List<UserRemoteConfig> createRemoteRepositories() throws IOException {
Expand Down Expand Up @@ -286,4 +288,13 @@ public String invoke(File f, VirtualChannel channel) throws IOException, Interru
}
});
}

/** A utility method that displays a git repo. Useful to visualise merges. */
public void showRepo(TestGitRepo repo, String msg) throws Exception {
System.out.println("*********** "+msg+" ***********");
ByteArrayOutputStream out = new ByteArrayOutputStream();
int returnCode = new Launcher.LocalLauncher(listener).launch().cmds("git", "log","--all","--graph","--decorate","--oneline").pwd(repo.gitDir.getCanonicalPath()).stdout(out).join();
System.out.println(out.toString());
out.close();
}
}

0 comments on commit 3d67ef2

Please sign in to comment.