summaryrefslogtreecommitdiff
path: root/morphlib/gitdir.py
diff options
context:
space:
mode:
Diffstat (limited to 'morphlib/gitdir.py')
-rw-r--r--morphlib/gitdir.py32
1 files changed, 32 insertions, 0 deletions
diff --git a/morphlib/gitdir.py b/morphlib/gitdir.py
index c075f456..7ee64f36 100644
--- a/morphlib/gitdir.py
+++ b/morphlib/gitdir.py
@@ -16,6 +16,7 @@
# =*= License: GPL-2 =*=
+import collections
import cliapp
import glob
import os
@@ -200,6 +201,37 @@ class GitDirectory(object):
output = self._runcmd(['git', 'rev-parse', '--abbrev-ref', 'HEAD'])
return output.strip()
+ def _get_status(self):
+ '''Runs git status and formats its output into something more useful.
+
+ This runs git status such that unusual filenames are preserved
+ and returns its output in a sequence of (status_code, to_path,
+ from_path).
+
+ from_path is None unless the status_code says there was a rename,
+ in which case it is the path it was renamed from.
+
+ Untracked and ignored changes are also included in the output,
+ their status codes are '??' and '!!' respectively.
+
+ '''
+ status = self._runcmd(['git', 'status', '-z', '--ignored'])
+ tokens = collections.deque(status.split('\0'))
+ while True:
+ tok = tokens.popleft()
+ # Terminates with an empty token, since status ends with a \0
+ if not tok:
+ return
+
+ code = tok[:2]
+ to_path = tok[3:]
+ yield code, to_path, tokens.popleft() if code[0] == 'R' else None
+
+ def get_uncommitted_changes(self):
+ for code, to_path, from_path in self._get_status():
+ if code not in ('??', '!!'):
+ yield code, to_path, from_path
+
def init(dirname):
'''Initialise a new git repository.'''