diff options
author | nfnty <git@nfnty.se> | 2016-08-01 01:35:47 +0200 |
---|---|---|
committer | nfnty <git@nfnty.se> | 2016-08-02 01:43:04 +0200 |
commit | 586021c0450593172827d54b766c70f692ef253b (patch) | |
tree | a9bd76d0ea87e3ed0e40e6a2895b8980e2ffaa59 | |
parent | ab6643976a91e2517af224e6c2ab99f631660cd7 (diff) | |
download | ranger-586021c0450593172827d54b766c70f692ef253b.tar.gz |
VCS: git: Fix log output containing control characters, Fixes #641
-rw-r--r-- | ranger/ext/vcs/git.py | 35 |
1 files changed, 18 insertions, 17 deletions
diff --git a/ranger/ext/vcs/git.py b/ranger/ext/vcs/git.py index 8f4d9ff8..0fbd6496 100644 --- a/ranger/ext/vcs/git.py +++ b/ranger/ext/vcs/git.py @@ -4,13 +4,19 @@ """Git module""" from datetime import datetime -import json import os import re +import unicodedata from .vcs import Vcs, VcsError +def string_control_replace(string, replacement): + """Replace all unicode control characters with replacement""" + return ''.join( + (replacement if unicodedata.category(char)[0] == 'C' else char for char in string)) + + class Git(Vcs): """VCS implementation for Git""" _status_translations = ( @@ -40,16 +46,7 @@ class Git(Vcs): def _log(self, refspec=None, maxres=None, filelist=None): """Returns an array of dicts containing revision info for refspec""" - args = [ - '--no-pager', 'log', - '--pretty={' - '%x00short%x00:%x00%h%x00,' - '%x00revid%x00:%x00%H%x00,' - '%x00author%x00:%x00%an <%ae>%x00,' - '%x00date%x00:%ct,' - '%x00summary%x00:%x00%s%x00' - '}' - ] + args = ['--no-pager', 'log', '--pretty=%h%x00%H%x00%an <%ae>%x00%ct%x00%s%x00%x00'] if refspec: args += ['-1', refspec] elif maxres: @@ -58,18 +55,22 @@ class Git(Vcs): args += ['--'] + filelist try: - output = self._run(args).rstrip('\n') + output = self._run(args) except VcsError: return None if not output: return None log = [] - for line in output\ - .replace('\\', '\\\\').replace('"', '\\"').replace('\x00', '"').split('\n'): - line = json.loads(line) - line['date'] = datetime.fromtimestamp(line['date']) - log.append(line) + for line in output.rstrip('\x00\x00\n').split('\x00\x00\n'): + commit_hash_abbrev, commit_hash, author, timestamp, subject = line.split('\x00') + log.append({ + 'short': commit_hash_abbrev, + 'revid': commit_hash, + 'author': string_control_replace(author, ' '), + 'date': datetime.fromtimestamp(int(timestamp)), + 'summary': string_control_replace(subject, ' '), + }) return log def _status_translate(self, code): |