summaryrefslogtreecommitdiff
path: root/morphlib/gitdir.py
diff options
context:
space:
mode:
authorRichard Maw <richard.maw@codethink.co.uk>2013-09-17 13:22:09 +0000
committerRichard Maw <richard.maw@codethink.co.uk>2013-09-17 14:34:17 +0000
commit3f5e504b947f5866e7922bf01347ef2c9ff5e7b6 (patch)
treec3c8e2f11f1ad8753fad1e5034ba781bffc96d38 /morphlib/gitdir.py
parent31b0ed683dfe0d99bc82accc05ad329fe527d68f (diff)
downloadmorph-3f5e504b947f5866e7922bf01347ef2c9ff5e7b6.tar.gz
gitdir: Add method for getting uncommitted changes
get_uncommitted_changes() is needed for morph status to tell if git repositories have changes in them. _get_status() is private, since it does not currently have a user, the small amount of code in get_uncommitted_changes() wrapping _get_status() is in the GitDirectory class instead of the branch and merge plugin, since `morph build` will also need to know about uncommitted changes.
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.'''