/** * Copyright (c) 2000-present Liferay, Inc. All rights reserved. * * This library is free software; you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License as published by the Free * Software Foundation; either version 2.1 of the License, or (at your option) * any later version. * * This library is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more * details. */ package com.liferay.jenkins.results.parser; import com.jcraft.jsch.Session; import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; import java.net.URISyntaxException; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.HashSet; import java.util.List; import java.util.Set; import org.eclipse.jgit.api.AddCommand; import org.eclipse.jgit.api.CleanCommand; import org.eclipse.jgit.api.CommitCommand; import org.eclipse.jgit.api.CreateBranchCommand; import org.eclipse.jgit.api.DeleteBranchCommand; import org.eclipse.jgit.api.Git; import org.eclipse.jgit.api.ListBranchCommand; import org.eclipse.jgit.api.ListBranchCommand.ListMode; import org.eclipse.jgit.api.LsRemoteCommand; import org.eclipse.jgit.api.PushCommand; import org.eclipse.jgit.api.RebaseCommand; import org.eclipse.jgit.api.ResetCommand; import org.eclipse.jgit.api.errors.GitAPIException; import org.eclipse.jgit.lib.Constants; import org.eclipse.jgit.lib.Ref; import org.eclipse.jgit.lib.Repository; import org.eclipse.jgit.lib.RepositoryState; import org.eclipse.jgit.lib.StoredConfig; import org.eclipse.jgit.storage.file.FileRepositoryBuilder; import org.eclipse.jgit.transport.JschConfigSessionFactory; import org.eclipse.jgit.transport.OpenSshConfig.Host; import org.eclipse.jgit.transport.PushResult; import org.eclipse.jgit.transport.RefSpec; import org.eclipse.jgit.transport.RemoteConfig; import org.eclipse.jgit.transport.RemoteRefUpdate; import org.eclipse.jgit.transport.SshSessionFactory; import org.eclipse.jgit.transport.URIish; import org.json.JSONObject; /** * @author Michael Hashimoto * @author Peter Yoo */ public class GitWorkingDirectory { public static String getGitHubUserName(RemoteConfig remoteConfig) throws GitAPIException { String remoteURL = getRemoteURL(remoteConfig); if (!remoteURL.contains("github.com")) { throw new IllegalArgumentException( JenkinsResultsParserUtil.combine( remoteConfig.getName(), " does not point to a GitHub repository")); } String userName = null; if (remoteURL.startsWith("https://github.com/")) { userName = remoteURL.substring("https://github.com/".length()); } else { userName = remoteURL.substring("git@github.com:".length()); } return userName.substring(0, userName.indexOf("/")); } public GitWorkingDirectory( String upstreamBranchName, String workingDirectory) throws GitAPIException, IOException { _upstreamBranchName = upstreamBranchName; setWorkingDirectory(workingDirectory); waitForIndexLock(); FileRepositoryBuilder fileRepositoryBuilder = new FileRepositoryBuilder(); fileRepositoryBuilder.setGitDir(_gitDirectory); fileRepositoryBuilder.setWorkTree(_workingDirectory); _repository = fileRepositoryBuilder.build(); _git = new Git(_repository); _repositoryName = loadRepositoryName(); _repositoryUsername = loadRepositoryUsername(); } public RemoteConfig addRemote( boolean force, String remoteName, String remoteURL) throws GitAPIException { System.out.println( JenkinsResultsParserUtil.combine( "Adding remote ", remoteName, " with url: ", remoteURL)); RemoteConfig remoteConfig = getRemoteConfig(remoteName); if (remoteConfig != null) { if (force) { removeRemote(remoteConfig); } else { throw new RuntimeException( JenkinsResultsParserUtil.combine( "Remote ", remoteName, " already exists")); } } Process process = null; try { process = JenkinsResultsParserUtil.executeBashCommands( true, _workingDirectory, 1000 * 10, JenkinsResultsParserUtil.combine( "git remote add ", remoteName, " ", remoteURL)); } catch (InterruptedException | IOException e) { throw new RuntimeException("Unable to add remote " + remoteName, e); } if ((process != null) && (process.exitValue() != 0)) { try { System.out.println( JenkinsResultsParserUtil.readInputStream( process.getErrorStream())); } catch (IOException ioe) { ioe.printStackTrace(); } throw new RuntimeException( JenkinsResultsParserUtil.combine( "Unable to add remote ", remoteName)); } _remoteConfigs = null; return getRemoteConfig(remoteName); } public boolean branchExists(String branchName, RemoteConfig remoteConfig) throws GitAPIException { List<String> branchNames = null; if (remoteConfig == null) { branchNames = getLocalBranchNames(); } else { branchNames = getRemoteBranchNames(remoteConfig); } return branchNames.contains(branchName); } public void checkoutBranch(String branchName) throws GitAPIException { checkoutBranch(branchName, "-f"); } public void checkoutBranch(String branchName, String options) throws GitAPIException { String currentBranchName = getCurrentBranch(); List<String> localBranchNames = getLocalBranchNames(); if (!branchName.contains("/") && !localBranchNames.contains(branchName)) { throw new IllegalArgumentException( JenkinsResultsParserUtil.combine( "Unable to checkout ", branchName, " because it does not exist")); } if (currentBranchName.equals(branchName)) { System.out.println(branchName + " is already checked out"); return; } System.out.println( JenkinsResultsParserUtil.combine( "The current branch is ", currentBranchName, ". Checking out branch ", branchName, ".")); waitForIndexLock(); StringBuilder sb = new StringBuilder(); sb.append("git checkout "); if (options != null) { sb.append(options); sb.append(" "); } sb.append(branchName); Process process = null; try { process = JenkinsResultsParserUtil.executeBashCommands( true, _workingDirectory, 1000 * 60 * 10, sb.toString()); } catch (InterruptedException | IOException e) { throw new RuntimeException( "Unable to checkout branch " + branchName, e); } if ((process != null) && (process.exitValue() != 0)) { try { System.out.println( JenkinsResultsParserUtil.readInputStream( process.getErrorStream())); } catch (IOException ioe) { ioe.printStackTrace(); } throw new RuntimeException( JenkinsResultsParserUtil.combine( "Unable to checkout branch ", branchName)); } int timeout = 0; File headFile = new File(_gitDirectory, "HEAD"); String expectedContent = null; if (!branchName.contains("/")) { expectedContent = JenkinsResultsParserUtil.combine( "ref: refs/heads/", branchName); } else { int i = branchName.indexOf("/"); String remoteBranchName = branchName.substring(i + 1); String remoteName = branchName.substring(0, i); expectedContent = getBranchSHA( remoteBranchName, getRemoteConfig(remoteName)); } while (true) { String headContent = null; try { headContent = JenkinsResultsParserUtil.read(headFile); } catch (IOException ioe) { throw new RuntimeException( "Unable to read file " + headFile.getPath(), ioe); } headContent = headContent.trim(); if (headContent.equals(expectedContent)) { return; } System.out.println( JenkinsResultsParserUtil.combine( "HEAD file content is currently: ", headContent, ". Waiting for branch to be updated.")); JenkinsResultsParserUtil.sleep(5000); timeout++; if (timeout >= 59) { if (branchName.equals(getCurrentBranch())) { return; } throw new RuntimeException( "Unable to checkout branch " + branchName); } } } public void clean() throws GitAPIException { StoredConfig storedConfig = _repository.getConfig(); boolean requireForce = storedConfig.getBoolean( "clean", "requireForce", true); if (requireForce == true) { updateConfig("clean", null, "requireForce", false); } try { CleanCommand cleanCommand = _git.clean(); cleanCommand.setCleanDirectories(true); cleanCommand.setIgnore(true); System.out.println("Cleaning repository"); cleanCommand.call(); } finally { if (requireForce != false) { updateConfig("clean", null, "requireForce", null); } } } public void commitFileToCurrentBranch(String fileName, String message) throws GitAPIException { System.out.println("Committing file to current branch " + fileName); stageFileInCurrentBranch(fileName); commitStagedFilesToCurrentBranch(message); } public void commitStagedFilesToCurrentBranch(String message) throws GitAPIException { System.out.println("Committing staged files to current branch"); CommitCommand commitCommand = _git.commit(); commitCommand.setMessage(message); commitCommand.call(); } public void createLocalBranch(String branchName) throws GitAPIException { createLocalBranch(branchName, false, null); } public void createLocalBranch( String branchName, boolean force, String startPoint) throws GitAPIException { System.out.println( JenkinsResultsParserUtil.combine( "Creating branch ", branchName, " at starting point ", startPoint)); CreateBranchCommand createBranchCommand = _git.branchCreate(); createBranchCommand.setForce(force); createBranchCommand.setName(branchName); if (startPoint != null) { createBranchCommand.setStartPoint(startPoint); } createBranchCommand.call(); } public String createPullRequest( String body, String pullRequestBranchName, String receiverUserName, String title) throws IOException { JSONObject requestJSONObject = new JSONObject(); requestJSONObject.put("base", _upstreamBranchName); requestJSONObject.put("body", body); requestJSONObject.put( "head", receiverUserName + ":" + pullRequestBranchName); requestJSONObject.put("title", title); String url = JenkinsResultsParserUtil.combine( "https://api.github.com/repos/", receiverUserName, "/", _repositoryName, "/pulls"); JSONObject responseJSONObject = JenkinsResultsParserUtil.toJSONObject( url, requestJSONObject.toString()); String pullRequestURL = responseJSONObject.getString("html_url"); System.out.println("Created a pull request at " + pullRequestURL); return pullRequestURL; } public void deleteLocalBranch(String localBranchName) throws GitAPIException { System.out.println("Deleting local branch " + localBranchName); DeleteBranchCommand deleteBranchCommand = _git.branchDelete(); deleteBranchCommand.setBranchNames(localBranchName); deleteBranchCommand.setForce(true); deleteBranchCommand.call(); } public void fetch(RefSpec refSpec, RemoteConfig remoteConfig) throws GitAPIException { StringBuilder sb = new StringBuilder(); sb.append("git fetch --progress -v -f "); sb.append(getRemoteURL(remoteConfig)); if (refSpec == null) { System.out.println( JenkinsResultsParserUtil.combine( "Fetching from ", getRemoteURL(remoteConfig))); List<RefSpec> fetchRefSpecs = remoteConfig.getFetchRefSpecs(); for (RefSpec fetchRefSpec : fetchRefSpecs) { sb.append(" "); sb.append(fetchRefSpec.toString()); } } else { System.out.println( JenkinsResultsParserUtil.combine( "Fetching from ", getRemoteURL(remoteConfig), " ", refSpec.toString())); sb.append(" "); sb.append(refSpec.toString()); } int retries = 0; long start = System.currentTimeMillis(); while (true) { try { Process process = JenkinsResultsParserUtil.executeBashCommands( true, getWorkingDirectory(), 1000 * 60 * 30, sb.toString()); if ((process != null) && (process.exitValue() != 0)) { try { System.out.println( JenkinsResultsParserUtil.readInputStream( process.getErrorStream())); } catch (IOException ioe) { ioe.printStackTrace(); } throw new RuntimeException("Unable to fetch"); } if (process == null) { throw new RuntimeException("Process failed to run"); } System.out.println( JenkinsResultsParserUtil.readInputStream( process.getInputStream())); } catch (Exception e) { if (retries < 3) { System.out.println( JenkinsResultsParserUtil.combine( "Fetch attempt ", Integer.toString(retries), " failed with an exception. ", e.getMessage(), "\nRetrying.")); retries++; JenkinsResultsParserUtil.sleep(30000); } else { throw new RuntimeException(e); } } break; } System.out.println( "Fetch completed in " + JenkinsResultsParserUtil.toDurationString( System.currentTimeMillis() - start)); } public void fetch( String localBranchName, String remoteBranchName, RemoteConfig remoteConfig) throws GitAPIException { RefSpec refSpec = new RefSpec( JenkinsResultsParserUtil.combine( "refs/heads/", remoteBranchName, ":", "refs/heads/", localBranchName)); fetch(refSpec, remoteConfig); } public List<String> getBranchNamesContainingSHA(String sha) { String command = "git branch --contains " + sha; try { Process process = JenkinsResultsParserUtil.executeBashCommands( true, getWorkingDirectory(), 1000 * 60 * 2, command); String output = JenkinsResultsParserUtil.readInputStream( process.getInputStream()); if (output.contains("no such commit")) { return Collections.emptyList(); } System.out.println(output); String[] outputLines = output.split("\n"); List<String> branchNamesList = new ArrayList<>( outputLines.length - 1); for (String outputLine : outputLines) { if (branchNamesList.size() == (outputLines.length - 1)) { break; } String branchName = outputLine.trim(); if (branchName.startsWith("* ")) { branchName = branchName.substring(2); } branchNamesList.add(branchName); } return branchNamesList; } catch (InterruptedException | IOException e) { throw new RuntimeException( "Unable to find branches with SHA " + sha, e); } } public List<Ref> getBranchRefs() throws GitAPIException { ListBranchCommand listBranchCommand = _git.branchList(); listBranchCommand.setListMode(ListMode.ALL); return listBranchCommand.call(); } public String getBranchSHA(String branchName) throws GitAPIException { String command = "git rev-parse " + branchName; try { Process process = JenkinsResultsParserUtil.executeBashCommands( true, getWorkingDirectory(), 1000 * 60 * 2, command); String output = JenkinsResultsParserUtil.readInputStream( process.getInputStream()); String firstLine = output.substring(0, output.indexOf("\n")); return firstLine.trim(); } catch (InterruptedException | IOException e) { throw new RuntimeException( "Unable to get SHA of branch " + branchName); } } public String getBranchSHA(String branchName, RemoteConfig remoteConfig) throws GitAPIException { if (remoteConfig == null) { return getBranchSHA(branchName); } String remoteURL = getRemoteURL(remoteConfig); if (remoteURL.contains("git@github.com")) { return getGitHubBranchSHA(branchName, remoteConfig); } LsRemoteCommand lsRemoteCommand = Git.lsRemoteRepository(); lsRemoteCommand.setHeads(true); lsRemoteCommand.setRemote(remoteURL); lsRemoteCommand.setTags(false); Collection<Ref> remoteRefs = lsRemoteCommand.call(); for (Ref remoteRef : remoteRefs) { String completeBranchName = "refs/heads/" + branchName; if (completeBranchName.equals(remoteRef.getName())) { return remoteRef.getObjectId().getName(); } } return null; } public String getCurrentBranch() { waitForIndexLock(); try { return _repository.getBranch(); } catch (IOException ioe) { throw new RuntimeException( "Unable to get current branch name from repository", ioe); } } public Git getGit() { return _git; } public File getGitDirectory() { return _gitDirectory; } public String getGitHubBranchSHA( String branchName, RemoteConfig remoteConfig) { String command = JenkinsResultsParserUtil.combine( "git ls-remote ", getRemoteURL(remoteConfig), " ", branchName); try { Process process = JenkinsResultsParserUtil.executeBashCommands( command); if (process.exitValue() != 0) { System.out.println( JenkinsResultsParserUtil.readInputStream( process.getErrorStream())); throw new RuntimeException( JenkinsResultsParserUtil.combine( "Unable to get branch sha for ", branchName, " on ", getRemoteURL(remoteConfig))); } String output = JenkinsResultsParserUtil.readInputStream( process.getInputStream()); for (String line : output.split("\n")) { if (line.endsWith("refs/heads/" + branchName)) { return line.substring(0, line.indexOf("\t")); } } } catch (InterruptedException | IOException e) { throw new RuntimeException(e); } return null; } public List<String> getLocalBranchNames() throws GitAPIException { List<Ref> allLocalBranchRefs = new ArrayList<>(); for (Ref branchRef : getBranchRefs()) { String branchName = branchRef.getName(); if (branchName.startsWith("refs/heads")) { allLocalBranchRefs.add(branchRef); } } return toShortNameList(allLocalBranchRefs); } public List<String> getRemoteBranchNames(RemoteConfig remoteConfig) throws GitAPIException { LsRemoteCommand lsRemoteCommand = Git.lsRemoteRepository(); lsRemoteCommand.setHeads(true); lsRemoteCommand.setRemote(getRemoteURL(remoteConfig)); lsRemoteCommand.setTags(false); List<String> remoteBranchNames = toShortNameList( lsRemoteCommand.call()); Collections.sort(remoteBranchNames); return remoteBranchNames; } public RemoteConfig getRemoteConfig(String remoteName) throws GitAPIException { if (remoteName.equals("upstream")) { return _getUpstreamRemoteConfig(); } return _getRemoteConfig(remoteName); } public List<RemoteConfig> getRemoteConfigs() throws GitAPIException { if (_remoteConfigs != null) { return _remoteConfigs; } try { _remoteConfigs = RemoteConfig.getAllRemoteConfigs( _repository.getConfig()); } catch (URISyntaxException urise) { throw new RuntimeException(urise); } return _remoteConfigs; } public Set<String> getRemoteNames() throws GitAPIException { List<RemoteConfig> remoteConfigs = getRemoteConfigs(); Set<String> remoteNames = new HashSet<>(remoteConfigs.size()); for (RemoteConfig remoteConfig : remoteConfigs) { remoteNames.add(remoteConfig.getName()); } return remoteNames; } public String getRepositoryName() { return _repositoryName; } public String getRepositoryUsername() { return _repositoryUsername; } public String getUpstreamBranchName() { return _upstreamBranchName; } public File getWorkingDirectory() { return _workingDirectory; } public boolean pushToRemote(boolean force, RemoteConfig remoteConfig) throws GitAPIException { return pushToRemote(force, getCurrentBranch(), remoteConfig); } public boolean pushToRemote( boolean force, String remoteBranchName, RemoteConfig remoteConfig) throws GitAPIException { return pushToRemote( force, getCurrentBranch(), remoteBranchName, remoteConfig); } public boolean pushToRemote( boolean force, String remoteBranchName, String remoteURL) throws GitAPIException { RemoteConfig remoteConfig = null; try { remoteConfig = addRemote(true, "temp", remoteURL); return pushToRemote(force, remoteBranchName, remoteConfig); } finally { removeRemote(remoteConfig); } } public boolean pushToRemote( boolean force, String localBranchName, String remoteBranchName, RemoteConfig remoteConfig) throws GitAPIException { String remoteURL = getRemoteURL(remoteConfig); System.out.println( JenkinsResultsParserUtil.combine( "Pushing ", localBranchName, " to ", remoteURL, " ", remoteBranchName)); PushCommand pushCommand = null; synchronized (_git) { pushCommand = _git.push(); } String remoteRefName = "refs/heads/" + remoteBranchName; RefSpec refSpec = new RefSpec( JenkinsResultsParserUtil.combine( localBranchName, ":", remoteRefName)); synchronized (pushCommand) { pushCommand.setForce(force); pushCommand.setRefSpecs(refSpec); pushCommand.setRemote(remoteURL); for (PushResult pushResult : pushCommand.call()) { for (RemoteRefUpdate remoteRefUpdate : pushResult.getRemoteUpdates()) { if ((remoteRefUpdate != null) && (remoteRefUpdate.getStatus() != RemoteRefUpdate.Status.OK)) { System.out.println( JenkinsResultsParserUtil.combine( "Unable to push ", localBranchName, " to ", getRemoteURL(remoteConfig), ".\nPush response: ", remoteRefUpdate.toString())); return false; } } } return true; } } public void rebase( boolean abortOnFail, String sourceBranchName, String targetBranchName) throws GitAPIException { String rebaseCommand = JenkinsResultsParserUtil.combine( "git rebase ", sourceBranchName, " ", targetBranchName); String sourceBranchSHA = getBranchSHA(sourceBranchName); System.out.println( JenkinsResultsParserUtil.combine( "Rebasing ", sourceBranchName, "(", sourceBranchSHA, ") to ", targetBranchName)); try { Process process = JenkinsResultsParserUtil.executeBashCommands( true, getWorkingDirectory(), 1000 * 60 * 10, rebaseCommand); if ((process != null) && (process.exitValue() != 0)) { try { System.out.println( JenkinsResultsParserUtil.readInputStream( process.getErrorStream())); } catch (IOException ioe) { ioe.printStackTrace(); } throw new RuntimeException("Unable to rebase"); } if (process != null) { System.out.println( JenkinsResultsParserUtil.readInputStream( process.getInputStream())); } int i = 0; while (i < 10) { List<String> branchNamesContainingSourceBranchSHA = getBranchNamesContainingSHA(sourceBranchSHA); if (!branchNamesContainingSourceBranchSHA.contains( targetBranchName)) { i++; JenkinsResultsParserUtil.sleep(1000 * 30); continue; } break; } } catch (Exception e) { RepositoryState repositoryState = _repository.getRepositoryState(); try { throw new RuntimeException( JenkinsResultsParserUtil.combine( "Unable to rebase ", targetBranchName, " to ", sourceBranchName, ". Repository is in the ", repositoryState.toString(), " state."), e); } finally { if (abortOnFail) { rebaseAbort(); } } } } public void rebaseAbort() throws GitAPIException { if (!_rebaseRepositoryStates.contains( _repository.getRepositoryState())) { return; } RebaseCommand rebaseCommand = _git.rebase(); rebaseCommand.setOperation(RebaseCommand.Operation.ABORT); System.out.println( "Aborting rebase " + RebaseCommand.Operation.ABORT.toString()); rebaseCommand.call(); } public boolean remoteExists(String remoteName) throws GitAPIException { Set<String> remoteNames = getRemoteNames(); return remoteNames.contains(remoteName); } public void removeRemote(RemoteConfig remoteConfig) { try { if (!remoteExists(remoteConfig.getName())) { return; } System.out.println("Removing remote " + remoteConfig.getName()); Process process = null; try { process = JenkinsResultsParserUtil.executeBashCommands( true, _workingDirectory, 1000 * 60, "git remote rm " + remoteConfig.getName()); } catch (InterruptedException | IOException | RuntimeException e) { throw new RuntimeException( "Unable to remove remote " + remoteConfig.getName(), e); } if ((process != null) && (process.exitValue() != 0)) { try { System.out.println( JenkinsResultsParserUtil.readInputStream( process.getErrorStream())); } catch (IOException ioe) { ioe.printStackTrace(); } throw new RuntimeException( JenkinsResultsParserUtil.combine( "Unable to remove remote", remoteConfig.getName())); } if (_remoteConfigs.contains(remoteConfig)) { _remoteConfigs.remove(remoteConfig); } else { _remoteConfigs = null; } } catch (GitAPIException gapie) { gapie.printStackTrace(); } } public void removeRemotes(List<RemoteConfig> remoteConfigs) { for (RemoteConfig remoteConfig : remoteConfigs) { removeRemote(remoteConfig); } } public void reset(String ref, ResetCommand.ResetType resetType) throws GitAPIException { if ((ref != null) && (ref.equals("head") || ref.equals("HEAD"))) { ref = null; } ResetCommand resetCommand = _git.reset(); resetCommand.setMode(resetType); if (ref != null) { resetCommand.setRef(ref); } else { ref = Constants.HEAD; } System.out.println( JenkinsResultsParserUtil.combine( "Resetting ", resetType.toString(), " to ", ref)); resetCommand.call(); } public void stageFileInCurrentBranch(String fileName) throws GitAPIException { AddCommand addCommand = _git.add(); addCommand.addFilepattern(fileName); System.out.println("Staging file in current branch " + fileName); addCommand.call(); } public void updateConfig( String section, String subsection, String name, Object value) { StoredConfig storedConfig = _repository.getConfig(); if (value == null) { storedConfig.unset(section, subsection, name); } if (value instanceof Boolean) { storedConfig.setBoolean(section, subsection, name, (Boolean)value); } if (value instanceof String) { storedConfig.setString(section, subsection, name, (String)value); } try { storedConfig.save(); } catch (IOException ioe) { throw new RuntimeException("Unable to save configuration change"); } } protected static String getRemoteURL(RemoteConfig remoteConfig) { List<URIish> uris = remoteConfig.getURIs(); URIish uri = uris.get(0); return uri.toString(); } protected String loadRepositoryName() throws GitAPIException { String remoteURL = getRemoteURL(_getRemoteConfig("upstream")); int x = remoteURL.lastIndexOf("/") + 1; int y = remoteURL.indexOf(".git"); String repositoryName = remoteURL.substring(x, y); if (repositoryName.equals("liferay-jenkins-tools-private")) { return repositoryName; } if ((repositoryName.equals("liferay-plugins-ee") || repositoryName.equals("liferay-portal-ee")) && !_upstreamBranchName.contains("ee-") && !_upstreamBranchName.contains("-private")) { repositoryName = repositoryName.replace("-ee", ""); } if (repositoryName.contains("-private") && !_upstreamBranchName.contains("-private")) { repositoryName = repositoryName.replace("-private", ""); } return repositoryName; } protected String loadRepositoryUsername() throws GitAPIException { String remoteURL = getRemoteURL(_getRemoteConfig("upstream")); int x = remoteURL.indexOf(":") + 1; int y = remoteURL.indexOf("/"); return remoteURL.substring(x, y); } protected void setWorkingDirectory(String workingDirectory) throws GitAPIException, IOException { _workingDirectory = new File(workingDirectory); if (!_workingDirectory.exists()) { throw new FileNotFoundException( _workingDirectory.getPath() + " is unavailable"); } _gitDirectory = new File(workingDirectory, ".git"); if (!_gitDirectory.exists()) { throw new FileNotFoundException( _gitDirectory.getPath() + " is unavailable"); } } protected List<String> toShortNameList(Collection<Ref> refs) { List<String> shortNames = new ArrayList<>(refs.size()); for (Ref ref : refs) { String refName = ref.getName(); shortNames.add(refName.substring(refName.lastIndexOf("/") + 1)); } return shortNames; } protected void waitForIndexLock() { int retries = 0; File file = new File(_gitDirectory, "index.lock"); while (file.exists()) { System.out.println("Waiting for index.lock to be cleared."); JenkinsResultsParserUtil.sleep(5000); retries++; if (retries >= 24) { file.delete(); } } } private RemoteConfig _getRemoteConfig(String remoteName) throws GitAPIException { List<RemoteConfig> remoteConfigs = getRemoteConfigs(); for (RemoteConfig remoteConfig : remoteConfigs) { if (remoteName.equals(remoteConfig.getName())) { return remoteConfig; } } return null; } private RemoteConfig _getUpstreamPublicRemoteConfig() throws GitAPIException { RemoteConfig upstreamPublicRemoteConfig = _getRemoteConfig( "upstream-public"); if (upstreamPublicRemoteConfig != null) { return upstreamPublicRemoteConfig; } String upstreamRemoteURL = getRemoteURL(_getRemoteConfig("upstream")); upstreamRemoteURL = upstreamRemoteURL.replace("-ee", ""); upstreamRemoteURL = upstreamRemoteURL.replace("-private", ""); return addRemote(true, "upstream-public", upstreamRemoteURL); } private RemoteConfig _getUpstreamRemoteConfig() throws GitAPIException { RemoteConfig upstreamRemoteConfig = _getRemoteConfig("upstream"); String upstreamRemoteURL = getRemoteURL(upstreamRemoteConfig); if (upstreamRemoteURL.contains(_repositoryName + ".git")) { return upstreamRemoteConfig; } return _getUpstreamPublicRemoteConfig(); } private static final List<RepositoryState> _rebaseRepositoryStates = Arrays.asList( RepositoryState.REBASING, RepositoryState.REBASING_INTERACTIVE, RepositoryState.REBASING_MERGE, RepositoryState.REBASING_REBASING); static { JschConfigSessionFactory jschConfigSessionFactory = new JschConfigSessionFactory() { @Override protected void configure(Host host, Session session) { session.setConfig("StrictHostKeyChecking", "no"); } }; SshSessionFactory.setInstance(jschConfigSessionFactory); } private final Git _git; private File _gitDirectory; private List<RemoteConfig> _remoteConfigs; private final Repository _repository; private final String _repositoryName; private final String _repositoryUsername; private final String _upstreamBranchName; private File _workingDirectory; }