Skip to content

Commit

Permalink
Merge pull request #232 from creste/JENKINS-35687
Browse files Browse the repository at this point in the history
[JENKINS-35687] Add simple git lfs support
  • Loading branch information
MarkEWaite committed Feb 27, 2017
2 parents 9c12a00 + 6db40db commit 470f125
Show file tree
Hide file tree
Showing 4 changed files with 68 additions and 2 deletions.
Expand Up @@ -49,4 +49,12 @@ public interface CheckoutCommand extends GitCommand {
* @return a {@link org.jenkinsci.plugins.gitclient.CheckoutCommand} object.
*/
CheckoutCommand timeout(Integer timeout);

/**
* Call "git lfs pull" for the given remote after checkout.
*
* @param remote a {@link java.lang.String} object.
* @return a {@link org.jenkinsci.plugins.gitclient.CheckoutCommand} object.
*/
CheckoutCommand lfsRemote(String lfsRemote);
}
33 changes: 31 additions & 2 deletions src/main/java/org/jenkinsci/plugins/gitclient/CliGitAPIImpl.java
Expand Up @@ -1983,6 +1983,7 @@ public CheckoutCommand checkout() {
public boolean deleteBranch;
public List<String> sparseCheckoutPaths = Collections.emptyList();
public Integer timeout;
public String lfsRemote;

public CheckoutCommand ref(String ref) {
this.ref = ref;
Expand All @@ -2009,6 +2010,11 @@ public CheckoutCommand timeout(Integer timeout) {
return this;
}

public CheckoutCommand lfsRemote(String lfsRemote) {
this.lfsRemote = lfsRemote;
return this;
}

/* Allow test of index.lock cleanup when checkout is interrupted */
private void interruptThisCheckout() throws InterruptedException {
final File indexFile = new File(workspace.getPath() + File.separator
Expand Down Expand Up @@ -2039,11 +2045,19 @@ public void execute() throws GitException, InterruptedException {
// Will activate or deactivate sparse checkout depending on the given paths
sparseCheckout(sparseCheckoutPaths);

EnvVars checkoutEnv = environment;
if (lfsRemote != null) {
// Disable the git-lfs smudge filter because it is much slower on
// certain OSes than doing a single "git lfs pull" after checkout.
checkoutEnv = new EnvVars(checkoutEnv);
checkoutEnv.put("GIT_LFS_SKIP_SMUDGE", "1");
}

if (branch!=null && deleteBranch) {
// First, checkout to detached HEAD, so we can delete the branch.
ArgumentListBuilder args = new ArgumentListBuilder();
args.add("checkout", "-f", ref);
launchCommandIn(args, workspace, environment, timeout);
launchCommandIn(args, workspace, checkoutEnv, timeout);

// Second, check to see if the branch actually exists, and then delete it if it does.
for (Branch b : getBranches()) {
Expand All @@ -2061,7 +2075,22 @@ public void execute() throws GitException, InterruptedException {
args.add("-f");
}
args.add(ref);
launchCommandIn(args, workspace, environment, timeout);
launchCommandIn(args, workspace, checkoutEnv, timeout);

if (lfsRemote != null) {
final String url = getRemoteUrl(lfsRemote);
StandardCredentials cred = credentials.get(url);
if (cred == null) cred = defaultCredentials;
ArgumentListBuilder lfsArgs = new ArgumentListBuilder();
lfsArgs.add("lfs");
lfsArgs.add("pull");
lfsArgs.add(lfsRemote);
try {
launchCommandWithCredentials(lfsArgs, workspace, cred, new URIish(url), timeout);
} catch (URISyntaxException e) {
throw new GitException("Invalid URL " + url, e);
}
}
} catch (GitException e) {
if (Pattern.compile("index\\.lock").matcher(e.getMessage()).find()) {
throw new GitLockFailedException("Could not lock repository. Please try again", e);
Expand Down
Expand Up @@ -275,6 +275,12 @@ public CheckoutCommand timeout(Integer timeout) {
return this;
}

@Override
public CheckoutCommand lfsRemote(String lfsRemote) {
listener.getLogger().println("[WARNING] JGit doesn't support LFS checkout. This flag is ignored.");
return this;
}

public void execute() throws GitException, InterruptedException {

if(! sparseCheckoutPaths.isEmpty()) {
Expand Down
23 changes: 23 additions & 0 deletions src/test/java/org/jenkinsci/plugins/gitclient/GitClientTest.java
Expand Up @@ -82,6 +82,7 @@ public class GitClientTest {

/* Capabilities of command line git in current environment */
private final boolean CLI_GIT_REPORTS_DETACHED_SHA1;
private final boolean CLI_GIT_SUPPORTS_GIT_LFS;
private final boolean CLI_GIT_SUPPORTS_SUBMODULES;
private final boolean CLI_GIT_SUPPORTS_SUBMODULE_DEINIT;
private final boolean CLI_GIT_SUPPORTS_SUBMODULE_RENAME;
Expand All @@ -104,6 +105,16 @@ public GitClientTest(final String gitImplName) throws IOException, InterruptedEx
CLI_GIT_SUPPORTS_SUBMODULES = cliGitClient.isAtLeastVersion(1, 8, 0, 0);
CLI_GIT_SUPPORTS_SUBMODULE_DEINIT = cliGitClient.isAtLeastVersion(1, 9, 0, 0);
CLI_GIT_SUPPORTS_SUBMODULE_RENAME = cliGitClient.isAtLeastVersion(1, 9, 0, 0);

boolean gitLFSExists = false;
try {
// If git-lfs is installed then the version string should look like this:
// git-lfs/1.4.4 (GitHub; linux amd64; go 1.7.3; git cbf91a9)
gitLFSExists = cliGitClient.launchCommand("lfs", "version").startsWith("git-lfs");
} catch (GitException exception) {
// This is expected when git-lfs is not installed.
}
CLI_GIT_SUPPORTS_GIT_LFS = gitLFSExists;
}

@Parameterized.Parameters(name = "{0}")
Expand Down Expand Up @@ -546,6 +557,18 @@ public void testCheckoutBranch() throws Exception {
assertTrue(src.isDirectory());
}

@Issue("35687") // Add simple git lfs support
@Test
public void testCheckoutWithGitLFS() throws Exception {
assumeThat(gitImplName, is("git")); // JGit implementation doesn't support git lfs
assumeTrue(CLI_GIT_SUPPORTS_GIT_LFS);
String branch = "tests/largeFileSupport";
String remote = fetchUpstream(branch);
gitClient.checkout().branch(branch).ref(remote + "/" + branch).lfsRemote(remote).execute();
File uuidFile = new File(repoFolder.getRoot(), "uuid.txt");
assertEquals("Incorrect file contents in " + uuidFile, "5e7733d8acc94636850cb466aec524e4", FileUtils.readFileToString(uuidFile, "utf-8").trim());
}

@Test
public void testDeleteRef() throws Exception {
assertThat(gitClient.getRefNames(""), is(empty()));
Expand Down

0 comments on commit 470f125

Please sign in to comment.