PageRenderTime 70ms CodeModel.GetById 31ms RepoModel.GetById 1ms app.codeStats 0ms

/src/main/java/com/atlassian/bamboo/plugins/git/GitRepository.java

https://bitbucket.org/atlassian/bamboo-git-plugin
Java | 1148 lines | 994 code | 125 blank | 29 comment | 69 complexity | 8a60d7ee85aa9a3d2cce979d4b434e02 MD5 | raw file
Possible License(s): Apache-2.0

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

  1. package com.atlassian.bamboo.plugins.git;
  2. import com.atlassian.bamboo.agent.AgentType;
  3. import com.atlassian.bamboo.agent.AgentTypeHolder;
  4. import com.atlassian.bamboo.author.Author;
  5. import com.atlassian.bamboo.build.logger.BuildLogger;
  6. import com.atlassian.bamboo.build.logger.NullBuildLogger;
  7. import com.atlassian.bamboo.commit.CommitContext;
  8. import com.atlassian.bamboo.commit.CommitContextImpl;
  9. import com.atlassian.bamboo.core.TransportProtocol;
  10. import com.atlassian.bamboo.credentials.CredentialsAccessor;
  11. import com.atlassian.bamboo.credentials.CredentialsData;
  12. import com.atlassian.bamboo.credentials.PrivateKeyCredentials;
  13. import com.atlassian.bamboo.credentials.SharedCredentialDepender;
  14. import com.atlassian.bamboo.credentials.SshCredentialsImpl;
  15. import com.atlassian.bamboo.plan.PlanKey;
  16. import com.atlassian.bamboo.plan.PlanKeys;
  17. import com.atlassian.bamboo.plan.branch.BranchIntegrationHelper;
  18. import com.atlassian.bamboo.plan.branch.VcsBranch;
  19. import com.atlassian.bamboo.plan.branch.VcsBranchImpl;
  20. import com.atlassian.bamboo.plan.vcsRevision.PlanVcsRevisionData;
  21. import com.atlassian.bamboo.repository.AbstractStandaloneRepository;
  22. import com.atlassian.bamboo.repository.AdvancedConfigurationAwareRepository;
  23. import com.atlassian.bamboo.repository.BranchDetectionCapableRepository;
  24. import com.atlassian.bamboo.repository.BranchMergingAwareRepository;
  25. import com.atlassian.bamboo.repository.CacheDescription;
  26. import com.atlassian.bamboo.repository.CacheHandler;
  27. import com.atlassian.bamboo.repository.CacheId;
  28. import com.atlassian.bamboo.repository.CachingAwareRepository;
  29. import com.atlassian.bamboo.repository.CheckoutCustomRevisionDataAwareRepository;
  30. import com.atlassian.bamboo.repository.CustomVariableProviderRepository;
  31. import com.atlassian.bamboo.repository.DeploymentAwareRepository;
  32. import com.atlassian.bamboo.repository.MavenPomAccessor;
  33. import com.atlassian.bamboo.repository.MavenPomAccessorCapableRepository;
  34. import com.atlassian.bamboo.repository.NameValuePair;
  35. import com.atlassian.bamboo.repository.PushCapableRepository;
  36. import com.atlassian.bamboo.repository.Repository;
  37. import com.atlassian.bamboo.repository.RepositoryException;
  38. import com.atlassian.bamboo.repository.SelectableAuthenticationRepository;
  39. import com.atlassian.bamboo.security.EncryptionService;
  40. import com.atlassian.bamboo.ssh.SshProxyService;
  41. import com.atlassian.bamboo.util.TextProviderUtils;
  42. import com.atlassian.bamboo.utils.BambooFieldValidate;
  43. import com.atlassian.bamboo.utils.SystemProperty;
  44. import com.atlassian.bamboo.utils.error.ErrorCollection;
  45. import com.atlassian.bamboo.utils.fage.Result;
  46. import com.atlassian.bamboo.v2.build.BuildContext;
  47. import com.atlassian.bamboo.v2.build.BuildRepositoryChanges;
  48. import com.atlassian.bamboo.v2.build.BuildRepositoryChangesImpl;
  49. import com.atlassian.bamboo.v2.build.agent.capability.CapabilityContext;
  50. import com.atlassian.bamboo.v2.build.agent.capability.Requirement;
  51. import com.atlassian.bamboo.v2.build.repository.CustomSourceDirectoryAwareRepository;
  52. import com.atlassian.bamboo.v2.build.repository.RequirementsAwareRepository;
  53. import com.atlassian.bamboo.ww2.actions.build.admin.create.BuildConfiguration;
  54. import com.atlassian.sal.api.message.I18nResolver;
  55. import com.atlassian.util.concurrent.Supplier;
  56. import com.google.common.annotations.VisibleForTesting;
  57. import com.google.common.base.Function;
  58. import com.google.common.collect.ImmutableList;
  59. import com.google.common.collect.Iterables;
  60. import com.google.common.collect.Lists;
  61. import com.google.common.collect.Maps;
  62. import com.google.common.collect.Sets;
  63. import com.opensymphony.webwork.ServletActionContext;
  64. import com.opensymphony.xwork.ValidationAware;
  65. import org.apache.commons.configuration.AbstractConfiguration;
  66. import org.apache.commons.configuration.HierarchicalConfiguration;
  67. import org.apache.commons.io.FileUtils;
  68. import org.apache.commons.lang.StringUtils;
  69. import org.apache.commons.lang.builder.EqualsBuilder;
  70. import org.apache.log4j.Logger;
  71. import org.eclipse.jgit.errors.TransportException;
  72. import org.eclipse.jgit.lib.Constants;
  73. import org.eclipse.jgit.transport.URIish;
  74. import org.jetbrains.annotations.NotNull;
  75. import org.jetbrains.annotations.Nullable;
  76. import org.jetbrains.annotations.TestOnly;
  77. import java.io.File;
  78. import java.io.IOException;
  79. import java.net.URISyntaxException;
  80. import java.util.Arrays;
  81. import java.util.Collection;
  82. import java.util.Collections;
  83. import java.util.Date;
  84. import java.util.List;
  85. import java.util.Map;
  86. import java.util.Set;
  87. import java.util.concurrent.Callable;
  88. public class GitRepository
  89. extends AbstractStandaloneRepository
  90. implements MavenPomAccessorCapableRepository,
  91. SelectableAuthenticationRepository,
  92. CustomVariableProviderRepository,
  93. CustomSourceDirectoryAwareRepository,
  94. CheckoutCustomRevisionDataAwareRepository,
  95. RequirementsAwareRepository,
  96. AdvancedConfigurationAwareRepository,
  97. BranchDetectionCapableRepository,
  98. PushCapableRepository,
  99. CachingAwareRepository,
  100. BranchMergingAwareRepository,
  101. CacheHandler,
  102. DeploymentAwareRepository,
  103. SharedCredentialDepender
  104. {
  105. // ------------------------------------------------------------------------------------------------------- Constants
  106. private static final String REPOSITORY_GIT_NAME = "repository.git.name";
  107. private static final String REPOSITORY_URL = "repositoryUrl";
  108. public static final String REPOSITORY_GIT_REPOSITORY_URL = "repository.git." + REPOSITORY_URL;
  109. public static final String REPOSITORY_GIT_AUTHENTICATION_TYPE = "repository.git.authenticationType";
  110. private static final String REPOSITORY_USERNAME = "username";
  111. public static final String REPOSITORY_GIT_USERNAME = "repository.git." + REPOSITORY_USERNAME;
  112. public static final String REPOSITORY_GIT_PASSWORD = "repository.git.password";
  113. private static final String REPOSITORY_BRANCH = "branch";
  114. public static final String REPOSITORY_GIT_BRANCH = "repository.git." + REPOSITORY_BRANCH;
  115. public static final String REPOSITORY_GIT_SSH_KEY = "repository.git.ssh.key";
  116. public static final String REPOSITORY_GIT_SSH_PASSPHRASE = "repository.git.ssh.passphrase";
  117. public static final String REPOSITORY_GIT_USE_SHALLOW_CLONES = "repository.git.useShallowClones";
  118. public static final String REPOSITORY_GIT_USE_REMOTE_AGENT_CACHE = "repository.git.useRemoteAgentCache";
  119. public static final String REPOSITORY_GIT_USE_SUBMODULES = "repository.git.useSubmodules";
  120. public static final String REPOSITORY_GIT_MAVEN_PATH = "repository.git.maven.path";
  121. public static final String REPOSITORY_GIT_COMMAND_TIMEOUT = "repository.git.commandTimeout";
  122. public static final String REPOSITORY_GIT_VERBOSE_LOGS = "repository.git.verbose.logs";
  123. public static final String REPOSITORY_GIT_FETCH_WHOLE_REPOSITORY = "repository.git.fetch.whole.repository";
  124. private static final String REPOSITORY_GIT_SHAREDCREDENTIALS_ID = "repository.git.sharedCrendentials";
  125. private static final String REPOSITORY_GIT_SHAREDCREDENTIALS_DELETED = "repository.git.sharedCredentials.deleted";
  126. private static final String TEMPORARY_GIT_PASSWORD = "temporary.git.password";
  127. private static final String TEMPORARY_GIT_PASSWORD_CHANGE = "temporary.git.password.change";
  128. private static final String TEMPORARY_GIT_SSH_PASSPHRASE = "temporary.git.ssh.passphrase";
  129. private static final String TEMPORARY_GIT_SSH_PASSPHRASE_CHANGE = "temporary.git.ssh.passphrase.change";
  130. private static final String TEMPORARY_GIT_SSH_KEY_FROM_FILE = "temporary.git.ssh.keyfile";
  131. private static final String TEMPORARY_GIT_SSH_KEY_CHANGE = "temporary.git.ssh.key.change";
  132. private static final String SHARED_CREDENTIALS = "SHARED_CREDENTIALS";
  133. protected static boolean USE_SHALLOW_CLONES = new SystemProperty(false, "atlassian.bamboo.git.useShallowClones", "ATLASSIAN_BAMBOO_GIT_USE_SHALLOW_CLONES").getValue(true);
  134. static final int DEFAULT_COMMAND_TIMEOUT_IN_MINUTES = 180;
  135. // ------------------------------------------------------------------------------------------------- Type Properties
  136. private static final Logger log = Logger.getLogger(GitRepository.class);
  137. private BranchIntegrationHelper branchIntegrationHelper;
  138. private GitRepositoryAccessData accessData = new GitRepositoryAccessData();
  139. // Maven 2 import
  140. private transient String pathToPom;
  141. private boolean sharedCredentialsDeleted;
  142. // ---------------------------------------------------------------------------------------------------- Dependencies
  143. private transient CapabilityContext capabilityContext;
  144. private transient I18nResolver i18nResolver;
  145. private transient GitCacheHandler gitCacheHandler;
  146. private transient SshProxyService sshProxyService;
  147. private transient EncryptionService encryptionService;
  148. private transient CredentialsAccessor credentialsAccessor;
  149. // ---------------------------------------------------------------------------------------------------- Constructors
  150. // ----------------------------------------------------------------------------------------------- Interface Methods
  151. @Override
  152. @NotNull
  153. public String getName()
  154. {
  155. return i18nResolver.getText(REPOSITORY_GIT_NAME);
  156. }
  157. @Override
  158. public String getHost()
  159. {
  160. return "";
  161. }
  162. @Override
  163. public boolean isRepositoryDifferent(@NotNull Repository repository)
  164. {
  165. if (repository instanceof GitRepository)
  166. {
  167. GitRepository gitRepo = (GitRepository) repository;
  168. return !new EqualsBuilder()
  169. .append(accessData.getRepositoryUrl(), gitRepo.accessData.getRepositoryUrl())
  170. .append(accessData.getVcsBranch(), gitRepo.accessData.getVcsBranch())
  171. .append(accessData.getUsername(), gitRepo.accessData.getUsername())
  172. .append(accessData.getSshKey(), gitRepo.accessData.getSshKey())
  173. .isEquals();
  174. }
  175. else
  176. {
  177. return true;
  178. }
  179. }
  180. @Override
  181. @NotNull
  182. public BuildRepositoryChanges collectChangesForRevision(@NotNull PlanKey planKey, @NotNull String targetRevision) throws RepositoryException
  183. {
  184. return collectChangesSinceLastBuild(planKey.getKey(), targetRevision, targetRevision);
  185. }
  186. @Override
  187. @NotNull
  188. public BuildRepositoryChanges collectChangesSinceLastBuild(@NotNull String planKey, @Nullable final String lastVcsRevisionKey) throws RepositoryException
  189. {
  190. return collectChangesSinceLastBuild(planKey, lastVcsRevisionKey, null);
  191. }
  192. @NotNull
  193. public BuildRepositoryChanges collectChangesSinceLastBuild(@NotNull String planKey, @Nullable final String lastVcsRevisionKey, @Nullable final String customRevision) throws RepositoryException
  194. {
  195. try
  196. {
  197. final BuildLogger buildLogger = buildLoggerManager.getLogger(PlanKeys.getPlanKey(planKey));
  198. final GitRepositoryAccessData substitutedAccessData = getSubstitutedAccessData();
  199. final GitOperationHelper helper = GitOperationHelperFactory.createGitOperationHelper(this, substitutedAccessData, sshProxyService, buildLogger, i18nResolver);
  200. final String latestRevision = helper.obtainLatestRevision();
  201. final String fetchRevision = customRevision != null ? customRevision : substitutedAccessData.getVcsBranch().getName();
  202. final String targetRevision = customRevision != null ? customRevision : latestRevision;
  203. final File cacheDirectory = getCacheDirectory();
  204. if (latestRevision.equals(lastVcsRevisionKey) && customRevision == null)
  205. {
  206. return new BuildRepositoryChangesImpl(latestRevision);
  207. }
  208. VcsBranch overriddenBranch = null;
  209. if (customRevision != null)
  210. {
  211. helper.fetch(cacheDirectory, customRevision, false);
  212. final String vcsBranchName = substitutedAccessData.getVcsBranch().getName();
  213. final String branchForSha = helper.getBranchForSha(cacheDirectory, customRevision, vcsBranchName);
  214. if (!StringUtils.equals(branchForSha, vcsBranchName))
  215. {
  216. overriddenBranch = new VcsBranchImpl(branchForSha);
  217. log.warn(buildLogger.addBuildLogEntry(i18nResolver.getText("repository.git.messages.adjustBranchForSha", vcsBranchName, customRevision, overriddenBranch.getName())));
  218. }
  219. }
  220. if (lastVcsRevisionKey == null)
  221. {
  222. buildLogger.addBuildLogEntry(i18nResolver.getText("repository.git.messages.ccRepositoryNeverChecked", fetchRevision));
  223. try
  224. {
  225. GitCacheDirectory.getCacheLock(cacheDirectory).withLock(new Callable<Void>()
  226. {
  227. public Void call() throws Exception
  228. {
  229. try
  230. {
  231. helper.fetch(cacheDirectory, fetchRevision, false);
  232. }
  233. catch (Exception e)
  234. {
  235. rethrowOrRemoveDirectory(e, buildLogger, cacheDirectory, "repository.git.messages.rsRecover.failedToFetchCache");
  236. buildLogger.addBuildLogEntry(i18nResolver.getText("repository.git.messages.rsRecover.cleanedCacheDirectory", cacheDirectory));
  237. helper.fetch(cacheDirectory, fetchRevision, false);
  238. }
  239. return null;
  240. }
  241. });
  242. }
  243. catch (Exception e)
  244. {
  245. throw new RepositoryException(e.getMessage(), e);
  246. }
  247. final BuildRepositoryChangesImpl buildRepositoryChanges = new BuildRepositoryChangesImpl(targetRevision);
  248. buildRepositoryChanges.setOverriddenVcsBranch(overriddenBranch);
  249. return buildRepositoryChanges;
  250. }
  251. final BuildRepositoryChanges buildChanges = GitCacheDirectory.getCacheLock(cacheDirectory).withLock(new Supplier<BuildRepositoryChanges>()
  252. {
  253. public BuildRepositoryChanges get()
  254. {
  255. try
  256. {
  257. helper.fetch(cacheDirectory, fetchRevision, false);
  258. return helper.extractCommits(cacheDirectory, lastVcsRevisionKey, targetRevision);
  259. }
  260. catch (Exception e) // not just RepositoryException - see HandlingSwitchingRepositoriesToUnrelatedOnesTest.testCollectChangesWithUnrelatedPreviousRevision
  261. {
  262. try
  263. {
  264. rethrowOrRemoveDirectory(e, buildLogger, cacheDirectory, "repository.git.messages.ccRecover.failedToCollectChangesets");
  265. buildLogger.addBuildLogEntry(i18nResolver.getText("repository.git.messages.ccRecover.cleanedCacheDirectory", cacheDirectory));
  266. helper.fetch(cacheDirectory, fetchRevision, false);
  267. buildLogger.addBuildLogEntry(i18nResolver.getText("repository.git.messages.ccRecover.fetchedRemoteRepository", cacheDirectory));
  268. BuildRepositoryChanges extractedChanges = helper.extractCommits(cacheDirectory, lastVcsRevisionKey, targetRevision);
  269. buildLogger.addBuildLogEntry(i18nResolver.getText("repository.git.messages.ccRecover.completed"));
  270. return extractedChanges;
  271. }
  272. catch (Exception e2)
  273. {
  274. log.error(buildLogger.addBuildLogEntry(i18nResolver.getText("repository.git.messages.ccRecover.failedToExtractChangesets")), e2);
  275. return null;
  276. }
  277. }
  278. }
  279. });
  280. if (buildChanges != null && !buildChanges.getChanges().isEmpty())
  281. {
  282. buildChanges.setOverriddenVcsBranch(overriddenBranch);
  283. return buildChanges;
  284. }
  285. else
  286. {
  287. return new BuildRepositoryChangesImpl(latestRevision, Collections.singletonList((CommitContext) CommitContextImpl.builder()
  288. .author(Author.UNKNOWN_AUTHOR)
  289. .comment(i18nResolver.getText("repository.git.messages.unknownChanges", lastVcsRevisionKey, targetRevision))
  290. .date(new Date())
  291. .build()));
  292. }
  293. }
  294. catch (RuntimeException e)
  295. {
  296. throw new RepositoryException(e.getMessage(), e);
  297. }
  298. }
  299. @Override
  300. @NotNull
  301. public String retrieveSourceCode(@NotNull final BuildContext buildContext, @Nullable final String vcsRevisionKey, @NotNull final File sourceDirectory) throws RepositoryException
  302. {
  303. return retrieveSourceCode(buildContext, vcsRevisionKey, sourceDirectory, 1);
  304. }
  305. @Override
  306. @NotNull
  307. public String retrieveSourceCode(@NotNull final BuildContext buildContext, @Nullable final String vcsRevisionKey, @NotNull final File sourceDirectory, int depth) throws RepositoryException
  308. {
  309. PlanVcsRevisionData planVcsRevisionData = new PlanVcsRevisionData(vcsRevisionKey, null);
  310. return retrieveSourceCode(buildContext, planVcsRevisionData, sourceDirectory, depth);
  311. }
  312. @NotNull
  313. @Override
  314. public String retrieveSourceCode(@NotNull final BuildContext buildContext, @Nullable final PlanVcsRevisionData planVcsRevisionData, @NotNull final File sourceDirectory, int depth) throws RepositoryException
  315. {
  316. final String vcsRevisionKey = planVcsRevisionData.getVcsRevisionKey();
  317. final VcsBranch effectiveBranch = planVcsRevisionData.getOverriddenBranch();
  318. try
  319. {
  320. final GitRepositoryAccessData.Builder substitutedAccessDataBuilder = getSubstitutedAccessDataBuilder();
  321. final boolean doShallowFetch = USE_SHALLOW_CLONES && accessData.isUseShallowClones() && depth == 1 && !isOnLocalAgent() && effectiveBranch == null;
  322. if (effectiveBranch != null)
  323. {
  324. substitutedAccessDataBuilder.branch(effectiveBranch);
  325. }
  326. substitutedAccessDataBuilder.useShallowClones(doShallowFetch);
  327. final GitRepositoryAccessData substitutedAccessData = substitutedAccessDataBuilder.build();
  328. final BuildLogger buildLogger = buildLoggerManager.getLogger(buildContext.getPlanResultKey());
  329. final GitOperationHelper helper = GitOperationHelperFactory.createGitOperationHelper(this, substitutedAccessData, sshProxyService, buildLogger, i18nResolver);
  330. final String revisionToCheckout = vcsRevisionKey != null ? vcsRevisionKey : helper.obtainLatestRevision();
  331. final String refToFetch = substitutedAccessData.getVcsBranch().getName();
  332. final String previousRevision = helper.getRevisionIfExists(sourceDirectory, Constants.HEAD);
  333. if (isOnLocalAgent() || substitutedAccessData.isUseRemoteAgentCache())
  334. {
  335. final File cacheDirectory = getCacheDirectory(substitutedAccessData);
  336. return GitCacheDirectory.getCacheLock(cacheDirectory).withLock(new Callable<String>()
  337. {
  338. public String call() throws Exception
  339. {
  340. try
  341. {
  342. helper.fetch(cacheDirectory, refToFetch, false);
  343. helper.checkRevisionExistsInCacheRepository(cacheDirectory, revisionToCheckout);
  344. }
  345. catch (Exception e)
  346. {
  347. rethrowOrRemoveDirectory(e, buildLogger, cacheDirectory, "repository.git.messages.rsRecover.failedToFetchCache");
  348. buildLogger.addBuildLogEntry(i18nResolver.getText("repository.git.messages.rsRecover.cleanedCacheDirectory", cacheDirectory));
  349. helper.fetch(cacheDirectory, refToFetch, false);
  350. buildLogger.addBuildLogEntry(i18nResolver.getText("repository.git.messages.rsRecover.fetchingCacheCompleted", cacheDirectory));
  351. }
  352. try
  353. {
  354. return helper.checkout(cacheDirectory, sourceDirectory, revisionToCheckout, previousRevision);
  355. }
  356. catch (Exception e)
  357. {
  358. rethrowOrRemoveDirectory(e, buildLogger, sourceDirectory, "repository.git.messages.rsRecover.failedToCheckout");
  359. buildLogger.addBuildLogEntry(i18nResolver.getText("repository.git.messages.rsRecover.cleanedSourceDirectory", sourceDirectory));
  360. String returnRevision = helper.checkout(cacheDirectory, sourceDirectory, revisionToCheckout, null);
  361. buildLogger.addBuildLogEntry(i18nResolver.getText("repository.git.messages.rsRecover.checkoutCompleted"));
  362. return returnRevision;
  363. }
  364. }
  365. });
  366. }
  367. else //isOnRemoteAgent
  368. {
  369. try
  370. {
  371. helper.fetch(sourceDirectory, refToFetch, doShallowFetch);
  372. return helper.checkout(null, sourceDirectory, revisionToCheckout, previousRevision);
  373. }
  374. catch (Exception e)
  375. {
  376. rethrowOrRemoveDirectory(e, buildLogger, sourceDirectory, "repository.git.messages.rsRecover.failedToCheckout");
  377. buildLogger.addBuildLogEntry(i18nResolver.getText("repository.git.messages.rsRecover.cleanedSourceDirectory", sourceDirectory));
  378. helper.fetch(sourceDirectory, refToFetch, false);
  379. buildLogger.addBuildLogEntry(i18nResolver.getText("repository.git.messages.rsRecover.fetchingCompleted", sourceDirectory));
  380. String returnRevision = helper.checkout(null, sourceDirectory, revisionToCheckout, null);
  381. buildLogger.addBuildLogEntry(i18nResolver.getText("repository.git.messages.rsRecover.checkoutCompleted"));
  382. return returnRevision;
  383. }
  384. }
  385. }
  386. catch (RepositoryException e)
  387. {
  388. throw e;
  389. }
  390. catch (Exception e)
  391. {
  392. throw new RepositoryException(i18nResolver.getText("repository.git.messages.runtimeException"), e);
  393. }
  394. }
  395. @VisibleForTesting
  396. @TestOnly
  397. protected boolean isOnLocalAgent()
  398. {
  399. return AgentTypeHolder.get()==AgentType.LOCAL;
  400. }
  401. @NotNull
  402. @Deprecated
  403. public List<VcsBranch> getOpenBranches() throws RepositoryException
  404. {
  405. return getOpenBranches(null);
  406. }
  407. @NotNull
  408. @Override
  409. public List<VcsBranch> getOpenBranches(@Nullable final String context) throws RepositoryException
  410. {
  411. final GitRepositoryAccessData substitutedAccessData = getSubstitutedAccessData();
  412. final GitOperationHelper helper = GitOperationHelperFactory.createGitOperationHelper(this, substitutedAccessData, sshProxyService, new NullBuildLogger(), i18nResolver);
  413. return helper.getOpenBranches(substitutedAccessData, getWorkingDirectory());
  414. }
  415. @Override
  416. public void pushRevision(@NotNull File sourceDirectory, @Nullable String vcsRevisionKey) throws RepositoryException
  417. {
  418. final GitRepositoryAccessData substitutedAccessData = getSubstitutedAccessData();
  419. final GitOperationHelper helper = GitOperationHelperFactory.createGitOperationHelper(this, substitutedAccessData, sshProxyService, new NullBuildLogger(), i18nResolver);
  420. helper.pushRevision(sourceDirectory, vcsRevisionKey);
  421. }
  422. @NotNull
  423. @Override
  424. public String commit(@NotNull File sourceDirectory, @NotNull String message) throws RepositoryException
  425. {
  426. final GitRepositoryAccessData substitutedAccessData = getSubstitutedAccessData();
  427. final GitOperationHelper helper =
  428. GitOperationHelperFactory.createGitOperationHelper(this, substitutedAccessData, sshProxyService, new NullBuildLogger(), i18nResolver);
  429. return helper.commit(sourceDirectory, message, branchIntegrationHelper.getCommitterName(this), branchIntegrationHelper.getCommitterEmail(this));
  430. }
  431. @Override
  432. public CacheId getCacheId(@NotNull final CachableOperation cachableOperation)
  433. {
  434. switch (cachableOperation)
  435. {
  436. case BRANCH_DETECTION:
  437. final GitRepositoryAccessData substitutedAccessData = getSubstitutedAccessData();
  438. return new CacheId(this, substitutedAccessData.getRepositoryUrl(), substitutedAccessData.getUsername(), substitutedAccessData.getSshKey());
  439. }
  440. return null;
  441. }
  442. @Override
  443. public boolean isCachingSupportedFor(@NotNull final CachableOperation cachableOperation)
  444. {
  445. return cachableOperation==CachableOperation.BRANCH_DETECTION;
  446. }
  447. @Override
  448. @NotNull
  449. public VcsBranch getVcsBranch()
  450. {
  451. return accessData.getVcsBranch();
  452. }
  453. @Override
  454. public void setVcsBranch(@NotNull final VcsBranch branch)
  455. {
  456. this.accessData = GitRepositoryAccessData.builder(accessData).branch(branch).build();
  457. }
  458. @Override
  459. public boolean mergeWorkspaceWith(@NotNull final BuildContext buildContext, @NotNull final File workspaceDir, @NotNull final String targetRevision) throws RepositoryException
  460. {
  461. final BuildLogger buildLogger = buildLoggerManager.getLogger(buildContext.getEntityKey());
  462. final GitRepositoryAccessData substitutedAccessData = getSubstitutedAccessDataBuilder().useShallowClones(false).build();
  463. final GitOperationHelper connector = GitOperationHelperFactory.createGitOperationHelper(this, substitutedAccessData, sshProxyService, buildLogger, i18nResolver);
  464. final File cacheDirectory = getCacheDirectory(substitutedAccessData);
  465. try
  466. {
  467. if (isOnLocalAgent() || getAccessData().isUseRemoteAgentCache())
  468. {
  469. GitCacheDirectory.getCacheLock(cacheDirectory).withLock(new Callable<Void>()
  470. {
  471. @Override
  472. public Void call() throws Exception
  473. {
  474. try
  475. {
  476. connector.fetch(cacheDirectory, targetRevision, false);
  477. connector.checkRevisionExistsInCacheRepository(cacheDirectory, targetRevision);
  478. }
  479. catch (Exception e)
  480. {
  481. rethrowOrRemoveDirectory(e, buildLogger, cacheDirectory, "repository.git.messages.rsRecover.failedToFetchCache");
  482. buildLogger.addBuildLogEntry(i18nResolver.getText("repository.git.messages.rsRecover.cleanedCacheDirectory", cacheDirectory));
  483. connector.fetch(cacheDirectory, targetRevision, false);
  484. buildLogger.addBuildLogEntry(i18nResolver.getText("repository.git.messages.rsRecover.fetchingCacheCompleted", cacheDirectory));
  485. }
  486. return null;
  487. }
  488. });
  489. }
  490. else
  491. {
  492. try
  493. {
  494. connector.fetch(workspaceDir, targetRevision, false);
  495. }
  496. catch (Exception e)
  497. {
  498. rethrowOrRemoveDirectory(e, buildLogger, workspaceDir, "repository.git.messages.rsRecover.failedToFetchWorkingDir");
  499. buildLogger.addBuildLogEntry(i18nResolver.getText("repository.git.messages.rsRecover.cleanedSourceDirectory", workspaceDir));
  500. connector.fetch(workspaceDir, targetRevision, false);
  501. }
  502. }
  503. }
  504. catch (Exception e)
  505. {
  506. throw new RepositoryException(i18nResolver.getText("repository.git.messages.runtimeException"), e);
  507. }
  508. return connector.merge(workspaceDir, targetRevision, branchIntegrationHelper.getCommitterName(this), branchIntegrationHelper.getCommitterEmail(this));
  509. }
  510. @Override
  511. public boolean isMergingSupported()
  512. {
  513. return GitOperationHelperFactory.isNativeGitEnabled(this);
  514. }
  515. @Override
  516. public CommitContext getFirstCommit() throws RepositoryException
  517. {
  518. return null;
  519. }
  520. @Override
  521. public CommitContext getLastCommit() throws RepositoryException
  522. {
  523. final BuildLogger buildLogger = new NullBuildLogger();
  524. final GitRepositoryAccessData substitutedAccessData = getSubstitutedAccessData();
  525. final GitOperationHelper helper = GitOperationHelperFactory.createGitOperationHelper(this, substitutedAccessData, sshProxyService, buildLogger, i18nResolver);
  526. final String targetRevision = helper.obtainLatestRevision();
  527. final File cacheDirectory = getCacheDirectory();
  528. Result<RepositoryException, CommitContext> result = GitCacheDirectory.getCacheLock(cacheDirectory).withLock(new Supplier<Result<RepositoryException, CommitContext>>()
  529. {
  530. public Result<RepositoryException, CommitContext> get()
  531. {
  532. try
  533. {
  534. try
  535. {
  536. final CommitContext commit = helper.getCommit(cacheDirectory, targetRevision);
  537. log.info("Found " + commit.getChangeSetId() + " as the last commit for " + this);
  538. return Result.result(commit);
  539. }
  540. catch (RepositoryException e)
  541. {
  542. // Commit might not exist locally yet, but a fetch is expensive, so let's try getting it first
  543. log.debug("Fetching remote repository");
  544. helper.fetch(cacheDirectory, targetRevision, false);
  545. return Result.result(helper.getCommit(cacheDirectory, targetRevision));
  546. }
  547. }
  548. catch (RepositoryException e)
  549. {
  550. return Result.exception(e);
  551. }
  552. }
  553. });
  554. return result.getResultThrowException();
  555. }
  556. @Override
  557. public void addDefaultValues(@NotNull BuildConfiguration buildConfiguration)
  558. {
  559. buildConfiguration.setProperty(REPOSITORY_GIT_COMMAND_TIMEOUT, Integer.valueOf(DEFAULT_COMMAND_TIMEOUT_IN_MINUTES));
  560. buildConfiguration.clearTree(REPOSITORY_GIT_VERBOSE_LOGS);
  561. buildConfiguration.clearTree(REPOSITORY_GIT_FETCH_WHOLE_REPOSITORY);
  562. buildConfiguration.setProperty(REPOSITORY_GIT_USE_SHALLOW_CLONES, true);
  563. buildConfiguration.setProperty(REPOSITORY_GIT_USE_REMOTE_AGENT_CACHE, false);
  564. buildConfiguration.clearTree(REPOSITORY_GIT_USE_SUBMODULES);
  565. buildConfiguration.setProperty(REPOSITORY_GIT_AUTHENTICATION_TYPE, GitAuthenticationType.NONE.name());
  566. }
  567. @Override
  568. public void prepareConfigObject(@NotNull BuildConfiguration buildConfiguration)
  569. {
  570. buildConfiguration.setProperty(REPOSITORY_GIT_COMMAND_TIMEOUT, buildConfiguration.getInt(REPOSITORY_GIT_COMMAND_TIMEOUT, DEFAULT_COMMAND_TIMEOUT_IN_MINUTES));
  571. if (buildConfiguration.getBoolean(TEMPORARY_GIT_PASSWORD_CHANGE))
  572. {
  573. buildConfiguration.setProperty(REPOSITORY_GIT_PASSWORD, encryptionService.encrypt(buildConfiguration.getString(TEMPORARY_GIT_PASSWORD)));
  574. }
  575. if (buildConfiguration.getBoolean(TEMPORARY_GIT_SSH_PASSPHRASE_CHANGE))
  576. {
  577. buildConfiguration.setProperty(REPOSITORY_GIT_SSH_PASSPHRASE, encryptionService.encrypt(buildConfiguration.getString(TEMPORARY_GIT_SSH_PASSPHRASE)));
  578. }
  579. if (buildConfiguration.getBoolean(TEMPORARY_GIT_SSH_KEY_CHANGE))
  580. {
  581. final Object o = buildConfiguration.getProperty(TEMPORARY_GIT_SSH_KEY_FROM_FILE);
  582. if (o instanceof File)
  583. {
  584. final String key;
  585. try
  586. {
  587. key = FileUtils.readFileToString((File) o);
  588. }
  589. catch (IOException e)
  590. {
  591. log.error("Cannot read uploaded ssh key file", e);
  592. return;
  593. }
  594. buildConfiguration.setProperty(REPOSITORY_GIT_SSH_KEY, encryptionService.encrypt(key));
  595. }
  596. else
  597. {
  598. buildConfiguration.clearProperty(REPOSITORY_GIT_SSH_KEY);
  599. }
  600. }
  601. }
  602. @Override
  603. public void populateFromConfig(@NotNull final HierarchicalConfiguration config)
  604. {
  605. super.populateFromConfig(config);
  606. final String sshPassphrase;
  607. final String sshKey;
  608. final GitAuthenticationType gitAuthenticationType;
  609. final Long sharedCredentialsId;
  610. final String chosenAuthentication = config.getString(REPOSITORY_GIT_AUTHENTICATION_TYPE, GitAuthenticationType.NONE.name());
  611. if (!chosenAuthentication.equals(SHARED_CREDENTIALS))
  612. {
  613. sharedCredentialsId = null;
  614. sshPassphrase = config.getString(REPOSITORY_GIT_SSH_PASSPHRASE, "");
  615. sshKey = config.getString(REPOSITORY_GIT_SSH_KEY, "");
  616. gitAuthenticationType = GitAuthenticationType.valueOf(chosenAuthentication);
  617. }
  618. else
  619. {
  620. sharedCredentialsId = config.getLong(REPOSITORY_GIT_SHAREDCREDENTIALS_ID, null);
  621. final CredentialsData credentials = credentialsAccessor.getCredentials(sharedCredentialsId);
  622. if (credentials != null)
  623. {
  624. final PrivateKeyCredentials sshCredentials = new SshCredentialsImpl(credentials);
  625. sshKey = sshCredentials.getKey();
  626. sshPassphrase = sshCredentials.getPassphrase();
  627. gitAuthenticationType = getAuthenticationTypeForSharedCredentials(config);
  628. }
  629. else
  630. {
  631. sharedCredentialsDeleted = true;
  632. sshKey = "";
  633. sshPassphrase = "";
  634. gitAuthenticationType = null;
  635. }
  636. }
  637. final VcsBranchImpl branch = new VcsBranchImpl(StringUtils.defaultIfEmpty(config.getString(REPOSITORY_GIT_BRANCH, ""), "master"));
  638. accessData = GitRepositoryAccessData.builder()
  639. .repositoryUrl(StringUtils.trimToEmpty(config.getString(REPOSITORY_GIT_REPOSITORY_URL)))
  640. .username(config.getString(REPOSITORY_GIT_USERNAME, ""))
  641. .password(config.getString(REPOSITORY_GIT_PASSWORD, null))
  642. .branch(branch)
  643. .sshKey(sshKey)
  644. .sshPassphrase(sshPassphrase)
  645. .authenticationType(gitAuthenticationType)
  646. .useShallowClones(config.getBoolean(REPOSITORY_GIT_USE_SHALLOW_CLONES))
  647. .useRemoteAgentCache(config.getBoolean(REPOSITORY_GIT_USE_REMOTE_AGENT_CACHE, false))
  648. .useSubmodules(config.getBoolean(REPOSITORY_GIT_USE_SUBMODULES, false))
  649. .commandTimeout(config.getInt(REPOSITORY_GIT_COMMAND_TIMEOUT, DEFAULT_COMMAND_TIMEOUT_IN_MINUTES))
  650. .verboseLogs(config.getBoolean(REPOSITORY_GIT_VERBOSE_LOGS, false))
  651. .refSpecOverride(config.getBoolean(REPOSITORY_GIT_FETCH_WHOLE_REPOSITORY, false) ? Constants.R_HEADS + "*" : null)
  652. .sharedCredentialsId(sharedCredentialsId)
  653. .build();
  654. pathToPom = config.getString(REPOSITORY_GIT_MAVEN_PATH);
  655. }
  656. @NotNull
  657. @Override
  658. public Iterable<Long> getSharedCredentialIds()
  659. {
  660. final Long sharedCredentialsId = accessData.getSharedCredentialsId();
  661. return sharedCredentialsId!=null ? ImmutableList.of(sharedCredentialsId) : Collections.<Long>emptyList();
  662. }
  663. @NotNull
  664. @Override
  665. public HierarchicalConfiguration toConfiguration()
  666. {
  667. final HierarchicalConfiguration configuration = super.toConfiguration();
  668. configuration.setProperty(REPOSITORY_GIT_REPOSITORY_URL, accessData.getRepositoryUrl());
  669. configuration.setProperty(REPOSITORY_GIT_BRANCH, accessData.getVcsBranch().getName());
  670. configuration.setProperty(REPOSITORY_GIT_USE_SHALLOW_CLONES, accessData.isUseShallowClones());
  671. configuration.setProperty(REPOSITORY_GIT_USE_REMOTE_AGENT_CACHE, accessData.isUseRemoteAgentCache());
  672. configuration.setProperty(REPOSITORY_GIT_USE_SUBMODULES, accessData.isUseSubmodules());
  673. configuration.setProperty(REPOSITORY_GIT_COMMAND_TIMEOUT, accessData.getCommandTimeout());
  674. configuration.setProperty(REPOSITORY_GIT_VERBOSE_LOGS, accessData.isVerboseLogs());
  675. configuration.setProperty(REPOSITORY_GIT_FETCH_WHOLE_REPOSITORY, accessData.getRefSpecOverride() != null);
  676. final Long sharedCredentialsId = accessData.getSharedCredentialsId();
  677. if (sharedCredentialsId!=null)
  678. {
  679. if (sharedCredentialsDeleted)
  680. {
  681. configuration.setProperty(REPOSITORY_GIT_SHAREDCREDENTIALS_DELETED, true);
  682. }
  683. configuration.setProperty(REPOSITORY_GIT_SHAREDCREDENTIALS_ID, sharedCredentialsId);
  684. configuration.setProperty(REPOSITORY_GIT_AUTHENTICATION_TYPE, SHARED_CREDENTIALS);
  685. }
  686. else
  687. {
  688. configuration.setProperty(REPOSITORY_GIT_SSH_KEY, accessData.getSshKey());
  689. configuration.setProperty(REPOSITORY_GIT_SSH_PASSPHRASE, accessData.getSshPassphrase());
  690. configuration.setProperty(REPOSITORY_GIT_USERNAME, accessData.getUsername());
  691. configuration.setProperty(REPOSITORY_GIT_PASSWORD, accessData.getPassword());
  692. configuration.setProperty(REPOSITORY_GIT_AUTHENTICATION_TYPE, accessData.getAuthenticationType().name());
  693. }
  694. return configuration;
  695. }
  696. @Override
  697. @NotNull
  698. public ErrorCollection validate(@NotNull BuildConfiguration buildConfiguration)
  699. {
  700. ErrorCollection errorCollection = super.validate(buildConfiguration);
  701. final String repositoryUrl = StringUtils.trim(buildConfiguration.getString(REPOSITORY_GIT_REPOSITORY_URL));
  702. final GitAuthenticationType authenticationType = getGitAuthenticationType(buildConfiguration);
  703. if (BambooFieldValidate.findFieldShellInjectionViolation(errorCollection, i18nResolver, REPOSITORY_GIT_REPOSITORY_URL, substituteString(buildConfiguration.getString(REPOSITORY_GIT_REPOSITORY_URL))))
  704. {
  705. return errorCollection;
  706. }
  707. if (BambooFieldValidate.findFieldShellInjectionViolation(errorCollection, i18nResolver, REPOSITORY_GIT_BRANCH, substituteString(buildConfiguration.getString(REPOSITORY_GIT_BRANCH))))
  708. {
  709. return errorCollection;
  710. }
  711. if (BambooFieldValidate.findFieldShellInjectionViolation(errorCollection, i18nResolver, REPOSITORY_GIT_USERNAME, substituteString(buildConfiguration.getString(REPOSITORY_GIT_USERNAME))))
  712. {
  713. return errorCollection;
  714. }
  715. if (StringUtils.isBlank(repositoryUrl))
  716. {
  717. errorCollection.addError(REPOSITORY_GIT_REPOSITORY_URL, i18nResolver.getText("repository.git.messages.missingRepositoryUrl"));
  718. }
  719. else
  720. {
  721. TransportProtocol transportProtocol = TransportProtocol.of(repositoryUrl, TransportProtocol.SSH);
  722. if (!featureManager.isTransportSupported(transportProtocol))
  723. {
  724. errorCollection.addError(REPOSITORY_GIT_REPOSITORY_URL, TextProviderUtils.getText(i18nResolver, "repository.git.messages.unsupportedTransportProtocol", transportProtocol.toString()));
  725. }
  726. final boolean hasUsername = StringUtils.isNotBlank(buildConfiguration.getString(REPOSITORY_GIT_USERNAME));
  727. final boolean hasPassword = StringUtils.isNotBlank(buildConfiguration.getString(REPOSITORY_GIT_PASSWORD));
  728. try
  729. {
  730. final URIish uri = new URIish(repositoryUrl);
  731. if (authenticationType == GitAuthenticationType.SSH_KEYPAIR && ("http".equals(uri.getScheme()) || "https".equals(uri.getScheme())))
  732. {
  733. errorCollection.addError(REPOSITORY_GIT_AUTHENTICATION_TYPE, i18nResolver.getText("repository.git.messages.unsupportedHttpAuthenticationType"));
  734. }
  735. else if (authenticationType == GitAuthenticationType.PASSWORD)
  736. {
  737. boolean duplicateUsername = hasUsername && StringUtils.isNotBlank(uri.getUser());
  738. boolean duplicatePassword = hasPassword && StringUtils.isNotBlank(uri.getPass());
  739. if (duplicateUsername || duplicatePassword)
  740. {
  741. errorCollection.addError(REPOSITORY_GIT_REPOSITORY_URL,
  742. (duplicateUsername ? i18nResolver.getText("repository.git.messages.duplicateUsernameField") : "")
  743. + ((duplicateUsername && duplicatePassword) ? " " : "")
  744. + (duplicatePassword ? i18nResolver.getText("repository.git.messages.duplicatePasswordField") : ""));
  745. }
  746. if (duplicateUsername)
  747. {
  748. errorCollection.addError(REPOSITORY_GIT_USERNAME, i18nResolver.getText("repository.git.messages.duplicateUsernameField"));
  749. }
  750. if (duplicatePassword)
  751. {
  752. errorCollection.addError(TEMPORARY_GIT_PASSWORD_CHANGE, i18nResolver.getText("repository.git.messages.duplicatePasswordField"));
  753. }
  754. if (uri.getHost() == null && hasUsername)
  755. {
  756. errorCollection.addError(REPOSITORY_GIT_USERNAME, i18nResolver.getText("repository.git.messages.unsupportedUsernameField"));
  757. }
  758. }
  759. }
  760. catch (URISyntaxException e)
  761. {
  762. if (hasUsername)
  763. {
  764. errorCollection.addError(REPOSITORY_GIT_USERNAME, i18nResolver.getText("repository.git.messages.unsupportedUsernameField"));
  765. }
  766. }
  767. }
  768. if (buildConfiguration.getString(REPOSITORY_GIT_MAVEN_PATH, "").contains(".."))
  769. {
  770. errorCollection.addError(REPOSITORY_GIT_MAVEN_PATH, i18nResolver.getText("repository.git.messages.invalidPomPath"));
  771. }
  772. return errorCollection;
  773. }
  774. private GitAuthenticationType getGitAuthenticationType(final BuildConfiguration buildConfiguration)
  775. {
  776. final String chosenAuthentication = buildConfiguration.getString(REPOSITORY_GIT_AUTHENTICATION_TYPE);
  777. if (chosenAuthentication.equals(SHARED_CREDENTIALS))
  778. {
  779. return getAuthenticationTypeForSharedCredentials(buildConfiguration);
  780. }
  781. return GitAuthenticationType.valueOf(chosenAuthentication);
  782. }
  783. private GitAuthenticationType getAuthenticationTypeForSharedCredentials(final AbstractConfiguration buildConfiguration)
  784. {
  785. return GitAuthenticationType.SSH_KEYPAIR;
  786. }
  787. @NotNull
  788. @Override
  789. public Map<String, String> getCustomVariables()
  790. {
  791. Map<String, String> variables = Maps.newHashMap();
  792. variables.put(REPOSITORY_GIT_REPOSITORY_URL, accessData.getRepositoryUrl());
  793. variables.put(REPOSITORY_GIT_BRANCH, accessData.getVcsBranch().getName());
  794. variables.put(REPOSITORY_GIT_USERNAME, accessData.getUsername());
  795. return variables;
  796. }
  797. @NotNull
  798. @Override
  799. public Map<String, String> getPlanRepositoryVariables()
  800. {
  801. Map<String, String> variables = Maps.newHashMap();
  802. variables.put(REPOSITORY_URL, accessData.getRepositoryUrl());
  803. variables.put(REPOSITORY_BRANCH, accessData.getVcsBranch().getName());
  804. variables.put(REPOSITORY_USERNAME, accessData.getUsername());
  805. return variables;
  806. }
  807. @NotNull
  808. public MavenPomAccessor getMavenPomAccessor()
  809. {
  810. return new GitMavenPomAccessor(this, sshProxyService, i18nResolver, getGitCapability()).withPath(pathToPom);
  811. }
  812. @Override
  813. @NotNull
  814. public List<NameValuePair> getAuthenticationTypes()
  815. {
  816. final List<NameValuePair> authTypes = Lists.newArrayList();
  817. for (final GitAuthenticationType gitAuthenticationType : GitAuthenticationType.values())
  818. {
  819. final String name = gitAuthenticationType.name();
  820. authTypes.add(new NameValuePair(name, getAuthTypeName(name)));
  821. }
  822. if (!getSharedCredentials().isEmpty())
  823. {
  824. authTypes.add(new NameValuePair(SHARED_CREDENTIALS, getAuthTypeName(SHARED_CREDENTIALS)));
  825. }
  826. return authTypes;
  827. }
  828. @NotNull
  829. public Collection<NameValuePair> getSharedCredentials()
  830. {
  831. return ImmutableList.copyOf(Iterables.transform(credentialsAccessor.getAllCredentials(), new Function<CredentialsData, NameValuePair>() {
  832. public NameValuePair apply(CredentialsData credentials)
  833. {
  834. return new NameValuePair(Long.toString(credentials.getId()), credentials.getName());
  835. }
  836. }));
  837. }
  838. @Override
  839. public String getAuthType()
  840. {
  841. return accessData.getAuthenticationType().name();
  842. }
  843. // -------------------------------------------------------------------------------------------------- Public Methods
  844. // -------------------------------------------------------------------------------------------------- Helper Methods
  845. private String getAuthTypeName(final String authType)
  846. {
  847. return i18nResolver.getText("repository.git.authenticationType." + StringUtils.lowerCase(authType));
  848. }
  849. GitRepositoryAccessData.Builder getSubstitutedAccessDataBuilder()
  850. {
  851. return GitRepositoryAccessData.builder(accessData)
  852. .repositoryUrl(substituteString(accessData.getRepositoryUrl()))
  853. .branch(new VcsBranchImpl(substituteString(accessData.getVcsBranch().getName())))
  854. .username(substituteString(accessData.getUsername()))
  855. .password(encryptionService.decrypt(accessData.getPassword()))
  856. .sshKey(encryptionService.decrypt(accessData.getSshKey()))
  857. .sshPassphrase(encryptionService.decrypt(accessData.getSshPassphrase()));
  858. }
  859. GitRepositoryAccessData getSubstitutedAccessData()
  860. {
  861. return getSubstitutedAccessDataBuilder().build();
  862. }
  863. private void rethrowOrRemoveDirectory(final Exception originalException, final BuildLogger buildLogger, final File directory, final String key) throws Exception
  864. {
  865. Throwable e = originalException;
  866. do
  867. {
  868. if (e instanceof TransportException)
  869. {
  870. throw originalException;
  871. }
  872. e = e.getCause();
  873. } while (e!=null);
  874. buildLogger.addBuildLogEntry(i18nResolver.getText(key, directory));
  875. log.warn("Deleting directory " + directory, e);
  876. // This section does not really work on Windows (files open by antivirus software or leaked by jgit - and it does leak handles - will remain on the harddrive),
  877. // so it should be entered if we know that the cache has to be blown away
  878. FileUtils.deleteQuietly(directory);
  879. final String[] filesInDirectory = directory.list();
  880. if (filesInDirectory !=null)
  881. {
  882. log.error("Unable to delete files: " + Arrays.toString(filesInDirectory) + ", expect trouble");
  883. }
  884. }
  885. // -------------------------------------------------------------------------------------- Basic Accessors / Mutators
  886. public boolean isUseShallowClones()
  887. {
  888. return accessData.isUseShallowClones();
  889. }
  890. public boolean isUseSubmodules()
  891. {
  892. return accessData.isUseSubmodules();
  893. }
  894. public String getRepositoryUrl()
  895. {
  896. return accessData.getRepositoryUrl();
  897. }
  898. /**
  899. * @deprecated since 4.0 use {@link com.atlassian.bamboo.repository.BranchAwareRepository methods)}
  900. * @return
  901. */
  902. @Deprecated
  903. public String getBranch()
  904. {
  905. return accessData.getBranch();
  906. }
  907. public int getCommandTimeout()
  908. {
  909. return accessData.getCommandTimeout();
  910. }
  911. public boolean getVerboseLogs()
  912. {
  913. return accessData.isVerboseLogs();
  914. }
  915. public String getAuthTypeName()
  916. {
  917. return getAuthTypeName(getAuthType());
  918. }
  919. public File getCacheDirectory()
  920. {
  921. return getCacheDirectory(getSubstitutedAccessData());
  922. }
  923. public File getCacheDirectory(GitRepositoryAccessData accessData)
  924. {
  925. return GitCacheDirectory.getCacheDirectory(buildDirectoryManager.getBaseBuildWorkingDirectory(), accessData);
  926. }
  927. public void setI18nResolver(I18nResolver i18nResolver)
  928. {
  929. this.i18nResolver = i18nResolver;
  930. }
  931. public void setEncryptionService(EncryptionService encryptionService)
  932. {
  933. this.encryptionService = encryptionService;
  934. }
  935. public void setCredentialsAccessor(final CredentialsAccessor credentialsAccessor)
  936. {
  937. this.credentialsAccessor = credentialsAccessor;
  938. }
  939. public String getOptionDescription()
  940. {
  941. Str

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