Skip to content

Commit

Permalink
ConDec-501: Extract decision knowledge elements from commit messages …
Browse files Browse the repository at this point in the history
…of a feature branch (#141)

* GitDecXtract passes feature branch commit message text to GitCommitMessageDecXtract, which will return a list of decision knowledge elements from message texts. GitDecXtract then fill project and key attributes for the dec. know. elements
    * returns empty results for bad git branch
* added specialized GitCommitMessageExtractor class to extract rationale from commit message texts
    * consult test code for expectations on extraction results
* improved GitClientImpl's getBranch() code
* further improved gitClient and its tests setup
* moved helper methods up in the class hierarchy
  • Loading branch information
lw2011 authored Jun 9, 2019
1 parent 530bbd0 commit e885166
Show file tree
Hide file tree
Showing 11 changed files with 813 additions and 63 deletions.
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
package de.uhd.ifi.se.decision.management.jira.extraction;

import java.io.File;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.*;

import com.atlassian.jira.issue.Issue;
import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.diff.DiffEntry;
import org.eclipse.jgit.diff.EditList;
import org.eclipse.jgit.lib.Ref;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.revwalk.RevCommit;

Expand Down Expand Up @@ -90,6 +89,36 @@ public interface GitClient {
*/
Map<DiffEntry, EditList> getDiff(RevCommit firstCommit, RevCommit lastCommit);

/**
* Get a list of remote branches in repository.
*
* @return Refs list
*/
List<Ref> getRemoteBranches();

/**
* Get a list of all commits of a "feature" branch,
* which do not exist in the "default" branch.
* Commits are sorted by age, beginning with the oldest.
*
* @param featureBranchName
* name of the feature branch
* @return ordered list of commits unique to this branch.
*/
List<RevCommit> getFeatureBranchCommits(String featureBranchName);

/**
* Get a list of all commits of a "feature" branch,
* which do not exist in the "default" branch.
* Commits are sorted by age, beginning with the oldest.
*
* @param featureBranch
* ref of the feature branch
* @return ordered list of commits unique to this branch.
*/
List<RevCommit> getFeatureBranchCommits(Ref featureBranch);


/**
* Get the jgit repository object.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,11 @@
import java.util.*;

import com.atlassian.jira.issue.Issue;
import com.google.common.collect.Lists;
import de.uhd.ifi.se.decision.management.jira.extraction.versioncontrol.GitRepositoryFSManager;
import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.api.ListBranchCommand;
import org.eclipse.jgit.api.errors.GitAPIException;
import org.eclipse.jgit.api.errors.*;
import org.eclipse.jgit.diff.DiffEntry;
import org.eclipse.jgit.diff.DiffFormatter;
import org.eclipse.jgit.diff.EditList;
Expand Down Expand Up @@ -217,7 +218,6 @@ public Map<DiffEntry, EditList> getDiff(List<RevCommit> commits) {
return getDiff(firstCommit, lastCommit);
}


@Override
public Map<DiffEntry, EditList> getDiff(Issue jiraIssue) {
if (jiraIssue == null) {
Expand Down Expand Up @@ -259,6 +259,66 @@ public Map<DiffEntry, EditList> getDiff(RevCommit revCommit) {
return getDiff(revCommit, revCommit);
}

/**
* @param featureBranch ref of the feature branch
*/
@Override
public List<RevCommit> getFeatureBranchCommits(Ref featureBranch) {
List<RevCommit> branchUniqueCommits = new ArrayList<RevCommit>();
List<RevCommit> branchCommits = getCommits(featureBranch);
RevCommit lastCommonAncestor = null;
for (RevCommit commit : branchCommits) {
if (defaultBranchCommits.contains(commit)) {
LOGGER.info("Found last common commit " + commit.toString());
lastCommonAncestor = commit;
break;
}
branchUniqueCommits.add(commit);
}

if (lastCommonAncestor == null) {
branchUniqueCommits = null;
} else {
branchUniqueCommits = Lists.reverse(branchUniqueCommits);
}

return branchUniqueCommits;
}

@Override
public List<RevCommit> getFeatureBranchCommits(String featureBranchName) {
Ref featureBranch = getBranch(featureBranchName);
if (null == featureBranch) {
/*
[issue] What is the return value of methods that would normally return a collection (e.g. list) with an invalid input parameter? [/issue]
[alternative] Methods with an invalid input parameter return an empty list! [/alternative]
[pro] Prevents a null pointer exception. [/pro]
[con] Is misleading since it is not clear whether the list is empty but has a valid input parameter or because of an invalid parameter. [/con]
[alternative] Methods with an invalid input parameter return null! [/alternative]
*/
return (List<RevCommit>) null;
}
return getFeatureBranchCommits(featureBranch);
}

private Ref getBranch(String featureBranchName) {
if (featureBranchName == null || featureBranchName.length() == 0) {
LOGGER.info("Null or empty branch name was passed.");
return null;
}
List<Ref> remoteBranches = getRemoteBranches();
if (remoteBranches != null) {
for (Ref branch : remoteBranches) {
String branchName = branch.getName();
if (branchName.endsWith(featureBranchName)) {
return branch;
}
}
}
LOGGER.info("Could not find branch " + featureBranchName);
return null;
}

private DiffFormatter getDiffFormater() {
DiffFormatter diffFormatter = new DiffFormatter(DisabledOutputStream.INSTANCE);
Repository repository = this.getRepository();
Expand Down Expand Up @@ -360,7 +420,7 @@ public List<RevCommit> getCommits(Issue jiraIssue) {
@Override
public List<RevCommit> getCommits() {
List<RevCommit> commits = new ArrayList<RevCommit>();
for (Ref branch : getOnlyRemoteRefs()) {
for (Ref branch : getRemoteBranches()) {
/* @issue: All branches will be created in separate file system
* folders for this method's loop. How can this be prevented?
*
Expand Down Expand Up @@ -409,7 +469,8 @@ private List<Ref> getAllRefs() {
return getRefs(ListBranchCommand.ListMode.ALL);
}

private List<Ref> getOnlyRemoteRefs() {
@Override
public List<Ref> getRemoteBranches() {
return getRefs(ListBranchCommand.ListMode.REMOTE);
}

Expand Down Expand Up @@ -448,17 +509,23 @@ private List<RevCommit> getCommits(Ref branch, boolean isDefaultBranch) {
canReleaseRepoDirectory = !fsManager.isBranchDirectoryInUse(branchShortName);
directory = new File(fsManager.prepareBranchDirectory(branchShortName));
}
try {
git.close();
git = git.open(directory);
git.checkout().setName(branchShortName).call();
Iterable<RevCommit> iterable = git.log().call();
for (RevCommit commit : iterable) {
commits.add(commit);

if (switchGitDirectory(directory)
&& createLocalBranchIfNotExists(branchShortName)
&& checkoutBranch(branchShortName)
&& pull()) {
Iterable<RevCommit> iterable = null;
try {
iterable = git.log().call();
} catch (GitAPIException e) {
LOGGER.error("Git could not get commits for the branch: "
+ branch.getName() + " Message: " + e.getMessage());
}
if (iterable != null) {
for (RevCommit commit : iterable) {
commits.add(commit);
}
}
} catch (IOException | GitAPIException e) {
LOGGER.error("Git could not get commits for the branch: "
+ branch.getName() + " Message: " + e.getMessage());
}
if (canReleaseRepoDirectory) {
fsManager.releaseBranchDirectoryNameToTemp(branchShortName);
Expand All @@ -467,6 +534,43 @@ private List<RevCommit> getCommits(Ref branch, boolean isDefaultBranch) {
return commits;
}

private boolean checkoutBranch(String branchShortName) {
try {
git.checkout().setName(branchShortName).call();
} catch (GitAPIException e) {
LOGGER.error("Could not checkout branch. " + e.getMessage());
return false;
}
return true;
}

private boolean createLocalBranchIfNotExists(String branchShortName) {
try {
git.branchCreate().setName(branchShortName).call();
} catch (RefAlreadyExistsException e) {
return true;
} catch (InvalidRefNameException | RefNotFoundException e) {
LOGGER.error("Could not create local branch. " + e.getMessage());
return false;
} catch (GitAPIException e) {
LOGGER.error("Could not create local branch. " + e.getMessage());
return false;
}
return true;
}

private boolean switchGitDirectory(File gitDirectory) {
git.close();
try {
git = git.open(gitDirectory);
} catch (IOException e) {
LOGGER.error("Could not switch into git directory " + gitDirectory.getAbsolutePath()
+ "\r\n" + e.getMessage());
return false;
}
return true;
}

private void switchGitClientBackToDefaultDirectory() {
File directory = new File(fsManager.getDefaultBranchPath());
try {
Expand Down
Loading

0 comments on commit e885166

Please sign in to comment.