Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[JENKINS-21248] shallow submodule update #344

Merged
merged 3 commits into from
Aug 1, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -394,7 +394,7 @@ public void execute() throws GitException, InterruptedException {
if (prune) args.add("--prune");

if (shallow) {
if (depth == null){
if (depth == null) {
depth = 1;
}
args.add("--depth=" + depth);
Expand Down Expand Up @@ -1067,9 +1067,11 @@ public SubmoduleUpdateCommand submoduleUpdate() {
boolean recursive = false;
boolean remoteTracking = false;
boolean parentCredentials = false;
boolean shallow = false;
String ref = null;
Map<String, String> submodBranch = new HashMap<>();
public Integer timeout;
Integer depth = 1;

public SubmoduleUpdateCommand recursive(boolean recursive) {
this.recursive = recursive;
Expand Down Expand Up @@ -1101,6 +1103,16 @@ public SubmoduleUpdateCommand timeout(Integer timeout) {
return this;
}

public SubmoduleUpdateCommand shallow(boolean shallow) {
this.shallow = shallow;
return this;
}

public SubmoduleUpdateCommand depth(Integer depth) {
this.depth = depth;
return this;
}

/**
* @throws GitException if executing the Git command fails
* @throws InterruptedException if called methods throw same exception
Expand Down Expand Up @@ -1131,7 +1143,16 @@ else if (!referencePath.isDirectory())
else
args.add("--reference", ref);
}

if (shallow) {
if (depth == null) {
depth = 1;
}
if (isAtLeastVersion(1, 8, 4, 0)) {
args.add("--depth=" + depth);
} else {
listener.getLogger().println("[WARNING] Git client older than 1.8.4 doesn't support shallow submodule updates. This flag is ignored.");
}
}

// We need to call submodule update for each configured
// submodule. Note that we can't reliably depend on the
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ public interface CloneCommand extends GitCommand {

/**
* When shallow cloning, allow for a depth to be set in cases where you need more than the immediate last commit.
* Has no effect if shallow is set to false (default)
* Has no effect if shallow is set to false (default).
*
* @param depth number of revisions to be included in shallow clone
* @return a {@link org.jenkinsci.plugins.gitclient.CloneCommand} object.
Expand Down
16 changes: 15 additions & 1 deletion src/main/java/org/jenkinsci/plugins/gitclient/JGitAPIImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -2175,7 +2175,7 @@ public void submoduleClean(boolean recursive) throws GitException {
}

/**
* submoduleUpdate.
* Update submodules.
*
* @return a {@link org.jenkinsci.plugins.gitclient.SubmoduleUpdateCommand} object.
*/
Expand Down Expand Up @@ -2216,6 +2216,20 @@ public org.jenkinsci.plugins.gitclient.SubmoduleUpdateCommand timeout(Integer ti
return this;
}

@Override
public org.jenkinsci.plugins.gitclient.SubmoduleUpdateCommand shallow(boolean shallow) {
if (shallow) {
listener.getLogger().println("[WARNING] JGit doesn't support shallow clone. This flag is ignored");
}
return this;
}

@Override
public org.jenkinsci.plugins.gitclient.SubmoduleUpdateCommand depth(Integer depth) {
listener.getLogger().println("[WARNING] JGit doesn't support shallow clone and therefore depth is meaningless. This flag is ignored");
return this;
}

@Override
public org.jenkinsci.plugins.gitclient.SubmoduleUpdateCommand useBranch(String submodule, String branchname) {
return this;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,4 +58,22 @@ public interface SubmoduleUpdateCommand extends GitCommand {
* @return a {@link org.jenkinsci.plugins.gitclient.SubmoduleUpdateCommand} object.
*/
SubmoduleUpdateCommand timeout(Integer timeout);

/**
* Only clone the most recent history, not preceding history. Depth of the
* shallow clone is controlled by the #depth method.
*
* @param shallow boolean controlling whether the clone is shallow (requires git&gt;=1.8.4)
* @return a {@link org.jenkinsci.plugins.gitclient.SubmoduleUpdateCommand} object.
*/
SubmoduleUpdateCommand shallow(boolean shallow);

/**
* When shallow cloning, allow for a depth to be set in cases where you need more than the immediate last commit.
* Has no effect if shallow is set to false (default).
*
* @param depth number of revisions to be included in shallow clone (requires git&gt;=1.8.4)
* @return a {@link org.jenkinsci.plugins.gitclient.SubmoduleUpdateCommand} object.
*/
SubmoduleUpdateCommand depth(Integer depth);
}
97 changes: 85 additions & 12 deletions src/test/java/org/jenkinsci/plugins/gitclient/GitAPITestCase.java
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
import java.io.StringWriter;
import java.lang.reflect.Field;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
Expand Down Expand Up @@ -556,21 +557,24 @@ public void test_clone_shallow() throws Exception
assertBranchesExist(w.git.getBranches(), "master");
assertAlternatesFileNotFound();
/* JGit does not support shallow clone */
assertEquals("isShallow?", w.igit() instanceof CliGitAPIImpl, w.cgit().isShallowRepository());
final String shallow = ".git" + File.separator + "shallow";
assertEquals("Shallow file existence: " + shallow, w.igit() instanceof CliGitAPIImpl, w.exists(shallow));
boolean hasShallowCloneSupport = w.git instanceof CliGitAPIImpl && w.cgit().isAtLeastVersion(1, 5, 0, 0);
assertEquals("isShallow?", hasShallowCloneSupport, w.cgit().isShallowRepository());
String shallow = ".git" + File.separator + "shallow";
assertEquals("shallow file existence: " + shallow, hasShallowCloneSupport, w.exists(shallow));
}

public void test_clone_shallow_with_depth() throws IOException, InterruptedException
public void test_clone_shallow_with_depth() throws Exception
{
w.git.clone_().url(localMirror()).repositoryName("origin").shallow(true).depth(2).execute();
w.git.checkout("origin/master", "master");
check_remote_url("origin");
assertBranchesExist(w.git.getBranches(), "master");
assertAlternatesFileNotFound();
/* JGit does not support shallow clone */
final String shallow = ".git" + File.separator + "shallow";
assertEquals("Shallow file existence: " + shallow, w.igit() instanceof CliGitAPIImpl, w.exists(shallow));
boolean hasShallowCloneSupport = w.git instanceof CliGitAPIImpl && w.cgit().isAtLeastVersion(1, 5, 0, 0);
assertEquals("isShallow?", hasShallowCloneSupport, w.cgit().isShallowRepository());
String shallow = ".git" + File.separator + "shallow";
assertEquals("shallow file existence: " + shallow, hasShallowCloneSupport, w.exists(shallow));
}

public void test_clone_shared() throws IOException, InterruptedException
Expand Down Expand Up @@ -1401,9 +1405,11 @@ public void test_fetch_shallow() throws Exception {
assertBranchesExist(w.git.getRemoteBranches(), "origin/master");
final String alternates = ".git" + File.separator + "objects" + File.separator + "info" + File.separator + "alternates";
assertFalse("Alternates file found: " + alternates, w.exists(alternates));
/* JGit does not support shallow clone */
final String shallow = ".git" + File.separator + "shallow";
assertEquals("Shallow file: " + shallow, w.igit() instanceof CliGitAPIImpl, w.exists(shallow));
/* JGit does not support shallow fetch */
boolean hasShallowFetchSupport = w.git instanceof CliGitAPIImpl && w.cgit().isAtLeastVersion(1, 5, 0, 0);
assertEquals("isShallow?", hasShallowFetchSupport, w.cgit().isShallowRepository());
String shallow = ".git" + File.separator + "shallow";
assertEquals("shallow file existence: " + shallow, hasShallowFetchSupport, w.exists(shallow));
}

public void test_fetch_shallow_depth() throws Exception {
Expand All @@ -1414,9 +1420,11 @@ public void test_fetch_shallow_depth() throws Exception {
assertBranchesExist(w.git.getRemoteBranches(), "origin/master");
final String alternates = ".git" + File.separator + "objects" + File.separator + "info" + File.separator + "alternates";
assertFalse("Alternates file found: " + alternates, w.exists(alternates));
/* JGit does not support shallow clone */
final String shallow = ".git" + File.separator + "shallow";
assertEquals("Shallow file: " + shallow, w.igit() instanceof CliGitAPIImpl, w.exists(shallow));
/* JGit does not support shallow fetch */
boolean hasShallowFetchSupport = w.git instanceof CliGitAPIImpl && w.cgit().isAtLeastVersion(1, 5, 0, 0);
assertEquals("isShallow?", hasShallowFetchSupport, w.cgit().isShallowRepository());
String shallow = ".git" + File.separator + "shallow";
assertEquals("shallow file existence: " + shallow, hasShallowFetchSupport, w.exists(shallow));
}

public void test_fetch_noTags() throws Exception {
Expand Down Expand Up @@ -2586,6 +2594,43 @@ public void test_submodule_update() throws Exception {
assertTrue("modules/sshkeys does not exist", w.exists("modules/sshkeys"));
}
assertFixSubmoduleUrlsThrows();

String shallow = Paths.get(".git", "modules", "module", "1", "shallow").toString();
assertFalse("shallow file existence: " + shallow, w.exists(shallow));
}

public void test_submodule_update_shallow() throws Exception {
WorkingArea remote = setupRepositoryWithSubmodule();
w.git.clone_().url("file://" + remote.file("dir-repository").getAbsolutePath()).repositoryName("origin").execute();
w.git.checkout().branch("master").ref("origin/master").execute();
w.git.submoduleInit();
w.git.submoduleUpdate().shallow(true).execute();

boolean hasShallowSubmoduleSupport = w.git instanceof CliGitAPIImpl && w.cgit().isAtLeastVersion(1, 8, 4, 0);

String shallow = Paths.get(".git", "modules", "submodule", "shallow").toString();
assertEquals("shallow file existence: " + shallow, hasShallowSubmoduleSupport, w.exists(shallow));

int localSubmoduleCommits = w.cgit().subGit("submodule").revList("master").size();
int remoteSubmoduleCommits = remote.cgit().subGit("dir-submodule").revList("master").size();
assertEquals("submodule commit count didn't match", hasShallowSubmoduleSupport ? 1 : remoteSubmoduleCommits, localSubmoduleCommits);
}

public void test_submodule_update_shallow_with_depth() throws Exception {
WorkingArea remote = setupRepositoryWithSubmodule();
w.git.clone_().url("file://" + remote.file("dir-repository").getAbsolutePath()).repositoryName("origin").execute();
w.git.checkout().branch("master").ref("origin/master").execute();
w.git.submoduleInit();
w.git.submoduleUpdate().shallow(true).depth(2).execute();

boolean hasShallowSubmoduleSupport = w.git instanceof CliGitAPIImpl && w.cgit().isAtLeastVersion(1, 8, 4, 0);

String shallow = Paths.get(".git", "modules", "submodule", "shallow").toString();
assertEquals("shallow file existence: " + shallow, hasShallowSubmoduleSupport, w.exists(shallow));

int localSubmoduleCommits = w.cgit().subGit("submodule").revList("master").size();
int remoteSubmoduleCommits = remote.cgit().subGit("dir-submodule").revList("master").size();
assertEquals("submodule commit count didn't match", hasShallowSubmoduleSupport ? 2 : remoteSubmoduleCommits, localSubmoduleCommits);
}

@NotImplementedInJGit
Expand Down Expand Up @@ -4640,4 +4685,32 @@ private void withSystemLocaleReporting(String fileName, TestedCode code) throws
interface TestedCode {
void run() throws Exception;
}

private WorkingArea setupRepositoryWithSubmodule() throws Exception {
WorkingArea workingArea = new WorkingArea();

File repositoryDir = workingArea.file("dir-repository");
File submoduleDir = workingArea.file("dir-submodule");

assertTrue("did not create dir " + repositoryDir.getName(), repositoryDir.mkdir());
assertTrue("did not create dir " + submoduleDir.getName(), submoduleDir.mkdir());

WorkingArea submoduleWorkingArea = new WorkingArea(submoduleDir).init();

for (int commit = 1; commit <= 5; commit++) {
submoduleWorkingArea.touch("file", String.format("submodule content-%d", commit));
submoduleWorkingArea.cgit().add("file");
submoduleWorkingArea.cgit().commit(String.format("submodule commit-%d", commit));
}

WorkingArea repositoryWorkingArea = new WorkingArea(repositoryDir).init();

repositoryWorkingArea.commitEmpty("init");

repositoryWorkingArea.cgit().add(".");
repositoryWorkingArea.cgit().addSubmodule("file://" + submoduleDir.getAbsolutePath(), "submodule");
repositoryWorkingArea.cgit().commit("submodule");

return workingArea;
}
}