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 d2730b5a941251057f99378916e88db467c4cc05..7ff96537728f710bc5f84fc5aa8f475ece5c2a1a 100644
--- a/src/de/uni_passau/fim/seibt/gitwrapper/repo/Status.java
+++ b/src/de/uni_passau/fim/seibt/gitwrapper/repo/Status.java
@@ -9,6 +9,12 @@ import java.util.Optional;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
+import static de.uni_passau.fim.seibt.gitwrapper.repo.Status.StatusCode.ADDED;
+import static de.uni_passau.fim.seibt.gitwrapper.repo.Status.StatusCode.DELETED;
+import static de.uni_passau.fim.seibt.gitwrapper.repo.Status.StatusCode.IGNORED;
+import static de.uni_passau.fim.seibt.gitwrapper.repo.Status.StatusCode.UNMERGED;
+import static de.uni_passau.fim.seibt.gitwrapper.repo.Status.StatusCode.UNTRACKED;
+
 /**
  * The status of a {@link Repository}.
  *
@@ -16,7 +22,105 @@ import java.util.regex.Pattern;
  */
 public class Status {
 
-    private static final Pattern STATUS_ENTRY = Pattern.compile("(.?.) (?:.*? )?(.*?)\0");
+    private static final Pattern STATUS_ENTRY = Pattern.compile("(..) ([^\0]*)\0(?:([^\0 ]*)\0)?");
+
+    /**
+     * Two {@link StatusCode StatusCodes} are used to represent the status of a file in a git {@link Repository}.
+     *
+     * @see <a href=https://git-scm.com/docs/git-status>The Documentation of 'git status'</a>
+     */
+    public enum StatusCode {
+        UNMODIFIED,
+        MODIFIED,
+        ADDED,
+        DELETED,
+        RENAMED,
+        COPIED,
+
+        /**
+         * Updated but unmerged.
+         */
+        UNMERGED,
+        UNTRACKED,
+        IGNORED;
+
+        /**
+         * Returns the enum constant representing the given status code character. Must be one of ' ', 'M', 'A', 'D',
+         * 'R', 'C', 'U', '?', '!'.
+         *
+         * @param c
+         *         the status character
+         * @return the corresponding enum constant
+         * @throws IllegalArgumentException
+         *         if there is no enum constant for the given character
+         * @see <a href=https://git-scm.com/docs/git-status>The Documentation of 'git status'</a>
+         */
+        private static StatusCode forChar(char c) {
+
+            switch (c) {
+                case ' ':
+                    return UNMODIFIED;
+                case 'M':
+                    return MODIFIED;
+                case 'A':
+                    return ADDED;
+                case 'D':
+                    return DELETED;
+                case 'R':
+                    return RENAMED;
+                case 'C':
+                    return COPIED;
+                case 'U':
+                    return UNMERGED;
+                case '?':
+                    return UNTRACKED;
+                case '!':
+                    return IGNORED;
+                default:
+                    throw new IllegalArgumentException("No enum constant for status code '" + c + "'.");
+            }
+        }
+    }
+
+    /**
+     * Represents the status of a file in a git {@link Repository}. For files with merge conflicts, {@link #x} and
+     * {@link #y} show the modification states of each side of the merge. For files that do not have merge conflicts,
+     * {@link #x} shows the status of the index, and {@link #y} shows the status of the work tree.
+     */
+    public static class FileStatus {
+
+        /**
+         * The first status code.
+         */
+        public final StatusCode x;
+
+        /**
+         * The second status code.
+         */
+        public final StatusCode y;
+
+        /**
+         * In case of renamings this path represents the filename before the renaming.
+         */
+        public final Optional<Path> oldFile;
+
+        /**
+         * The file whose status is represented by this {@link FileStatus} instance.
+         */
+        public final Path file;
+
+        private FileStatus(StatusCode x, StatusCode y, Optional<Path> oldFile, Path file) {
+
+            if ((x == UNTRACKED ^ y == UNTRACKED) || (x == IGNORED ^ y == IGNORED)) {
+                throw new IllegalArgumentException("If one of the two status codes is UNTRACKED or IGNORED, the other must be the same.");
+            }
+
+            this.x = x;
+            this.y = y;
+            this.oldFile = oldFile;
+            this.file = file;
+        }
+    }
 
     /**
      * The commit, this {@link Status} is based on.
@@ -26,12 +130,12 @@ public class Status {
     /**
      * A map of files which were changed since the last {@link #commit} and their status codes.
      */
-    public final Map<Path, String> changed;
+    public final Map<Path, FileStatus> changed;
 
     /**
      * A map of files which are in an unmerged state and their status codes.
      */
-    public final Map<Path, String> unmerged;
+    public final Map<Path, FileStatus> unmerged;
 
     /**
      * Constructs a new {@link Status}.
@@ -43,7 +147,7 @@ public class Status {
      * @param unmerged
      *         a map of unmerged files an their status code.
      */
-    private Status(Commit commit, Map<Path, String> changed, Map<Path, String> unmerged) {
+    private Status(Commit commit, Map<Path, FileStatus> changed, Map<Path, FileStatus> unmerged) {
         this.commit = commit;
         this.changed = Collections.unmodifiableMap(changed);
         this.unmerged = Collections.unmodifiableMap(unmerged);
@@ -98,17 +202,25 @@ public class Status {
      * @return optionally a {@link Status} object, representing the status read from the git output
      */
     static Optional<Status> parseStatus(Repository repo, String gitOutput) {
-        Map<Path, String> changed = new HashMap<>();
-        Map<Path, String> unmerged = new HashMap<>();
+        Map<Path, FileStatus> changed = new HashMap<>();
+        Map<Path, FileStatus> unmerged = new HashMap<>();
+
         Matcher matcher = STATUS_ENTRY.matcher(gitOutput);
+
         while (matcher.find()) {
-            // used new path, if file was moved
-            Path file = Paths.get(matcher.group(2));
             String code = matcher.group(1).toUpperCase();
-            if (code.contains("U")) {
-                unmerged.put(file, code);
+            StatusCode x = StatusCode.forChar(code.charAt(0));
+            StatusCode y = StatusCode.forChar(code.charAt(1));
+
+            Path file = Paths.get(matcher.group(2));
+            Optional<Path> oldFile = Optional.ofNullable(matcher.group(3)).map(Paths::get);
+
+            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, code);
+                changed.put(file, status);
             }
         }