Skip to content

Commit c750b63

Browse files
committed
Merge pull request hudson2-plugins#39 from onemanbucket/master
[FIXES JENKINS-10131] (for simple cases) Poll changes without workspace using git ls-remote
2 parents e437692 + a33a0de commit c750b63

File tree

6 files changed

+132
-33
lines changed

6 files changed

+132
-33
lines changed

src/main/java/hudson/plugins/git/GitAPI.java

Lines changed: 26 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ private int[] getGitVersion() {
8585

8686
return new int[]{majorVer,minorVer};
8787
}
88-
88+
8989
public void init() throws GitException {
9090
if (hasGitRepo()) {
9191
throw new GitException(".git directory already exists! Has it already been initialised?");
@@ -199,7 +199,7 @@ public void fetch() throws GitException {
199199
public void clone(final RemoteConfig remoteConfig) throws GitException {
200200
listener.getLogger().println("Cloning repository " + remoteConfig.getName());
201201
final int[] gitVer = getGitVersion();
202-
202+
203203
// TODO: Not here!
204204
try {
205205
workspace.deleteRecursive();
@@ -220,7 +220,7 @@ public String invoke(File workspace,
220220
VirtualChannel channel) throws IOException {
221221
final ArgumentListBuilder args = new ArgumentListBuilder();
222222
args.add("clone");
223-
if ((gitVer[0] >= 1) && (gitVer[1] >= 7)) {
223+
if ((gitVer[0] >= 1) && (gitVer[1] >= 7)) {
224224
args.add("--progress");
225225
}
226226
args.add("-o", remoteConfig.getName());
@@ -258,11 +258,11 @@ public void prune(RemoteConfig repository) throws GitException {
258258
!getRemoteUrl(repository.getName()).equals("")) {
259259
ArgumentListBuilder args = new ArgumentListBuilder();
260260
args.add("remote", "prune", repository.getName());
261-
261+
262262
launchCommand(args);
263263
}
264264
}
265-
265+
266266
private String firstLine(String result) {
267267
BufferedReader reader = new BufferedReader(new StringReader(result));
268268
String line;
@@ -325,7 +325,7 @@ public List<String> showRevision(Revision r) throws GitException {
325325

326326
return revShow;
327327
}
328-
328+
329329
/**
330330
* Merge any changes into the head.
331331
*
@@ -358,12 +358,12 @@ public void submoduleSync() throws GitException {
358358
launchCommand("submodule", "sync");
359359
}
360360

361-
361+
362362
/**
363363
* Update submodules.
364364
*
365365
* @param recursive if true, will recursively update submodules (requires git>=1.6.5)
366-
*
366+
*
367367
* @throws GitException if executing the Git command fails
368368
*/
369369
public void submoduleUpdate(boolean recursive) throws GitException {
@@ -372,7 +372,7 @@ public void submoduleUpdate(boolean recursive) throws GitException {
372372
if (recursive) {
373373
args.add("--init", "--recursive");
374374
}
375-
375+
376376
launchCommand(args);
377377
}
378378

@@ -390,7 +390,7 @@ public void submoduleClean(boolean recursive) throws GitException {
390390
args.add("--recursive");
391391
}
392392
args.add("git clean -fdx");
393-
393+
394394
launchCommand(args);
395395
}
396396

@@ -664,10 +664,10 @@ public void setupSubmoduleUrls( Revision rev, TaskListener listener ) throws Git
664664
String b = bi.next().getName();
665665
if (b != null) {
666666
int slash = b.indexOf('/');
667-
667+
668668
if ( slash == -1 )
669669
throw new GitException("no remote from branch name ("+b+")");
670-
670+
671671
remote = getDefaultRemote( b.substring(0,slash) );
672672
}
673673
else {
@@ -831,7 +831,7 @@ public void checkoutBranch(String branch, String commitish) throws GitException
831831
throw new GitException("Could not checkout " + branch + " with start point " + commitish, e);
832832
}
833833
}
834-
834+
835835
public boolean tagExists(String tagName) throws GitException {
836836
tagName = tagName.replace(' ', '_');
837837

@@ -846,7 +846,7 @@ public void deleteBranch(String name) throws GitException {
846846
}
847847

848848
}
849-
849+
850850
public void deleteTag(String tagName) throws GitException {
851851
tagName = tagName.replace(' ', '_');
852852
try {
@@ -916,7 +916,7 @@ public boolean isCommitInRepo(String sha1) {
916916
return false;
917917
}
918918
}
919-
919+
920920
public void add(String filePattern) throws GitException {
921921
try {
922922
launchCommand("add", filePattern);
@@ -1012,4 +1012,15 @@ public Set<String> getTagNames(String tagPattern) throws GitException {
10121012
throw new GitException("Error retrieving tag names", e);
10131013
}
10141014
}
1015+
1016+
public String getHeadRev(String remoteRepoUrl, String branch) throws GitException {
1017+
String[] branchExploded = branch.split("/");
1018+
branch = branchExploded[branchExploded.length-1];
1019+
ArgumentListBuilder args = new ArgumentListBuilder("ls-remote");
1020+
args.add("-h");
1021+
args.add(remoteRepoUrl);
1022+
args.add(branch);
1023+
String result = launchCommand(args);
1024+
return result.length()>=40 ? result.substring(0,40) : "";
1025+
}
10151026
}

src/main/java/hudson/plugins/git/GitSCM.java

Lines changed: 56 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
package hudson.plugins.git;
22

33
import static hudson.Util.fixEmptyAndTrim;
4-
54
import hudson.AbortException;
65
import hudson.EnvVars;
76
import hudson.Extension;
@@ -11,7 +10,6 @@
1110
import hudson.Util;
1211
import hudson.matrix.MatrixRun;
1312
import hudson.matrix.MatrixBuild;
14-
import hudson.model.Action;
1513
import hudson.model.BuildListener;
1614
import hudson.model.Descriptor.FormException;
1715
import hudson.model.Items;
@@ -30,16 +28,17 @@
3028
import hudson.plugins.git.util.Build;
3129
import hudson.plugins.git.util.BuildChooser;
3230
import hudson.plugins.git.util.BuildChooserDescriptor;
33-
import hudson.plugins.git.util.BuildData;
3431
import hudson.plugins.git.util.DefaultBuildChooser;
3532
import hudson.plugins.git.util.GitUtils;
33+
import hudson.plugins.git.util.BuildData;
3634
import hudson.remoting.VirtualChannel;
3735
import hudson.scm.ChangeLogParser;
3836
import hudson.scm.PollingResult;
3937
import hudson.scm.SCMDescriptor;
4038
import hudson.scm.SCMRevisionState;
4139
import hudson.scm.SCM;
4240
import hudson.util.FormValidation;
41+
import hudson.util.IOUtils;
4342

4443
import java.io.File;
4544
import java.io.FileOutputStream;
@@ -61,7 +60,6 @@
6160

6261
import javax.servlet.ServletException;
6362

64-
import hudson.util.IOUtils;
6563
import net.sf.json.JSONObject;
6664

6765
import org.eclipse.jgit.lib.Config;
@@ -119,6 +117,8 @@ public class GitSCM extends SCM implements Serializable {
119117
private boolean clean;
120118
private boolean wipeOutWorkspace;
121119
private boolean pruneBranches;
120+
private boolean remotePoll;
121+
122122
/**
123123
* @deprecated
124124
* Replaced by {@link #buildChooser} instead.
@@ -166,7 +166,7 @@ public GitSCM(String repositoryUrl) {
166166
null,
167167
false, Collections.<SubmoduleConfig>emptyList(), false,
168168
false, new DefaultBuildChooser(), null, null, false, null,
169-
null, null, null, false, false, null, null, false);
169+
null, null, null, false, false, false, null, null, false);
170170
}
171171

172172
@DataBoundConstructor
@@ -188,6 +188,7 @@ public GitSCM(
188188
String localBranch,
189189
boolean recursiveSubmodules,
190190
boolean pruneBranches,
191+
boolean remotePoll,
191192
String gitConfigName,
192193
String gitConfigEmail,
193194
boolean skipTag) {
@@ -235,6 +236,19 @@ public GitSCM(
235236
this.excludedUsers = excludedUsers;
236237
this.recursiveSubmodules = recursiveSubmodules;
237238
this.pruneBranches = pruneBranches;
239+
if (remotePoll
240+
&& (branches.size() != 1
241+
|| branches.get(0).getName().contains("*")
242+
|| repo.size() != 1
243+
|| (excludedRegions != null && excludedRegions.length() > 0)
244+
|| (submoduleCfg.size() != 0)
245+
|| (excludedUsers != null && excludedUsers.length() > 0))) {
246+
LOGGER.log(Level.WARNING, "Cannot poll remotely with current configuration.");
247+
this.remotePoll = false;
248+
} else {
249+
this.remotePoll = remotePoll;
250+
}
251+
238252
this.gitConfigName = gitConfigName;
239253
this.gitConfigEmail = gitConfigEmail;
240254
this.skipTag = skipTag;
@@ -450,6 +464,10 @@ public boolean getPruneBranches() {
450464
return this.pruneBranches;
451465
}
452466

467+
public boolean getRemotePoll() {
468+
return this.remotePoll;
469+
}
470+
453471
public boolean getWipeOutWorkspace() {
454472
return this.wipeOutWorkspace;
455473
}
@@ -560,6 +578,13 @@ public SCMRevisionState calcRevisionsFromBuild(AbstractBuild<?, ?> abstractBuild
560578
return SCMRevisionState.NONE;
561579
}
562580

581+
@Override
582+
public boolean requiresWorkspaceForPolling() {
583+
if(remotePoll)
584+
return false;
585+
return true;
586+
}
587+
563588
@Override
564589
protected PollingResult compareRemoteRevisionWith(AbstractProject<?, ?> project, Launcher launcher, FilePath workspace, final TaskListener listener, SCMRevisionState baseline) throws IOException, InterruptedException {
565590
// Poll for changes. Are there any unbuilt revisions that Hudson ought to build ?
@@ -582,6 +607,30 @@ protected PollingResult compareRemoteRevisionWith(AbstractProject<?, ?> project,
582607
listener.getLogger().println("[poll] Last Built Revision: " + buildData.lastBuild.revision);
583608
}
584609

610+
final String singleBranch = getSingleBranch(lastBuild);
611+
612+
if (singleBranch != null && this.remotePoll) {
613+
String gitExe = "";
614+
GitTool[] installations = ((hudson.plugins.git.GitTool.DescriptorImpl)Hudson.getInstance().getDescriptorByType(GitTool.DescriptorImpl.class)).getInstallations();
615+
for(GitTool i : installations) {
616+
if(i.getName().equals(gitTool)) {
617+
gitExe = i.getGitExe();
618+
break;
619+
}
620+
}
621+
final EnvVars environment = GitUtils.getPollEnvironment(project, workspace, launcher, listener);
622+
IGitAPI git = new GitAPI(gitExe, workspace, listener, environment);
623+
String gitRepo = getParamExpandedRepos(lastBuild).get(0).getURIs().get(0).toString();
624+
String headRevision = git.getHeadRev(gitRepo, getBranches().get(0).getName());
625+
626+
if(buildData.lastBuild.getRevision().getSha1String().equals(headRevision)) {
627+
return PollingResult.NO_CHANGES;
628+
} else {
629+
return PollingResult.BUILD_NOW;
630+
}
631+
632+
}
633+
585634
final String gitExe;
586635
{
587636
//If this project is tied onto a node, it's built always there. On other cases,
@@ -611,7 +660,7 @@ protected PollingResult compareRemoteRevisionWith(AbstractProject<?, ?> project,
611660

612661
final EnvVars environment = GitUtils.getPollEnvironment(project, workspace, launcher, listener);
613662
final List<RemoteConfig> paramRepos = getParamExpandedRepos(lastBuild);
614-
final String singleBranch = getSingleBranch(lastBuild);
663+
// final String singleBranch = getSingleBranch(lastBuild);
615664

616665
boolean pollChangesResult = workingDirectory.act(new FileCallable<Boolean>() {
617666

@@ -1581,7 +1630,7 @@ public BuildData getBuildData(Run build, boolean clone) {
15811630
/**
15821631
* Given the workspace, gets the working directory, which will be the workspace
15831632
* if no relative target dir is specified. Otherwise, it'll be "workspace/relativeTargetDir".
1584-
*
1633+
*
15851634
* @param workspace
15861635
* @return working directory
15871636
*/

src/main/java/hudson/plugins/git/IGitAPI.java

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
public interface IGitAPI {
2020
String getGitExe();
2121
EnvVars getEnvironment();
22-
Repository getRepository() throws IOException;
22+
Repository getRepository() throws IOException;
2323

2424
public void init() throws GitException;
2525

@@ -58,7 +58,7 @@ public interface IGitAPI {
5858
void clone(RemoteConfig source) throws GitException;
5959
void clean() throws GitException;
6060
void prune(RemoteConfig repository) throws GitException;
61-
61+
6262
ObjectId revParse(String revName) throws GitException;
6363
List<Branch> getBranches() throws GitException;
6464
List<Branch> getRemoteBranches() throws GitException, IOException;
@@ -92,15 +92,16 @@ public interface IGitAPI {
9292
* If non-null, move/create the branch in this name at the specified commit-ish and check out that branch.
9393
*/
9494
void checkoutBranch(String branch, String commitish) throws GitException;
95-
95+
9696
void add(String filePattern) throws GitException;
9797
void branch(String name) throws GitException;
9898
void deleteBranch(String name) throws GitException;
99-
99+
100100
void commit(File f) throws GitException;
101101

102102
ObjectId mergeBase(ObjectId sha1, ObjectId sha12);
103103
String getAllLogEntries(String branch);
104104

105105
List<String> showRevision(Revision r) throws GitException;
106+
String getHeadRev(String remoteRepoUrl, String branch) throws GitException;
106107
}

src/main/resources/hudson/plugins/git/GitSCM/config.jelly

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,9 @@
149149
<f:entry title="Clean after checkout" field="clean" help="/plugin/git/clean.html">
150150
<f:checkbox />
151151
</f:entry>
152+
<f:entry title="Fast remote polling" help="/plugin/git/help-fastremote.html">
153+
<f:checkbox name="git.remotePoll" checked="${scm.remotePoll}" />
154+
</f:entry>
152155
<f:entry title="Recursively update submodules" field="recursiveSubmodules" help="/plugin/git/help-recursiveSubmodules.html">
153156
<f:checkbox />
154157
</f:entry>
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
<div>
2+
Use git ls-remote polling mechanism. This will compare latest built commit SHA with remote branch without cloning a local copy of the repo
3+
</div>

0 commit comments

Comments
 (0)