diff --git a/src/de/uni_passau/fim/seibt/gitwrapper/repo/Repository.java b/src/de/uni_passau/fim/seibt/gitwrapper/repo/Repository.java index fa585f968cbd48d45b2e907a3b2bc5ca7a89f3fc..48e969be2f71318f15501063d072583886039535 100644 --- a/src/de/uni_passau/fim/seibt/gitwrapper/repo/Repository.java +++ b/src/de/uni_passau/fim/seibt/gitwrapper/repo/Repository.java @@ -3,7 +3,6 @@ package de.uni_passau.fim.seibt.gitwrapper.repo; import java.io.File; import java.io.IOException; import java.nio.file.Path; -import java.nio.file.Paths; import java.time.Instant; import java.time.OffsetDateTime; import java.time.ZoneId; @@ -415,6 +414,7 @@ public class Repository { List<BlameLine> bLines = new ArrayList<>(); Map<Commit, BlameLine> firstOccurrences = new HashMap<>(); + blameLineLoop: while (lines.hasNextLine()) { String line; Scanner lineScanner; @@ -470,9 +470,18 @@ public class Repository { case COMMITTER_TZ: committerTZ = ZoneId.of(lineScanner.next()); break; - case FILENAME: - commitFile = Paths.get(lineScanner.nextLine().trim()); - break; + case FILENAME: { + Optional<Path> oPath = git.getPath(lineScanner.nextLine().substring(1)); + + if (oPath.isPresent()) { + commitFile = oPath.get(); + } else { + // TODO return Optional.empty() from the blameFile() method? + LOG.warning(() -> "Failed to parse the file path for a line in the blame output. Skipping."); + skipBlameLine(lines); + continue blameLineLoop; + } + } break; case SUMMARY: // We do not explicitly store the summary of the commit as it is just the first line of its message (for which there is a getter). case BOUNDARY: @@ -507,6 +516,16 @@ public class Repository { return bLines; } + /** + * Skips all lines returned from the {@code lines} {@link Scanner} up to and including the first one starting + * with a TAB. + * + * @param lines the {@link Scanner} in which to skip lines + */ + private void skipBlameLine(Scanner lines) { + while (lines.hasNextLine() && !lines.nextLine().startsWith("\t")); + } + /** * Parses the output of 'git blame' for an unmerged file and extracts the merge conflicts that occurred in the file. * Every merge conflict is represented by a {@link MergeConflict} instance containing the {@link BlameLine BlameLines} diff --git a/src/de/uni_passau/fim/seibt/gitwrapper/repo/Status.java b/src/de/uni_passau/fim/seibt/gitwrapper/repo/Status.java index a3809129882b16d63195d9a0411c25de4c164239..1b063cdaca3a07eda5d6423777b88baaef40119e 100644 --- a/src/de/uni_passau/fim/seibt/gitwrapper/repo/Status.java +++ b/src/de/uni_passau/fim/seibt/gitwrapper/repo/Status.java @@ -236,6 +236,7 @@ public class Status { List<Path> untracked = new ArrayList<>(); List<Path> ignored = new ArrayList<>(); + GitWrapper git = repo.getGit(); Matcher matcher = STATUS_ENTRY.matcher(gitOutput); while (matcher.find()) { @@ -247,11 +248,26 @@ public class Status { Optional<Path> oldFile; if ((code = matcher.group(G_CODE)) != null) { - file = Paths.get(matcher.group(G_PATH)); - oldFile = Optional.empty(); + Optional<Path> oPath = git.getPath(matcher.group(G_PATH)); + + if (oPath.isPresent()) { + file = oPath.get(); + oldFile = Optional.empty(); + } else { + LOG.warning(() -> "Failed to parse the file path for status entry '" + matcher.group() + "'."); + continue; + } } else if ((code = matcher.group(G_RCODE)) != null) { - file = Paths.get(matcher.group(G_TO)); - oldFile = Optional.of(matcher.group(G_FROM)).map(Paths::get); + Optional<Path> oToPath = git.getPath(matcher.group(G_TO)); + Optional<Path> oFromPath = git.getPath(matcher.group(G_FROM)); + + if (oToPath.isPresent() && oFromPath.isPresent()) { + file = oToPath.get(); + oldFile = oFromPath; + } else { + LOG.warning(() -> "Failed to parse a file path for status entry '" + matcher.group() + "'."); + continue; + } } else { // This 'should' not be possible... LOG.warning(() -> "Could not find the status codes for the status entry '" + matcher.group() + "'.");