|
23 | 23 | import org.commonwl.view.researchobject.HashableAgent;
|
24 | 24 | import org.eclipse.jgit.api.Git;
|
25 | 25 | import org.eclipse.jgit.api.errors.GitAPIException;
|
| 26 | +import org.eclipse.jgit.api.errors.RefNotFoundException; |
26 | 27 | import org.eclipse.jgit.lib.ObjectId;
|
27 | 28 | import org.eclipse.jgit.lib.PersonIdent;
|
28 | 29 | import org.eclipse.jgit.revwalk.RevCommit;
|
@@ -72,53 +73,63 @@ public GitService(@Value("${gitStorage}") Path gitStorage,
|
72 | 73 | public Git getRepository(GitDetails gitDetails, boolean reuseDir)
|
73 | 74 | throws GitAPIException {
|
74 | 75 | Git repo = null;
|
75 |
| - try { |
76 |
| - if (reuseDir) { |
77 |
| - // Base dir from configuration, name from hash of repository URL |
78 |
| - File baseDir = new File(gitStorage.toString()); |
79 |
| - String baseName = DigestUtils.sha1Hex(GitDetails.normaliseUrl(gitDetails.getRepoUrl())); |
80 |
| - |
81 |
| - // Check if folder already exists |
82 |
| - File repoDir = new File(baseDir, baseName); |
83 |
| - if (repoDir.exists() && repoDir.isDirectory()) { |
84 |
| - repo = Git.open(repoDir); |
85 |
| - repo.fetch().call(); |
86 |
| - } else { |
87 |
| - // Create a folder and clone repository into it |
88 |
| - if (repoDir.mkdir()) { |
89 |
| - repo = Git.cloneRepository() |
90 |
| - .setCloneSubmodules(cloneSubmodules) |
91 |
| - .setURI(gitDetails.getRepoUrl()) |
92 |
| - .setDirectory(repoDir) |
93 |
| - .setCloneAllBranches(true) |
94 |
| - .call(); |
| 76 | + while (repo == null) { |
| 77 | + try { |
| 78 | + if (reuseDir) { |
| 79 | + // Base dir from configuration, name from hash of repository URL |
| 80 | + File baseDir = new File(gitStorage.toString()); |
| 81 | + String baseName = DigestUtils.sha1Hex(GitDetails.normaliseUrl(gitDetails.getRepoUrl())); |
| 82 | + |
| 83 | + // Check if folder already exists |
| 84 | + File repoDir = new File(baseDir, baseName); |
| 85 | + if (repoDir.exists() && repoDir.isDirectory()) { |
| 86 | + repo = Git.open(repoDir); |
| 87 | + repo.fetch().call(); |
| 88 | + } else { |
| 89 | + // Create a folder and clone repository into it |
| 90 | + if (repoDir.mkdir()) { |
| 91 | + repo = Git.cloneRepository() |
| 92 | + .setCloneSubmodules(cloneSubmodules) |
| 93 | + .setURI(gitDetails.getRepoUrl()) |
| 94 | + .setDirectory(repoDir) |
| 95 | + .setCloneAllBranches(true) |
| 96 | + .call(); |
| 97 | + } |
95 | 98 | }
|
| 99 | + } else { |
| 100 | + // Another thread is already using the existing folder |
| 101 | + // Must create another temporary one |
| 102 | + repo = Git.cloneRepository() |
| 103 | + .setCloneSubmodules(cloneSubmodules) |
| 104 | + .setURI(gitDetails.getRepoUrl()) |
| 105 | + .setDirectory(createTempDir()) |
| 106 | + .setCloneAllBranches(true) |
| 107 | + .call(); |
96 | 108 | }
|
97 |
| - } else { |
98 |
| - // Another thread is already using the existing folder |
99 |
| - // Must create another temporary one |
100 |
| - repo = Git.cloneRepository() |
101 |
| - .setCloneSubmodules(cloneSubmodules) |
102 |
| - .setURI(gitDetails.getRepoUrl()) |
103 |
| - .setDirectory(createTempDir()) |
104 |
| - .setCloneAllBranches(true) |
105 |
| - .call(); |
106 |
| - } |
107 | 109 |
|
108 |
| - // Checkout the specific branch or commit ID |
109 |
| - if (repo != null) { |
110 |
| - // Create a new local branch if it does not exist and not a commit ID |
111 |
| - String branchOrCommitId = gitDetails.getBranch(); |
112 |
| - if (!ObjectId.isId(branchOrCommitId)) { |
113 |
| - branchOrCommitId = "refs/remotes/origin/" + branchOrCommitId; |
| 110 | + // Checkout the specific branch or commit ID |
| 111 | + if (repo != null) { |
| 112 | + // Create a new local branch if it does not exist and not a commit ID |
| 113 | + String branchOrCommitId = gitDetails.getBranch(); |
| 114 | + if (!ObjectId.isId(branchOrCommitId)) { |
| 115 | + branchOrCommitId = "refs/remotes/origin/" + branchOrCommitId; |
| 116 | + } |
| 117 | + repo.checkout() |
| 118 | + .setName(branchOrCommitId) |
| 119 | + .call(); |
| 120 | + } |
| 121 | + } catch (RefNotFoundException ex) { |
| 122 | + // Attempt slashes in branch fix |
| 123 | + GitDetails correctedForSlash = transferPathToBranch(gitDetails); |
| 124 | + if (correctedForSlash != null) { |
| 125 | + gitDetails = correctedForSlash; |
| 126 | + } else { |
| 127 | + throw ex; |
114 | 128 | }
|
115 |
| - repo.checkout() |
116 |
| - .setName(branchOrCommitId) |
117 |
| - .call(); |
| 129 | + } catch (IOException ex) { |
| 130 | + logger.error("Could not open existing Git repository for '" |
| 131 | + + gitDetails.getRepoUrl() + "'", ex); |
118 | 132 | }
|
119 |
| - } catch (IOException ex) { |
120 |
| - logger.error("Could not open existing Git repository for '" |
121 |
| - + gitDetails.getRepoUrl() + "'", ex); |
122 | 133 | }
|
123 | 134 |
|
124 | 135 | return repo;
|
@@ -168,4 +179,26 @@ public Set<HashableAgent> getAuthors(Git repo, String path) throws GitAPIExcepti
|
168 | 179 | return fileAuthors;
|
169 | 180 | }
|
170 | 181 |
|
| 182 | + /** |
| 183 | + * Transfers part of the path to the branch to fix / in branch names |
| 184 | + * @param githubInfo The current Github info possibly with |
| 185 | + * part of the branch name in the path |
| 186 | + * @return A potentially corrected set of Github details, |
| 187 | + * or null if there are no slashes in the path |
| 188 | + */ |
| 189 | + public GitDetails transferPathToBranch(GitDetails githubInfo) { |
| 190 | + String path = githubInfo.getPath(); |
| 191 | + String branch = githubInfo.getBranch(); |
| 192 | + |
| 193 | + int firstSlash = path.indexOf("/"); |
| 194 | + if (firstSlash > 0) { |
| 195 | + branch += "/" + path.substring(0, firstSlash); |
| 196 | + path = path.substring(firstSlash + 1); |
| 197 | + return new GitDetails(githubInfo.getRepoUrl(), branch, |
| 198 | + path); |
| 199 | + } else { |
| 200 | + return null; |
| 201 | + } |
| 202 | + } |
| 203 | + |
171 | 204 | }
|
0 commit comments