com.tw.go.plugin.jgit.JGitHelper Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of git-cmd Show documentation
Show all versions of git-cmd Show documentation
Common module that all Go CD plugins can use to poll Git repository.
package com.tw.go.plugin.jgit;
import com.tw.go.plugin.GitHelper;
import com.tw.go.plugin.cmd.InMemoryConsumer;
import com.tw.go.plugin.cmd.ProcessOutputStreamConsumer;
import com.tw.go.plugin.model.GitConfig;
import com.tw.go.plugin.model.ModifiedFile;
import com.tw.go.plugin.model.Revision;
import com.tw.go.plugin.util.StringUtil;
import org.apache.commons.io.FileUtils;
import org.eclipse.jgit.api.*;
import org.eclipse.jgit.diff.DiffEntry;
import org.eclipse.jgit.diff.DiffFormatter;
import org.eclipse.jgit.diff.RawTextComparator;
import org.eclipse.jgit.lib.*;
import org.eclipse.jgit.revwalk.RevCommit;
import org.eclipse.jgit.revwalk.RevWalk;
import org.eclipse.jgit.storage.file.FileBasedConfig;
import org.eclipse.jgit.storage.file.FileRepositoryBuilder;
import org.eclipse.jgit.submodule.SubmoduleStatus;
import org.eclipse.jgit.submodule.SubmoduleWalk;
import org.eclipse.jgit.transport.RefSpec;
import org.eclipse.jgit.transport.UsernamePasswordCredentialsProvider;
import org.eclipse.jgit.treewalk.TreeWalk;
import org.eclipse.jgit.util.FS;
import org.eclipse.jgit.util.io.DisabledOutputStream;
import java.io.File;
import java.io.IOException;
import java.util.*;
public class JGitHelper extends GitHelper {
public JGitHelper(GitConfig gitConfig, File workingDir) {
this(gitConfig, workingDir, new ProcessOutputStreamConsumer(new InMemoryConsumer()), new ProcessOutputStreamConsumer(new InMemoryConsumer()));
}
public JGitHelper(GitConfig gitConfig, File workingDir, ProcessOutputStreamConsumer stdOut, ProcessOutputStreamConsumer stdErr) {
super(gitConfig, workingDir, stdOut, stdErr);
}
@Override
public String version() {
return "3.6.2.201501210735-r";
}
@Override
public void checkConnection() {
try {
LsRemoteCommand lsRemote = Git.lsRemoteRepository().setHeads(true).setRemote(gitConfig.getUrl());
setCredentials(lsRemote);
lsRemote.call();
} catch (Exception e) {
throw new RuntimeException("check connection (ls-remote) failed", e);
}
}
@Override
public void cloneRepository() {
CloneCommand clone = Git.cloneRepository().setURI(gitConfig.getUrl()).setBranch(gitConfig.getEffectiveBranch()).setDirectory(workingDir);
if (gitConfig.isRecursiveSubModuleUpdate()) {
clone.setCloneSubmodules(true);
}
setCredentials(clone);
try {
clone.call();
} catch (Exception e) {
throw new RuntimeException("clone failed", e);
}
}
@Override
public void checkoutRemoteBranchToLocal() {
Repository repository = null;
try {
repository = getRepository(workingDir);
Git git = new Git(repository);
CheckoutCommand checkout = git.checkout().setForce(true).setName(gitConfig.getEffectiveBranch());
checkout.call();
} catch (Exception e) {
throw new RuntimeException("checkout failed", e);
} finally {
if (repository != null) {
repository.close();
}
}
}
@Override
public String workingRepositoryUrl() {
Repository repository = null;
try {
repository = getRepository(workingDir);
return repository.getConfig().getString("remote", "origin", "url");
} catch (Exception e) {
throw new RuntimeException("clean failed", e);
} finally {
if (repository != null) {
repository.close();
}
}
}
@Override
public String getCurrentBranch() {
Repository repository = null;
try {
repository = getRepository(workingDir);
return repository.getBranch();
} catch (Exception e) {
throw new RuntimeException("current branch failed", e);
} finally {
if (repository != null) {
repository.close();
}
}
}
@Override
public int getCommitCount() {
Repository repository = null;
int count = 0;
try {
repository = getRepository(workingDir);
Git git = new Git(repository);
LogCommand logCmd = git.log();
Iterable log = logCmd.call();
for (RevCommit commit : log) {
count++;
}
} catch (Exception e) {
throw new RuntimeException("commit count failed", e);
} finally {
if (repository != null) {
repository.close();
}
}
return count;
}
@Override
public String currentRevision() {
return getLatestRevision().getRevision();
}
@Override
public List getAllRevisions() {
Repository repository = null;
try {
repository = getRepository(workingDir);
Git git = new Git(repository);
LogCommand logCmd = git.log();
Iterable log = logCmd.call();
List revisionObjs = new ArrayList();
for (RevCommit commit : log) {
Revision revisionObj = getRevisionObj(repository, commit);
revisionObjs.add(revisionObj);
}
return revisionObjs;
} catch (Exception e) {
throw new RuntimeException("get all revisions failed", e);
} finally {
if (repository != null) {
repository.close();
}
}
}
@Override
public Revision getLatestRevision() {
Repository repository = null;
try {
repository = getRepository(workingDir);
Git git = new Git(repository);
LogCommand logCmd = git.log().setMaxCount(1);
Iterable log = logCmd.call();
Iterator iterator = log.iterator();
if (iterator.hasNext()) {
return getRevisionObj(repository, iterator.next());
}
} catch (Exception e) {
throw new RuntimeException("get latest revision failed", e);
} finally {
if (repository != null) {
repository.close();
}
}
return null;
}
@Override
public List getRevisionsSince(String previousRevision) {
Repository repository = null;
try {
repository = getRepository(workingDir);
Git git = new Git(repository);
LogCommand logCmd = git.log();
Iterable log = logCmd.call();
List newCommits = new ArrayList();
for (RevCommit commit : log) {
if (commit.getName().equals(previousRevision)) {
break;
}
newCommits.add(commit);
}
List revisionObjs = new ArrayList();
if (!newCommits.isEmpty()) {
for (RevCommit newCommit : newCommits) {
Revision revisionObj = getRevisionObj(repository, newCommit);
revisionObjs.add(revisionObj);
}
}
return revisionObjs;
} catch (Exception e) {
throw new RuntimeException("get newer revisions failed", e);
} finally {
if (repository != null) {
repository.close();
}
}
}
@Override
public Revision getDetailsForRevision(String sha) {
Repository repository = null;
try {
repository = getRepository(workingDir);
Git git = new Git(repository);
LogCommand logCmd = git.log().all();
Iterable log = logCmd.call();
for (RevCommit commit : log) {
if (commit.getName().equals(sha)) {
return getRevisionObj(repository, commit);
}
}
return null;
} catch (Exception e) {
throw new RuntimeException("get latest revision failed", e);
} finally {
if (repository != null) {
repository.close();
}
}
}
@Override
public Map getBranchToRevisionMap(String pattern) {
Repository repository = null;
try {
repository = getRepository(workingDir);
Map allRefs = repository.getAllRefs();
Map branchToRevisionMap = new HashMap();
for (String refName : allRefs.keySet()) {
if (refName.contains(pattern)) {
String branch = refName.replace(pattern, "");
String revision = allRefs.get(refName).getObjectId().getName();
branchToRevisionMap.put(branch, revision);
}
}
return branchToRevisionMap;
} catch (Exception e) {
throw new RuntimeException("fetch failed", e);
} finally {
if (repository != null) {
repository.close();
}
}
}
@Override
public void pull() {
}
@Override
public void fetch(String refSpec) {
Repository repository = null;
try {
repository = getRepository(workingDir);
Git git = new Git(repository);
FetchCommand fetch = git.fetch().setRemoveDeletedRefs(true);
if (!StringUtil.isEmpty(refSpec)) {
fetch.setRefSpecs(new RefSpec(refSpec));
}
setCredentials(fetch);
fetch.call();
} catch (Exception e) {
throw new RuntimeException("fetch failed", e);
} finally {
if (repository != null) {
repository.close();
}
}
}
@Override
public void resetHard(String revision) {
Repository repository = null;
try {
repository = getRepository(workingDir);
Git git = new Git(repository);
ResetCommand reset = git.reset().setMode(ResetCommand.ResetType.HARD).setRef(revision);
reset.call();
} catch (Exception e) {
throw new RuntimeException("reset failed", e);
} finally {
if (repository != null) {
repository.close();
}
}
}
@Override
public void cleanAllUnversionedFiles() {
Repository repository = null;
SubmoduleWalk walk = null;
try {
repository = getRepository(workingDir);
Git git = new Git(repository);
walk = SubmoduleWalk.forIndex(repository);
if (walk != null) {
while (walk.next()) {
cleanSubmoduleOfAllUnversionedFiles(walk);
}
}
CleanCommand clean = git.clean().setCleanDirectories(true);
clean.call();
} catch (Exception e) {
throw new RuntimeException("clean failed", e);
} finally {
if (walk != null) {
walk.close();
}
if (repository != null) {
repository.close();
}
}
}
private void cleanSubmoduleOfAllUnversionedFiles(SubmoduleWalk walk) {
Repository submoduleRepository = null;
try {
submoduleRepository = walk.getRepository();
if (submoduleRepository != null) {
CleanCommand clean = Git.wrap(submoduleRepository).clean().setCleanDirectories(true);
clean.call();
}
} catch (Exception e) {
throw new RuntimeException("sub-module clean failed", e);
} finally {
if (submoduleRepository != null) {
submoduleRepository.close();
}
}
}
@Override
public void gc() {
Repository repository = null;
try {
repository = getRepository(workingDir);
Git git = new Git(repository);
GarbageCollectCommand gc = git.gc();
gc.call();
} catch (Exception e) {
throw new RuntimeException("gc failed", e);
} finally {
if (repository != null) {
repository.close();
}
}
}
@Override
public Map submoduleUrls() {
return null;
}
@Override
public List submoduleFolders() {
Repository repository = null;
try {
repository = getRepository(workingDir);
Git git = new Git(repository);
SubmoduleStatusCommand submoduleStatus = git.submoduleStatus();
Map submoduleStatusMap = submoduleStatus.call();
List submoduleFolders = new ArrayList();
for (String submoduleFolder : submoduleStatusMap.keySet()) {
submoduleFolders.add(submoduleFolder);
}
return submoduleFolders;
} catch (Exception e) {
throw new RuntimeException("sub-module folders list failed", e);
} finally {
if (repository != null) {
repository.close();
}
}
}
@Override
public void printSubmoduleStatus() {
Repository repository = null;
try {
repository = getRepository(workingDir);
Git git = new Git(repository);
SubmoduleStatusCommand submoduleStatus = git.submoduleStatus();
Map submoduleStatusMap = submoduleStatus.call();
for (String submoduleFolder : submoduleStatusMap.keySet()) {
stdOut.consumeLine(submoduleFolder + " " + submoduleStatusMap.get(submoduleFolder).getType());
}
} catch (Exception e) {
throw new RuntimeException("sub-module print status failed", e);
} finally {
if (repository != null) {
repository.close();
}
}
}
@Override
public void checkoutAllModifiedFilesInSubmodules() {
Repository repository = null;
SubmoduleWalk walk = null;
try {
repository = getRepository(workingDir);
walk = SubmoduleWalk.forIndex(repository);
while (walk.next()) {
checkoutSubmodule(walk);
}
} catch (Exception e) {
throw new RuntimeException("checkout all sub-modules failed", e);
} finally {
if (walk != null) {
walk.close();
}
if (repository != null) {
repository.close();
}
}
}
private void checkoutSubmodule(SubmoduleWalk walk) {
Repository submoduleRepository = null;
try {
submoduleRepository = walk.getRepository();
CheckoutCommand checkout = Git.wrap(submoduleRepository).checkout().setForce(true).setName("HEAD");
checkout.call();
} catch (Exception e) {
throw new RuntimeException("sub-module checkout failed", e);
} finally {
if (submoduleRepository != null) {
submoduleRepository.close();
}
}
}
@Override
public int getSubModuleCommitCount(String subModuleFolder) {
Repository repository = null;
Repository subModuleRepository = null;
int count = 0;
try {
repository = getRepository(workingDir);
subModuleRepository = SubmoduleWalk.getSubmoduleRepository(repository, subModuleFolder);
Git git = new Git(subModuleRepository);
Iterable log = git.log().call();
for (RevCommit commit : log) {
count++;
}
} catch (Exception e) {
throw new RuntimeException("sub-module commit count failed", e);
} finally {
if (repository != null) {
repository.close();
}
if (subModuleRepository != null) {
subModuleRepository.close();
}
}
return count;
}
@Override
public void submoduleInit() {
Repository repository = null;
try {
repository = getRepository(workingDir);
Git git = new Git(repository);
git.submoduleInit().call();
} catch (Exception e) {
throw new RuntimeException("sub-module init failed", e);
} finally {
if (repository != null) {
repository.close();
}
}
}
@Override
public void submoduleSync() {
Repository repository = null;
try {
repository = getRepository(workingDir);
Git git = new Git(repository);
git.submoduleSync().call();
} catch (Exception e) {
throw new RuntimeException("sub-module sync failed", e);
} finally {
if (repository != null) {
repository.close();
}
}
}
@Override
public void submoduleUpdate() {
Repository repository = null;
try {
repository = getRepository(workingDir);
Git git = new Git(repository);
git.submoduleUpdate().call();
} catch (Exception e) {
throw new RuntimeException("sub-module update failed", e);
} finally {
if (repository != null) {
repository.close();
}
}
}
@Override
public void init() {
Repository repository = null;
try {
Git.init().setDirectory(workingDir).call();
repository = FileRepositoryBuilder.create(new File(workingDir.getAbsolutePath(), ".git"));
} catch (Exception e) {
throw new RuntimeException("init failed", e);
} finally {
if (repository != null) {
repository.close();
}
}
}
@Override
public void add(File fileToAdd) {
Repository repository = null;
try {
repository = getRepository(workingDir);
Git git = new Git(repository);
AddCommand add = git.add().addFilepattern(fileToAdd.getName());
add.call();
} catch (Exception e) {
throw new RuntimeException("add failed", e);
} finally {
if (repository != null) {
repository.close();
}
}
}
@Override
public void commit(String message) {
Repository repository = null;
try {
repository = getRepository(workingDir);
Git git = new Git(repository);
CommitCommand commit = git.commit().setAuthor("author", "[email protected]").setMessage(message);
commit.call();
} catch (Exception e) {
throw new RuntimeException("commit failed", e);
} finally {
if (repository != null) {
repository.close();
}
}
}
@Override
public void commitOnDate(String message, Date commitDate) {
}
@Override
public void submoduleAdd(String subModuleFolder, String subModuleName, String relativePath) {
Repository parentRepository = null;
Repository subModuleRepository = null;
try {
parentRepository = getRepository(workingDir);
subModuleRepository = getRepository(new File(subModuleFolder));
Git git = new Git(parentRepository);
SubmoduleAddCommand subModuleAdd = git.submoduleAdd().setURI(subModuleRepository.getDirectory().getCanonicalPath()).setPath(relativePath);
subModuleAdd.call();
} catch (Exception e) {
throw new RuntimeException("add sub-module failed", e);
} finally {
if (parentRepository != null) {
parentRepository.close();
}
if (subModuleRepository != null) {
subModuleRepository.close();
}
}
}
@Override
public void removeSubmoduleSectionsFromGitConfig() {
List submoduleFolders = submoduleFolders();
for (String submoduleFolder : submoduleFolders) {
configRemoveSection(submoduleFolder);
}
}
@Override
public void submoduleRemove(String folderName) {
configRemoveSection(folderName);
Repository repository = null;
try {
repository = getRepository(workingDir);
StoredConfig gitSubmodulesConfig = new FileBasedConfig(null, new File(repository.getWorkTree(), Constants.DOT_GIT_MODULES), FS.DETECTED);
gitSubmodulesConfig.unsetSection(ConfigConstants.CONFIG_SUBMODULE_SECTION, folderName);
gitSubmodulesConfig.save();
Git git = Git.wrap(repository);
git.rm().setCached(true).addFilepattern(folderName).call();
FileUtils.deleteQuietly(new File(workingDir, folderName));
} catch (Exception e) {
throw new RuntimeException("sub-module remove failed", e);
} finally {
if (repository != null) {
repository.close();
}
}
}
private void configRemoveSection(String folderName) {
Repository repository = null;
try {
repository = getRepository(workingDir);
StoredConfig repositoryConfig = repository.getConfig();
repositoryConfig.unsetSection(ConfigConstants.CONFIG_SUBMODULE_SECTION, folderName);
repositoryConfig.save();
} catch (Exception e) {
throw new RuntimeException("sub-module section remove failed", e);
} finally {
if (repository != null) {
repository.close();
}
}
}
@Override
public void changeSubmoduleUrl(String submoduleName, String newUrl) {
}
@Override
public void push() {
}
private Revision getRevisionObj(Repository repository, RevCommit commit) throws IOException {
String commitSHA = commit.getName();
Date commitTime = commit.getAuthorIdent().getWhen();
String comment = commit.getFullMessage().trim();
String user = commit.getAuthorIdent().getName();
String emailId = commit.getAuthorIdent().getEmailAddress();
List modifiedFiles = new ArrayList();
if (commit.getParentCount() == 0) {
TreeWalk treeWalk = new TreeWalk(repository);
treeWalk.addTree(commit.getTree());
treeWalk.setRecursive(false);
while (treeWalk.next()) {
modifiedFiles.add(new ModifiedFile(treeWalk.getPathString(), "added"));
}
} else {
RevWalk rw = new RevWalk(repository);
RevCommit parent = rw.parseCommit(commit.getParent(0).getId());
DiffFormatter diffFormatter = new DiffFormatter(DisabledOutputStream.INSTANCE);
diffFormatter.setRepository(repository);
diffFormatter.setDiffComparator(RawTextComparator.DEFAULT);
diffFormatter.setDetectRenames(true);
List diffEntries = diffFormatter.scan(parent.getTree(), commit.getTree());
for (DiffEntry diffEntry : diffEntries) {
modifiedFiles.add(new ModifiedFile(diffEntry.getNewPath(), getAction(diffEntry.getChangeType().name())));
}
}
boolean isMergeCommit = commit.getParentCount() > 1;
Revision revision = new Revision(commitSHA, commitTime, comment, user, emailId, modifiedFiles);
revision.setMergeCommit(isMergeCommit);
return revision;
}
private String getAction(String gitAction) {
if (gitAction.equalsIgnoreCase("ADD") || gitAction.equalsIgnoreCase("RENAME")) {
return "added";
}
if (gitAction.equals("MODIFY")) {
return "modified";
}
if (gitAction.equals("DELETE")) {
return "deleted";
}
return "unknown";
}
private Repository getRepository(File folder) throws IOException {
return new FileRepositoryBuilder().setGitDir(getGitDir(folder)).readEnvironment().findGitDir().build();
}
private File getGitDir(File folder) {
return new File(folder, ".git");
}
private void setCredentials(TransportCommand command) {
if (gitConfig.isRemoteUrl() && gitConfig.hasCredentials()) {
command.setCredentialsProvider(new UsernamePasswordCredentialsProvider(gitConfig.getUsername(), gitConfig.getPassword()));
}
}
}