summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorLuis R. Rodriguez <mcgrof@do-not-panic.com>2013-10-21 11:08:26 +0200
committerHauke Mehrtens <hauke@hauke-m.de>2013-10-21 21:50:38 +0200
commit276bf778df6e33f66391e4cea9cbceb888db6f9d (patch)
tree8eeb6745f48aad525d67dbbf086d186c11a59eb1 /lib
parentea70308d746325654d44851be602fe02492b59f9 (diff)
lib/bpgit.py: add git status support
We use --porcelain given that this spits out the results in an easy-to-parse format for scripts and will remain stable across git versions and regardless of user configuration. We will use this later. Signed-off-by: Luis R. Rodriguez <mcgrof@do-not-panic.com>
Diffstat (limited to 'lib')
-rw-r--r--lib/bpgit.py54
1 files changed, 54 insertions, 0 deletions
diff --git a/lib/bpgit.py b/lib/bpgit.py
index 9a3f430b..d2fb9862 100644
--- a/lib/bpgit.py
+++ b/lib/bpgit.py
@@ -27,6 +27,60 @@ def rev_parse(rev='HEAD', tree=None):
raise SHAError()
return sha
+def status(tree=None):
+ '''
+ For interpretation of the porcelain output refer to
+ the git status(1) man page. In summary the first column is the
+ index state, the second represents the working tree state and
+ the third column are files in cases of renames. This gives back
+ None in case no changes are present, otherwise it returns a list
+ of dict entries with key values: index, work_tree, and files. The
+ files are a list of all files found on that entry, in case of a rename
+ this would consist of a list of 2 files.
+
+ As an example if you had this on your git status:
+
+ R udev/foo.sh -> poo/foo.sh
+ D scripts/bar.sh
+ ?? .poo.py.swp
+
+ This would be transposed into the following dict:
+
+ results = status(tree=your_git_tree_path)
+ if not results:
+ return 0
+ for entry in results:
+ print entry
+
+ {'files': [' udev/foo.sh', 'poo/foo.sh'], 'index': 'R', 'work_tree': ' '}
+ {'files': [' scripts/bar.sh'], 'index': 'D', 'work_tree': ' '}
+ {'files': [' .poo.py.swp'], 'index': '?', 'work_tree': '?'}
+ '''
+ def split_status(entry):
+ if len(entry) == 0:
+ return None
+ if len(entry) == 1:
+ return dict(index=entry[0], work_tree=None, files=None)
+ if len(entry) == 2:
+ return dict(index=entry[0], work_tree=entry[1], files=None)
+ else:
+ return dict(index=entry[0], work_tree=entry[1],
+ files=entry[2:].split(' -> '))
+
+ cmd = ['git', 'status', '--porcelain']
+
+ process = subprocess.Popen(cmd,
+ stdout=subprocess.PIPE, stderr=subprocess.STDOUT, close_fds=True,
+ universal_newlines=True, cwd=tree)
+ stdout = process.communicate()[0]
+ process.wait()
+ _check(process)
+
+ list_status = stdout.split('\n')
+ if (len(list_status) == 1 and list_status[0] == ''):
+ return None
+ return [split_status(entry) for entry in list_status]
+
def describe(rev='HEAD', tree=None, extra_args=[]):
cmd = ['git', 'describe', '--always']