Skip to content
Snippets Groups Projects
Commit 8d497e86 authored by Georg Seibt's avatar Georg Seibt :nerd:
Browse files

parse status correctly

parent 082cc0d3
No related branches found
No related tags found
No related merge requests found
......@@ -2,10 +2,13 @@ package de.uni_passau.fim.seibt.gitwrapper.repo;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.logging.Logger;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
......@@ -22,7 +25,17 @@ import static de.uni_passau.fim.seibt.gitwrapper.repo.Status.StatusCode.UNTRACKE
*/
public class Status {
private static final Pattern STATUS_ENTRY = Pattern.compile("(..) ([^\0]*)\0(?:([^\0 ]*)\0)?");
private static final Logger LOG = Logger.getLogger(Status.class.getCanonicalName());
private static final String G_RCODE = "rcode";
private static final String G_TO = "to";
private static final String G_FROM = "from";
private static final String G_CODE = "code";
private static final String G_PATH = "path";
private static final String regex = String.format("(?:(?<%s>R[ MD]) (?<%s>[^\0]*)\0(?<%s>[^\0]*)\0|(?<%s>[ MADRCU]{2}|\\?\\?|!!) (?<%s>[^\0]*)\0)",
G_RCODE, G_TO, G_FROM, G_CODE, G_PATH);
private static final Pattern STATUS_ENTRY = Pattern.compile(regex);
/**
* Two {@link StatusCode StatusCodes} are used to represent the status of a file in a git {@link Repository}.
......@@ -137,20 +150,36 @@ public class Status {
*/
public final Map<Path, FileStatus> unmerged;
/**
* The list of untracked files.
*/
public final List<Path> untracked;
/**
* The list of ignored files.
*/
public final List<Path> ignored;
/**
* Constructs a new {@link Status}.
*
* @param commit
* the current HEAD {@link Commit} at the time this {@link Status} is constructed
* @param changed
* a map of changed files and heir status codes
* the map of changed files and heir status codes
* @param unmerged
* a map of unmerged files an their status code.
* the map of unmerged files an their status code
* @param untracked
* the list of untracked files
* @param ignored
* the list of ignored files
*/
private Status(Commit commit, Map<Path, FileStatus> changed, Map<Path, FileStatus> unmerged) {
private Status(Commit commit, Map<Path, FileStatus> changed, Map<Path, FileStatus> unmerged, List<Path> untracked, List<Path> ignored) {
this.commit = commit;
this.changed = Collections.unmodifiableMap(changed);
this.unmerged = Collections.unmodifiableMap(unmerged);
this.changed = changed.isEmpty() ? Collections.emptyMap() : Collections.unmodifiableMap(changed);
this.unmerged = unmerged.isEmpty() ? Collections.emptyMap() : Collections.unmodifiableMap(unmerged);
this.untracked = untracked.isEmpty() ? Collections.emptyList() : Collections.unmodifiableList(untracked);
this.ignored = ignored.isEmpty() ? Collections.emptyList() : Collections.unmodifiableList(ignored);
}
/**
......@@ -204,26 +233,49 @@ public class Status {
static Optional<Status> parseStatus(Repository repo, String gitOutput) {
Map<Path, FileStatus> changed = new HashMap<>();
Map<Path, FileStatus> unmerged = new HashMap<>();
List<Path> untracked = new ArrayList<>();
List<Path> ignored = new ArrayList<>();
Matcher matcher = STATUS_ENTRY.matcher(gitOutput);
while (matcher.find()) {
String code = matcher.group(1).toUpperCase();
StatusCode x = StatusCode.forChar(code.charAt(0));
StatusCode y = StatusCode.forChar(code.charAt(1));
String code;
StatusCode x;
StatusCode y;
Path file = Paths.get(matcher.group(2));
Optional<Path> oldFile = Optional.ofNullable(matcher.group(3)).map(Paths::get);
Path file;
Optional<Path> oldFile;
FileStatus status = new FileStatus(x, y, oldFile, file);
if ((code = matcher.group(G_CODE)) != null) {
file = Paths.get(matcher.group(G_PATH));
oldFile = Optional.empty();
} 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);
} else {
// This 'should' not be possible...
LOG.warning(() -> "Could not find the status codes for the status entry '" + matcher.group() + "'.");
continue;
}
if (x == UNMERGED || y == UNMERGED || (x == ADDED && y == ADDED) || (x == DELETED && y == DELETED)) {
unmerged.put(file, status);
x = StatusCode.forChar(code.charAt(0));
y = StatusCode.forChar(code.charAt(1));
if (x == UNTRACKED && y == UNTRACKED) {
untracked.add(file);
} else if (x == IGNORED && y == IGNORED) {
ignored.add(file);
} else {
changed.put(file, status);
FileStatus status = new FileStatus(x, y, oldFile, file);
if (x == UNMERGED || y == UNMERGED || (x == ADDED && y == ADDED) || (x == DELETED && y == DELETED)) {
unmerged.put(file, status);
} else {
changed.put(file, status);
}
}
}
return repo.getCurrentHEAD().map(head -> new Status(head, changed, unmerged));
return repo.getCurrentHEAD().map(head -> new Status(head, changed, unmerged, untracked, ignored));
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment