From 7ae542a92420c21344009d5ae89a0df19ccb73b1 Mon Sep 17 00:00:00 2001 From: Georg Seibt <seibt@fim.uni-passau.de> Date: Tue, 12 Apr 2016 14:05:30 +0200 Subject: [PATCH] only clone if it is necessary --- .../fim/seibt/gitwrapper/repo/Git.java | 49 +++++++++++++++---- 1 file changed, 40 insertions(+), 9 deletions(-) diff --git a/src/de/uni_passau/fim/seibt/gitwrapper/repo/Git.java b/src/de/uni_passau/fim/seibt/gitwrapper/repo/Git.java index f223ccb..aa70b2a 100644 --- a/src/de/uni_passau/fim/seibt/gitwrapper/repo/Git.java +++ b/src/de/uni_passau/fim/seibt/gitwrapper/repo/Git.java @@ -20,6 +20,7 @@ public class Git { private static final Logger LOG = Logger.getLogger(Git.class.getCanonicalName()); private static final Pattern CLONING_INTO = Pattern.compile("Cloning into '(.*)'\\.\\.\\."); + private static final Pattern ALREADY_EXISTS = Pattern.compile("fatal: destination path '(.*)' already exists and is not an empty directory\\."); private class ExecRes { private int code; @@ -37,13 +38,6 @@ public class Git { Optional<ExecRes> res = exec(parentDir, "clone", url); Function<ExecRes, Repository> toRepo = execRes -> { - - if (execRes.code != EXIT_SUCCESS) { - // the repo may already exist (resulting in code 128) - pull it? delete it? - LOG.warning(() -> String.format("Exit code %d indicates failure while cloning '%s'.", execRes.code, url)); - return null; - } - Scanner sc = new Scanner(execRes.output); if (!sc.hasNextLine()) { @@ -51,7 +45,14 @@ public class Git { return null; } - Matcher matcher = CLONING_INTO.matcher(sc.nextLine()); + String firstLine = sc.nextLine(); + Matcher matcher; + + if (execRes.code == EXIT_SUCCESS) { + matcher = CLONING_INTO.matcher(firstLine); + } else { + matcher = ALREADY_EXISTS.matcher(firstLine); + } if (!matcher.find()) { LOG.warning(() -> String.format("Unexpected output while cloning '%s'.", url)); @@ -60,8 +61,20 @@ public class Git { String name = matcher.group(1); File repoDir = new File(parentDir, name); + String repoPath = repoDir.getAbsolutePath(); + + if (execRes.code == EXIT_SUCCESS) { + LOG.fine(() -> String.format("Cloned '%s' into '%s'.", url, repoPath)); + } else { + LOG.fine(() -> String.format("Found '%s' which would be produced for '%s'", repoPath, url)); - LOG.fine(() -> String.format("Cloned '%s' into '%s'.", url, repoDir.getAbsolutePath())); + if (!isGitDir(repoDir)) { + LOG.warning(() -> String.format("'%s' is not a git repository.", repoPath)); + return null; + } + + LOG.fine(() -> String.format("'%s' is a git repository. Assuming it is a clone of '%s'.", repoPath, url)); + } return new Repository(this, url, repoDir); }; @@ -69,6 +82,24 @@ public class Git { return res.map(toRepo); } + /** + * Returns whether the given directory (or any of its parent directories) is a git repository. Returns false if + * <code>directory</code> is not a directory. + * + * @param directory + * the directory to check + * @return true iff the given directory (or any of its parent directories) is a git repository + */ + public boolean isGitDir(File directory) { + + if (!directory.isDirectory()) { + return false; + } + + Optional<ExecRes> status = exec(directory, "rev-parse", "--is-inside-git-dir"); + return status.map(res -> res.code == EXIT_SUCCESS).orElse(false); + } + public Optional<ExecRes> exec(File workingDirectory, String... parameters) { ProcessBuilder b = new ProcessBuilder(); String[] cmdArray = new String[parameters.length + 1]; -- GitLab