PageRenderTime 58ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 1ms

/modules/test/jenkins-results-parser/src/main/java/com/liferay/jenkins/results/parser/GitWorkingDirectory.java

http://github.com/liferay/liferay-portal
Java | 2543 lines | 1853 code | 673 blank | 17 comment | 299 complexity | 0ff32e0cedb94fbdb6d239f7b20b8a82 MD5 | raw file
Possible License(s): LGPL-2.0

Large files files are truncated, but you can click here to view the full file

  1. /**
  2. * Copyright (c) 2000-present Liferay, Inc. All rights reserved.
  3. *
  4. * This library is free software; you can redistribute it and/or modify it under
  5. * the terms of the GNU Lesser General Public License as published by the Free
  6. * Software Foundation; either version 2.1 of the License, or (at your option)
  7. * any later version.
  8. *
  9. * This library is distributed in the hope that it will be useful, but WITHOUT
  10. * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
  11. * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
  12. * details.
  13. */
  14. package com.liferay.jenkins.results.parser;
  15. import com.google.common.collect.Lists;
  16. import java.io.File;
  17. import java.io.FileNotFoundException;
  18. import java.io.IOException;
  19. import java.nio.file.PathMatcher;
  20. import java.util.ArrayList;
  21. import java.util.Arrays;
  22. import java.util.Collections;
  23. import java.util.HashMap;
  24. import java.util.HashSet;
  25. import java.util.List;
  26. import java.util.Map;
  27. import java.util.Objects;
  28. import java.util.Set;
  29. import java.util.regex.Matcher;
  30. import java.util.regex.Pattern;
  31. import org.json.JSONObject;
  32. /**
  33. * @author Michael Hashimoto
  34. * @author Peter Yoo
  35. */
  36. public class GitWorkingDirectory {
  37. public static String getGitHubUserName(GitRemote gitRemote) {
  38. String remoteURL = gitRemote.getRemoteURL();
  39. if (!remoteURL.contains("github.com")) {
  40. throw new IllegalArgumentException(
  41. JenkinsResultsParserUtil.combine(
  42. gitRemote.getName(),
  43. " does not point to a GitHub repository"));
  44. }
  45. String userName = null;
  46. if (remoteURL.startsWith("https://github.com/")) {
  47. userName = remoteURL.substring("https://github.com/".length());
  48. }
  49. else {
  50. userName = remoteURL.substring("git@github.com:".length());
  51. }
  52. return userName.substring(0, userName.indexOf("/"));
  53. }
  54. public GitRemote addGitRemote(
  55. boolean force, String gitRemoteName, String remoteURL) {
  56. return addGitRemote(force, gitRemoteName, remoteURL, false);
  57. }
  58. public GitRemote addGitRemote(
  59. boolean force, String gitRemoteName, String remoteURL, boolean write) {
  60. if (gitRemoteExists(gitRemoteName)) {
  61. if (force) {
  62. removeGitRemote(getGitRemote(gitRemoteName));
  63. }
  64. else {
  65. throw new IllegalArgumentException(
  66. JenkinsResultsParserUtil.combine(
  67. "Git remote ", gitRemoteName, " already exists"));
  68. }
  69. }
  70. GitRemote newGitRemote = new GitRemote(this, gitRemoteName, remoteURL);
  71. _gitRemotes.put(gitRemoteName, newGitRemote);
  72. if (write) {
  73. String[] commands = {
  74. JenkinsResultsParserUtil.combine(
  75. "if [ \"$(git remote | grep ", gitRemoteName,
  76. ")\" != \"\" ] ; then git remote remove ", gitRemoteName,
  77. " ; fi"),
  78. JenkinsResultsParserUtil.combine(
  79. "git remote add ", gitRemoteName, " ", remoteURL)
  80. };
  81. GitUtil.ExecutionResult executionResult = executeBashCommands(
  82. GitUtil.RETRIES_SIZE_MAX, GitUtil.MILLIS_RETRY_DELAY,
  83. GitUtil.MILLIS_TIMEOUT, commands);
  84. if (executionResult.getExitValue() != 0) {
  85. throw new RuntimeException(
  86. JenkinsResultsParserUtil.combine(
  87. "Unable to write Git remote ", gitRemoteName, "\n",
  88. executionResult.getStandardError()));
  89. }
  90. }
  91. return newGitRemote;
  92. }
  93. public void checkoutLocalGitBranch(LocalGitBranch localGitBranch) {
  94. checkoutLocalGitBranch(localGitBranch, "-f");
  95. }
  96. public void checkoutLocalGitBranch(
  97. LocalGitBranch localGitBranch, String options) {
  98. waitForIndexLock();
  99. StringBuilder sb = new StringBuilder();
  100. sb.append("git checkout ");
  101. if (options != null) {
  102. sb.append(options);
  103. sb.append(" ");
  104. }
  105. String branchName = localGitBranch.getName();
  106. sb.append(branchName);
  107. GitUtil.ExecutionResult executionResult = executeBashCommands(
  108. GitUtil.RETRIES_SIZE_MAX, GitUtil.MILLIS_RETRY_DELAY,
  109. 1000 * 60 * 10, sb.toString());
  110. if (executionResult.getExitValue() != 0) {
  111. throw new RuntimeException(
  112. JenkinsResultsParserUtil.combine(
  113. "Unable to checkout ", branchName, "\n",
  114. executionResult.getStandardError()));
  115. }
  116. int timeout = 0;
  117. File headFile = new File(_gitDirectory, "HEAD");
  118. String expectedContent = JenkinsResultsParserUtil.combine(
  119. "ref: refs/heads/", branchName);
  120. while (true) {
  121. String headContent = null;
  122. try {
  123. headContent = JenkinsResultsParserUtil.read(headFile);
  124. }
  125. catch (IOException ioException) {
  126. throw new RuntimeException(
  127. "Unable to read file " + headFile.getPath(), ioException);
  128. }
  129. headContent = headContent.trim();
  130. if (headContent.equals(expectedContent)) {
  131. return;
  132. }
  133. System.out.println(
  134. JenkinsResultsParserUtil.combine(
  135. "HEAD file content is: ", headContent,
  136. ". Waiting for branch to be updated."));
  137. JenkinsResultsParserUtil.sleep(5000);
  138. timeout++;
  139. if (timeout >= 59) {
  140. if (Objects.equals(branchName, getCurrentBranchName())) {
  141. return;
  142. }
  143. throw new RuntimeException(
  144. "Unable to checkout branch " + branchName);
  145. }
  146. }
  147. }
  148. public void checkoutUpstreamLocalGitBranch() {
  149. if (!Objects.equals(getCurrentBranchName(), getUpstreamBranchName())) {
  150. checkoutLocalGitBranch(getUpstreamLocalGitBranch());
  151. }
  152. }
  153. public void cherryPick(LocalGitCommit localGitCommit) {
  154. String cherryPickCommand = JenkinsResultsParserUtil.combine(
  155. "git cherry-pick " + localGitCommit.getSHA());
  156. GitUtil.ExecutionResult executionResult = executeBashCommands(
  157. GitUtil.RETRIES_SIZE_MAX, GitUtil.MILLIS_RETRY_DELAY,
  158. GitUtil.MILLIS_TIMEOUT, cherryPickCommand);
  159. if (executionResult.getExitValue() != 0) {
  160. throw new RuntimeException(
  161. JenkinsResultsParserUtil.combine(
  162. "Unable to cherry pick commit ", localGitCommit.getSHA(),
  163. "\n", executionResult.getStandardError()));
  164. }
  165. }
  166. public void clean() {
  167. GitUtil.ExecutionResult executionResult = executeBashCommands(
  168. GitUtil.RETRIES_SIZE_MAX, GitUtil.MILLIS_RETRY_DELAY,
  169. 1000 * 60 * 10, "git clean -dfx");
  170. if (executionResult.getExitValue() != 0) {
  171. throw new RuntimeException(
  172. JenkinsResultsParserUtil.combine(
  173. "Unable to clean Git repository\n",
  174. executionResult.getStandardError()));
  175. }
  176. }
  177. public void cleanTempBranches() {
  178. checkoutUpstreamLocalGitBranch();
  179. List<String> localGitBranchNames = getLocalGitBranchNames();
  180. List<String> tempBranchNames = new ArrayList<>(
  181. localGitBranchNames.size());
  182. String pattern = JenkinsResultsParserUtil.combine(
  183. ".*", Pattern.quote(getUpstreamBranchName()), "-temp", ".*");
  184. for (String localGitBranchName : localGitBranchNames) {
  185. if (localGitBranchName.matches(pattern)) {
  186. tempBranchNames.add(localGitBranchName);
  187. }
  188. }
  189. if (!tempBranchNames.isEmpty()) {
  190. for (List<String> branchNames :
  191. Lists.partition(
  192. new ArrayList<>(tempBranchNames),
  193. _BRANCHES_DELETE_BATCH_SIZE)) {
  194. _deleteLocalGitBranches(branchNames.toArray(new String[0]));
  195. }
  196. }
  197. }
  198. public void commitFileToCurrentBranch(String fileName, String message) {
  199. String commitCommand = JenkinsResultsParserUtil.combine(
  200. "git commit -m \"", message, "\" ", fileName);
  201. GitUtil.ExecutionResult executionResult = executeBashCommands(
  202. GitUtil.RETRIES_SIZE_MAX, GitUtil.MILLIS_RETRY_DELAY,
  203. GitUtil.MILLIS_TIMEOUT, commitCommand);
  204. if (executionResult.getExitValue() != 0) {
  205. throw new RuntimeException(
  206. JenkinsResultsParserUtil.combine(
  207. "Unable to commit file ", fileName, "\n",
  208. executionResult.getStandardError()));
  209. }
  210. }
  211. public void commitStagedFilesToCurrentBranch(String message) {
  212. String commitCommand = JenkinsResultsParserUtil.combine(
  213. "git commit -m \"", message, "\" ");
  214. GitUtil.ExecutionResult executionResult = executeBashCommands(
  215. GitUtil.RETRIES_SIZE_MAX, GitUtil.MILLIS_RETRY_DELAY,
  216. GitUtil.MILLIS_TIMEOUT, commitCommand);
  217. if (executionResult.getExitValue() != 0) {
  218. throw new RuntimeException(
  219. JenkinsResultsParserUtil.combine(
  220. "Unable to commit staged files", "\n",
  221. executionResult.getStandardError()));
  222. }
  223. }
  224. public void configure(Map<String, String> configMap, String options) {
  225. String[] commands = new String[configMap.size()];
  226. int i = 0;
  227. for (Map.Entry<String, String> entry : configMap.entrySet()) {
  228. StringBuilder sb = new StringBuilder();
  229. sb.append("git config ");
  230. if ((options != null) && !options.isEmpty()) {
  231. sb.append(options);
  232. sb.append(" ");
  233. }
  234. sb.append(entry.getKey());
  235. sb.append(" ");
  236. sb.append(entry.getValue());
  237. commands[i] = sb.toString();
  238. i++;
  239. }
  240. GitUtil.ExecutionResult executionResult = executeBashCommands(
  241. GitUtil.RETRIES_SIZE_MAX, GitUtil.MILLIS_RETRY_DELAY,
  242. GitUtil.MILLIS_TIMEOUT, commands);
  243. if (executionResult.getExitValue() != 0) {
  244. throw new RuntimeException(
  245. "Unable to configure git repository.\n" +
  246. executionResult.getStandardError());
  247. }
  248. }
  249. public void configure(
  250. String configName, String configValue, String options) {
  251. Map<String, String> configMap = new HashMap<>();
  252. configMap.put(configName, configValue);
  253. configure(configMap, options);
  254. }
  255. public LocalGitBranch createLocalGitBranch(LocalGitBranch localGitBranch) {
  256. return createLocalGitBranch(
  257. localGitBranch.getName(), false, localGitBranch.getSHA());
  258. }
  259. public LocalGitBranch createLocalGitBranch(
  260. LocalGitBranch localGitBranch, boolean force) {
  261. return createLocalGitBranch(
  262. localGitBranch.getName(), force, localGitBranch.getSHA());
  263. }
  264. public LocalGitBranch createLocalGitBranch(String localGitBranchName) {
  265. return createLocalGitBranch(localGitBranchName, false, null);
  266. }
  267. public LocalGitBranch createLocalGitBranch(
  268. String localGitBranchName, boolean force) {
  269. return createLocalGitBranch(localGitBranchName, force, null);
  270. }
  271. public LocalGitBranch createLocalGitBranch(
  272. String localGitBranchName, boolean force, String startPoint) {
  273. LocalGitBranch currentLocalGitBranch = getCurrentLocalGitBranch();
  274. LocalGitBranch tempLocalGitBranch = null;
  275. try {
  276. if ((currentLocalGitBranch == null) ||
  277. localGitBranchName.equals(currentLocalGitBranch.getName())) {
  278. tempLocalGitBranch = createLocalGitBranch(
  279. "temp-" + System.currentTimeMillis());
  280. checkoutLocalGitBranch(tempLocalGitBranch);
  281. }
  282. StringBuilder sb = new StringBuilder();
  283. sb.append("git branch ");
  284. if (force) {
  285. sb.append("-f ");
  286. }
  287. sb.append(localGitBranchName);
  288. if (startPoint != null) {
  289. sb.append(" ");
  290. sb.append(startPoint);
  291. }
  292. GitUtil.ExecutionResult executionResult = executeBashCommands(
  293. GitUtil.RETRIES_SIZE_MAX, GitUtil.MILLIS_RETRY_DELAY,
  294. GitUtil.MILLIS_TIMEOUT, sb.toString());
  295. if (executionResult.getExitValue() != 0) {
  296. throw new RuntimeException(
  297. JenkinsResultsParserUtil.combine(
  298. "Unable to create local branch ", localGitBranchName,
  299. " at ", startPoint, "\n",
  300. executionResult.getStandardError()));
  301. }
  302. }
  303. finally {
  304. if (tempLocalGitBranch != null) {
  305. checkoutLocalGitBranch(currentLocalGitBranch);
  306. deleteLocalGitBranch(tempLocalGitBranch);
  307. }
  308. }
  309. return getLocalGitBranch(localGitBranchName, true);
  310. }
  311. public String createPullRequest(
  312. String body, String pullRequestBranchName, String receiverUserName,
  313. String senderUserName, String title)
  314. throws IOException {
  315. JSONObject requestJSONObject = new JSONObject();
  316. requestJSONObject.put("base", _upstreamBranchName);
  317. requestJSONObject.put("body", body);
  318. requestJSONObject.put(
  319. "head", senderUserName + ":" + pullRequestBranchName);
  320. requestJSONObject.put("title", title);
  321. String url = JenkinsResultsParserUtil.getGitHubApiUrl(
  322. _gitRepositoryName, receiverUserName, "pulls");
  323. JSONObject responseJSONObject = JenkinsResultsParserUtil.toJSONObject(
  324. url, requestJSONObject.toString());
  325. String pullRequestURL = responseJSONObject.getString("html_url");
  326. System.out.println("Created a pull request at " + pullRequestURL);
  327. return pullRequestURL;
  328. }
  329. public void deleteLocalGitBranch(LocalGitBranch localGitBranch) {
  330. if (localGitBranch == null) {
  331. return;
  332. }
  333. deleteLocalGitBranches(Arrays.asList(localGitBranch));
  334. }
  335. public void deleteLocalGitBranch(String branchName) {
  336. deleteLocalGitBranch(getLocalGitBranch(branchName));
  337. }
  338. public void deleteLocalGitBranches(List<LocalGitBranch> localGitBranches) {
  339. if (localGitBranches.isEmpty()) {
  340. return;
  341. }
  342. Set<String> localGitBranchNames = new HashSet<>();
  343. for (LocalGitBranch localGitBranch : localGitBranches) {
  344. localGitBranchNames.add(localGitBranch.getName());
  345. }
  346. for (List<String> branchNames :
  347. Lists.partition(
  348. new ArrayList<>(localGitBranchNames),
  349. _BRANCHES_DELETE_BATCH_SIZE)) {
  350. _deleteLocalGitBranches(branchNames.toArray(new String[0]));
  351. }
  352. }
  353. public void deleteRemoteGitBranch(RemoteGitBranch remoteGitBranch) {
  354. deleteRemoteGitBranches(Arrays.asList(remoteGitBranch));
  355. }
  356. public void deleteRemoteGitBranch(String branchName, GitRemote gitRemote) {
  357. deleteRemoteGitBranch(branchName, gitRemote.getRemoteURL());
  358. }
  359. public void deleteRemoteGitBranch(
  360. String branchName, RemoteGitRepository remoteGitRepository) {
  361. deleteRemoteGitBranch(branchName, remoteGitRepository.getRemoteURL());
  362. }
  363. public void deleteRemoteGitBranch(String branchName, String remoteURL) {
  364. deleteRemoteGitBranch(getRemoteGitBranch(branchName, remoteURL));
  365. }
  366. public void deleteRemoteGitBranches(
  367. List<RemoteGitBranch> remoteGitBranches) {
  368. Map<String, Set<String>> remoteURLGitBranchNameMap = new HashMap<>();
  369. for (RemoteGitBranch remoteGitBranch : remoteGitBranches) {
  370. RemoteGitRepository remoteGitRepository =
  371. remoteGitBranch.getRemoteGitRepository();
  372. String remoteURL = remoteGitRepository.getRemoteURL();
  373. if (!remoteURLGitBranchNameMap.containsKey(remoteURL)) {
  374. remoteURLGitBranchNameMap.put(remoteURL, new HashSet<String>());
  375. }
  376. Set<String> remoteGitBranchNames = remoteURLGitBranchNameMap.get(
  377. remoteURL);
  378. remoteGitBranchNames.add(remoteGitBranch.getName());
  379. remoteURLGitBranchNameMap.put(remoteURL, remoteGitBranchNames);
  380. }
  381. for (Map.Entry<String, Set<String>> remoteURLBranchNamesEntry :
  382. remoteURLGitBranchNameMap.entrySet()) {
  383. String remoteURL = remoteURLBranchNamesEntry.getKey();
  384. for (List<String> branchNames :
  385. Lists.partition(
  386. new ArrayList<String>(
  387. remoteURLBranchNamesEntry.getValue()),
  388. _BRANCHES_DELETE_BATCH_SIZE)) {
  389. _deleteRemoteGitBranches(
  390. remoteURL, branchNames.toArray(new String[0]));
  391. }
  392. }
  393. }
  394. public void displayLog() {
  395. displayLog(1);
  396. }
  397. public void displayLog(int logNumber) {
  398. String command = "git log -n " + logNumber;
  399. GitUtil.ExecutionResult executionResult = executeBashCommands(
  400. GitUtil.RETRIES_SIZE_MAX, GitUtil.MILLIS_RETRY_DELAY, 1000 * 60 * 3,
  401. command);
  402. if (executionResult.getExitValue() != 0) {
  403. throw new RuntimeException("Unable to display log");
  404. }
  405. System.out.println();
  406. System.out.println(executionResult.getStandardOut());
  407. System.out.println();
  408. }
  409. public void fetch(GitRemote gitRemote) {
  410. fetch(gitRemote.getRemoteURL());
  411. }
  412. public void fetch(GitRemote gitRemote, boolean noTags) {
  413. fetch(gitRemote.getRemoteURL(), noTags);
  414. }
  415. public LocalGitBranch fetch(LocalGitBranch localGitBranch) {
  416. return fetch(null, localGitBranch);
  417. }
  418. public LocalGitBranch fetch(
  419. LocalGitBranch localGitBranch, boolean noTags,
  420. RemoteGitRef remoteGitRef) {
  421. if (remoteGitRef == null) {
  422. throw new IllegalArgumentException("Remote Git reference is null");
  423. }
  424. String remoteGitRefSHA = remoteGitRef.getSHA();
  425. if (localSHAExists(remoteGitRefSHA)) {
  426. System.out.println(
  427. remoteGitRefSHA + " already exists in Git repository");
  428. if (localGitBranch != null) {
  429. return createLocalGitBranch(
  430. localGitBranch.getName(), true, remoteGitRefSHA);
  431. }
  432. return null;
  433. }
  434. StringBuilder gitBranchesSHAReportStringBuilder = new StringBuilder();
  435. gitBranchesSHAReportStringBuilder.append(
  436. _getLocalGitBranchesSHAReport());
  437. gitBranchesSHAReportStringBuilder.append("\nRemote Git branch\n ");
  438. gitBranchesSHAReportStringBuilder.append(remoteGitRef.getName());
  439. gitBranchesSHAReportStringBuilder.append(": ");
  440. gitBranchesSHAReportStringBuilder.append(remoteGitRef.getSHA());
  441. RemoteGitRepository remoteGitRepository =
  442. remoteGitRef.getRemoteGitRepository();
  443. String remoteURL = remoteGitRepository.getRemoteURL();
  444. if (JenkinsResultsParserUtil.isCINode() &&
  445. remoteURL.contains("github.com:liferay/")) {
  446. String gitHubDevRemoteURL = remoteURL.replace(
  447. "github.com:liferay/", "github-dev.liferay.com:liferay/");
  448. RemoteGitBranch gitHubDevRemoteGitBranch = getRemoteGitBranch(
  449. remoteGitRef.getName(), gitHubDevRemoteURL);
  450. if (gitHubDevRemoteGitBranch != null) {
  451. fetch(null, noTags, gitHubDevRemoteGitBranch);
  452. if (localSHAExists(remoteGitRefSHA)) {
  453. if (localGitBranch != null) {
  454. return createLocalGitBranch(
  455. localGitBranch.getName(), true, remoteGitRefSHA);
  456. }
  457. return null;
  458. }
  459. }
  460. }
  461. StringBuilder sb = new StringBuilder();
  462. sb.append("git fetch -f ");
  463. if (noTags) {
  464. sb.append("--no-tags ");
  465. }
  466. else {
  467. sb.append("--tags ");
  468. }
  469. sb.append(remoteURL);
  470. String remoteGitRefName = remoteGitRef.getName();
  471. if ((remoteGitRefName != null) && !remoteGitRefName.isEmpty()) {
  472. sb.append(" ");
  473. sb.append(remoteGitRefName);
  474. if (localGitBranch != null) {
  475. sb.append(":");
  476. sb.append(localGitBranch.getName());
  477. }
  478. }
  479. long start = System.currentTimeMillis();
  480. GitUtil.ExecutionResult executionResult = executeBashCommands(
  481. 3, GitUtil.MILLIS_RETRY_DELAY, 1000 * 60 * 15, sb.toString());
  482. long duration = System.currentTimeMillis() - start;
  483. if (executionResult.getExitValue() != 0) {
  484. System.out.println(executionResult.getStandardOut());
  485. System.out.println(executionResult.getStandardError());
  486. System.out.println(gitBranchesSHAReportStringBuilder.toString());
  487. throw new RuntimeException(
  488. JenkinsResultsParserUtil.combine(
  489. "Unable to fetch remote git ref ", remoteGitRefName,
  490. " after ",
  491. JenkinsResultsParserUtil.toDurationString(duration), "\n",
  492. executionResult.getStandardError()));
  493. }
  494. System.out.println(
  495. "Fetch completed in " +
  496. JenkinsResultsParserUtil.toDurationString(duration));
  497. if (duration > (1000 * 60)) {
  498. System.out.println(gitBranchesSHAReportStringBuilder.toString());
  499. }
  500. if (JenkinsResultsParserUtil.isCINode() &&
  501. (remoteGitRef instanceof RemoteGitBranch) &&
  502. remoteURL.contains("github.com:liferay/")) {
  503. LocalGitBranch liferayGitHubLocalGitBranch = createLocalGitBranch(
  504. JenkinsResultsParserUtil.combine(
  505. "temp-", remoteGitRef.getName()),
  506. true, remoteGitRef.getSHA());
  507. List<GitRemote> gitHubDevGitRemotes =
  508. GitHubDevSyncUtil.getGitHubDevGitRemotes(this);
  509. try {
  510. GitHubDevSyncUtil.pushToAllRemotes(
  511. true, liferayGitHubLocalGitBranch, remoteGitRef.getName(),
  512. gitHubDevGitRemotes);
  513. }
  514. finally {
  515. if (localGitBranch == null) {
  516. deleteLocalGitBranch(liferayGitHubLocalGitBranch);
  517. }
  518. removeGitRemotes(gitHubDevGitRemotes);
  519. }
  520. }
  521. if (localSHAExists(remoteGitRefSHA) && (localGitBranch != null)) {
  522. return createLocalGitBranch(
  523. localGitBranch.getName(), true, remoteGitRefSHA);
  524. }
  525. return null;
  526. }
  527. public LocalGitBranch fetch(
  528. LocalGitBranch localGitBranch, RemoteGitBranch remoteGitBranch) {
  529. return fetch(localGitBranch, true, remoteGitBranch);
  530. }
  531. public LocalGitBranch fetch(RemoteGitRef remoteGitRef) {
  532. return fetch(null, true, remoteGitRef);
  533. }
  534. public void fetch(RemoteGitRepository remoteGitRepository) {
  535. fetch(remoteGitRepository.getRemoteURL());
  536. }
  537. public void fetch(RemoteGitRepository remoteGitRepository, boolean noTags) {
  538. fetch(remoteGitRepository.getRemoteURL(), noTags);
  539. }
  540. public void fetch(String remoteURL) {
  541. fetch(remoteURL, true);
  542. }
  543. public void fetch(String remoteURL, boolean noTags) {
  544. if (remoteURL == null) {
  545. throw new IllegalArgumentException("Remote URL is null");
  546. }
  547. if (!GitUtil.isValidRemoteURL(remoteURL)) {
  548. throw new IllegalArgumentException(
  549. "Invalid remote url " + remoteURL);
  550. }
  551. StringBuilder gitBranchesSHAReportStringBuilder = new StringBuilder();
  552. gitBranchesSHAReportStringBuilder.append(
  553. _getLocalGitBranchesSHAReport());
  554. gitBranchesSHAReportStringBuilder.append("\n");
  555. gitBranchesSHAReportStringBuilder.append(
  556. _getRemoteGitBranchesSHAReport(null, remoteURL));
  557. StringBuilder sb = new StringBuilder();
  558. sb.append("git fetch -f");
  559. if (noTags) {
  560. sb.append(" --no-tags");
  561. }
  562. else {
  563. sb.append(" --tags");
  564. }
  565. sb.append(" ");
  566. sb.append(remoteURL);
  567. sb.append(" refs/heads/*:refs/remotes/origin/*");
  568. long start = System.currentTimeMillis();
  569. GitUtil.ExecutionResult executionResult = executeBashCommands(
  570. 3, GitUtil.MILLIS_RETRY_DELAY, 1000 * 60 * 30, sb.toString());
  571. long duration = System.currentTimeMillis() - start;
  572. if (executionResult.getExitValue() != 0) {
  573. System.out.println(gitBranchesSHAReportStringBuilder.toString());
  574. throw new RuntimeException(
  575. JenkinsResultsParserUtil.combine(
  576. "Unable to fetch remote url ", remoteURL, " after ",
  577. JenkinsResultsParserUtil.toDurationString(duration), "\n",
  578. executionResult.getStandardError()));
  579. }
  580. System.out.println(
  581. "Fetch completed in " +
  582. JenkinsResultsParserUtil.toDurationString(duration));
  583. if (duration > (1000 * 60)) {
  584. System.out.println(gitBranchesSHAReportStringBuilder.toString());
  585. }
  586. }
  587. public LocalGitBranch fetch(
  588. String branchName, LocalGitBranch localGitBranch) {
  589. if (localGitBranch == null) {
  590. throw new IllegalArgumentException("Local Git branch is null");
  591. }
  592. StringBuilder sb = new StringBuilder();
  593. sb.append("git fetch -f --no-tags ");
  594. sb.append(String.valueOf(localGitBranch.getDirectory()));
  595. sb.append(" ");
  596. sb.append(localGitBranch.getName());
  597. if ((branchName != null) && !branchName.isEmpty()) {
  598. sb.append(":");
  599. sb.append(branchName);
  600. }
  601. long start = System.currentTimeMillis();
  602. GitUtil.ExecutionResult executionResult = executeBashCommands(
  603. 3, GitUtil.MILLIS_RETRY_DELAY, 1000 * 60 * 30, sb.toString());
  604. if (executionResult.getExitValue() != 0) {
  605. throw new RuntimeException(
  606. JenkinsResultsParserUtil.combine(
  607. "Unable to fetch from local Git repository ",
  608. String.valueOf(localGitBranch.getDirectory()), "\n",
  609. executionResult.getStandardError()));
  610. }
  611. String durationString = JenkinsResultsParserUtil.toDurationString(
  612. System.currentTimeMillis() - start);
  613. System.out.println("Fetch completed in " + durationString);
  614. return createLocalGitBranch(
  615. localGitBranch.getName(), true, localGitBranch.getSHA());
  616. }
  617. public void gc() {
  618. int retries = 0;
  619. while (true) {
  620. GitUtil.ExecutionResult executionResult = null;
  621. boolean exceptionThrown = false;
  622. try {
  623. executionResult = executeBashCommands(
  624. GitUtil.RETRIES_SIZE_MAX, GitUtil.MILLIS_RETRY_DELAY,
  625. 60 * 60 * 1000, "git gc");
  626. }
  627. catch (RuntimeException runtimeException) {
  628. exceptionThrown = true;
  629. }
  630. System.out.println(executionResult.getStandardOut());
  631. if (exceptionThrown || (executionResult.getExitValue() != 0)) {
  632. String standardError = executionResult.getStandardError();
  633. Matcher matcher = _badRefPattern.matcher(standardError);
  634. if (matcher.find()) {
  635. File badRefFile = new File(
  636. getWorkingDirectory(),
  637. ".git/" + matcher.group("badRef"));
  638. badRefFile.delete();
  639. }
  640. if (retries > 1) {
  641. throw new RuntimeException(
  642. JenkinsResultsParserUtil.combine(
  643. "Unable to garbage collect Git\n", standardError));
  644. }
  645. }
  646. else {
  647. return;
  648. }
  649. retries++;
  650. JenkinsResultsParserUtil.sleep(GitUtil.MILLIS_RETRY_DELAY);
  651. System.out.println(
  652. JenkinsResultsParserUtil.combine(
  653. "Retry garbage collect Git in ",
  654. String.valueOf(GitUtil.MILLIS_RETRY_DELAY), "ms"));
  655. }
  656. }
  657. public List<String> getBranchNamesContainingSHA(String sha) {
  658. GitUtil.ExecutionResult executionResult = executeBashCommands(
  659. GitUtil.RETRIES_SIZE_MAX, GitUtil.MILLIS_RETRY_DELAY, 1000 * 60 * 2,
  660. "git branch --contains " + sha);
  661. if (executionResult.getExitValue() != 0) {
  662. String standardError = executionResult.getStandardError();
  663. if (standardError.contains("no such commit")) {
  664. return Collections.emptyList();
  665. }
  666. throw new RuntimeException(
  667. JenkinsResultsParserUtil.combine(
  668. "Unable to get branches with SHA ", sha, "\n",
  669. standardError));
  670. }
  671. String standardOut = executionResult.getStandardOut();
  672. if (standardOut.contains("no such commit")) {
  673. return Collections.emptyList();
  674. }
  675. String[] lines = standardOut.split("\n");
  676. List<String> branchNamesList = new ArrayList<>(lines.length - 1);
  677. for (String line : lines) {
  678. String branchName = line.trim();
  679. if (branchName.startsWith("* ")) {
  680. branchName = branchName.substring(2);
  681. }
  682. if (branchName.isEmpty()) {
  683. continue;
  684. }
  685. branchNamesList.add(branchName);
  686. }
  687. return branchNamesList;
  688. }
  689. public String getCurrentBranchName() {
  690. return getCurrentBranchName(false);
  691. }
  692. public String getCurrentBranchName(boolean required) {
  693. waitForIndexLock();
  694. GitUtil.ExecutionResult executionResult = executeBashCommands(
  695. GitUtil.RETRIES_SIZE_MAX, GitUtil.MILLIS_RETRY_DELAY,
  696. GitUtil.MILLIS_TIMEOUT, "git branch | grep \\*");
  697. if (executionResult.getExitValue() != 0) {
  698. System.out.println(executionResult.getStandardError());
  699. if (required) {
  700. throw new RuntimeException(
  701. "Unable to find required local branch HEAD");
  702. }
  703. return null;
  704. }
  705. String currentBranchName = executionResult.getStandardOut();
  706. currentBranchName = currentBranchName.replaceFirst("\\*\\s*", "");
  707. currentBranchName = currentBranchName.trim();
  708. if (currentBranchName.isEmpty()) {
  709. return null;
  710. }
  711. return currentBranchName;
  712. }
  713. public LocalGitBranch getCurrentLocalGitBranch() {
  714. String currentBranchName = getCurrentBranchName();
  715. if (currentBranchName == null) {
  716. return null;
  717. }
  718. return getLocalGitBranch(currentBranchName);
  719. }
  720. public String getGitConfigProperty(String gitConfigPropertyName) {
  721. GitUtil.ExecutionResult executionResult = executeBashCommands(
  722. GitUtil.RETRIES_SIZE_MAX, GitUtil.MILLIS_RETRY_DELAY,
  723. GitUtil.MILLIS_TIMEOUT, "git config " + gitConfigPropertyName);
  724. if (executionResult.getExitValue() != 0) {
  725. throw new RuntimeException(
  726. JenkinsResultsParserUtil.combine(
  727. "Unable to read Git config property ",
  728. gitConfigPropertyName, "\n",
  729. executionResult.getStandardError()));
  730. }
  731. String configProperty = executionResult.getStandardOut();
  732. if (configProperty != null) {
  733. configProperty = configProperty.trim();
  734. }
  735. if ((configProperty == null) || configProperty.isEmpty()) {
  736. return null;
  737. }
  738. return configProperty;
  739. }
  740. public Boolean getGitConfigPropertyBoolean(
  741. String gitConfigPropertyName, Boolean defaultValue) {
  742. String gitConfigProperty = getGitConfigProperty(gitConfigPropertyName);
  743. if (gitConfigProperty == null) {
  744. if (defaultValue != null) {
  745. return defaultValue;
  746. }
  747. return null;
  748. }
  749. return Boolean.parseBoolean(gitConfigProperty);
  750. }
  751. public File getGitDirectory() {
  752. return _gitDirectory;
  753. }
  754. public GitRemote getGitRemote(String name) {
  755. if (name.equals("upstream")) {
  756. name = "upstream-temp";
  757. }
  758. if (_gitRemotes.isEmpty()) {
  759. getGitRemotes();
  760. }
  761. name = name.trim();
  762. return _gitRemotes.get(name);
  763. }
  764. public Set<String> getGitRemoteNames() {
  765. Map<String, GitRemote> gitRemotes = getGitRemotes();
  766. return gitRemotes.keySet();
  767. }
  768. public Map<String, GitRemote> getGitRemotes() {
  769. if (!_gitRemotes.isEmpty()) {
  770. return _gitRemotes;
  771. }
  772. int retries = 0;
  773. String standardOut = null;
  774. while (true) {
  775. if (retries > 1) {
  776. return _gitRemotes;
  777. }
  778. GitUtil.ExecutionResult executionResult = executeBashCommands(
  779. GitUtil.RETRIES_SIZE_MAX, GitUtil.MILLIS_RETRY_DELAY,
  780. GitUtil.MILLIS_TIMEOUT, "git remote -v");
  781. if (executionResult.getExitValue() != 0) {
  782. throw new RuntimeException(
  783. JenkinsResultsParserUtil.combine(
  784. "Unable to get list of git remotes\n",
  785. executionResult.getStandardError()));
  786. }
  787. standardOut = executionResult.getStandardOut();
  788. standardOut = standardOut.trim();
  789. if (!standardOut.isEmpty()) {
  790. break;
  791. }
  792. retries++;
  793. JenkinsResultsParserUtil.sleep(1000);
  794. }
  795. String[] lines = standardOut.split("\n");
  796. Arrays.sort(lines);
  797. int x = 0;
  798. for (int i = 0; i < lines.length; i++) {
  799. String line = lines[i];
  800. if (line == null) {
  801. continue;
  802. }
  803. line = line.trim();
  804. if (line.isEmpty()) {
  805. continue;
  806. }
  807. x = i;
  808. break;
  809. }
  810. lines = Arrays.copyOfRange(lines, x, lines.length);
  811. try {
  812. StringBuilder sb = new StringBuilder();
  813. sb.append("Found git remotes: ");
  814. for (int i = 0; i < lines.length; i = i + 2) {
  815. GitRemote gitRemote = new GitRemote(
  816. this, Arrays.copyOfRange(lines, i, i + 2));
  817. if (i > 0) {
  818. sb.append(", ");
  819. }
  820. sb.append(gitRemote.getName());
  821. _gitRemotes.put(gitRemote.getName(), gitRemote);
  822. }
  823. System.out.println(sb);
  824. }
  825. catch (Throwable t) {
  826. System.out.println("Unable to parse git remotes\n" + standardOut);
  827. throw t;
  828. }
  829. return _gitRemotes;
  830. }
  831. public String getGitRepositoryName() {
  832. return _gitRepositoryName;
  833. }
  834. public String getGitRepositoryUsername() {
  835. return _gitRepositoryUsername;
  836. }
  837. public File getJavaFileFromFullClassName(String fullClassName) {
  838. if (_javaDirPaths == null) {
  839. List<File> javaFiles = JenkinsResultsParserUtil.findFiles(
  840. getWorkingDirectory(), ".*\\.java");
  841. _javaDirPaths = new HashSet<>();
  842. for (File javaFile : javaFiles) {
  843. File parentFile = javaFile.getParentFile();
  844. _javaDirPaths.add(parentFile.getPath());
  845. }
  846. }
  847. String classFileName =
  848. fullClassName.replaceAll(".*\\.([^\\.]+)", "$1") + ".java";
  849. String classPackageName = fullClassName.substring(
  850. 0, fullClassName.lastIndexOf("."));
  851. String classPackagePath = classPackageName.replaceAll("\\.", "/");
  852. for (String javaDirPath : _javaDirPaths) {
  853. if (!javaDirPath.contains(classPackagePath)) {
  854. continue;
  855. }
  856. File classFile = new File(javaDirPath, classFileName);
  857. if (!classFile.exists()) {
  858. continue;
  859. }
  860. String classFilePath = classFile.getPath();
  861. if (!classFilePath.contains(
  862. classPackagePath + "/" + classFileName)) {
  863. continue;
  864. }
  865. return classFile;
  866. }
  867. return null;
  868. }
  869. public LocalGitBranch getLocalGitBranch(String branchName) {
  870. return getLocalGitBranch(branchName, false);
  871. }
  872. public LocalGitBranch getLocalGitBranch(
  873. String branchName, boolean required) {
  874. if (branchName.equals(getUpstreamBranchName())) {
  875. return getUpstreamLocalGitBranch();
  876. }
  877. if (!localGitBranchExists(branchName)) {
  878. return null;
  879. }
  880. return _getLocalGitBranch(branchName, required);
  881. }
  882. public List<LocalGitBranch> getLocalGitBranches(String branchName) {
  883. String upstreamBranchName = getUpstreamBranchName();
  884. LocalGitRepository localGitRepository =
  885. GitRepositoryFactory.getLocalGitRepository(
  886. getGitRepositoryName(), upstreamBranchName);
  887. if (branchName != null) {
  888. try {
  889. return Arrays.asList(
  890. GitBranchFactory.newLocalGitBranch(
  891. localGitRepository, branchName,
  892. getLocalGitBranchSHA(branchName)));
  893. }
  894. catch (Exception exception) {
  895. if (!branchName.equals(upstreamBranchName)) {
  896. return null;
  897. }
  898. }
  899. }
  900. List<String> localGitBranchNames = getLocalGitBranchNames();
  901. List<LocalGitBranch> localGitBranches = new ArrayList<>(
  902. localGitBranchNames.size());
  903. Map<String, String> localGitBranchesShaMap =
  904. getLocalGitBranchesShaMap();
  905. for (String localGitBranchName : localGitBranchNames) {
  906. localGitBranches.add(
  907. GitBranchFactory.newLocalGitBranch(
  908. localGitRepository, localGitBranchName,
  909. localGitBranchesShaMap.get(localGitBranchName)));
  910. }
  911. return localGitBranches;
  912. }
  913. public String getLocalGitBranchSHA(String localGitBranchName) {
  914. if (localGitBranchName == null) {
  915. throw new IllegalArgumentException("Local branch name is null");
  916. }
  917. GitUtil.ExecutionResult executionResult = executeBashCommands(
  918. GitUtil.RETRIES_SIZE_MAX, GitUtil.MILLIS_RETRY_DELAY, 1000 * 60 * 2,
  919. "git rev-parse " + localGitBranchName);
  920. if (executionResult.getExitValue() != 0) {
  921. throw new RuntimeException(
  922. JenkinsResultsParserUtil.combine(
  923. "Unable to determine SHA of branch ", localGitBranchName,
  924. "\n", executionResult.getStandardError()));
  925. }
  926. return executionResult.getStandardOut();
  927. }
  928. public List<File> getModifiedDirsList(
  929. boolean checkUnstagedFiles, List<PathMatcher> excludesPathMatchers,
  930. List<PathMatcher> includesPathMatchers) {
  931. return getModifiedDirsList(
  932. checkUnstagedFiles, excludesPathMatchers, includesPathMatchers,
  933. getWorkingDirectory());
  934. }
  935. public List<File> getModifiedDirsList(
  936. boolean checkUnstagedFiles, List<PathMatcher> excludesPathMatchers,
  937. List<PathMatcher> includesPathMatchers, File rootDirectory) {
  938. List<File> subdirectories = getSubdirectoriesContainingFiles(
  939. 1, getModifiedFilesList(checkUnstagedFiles, null, null),
  940. rootDirectory);
  941. return JenkinsResultsParserUtil.getIncludedFiles(
  942. excludesPathMatchers, includesPathMatchers, subdirectories);
  943. }
  944. public List<File> getModifiedFilesList() {
  945. return getModifiedFilesList(false, null, null);
  946. }
  947. public List<File> getModifiedFilesList(boolean checkUnstagedFiles) {
  948. return getModifiedFilesList(checkUnstagedFiles, null, null);
  949. }
  950. public List<File> getModifiedFilesList(
  951. boolean checkUnstagedFiles, List<PathMatcher> excludesPathMatchers,
  952. List<PathMatcher> includesPathMatchers) {
  953. LocalGitBranch currentLocalGitBranch = getCurrentLocalGitBranch();
  954. if (currentLocalGitBranch == null) {
  955. throw new RuntimeException(
  956. "Unable to determine the current branch");
  957. }
  958. StringBuilder sb = new StringBuilder();
  959. sb.append("git diff --diff-filter=ADMR --name-only ");
  960. sb.append(
  961. _getMergeBaseCommitSHA(
  962. currentLocalGitBranch,
  963. getLocalGitBranch(getUpstreamBranchName(), true)));
  964. if (!checkUnstagedFiles) {
  965. sb.append(" ");
  966. sb.append(currentLocalGitBranch.getSHA());
  967. }
  968. String gitDiffCommandString = sb.toString();
  969. List<File> modifiedFiles = _modifiedFilesMap.get(gitDiffCommandString);
  970. if (modifiedFiles == null) {
  971. GitUtil.ExecutionResult executionResult = executeBashCommands(
  972. GitUtil.RETRIES_SIZE_MAX, GitUtil.MILLIS_RETRY_DELAY,
  973. GitUtil.MILLIS_TIMEOUT, gitDiffCommandString);
  974. if (executionResult.getExitValue() == 1) {
  975. return Collections.emptyList();
  976. }
  977. if (executionResult.getExitValue() != 0) {
  978. throw new RuntimeException(
  979. "Unable to get current branch modified files\n" +
  980. executionResult.getStandardError());
  981. }
  982. modifiedFiles = new ArrayList<>();
  983. String gitDiffOutput = executionResult.getStandardOut();
  984. for (String line : gitDiffOutput.split("\n")) {
  985. modifiedFiles.add(new File(_workingDirectory, line));
  986. }
  987. _modifiedFilesMap.put(gitDiffCommandString, modifiedFiles);
  988. }
  989. return JenkinsResultsParserUtil.getIncludedFiles(
  990. excludesPathMatchers, includesPathMatchers, modifiedFiles);
  991. }
  992. public List<File> getModifiedFilesList(
  993. List<PathMatcher> excludesPathMatchers,
  994. List<PathMatcher> includesPathMatchers) {
  995. return getModifiedFilesList(
  996. false, excludesPathMatchers, includesPathMatchers);
  997. }
  998. public LocalGitBranch getRebasedLocalGitBranch(PullRequest pullRequest) {
  999. return getRebasedLocalGitBranch(
  1000. pullRequest.getLocalSenderBranchName(),
  1001. pullRequest.getSenderBranchName(), pullRequest.getSenderRemoteURL(),
  1002. pullRequest.getSenderSHA(), pullRequest.getUpstreamBranchName(),
  1003. pullRequest.getLiferayRemoteBranchSHA());
  1004. }
  1005. public LocalGitBranch getRebasedLocalGitBranch(
  1006. String rebasedLocalGitBranchName, String senderBranchName,
  1007. String senderRemoteURL, String senderSHA, String upstreamBranchName,
  1008. String upstreamBranchSHA) {
  1009. String currentBranchName = getCurrentBranchName();
  1010. LocalGitBranch tempLocalGitBranch = null;
  1011. try {
  1012. if ((currentBranchName == null) ||
  1013. currentBranchName.equals(rebasedLocalGitBranchName)) {
  1014. tempLocalGitBranch = createLocalGitBranch(
  1015. "temp-" + System.currentTimeMillis());
  1016. checkoutLocalGitBranch(tempLocalGitBranch);
  1017. }
  1018. RemoteGitRef senderRemoteGitRef = getRemoteGitRef(
  1019. senderBranchName, senderRemoteURL, true);
  1020. fetch(senderRemoteGitRef);
  1021. LocalGitBranch rebasedLocalGitBranch = createLocalGitBranch(
  1022. rebasedLocalGitBranchName, true, senderSHA);
  1023. RemoteGitBranch upstreamRemoteGitBranch = getRemoteGitBranch(
  1024. upstreamBranchName, getUpstreamGitRemote(), true);
  1025. if (upstreamBranchSHA == null) {
  1026. upstreamBranchSHA = upstreamRemoteGitBranch.getSHA();
  1027. }
  1028. if (!localSHAExists(upstreamBranchSHA)) {
  1029. fetch(upstreamRemoteGitBranch);
  1030. }
  1031. LocalGitBranch upstreamLocalGitBranch = createLocalGitBranch(
  1032. upstreamRemoteGitBranch.getName(), true, upstreamBranchSHA);
  1033. rebasedLocalGitBranch = rebase(
  1034. true, upstreamLocalGitBranch, rebasedLocalGitBranch);
  1035. clean();
  1036. reset("--hard");
  1037. return rebasedLocalGitBranch;
  1038. }
  1039. finally {
  1040. if (tempLocalGitBranch != null) {
  1041. deleteLocalGitBranch(tempLocalGitBranch);
  1042. }
  1043. }
  1044. }
  1045. public RemoteGitBranch getRemoteGitBranch(
  1046. String remoteGitBranchName, GitRemote gitRemote) {
  1047. return getRemoteGitBranch(
  1048. remoteGitBranchName, gitRemote.getRemoteURL(), false);
  1049. }
  1050. public RemoteGitBranch getRemoteGitBranch(
  1051. String remoteGitBranchName, GitRemote gitRemote, boolean required) {
  1052. return getRemoteGitBranch(
  1053. remoteGitBranchName, gitRemote.getRemoteURL(), required);
  1054. }
  1055. public RemoteGitBranch getRemoteGitBranch(
  1056. String remoteGitBranchName, RemoteGitRepository remoteGitRepository) {
  1057. return getRemoteGitBranch(
  1058. remoteGitBranchName, remoteGitRepository.getRemoteURL(), false);
  1059. }
  1060. public RemoteGitBranch getRemoteGitBranch(
  1061. String remoteGitBranchName, RemoteGitRepository remoteGitRepository,
  1062. boolean required) {
  1063. return getRemoteGitBranch(
  1064. remoteGitBranchName, remoteGitRepository.getRemoteURL(), required);
  1065. }
  1066. public RemoteGitBranch getRemoteGitBranch(
  1067. String remoteGitBranchName, String remoteURL) {
  1068. return getRemoteGitBranch(remoteGitBranchName, remoteURL, false);
  1069. }
  1070. public RemoteGitBranch getRemoteGitBranch(
  1071. String remoteGitBranchName, String remoteURL, boolean required) {
  1072. List<RemoteGitBranch> remoteGitBranches = getRemoteGitBranches(
  1073. remoteGitBranchName, remoteURL);
  1074. for (RemoteGitBranch remoteGitBranch : remoteGitBranches) {
  1075. if (remoteGitBranchName.equals(remoteGitBranch.getName())) {
  1076. return remoteGitBranch;
  1077. }
  1078. }
  1079. if (required) {
  1080. throw new RuntimeException(
  1081. JenkinsResultsParserUtil.combine(
  1082. "Unable to find required branch ", remoteGitBranchName,
  1083. " from remote URL ", remoteURL));
  1084. }
  1085. return null;
  1086. }
  1087. public List<RemoteGitBranch> getRemoteGitBranches(GitRemote gitRemote) {
  1088. return getRemoteGitBranches(null, gitRemote.getRemoteURL());
  1089. }
  1090. public List<RemoteGitBranch> getRemoteGitBranches(
  1091. RemoteGitRepository remoteGitRepository) {
  1092. return getRemoteGitBranches(null, remoteGitRepository.getRemoteURL());
  1093. }
  1094. public List<RemoteGitBranch> getRemoteGitBranches(String remoteURL) {
  1095. return getRemoteGitBranches(null, remoteURL);
  1096. }
  1097. public List<RemoteGitBranch> getRemoteGitBranches(
  1098. String remoteGitBranchName, GitRemote gitRemote) {
  1099. return getRemoteGitBranches(
  1100. remoteGitBranchName, gitRemote.getRemoteURL());
  1101. }
  1102. public List<RemoteGitBranch> getRemoteGitBranches(
  1103. String remoteGitBranchName, RemoteGitRepository remoteGitRepository) {
  1104. return getRemoteGitBranches(
  1105. remoteGitBranchName, remoteGitRepository.getRemoteURL());
  1106. }
  1107. public List<RemoteGitBranch> getRemoteGitBranches(
  1108. String remoteGitBranchName, String remoteURL) {
  1109. return GitUtil.getRemoteGitBranches(
  1110. remoteGitBranchName, _workingDirectory, remoteURL);
  1111. }
  1112. public List<String> getRemoteGitBranchNames(GitRemote gitRemote) {
  1113. return getRemoteGitBranchNames(gitRemote.getRemoteURL());
  1114. }
  1115. public List<String> getRemoteGitBranchNames(
  1116. RemoteGitRepository remoteGitRepository) {
  1117. return getRemoteGitBranchNames(remoteGitRepository.getRemoteURL());
  1118. }
  1119. public List<String> getRemoteGitBranchNames(String remoteURL) {
  1120. List<String> remoteGitBranchNames = new ArrayList<>();
  1121. List<RemoteGitBranch> remoteGitBranches = getRemoteGitBranches(
  1122. remoteURL);
  1123. for (RemoteGitBranch remoteGitBranch : remoteGitBranches) {
  1124. remoteGitBranchNames.add(remoteGitBranch.getName());
  1125. }
  1126. return remoteGitBranchNames;
  1127. }
  1128. public String getRemoteGitBranchSHA(
  1129. String remoteGitBranchName, GitRemote gitRemote) {
  1130. return getRemoteGitBranchSHA(
  1131. remoteGitBranchName, gitRemote.getRemoteURL());
  1132. }
  1133. public String getRemoteGitBranchSHA(
  1134. String remoteGitBranchName, RemoteGitRepository remoteGitRepository) {
  1135. return getRemoteGitBranchSHA(
  1136. remoteGitBranchName, remoteGitRepository.getRemoteURL());
  1137. }
  1138. public String getRemoteGitBranchSHA(
  1139. String remoteGitBranchName, String remoteURL) {
  1140. if (remoteGitBranchName == null) {
  1141. throw new IllegalArgumentException("Remote branch name is null");
  1142. }
  1143. if (remoteURL == null) {
  1144. throw new IllegalArgumentException("Remote URL is null");
  1145. }
  1146. if (!GitUtil.isValidRemoteURL(remoteURL)) {
  1147. throw new IllegalArgumentException(
  1148. "Invalid remote url " + remoteURL);
  1149. }
  1150. String command = JenkinsResultsParserUtil.combine(
  1151. "git ls-remote -h ", remoteURL, " ", remoteGitBranchName);
  1152. GitUtil.ExecutionResult executionResult = executeBashCommands(
  1153. 3, GitUtil.MILLIS_RETRY_DELAY, 1000 * 60 * 10, command);
  1154. if (executionResult.getExitValue() != 0) {
  1155. throw new RuntimeException(
  1156. JenkinsResultsParserUtil.combine(
  1157. "Unable to get remote branch SHA ", remoteURL, " ",
  1158. remoteGitBranchName, "\n",
  1159. executionResult.getStandardError()));
  1160. }
  1161. String input = executionResult.getStandardOut();
  1162. for (String line : input.split("\n")) {
  1163. Matcher matcher = GitRemote.gitLsRemotePattern.matcher(line);
  1164. if (matcher.find()) {
  1165. return matcher.group("sha");
  1166. }
  1167. }
  1168. return null;
  1169. }
  1170. public RemoteGitRef getRemoteGitRef(
  1171. String remoteGitRefName, GitRemote gitRemote, boolean required) {
  1172. return getRemoteGitRef(
  1173. remoteGitRefName, gitRemote.getRemoteURL(), required);
  1174. }
  1175. public RemoteGitRef getRemoteGitRef(
  1176. String remoteGitRefName, String remoteURL, boolean required) {
  1177. List<RemoteGitRef> remoteGitRefs = GitUtil.getRemoteGitRefs(
  1178. remoteGitRefName, getWorkingDirectory(), remoteURL);
  1179. for (RemoteGitRef remoteGitRef : remoteGitRefs) {
  1180. if (remoteGitRefName.equals(remoteGitRef.getName())) {
  1181. return remoteGitRef;
  1182. }
  1183. }
  1184. if (required) {
  1185. throw new RuntimeException(
  1186. JenkinsResultsParserUtil.combine(
  1187. "Unable to find required ref ", remoteGitRefName,
  1188. " from remote URL ", remoteURL));
  1189. }
  1190. return null;
  1191. }
  1192. public String getUpstreamBranchName() {
  1193. return _upstreamBranchName;
  1194. }
  1195. public GitRemote getUpstreamGitRemote() {
  1196. Map<String, GitRemote> gitRemotes = getGitRemotes();
  1197. GitRemote gitRemote = gitRemotes.get("upstream");
  1198. if (gitRemote == null) {
  1199. gitRemote = addGitRemote(
  1200. true, "upstream",
  1201. JenkinsResultsParserUtil.combine(
  1202. "git@github.com:liferay/", getGitRepositoryName(), ".git"));
  1203. }
  1204. return gitRemote;
  1205. }
  1206. public LocalGitBranch getUpstreamLocalGitBranch() {
  1207. String upstreamBranchName = getUpstreamBranchName();
  1208. if (localGitBranchExists(upstreamBranchName)) {
  1209. return _getLocalGitBranch(upstreamBranchName, true);
  1210. }
  1211. RemoteGitBranch upstreamRemoteGitBranch = getRemoteGitBranch(
  1212. upstreamBranchName, getGitRemote("upstream"));
  1213. fetch(upstreamRemoteGitBranch);
  1214. String currentBranchName = getCurrentBranchName();
  1215. if (currentBranchName == null) {
  1216. List<String> localGitBranchNames = getLocalGitBranchNames();
  1217. List<LocalGitBranch> localGitBranches = getLocalGitBranches(
  1218. localGitBranchNames.get(0));
  1219. checkoutLocalGitBranch(localGitBranches.get(0));
  1220. }
  1221. return createLocalGitBranch(
  1222. upstreamBranchName, true, upstreamRemoteGitBranch.getSHA());
  1223. }
  1224. public RemoteGitBranch getUpstreamRemoteGitBranch() {
  1225. return getRemoteGitBranch(
  1226. getUpstreamBranchName(),
  1227. JenkinsResultsParserUtil.combine(
  1228. "git@github.com:liferay/", getGitRepositoryName()));
  1229. }
  1230. public File getWorkingDirectory() {
  1231. return _workingDirectory;
  1232. }
  1233. public boolean gitRemoteExists(String gitRemoteName) {
  1234. if (getGitRemote(gitRemoteName) != null) {
  1235. return true;
  1236. }
  1237. return false;
  1238. }
  1239. public boolean isRemoteGitRepositoryAlive(String remoteURL) {
  1240. String command = JenkinsResultsParserUtil.combine(
  1241. "git ls-remote -h ", remoteURL, " HEAD");
  1242. GitUtil.ExecutionResult executionResult = executeBashCommands(
  1243. GitUtil.RETRIES_SIZE_MAX, GitUtil.MILLIS_RETRY_DELAY,
  1244. 1000 * 60 * 10, command);
  1245. if (executionResult.getExitValue() != 0) {
  1246. System.out.println("Unable to connect to " + remoteURL);
  1247. return false;
  1248. }
  1249. System.out.println(remoteURL + " is alive");
  1250. return true;
  1251. }
  1252. public boolean localGitBranchExists(String branchName) {
  1253. waitForIndexLock();
  1254. GitUtil.ExecutionResult executionResult = executeBashCommands(
  1255. GitUtil.RETRIES_SIZE_MAX, GitUtil.MILLIS_RETRY_DELAY,
  1256. GitUtil.MILLIS_TIMEOUT,
  1257. "git branch | grep [\\s\\*]*" + branchName + "$");
  1258. if (executionResult.getExitValue() == 0) {
  1259. String standardOut = executionResult.getStandardOut();
  1260. if (standardOut.isEmpty()) {
  1261. return false;
  1262. }
  1263. return true;
  1264. }
  1265. return false;
  1266. }
  1267. public boolean localSHAExists(String sha) {
  1268. String command = "git cat-file -t " + sha;
  1269. GitUtil.ExecutionResult executionResult = executeBashCommands(
  1270. GitUtil.RETRIES_SIZE_MAX, GitUtil.MILLIS_RETRY_DELAY, 1000 * 60 * 3,
  1271. command);
  1272. if (executionResult.getExitValue() == 0) {
  1273. return true;
  1274. }
  1275. return false;
  1276. }
  1277. public List<LocalGitCommit> log(int num) {
  1278. return _log(0, num, null, null);
  1279. }
  1280. public List<LocalGitCommit> log(int num, File file) {
  1281. return _log(0, num, file, null);
  1282. }
  1283. public List<LocalGitCommit> log(int start, int num) {
  1284. return _log(start, num, null, null);
  1285. }
  1286. public List<LocalGitCommit> log(int start, int num, String sha) {
  1287. return _log(start, num, null, sha);
  1288. }
  1289. public RemoteGitBranch pushToRemoteGitRepository(
  1290. boolean force, LocalGitBranch localGitBranch,
  1291. String remoteGitBranchName, GitRemote gitRemote) {
  1292. return pushToRemoteGitRepository(
  1293. force, localGitBranch, remoteGitBranchName,
  1294. gitRemote.getRemoteURL());
  1295. }
  1296. public RemoteGitBranch pushToRemoteGitRepository(
  1297. boolean force, LocalGitBranch localGitBranch,
  1298. String remoteGitBranchName, RemoteGitRepository remoteGitRepository) {
  1299. return pushToRemoteGitRepository(
  1300. force, localGitBranch, remoteGitBranchName,
  1301. remoteGitRepository.getRemoteURL());
  1302. }
  1303. public RemoteGitBranch pushToRemoteGitRepository(
  1304. boolean force, LocalGitBranch localGitBranch,
  1305. String remoteGitBranchName, String remoteURL) {
  1306. if (localGitBranch == null) {
  1307. throw new IllegalArgumentException("Local Git branch is null");
  1308. }
  1309. if (remoteURL == null) {
  1310. throw new IllegalArgumentException("Remote URL is null");
  1311. }
  1312. if (!GitUtil.isValidRemoteURL(remoteURL)) {
  1313. throw new IllegalArgumentException(
  1314. "Invalid remote url " + remoteURL);
  1315. }
  1316. StringBuilder sb = new StringBuilder();
  1317. sb.append("git push ");
  1318. if (force) {
  1319. sb.append("-f ");
  1320. }
  1321. sb.append(remoteURL);
  1322. sb.append(" ");
  1323. sb.append(localGitBranch.getName());
  1324. if (remoteGitBranchName != null) {
  1325. sb.append(":");
  1326. sb.append(remoteGitBranchName);
  1327. }
  1328. try {
  1329. GitUtil.ExecutionResult executionResult = executeBashCommands(
  1330. GitUtil.RETRIES_SIZE_MAX, GitUtil.MILLIS_RETRY_DELAY,
  1331. 1000 * 60 * 10, sb.toString());
  1332. if (executionResult.getExitValue() != 0) {
  1333. return null;
  1334. }
  1335. }
  1336. catch (RuntimeException runtimeException) {
  1337. runtimeException.printStackTrace();
  1338. return null;
  1339. }
  1340. return (RemoteGitBranch)GitBranchFactory.newRemoteGitRef(
  1341. GitRepositoryFactory.getRemoteGitRepository(remoteURL),
  1342. remoteGitBranchName, localGitBranch.getSHA(), "heads");
  1343. }
  1344. public LocalGitBranch rebase(
  1345. boolean abortOnFail, LocalGitBranch baseLocalGitBranch,
  1346. LocalGitBranch localGitBranch) {
  1347. List<String> branchNamesContainingSHA = getBranchNamesContainingSHA(
  1348. baseLocalGitBranch.getSHA());
  1349. if (branchNamesContainingSHA.contains(localGitBranch.getName())) {
  1350. checkoutLocalGitBranch(localGitBranch);
  1351. return localGitBranch;
  1352. }
  1353. checkoutLocalGitBranch(baseLocalGitBranch);
  1354. reset("--hard " + baseLocalGitBranch.getSHA());
  1355. String rebaseCommand = JenkinsResultsParserUtil.combine(
  1356. "git rebase ", baseLocalGitBranch.getName(), " ",
  1357. localGitBranch.getName());
  1358. GitUtil.ExecutionResult executionResult = executeBashCommands(
  1359. GitUtil.RETRIES_SIZE_MAX, GitUtil.MILLIS_RETRY_DELAY,
  1360. 1000 * 60 * 10, rebaseCommand);
  1361. if (executionResult.getExitValue() != 0) {
  1362. if (abortOnFail) {
  1363. rebaseAbort();
  1364. }
  1365. throw new RuntimeException(
  1366. JenkinsResultsParserUtil.combine(
  1367. "Unable to rebase ", localGitBranch.getName(), " to ",
  1368. baseLocalGitBranch.getName(), "\n",
  1369. executionResult.getStandardError()));
  1370. }
  1371. return getCurrentLocalGitBranch();
  1372. }
  1373. public void rebaseAbort() {
  1374. rebaseAbort(true);
  1375. }
  1376. public void rebaseAbort(boolean ignoreFailure) {
  1377. GitUtil.ExecutionResult executionResult = executeBashCommands(
  1378. GitUtil.RETRIES_SIZE_MAX, GitUtil.MILLIS_RETRY_DELAY,
  1379. GitUtil.MILLIS_TIMEOUT, "git rebase --abort");
  1380. if (!ignoreFailure && (executionResult.getExitValue() != 0)) {
  1381. throw new RuntimeException(
  1382. JenkinsResultsParserUtil.combine(
  1383. "Unable to abort rebase\n",
  1384. executionResult.getStandardError()));
  1385. }
  1386. }
  1387. public boolean remoteGitBranchExists(
  1388. String branchName, GitRemote gitRemote) {
  1389. return remoteGitBranchExists(branchName, gitRemote.getRemoteURL());
  1390. }
  1391. public boolean remote

Large files files are truncated, but you can click here to view the full file