parent
fe680f26dc
commit
f93c8bed23
|
@ -153,6 +153,7 @@ class Application(object):
|
||||||
'method.buffers', 'method.move', 'method.shell',
|
'method.buffers', 'method.move', 'method.shell',
|
||||||
'method.introspect', 'method.help', 'method.numbers',
|
'method.introspect', 'method.help', 'method.numbers',
|
||||||
'method.spell', 'method.hg', 'method.utf8', 'method.tags',
|
'method.spell', 'method.hg', 'method.utf8', 'method.tags',
|
||||||
|
'method.git',
|
||||||
)
|
)
|
||||||
for name in names:
|
for name in names:
|
||||||
exec("import %s" % name)
|
exec("import %s" % name)
|
||||||
|
|
|
@ -0,0 +1,212 @@
|
||||||
|
import os, commands, re, tempfile
|
||||||
|
from subprocess import Popen, PIPE, STDOUT
|
||||||
|
|
||||||
|
import buffer, default, dirutil, lex, regex, util, window
|
||||||
|
from point import Point
|
||||||
|
import buffer.colors
|
||||||
|
from method.vc import VcBlame, VcRevView, VcBase
|
||||||
|
|
||||||
|
from method import Method, Argument, arg
|
||||||
|
|
||||||
|
if os.system('which git >/dev/null 2>/dev/null') == 0:
|
||||||
|
has_git = True
|
||||||
|
else:
|
||||||
|
has_git = False
|
||||||
|
|
||||||
|
class GitException(Exception):
|
||||||
|
pass
|
||||||
|
|
||||||
|
class GitCommit(VcBase):
|
||||||
|
'''commit this file's changes'''
|
||||||
|
args = [Argument("msg", type=type(""), prompt="Commit Message: ")]
|
||||||
|
regex = re.compile(r'^Committed revision ([0-9]+)\.$')
|
||||||
|
def _execute(self, w, **vargs):
|
||||||
|
raise GitException("unimplemented")
|
||||||
|
|
||||||
|
class GitStatus(VcBase):
|
||||||
|
_is_method = True
|
||||||
|
def _execute(self, w, **vargs):
|
||||||
|
path = self._get_path(w)
|
||||||
|
|
||||||
|
cmd = "git status --porcelain %r" % path
|
||||||
|
status, data = commands.getstatusoutput(cmd)
|
||||||
|
status = status >> 8
|
||||||
|
|
||||||
|
if status != 0:
|
||||||
|
raise GitException("Problems with 'git status': %d" % status)
|
||||||
|
|
||||||
|
if not data:
|
||||||
|
w.set_error("%s unchanged" % path)
|
||||||
|
return
|
||||||
|
|
||||||
|
cx = data[0]
|
||||||
|
cy = data[1]
|
||||||
|
if cx == ' ':
|
||||||
|
w.set_error("%s working=%s" % (path, cy))
|
||||||
|
elif cy == ' ':
|
||||||
|
w.set_error("%s index=%s" % (path, cx))
|
||||||
|
else:
|
||||||
|
w.set_error("%s index=%s working=%s" % (path, cx, cy))
|
||||||
|
|
||||||
|
# TODO: handle metadata
|
||||||
|
#w.buffer.metadata['git-filename'] = filename
|
||||||
|
#w.buffer.metadata['git-status'] = status
|
||||||
|
#w.buffer.metadata['git-lrev'] = lrev
|
||||||
|
#w.buffer.metadata['git-rrev'] = rrev
|
||||||
|
#w.buffer.metadata['git-author'] = lauthor
|
||||||
|
#w.buffer.metadata['vc-info'] = '[git:%s/%s]' % (lrev, rrev)
|
||||||
|
|
||||||
|
class GitLog(Method):
|
||||||
|
'''display the Git log for the current file'''
|
||||||
|
_commit_re = re.compile('^(commit) ([0-9a-f]+)$')
|
||||||
|
_log_re = re.compile('^([^ ]+:) (.*)$')
|
||||||
|
def _e(self, s):
|
||||||
|
return s.replace('\\', '\\\\').replace('[', '\\[').replace(']', '\\]')
|
||||||
|
def _em(self, m, i):
|
||||||
|
return self._e(m.group(i))
|
||||||
|
def _execute(self, w, **vargs):
|
||||||
|
cmd = "git log %r" % w.buffer.path
|
||||||
|
status, data = commands.getstatusoutput(cmd)
|
||||||
|
entries = []
|
||||||
|
for line in data.split('\n'):
|
||||||
|
m = self._commit_re.match(line)
|
||||||
|
if m:
|
||||||
|
entries.append('[b:d:*]commit [y:d:*]' + self._em(m, 2) + "\n")
|
||||||
|
continue
|
||||||
|
|
||||||
|
m = self._log_re.match(line)
|
||||||
|
if m:
|
||||||
|
entries.append('[b:d:*]' + self._em(m, 1) + " [c:d:*]" + self._em(m, 2) + "\n")
|
||||||
|
continue
|
||||||
|
|
||||||
|
entries.append(self._e(line) + "\n")
|
||||||
|
data2 = ''.join(entries)
|
||||||
|
|
||||||
|
if status == 0 and data:
|
||||||
|
w.application.color_data_buffer("*Log*", data2, switch_to=True)
|
||||||
|
elif status == 0:
|
||||||
|
w.set_error("%s: There was no data" % self.name)
|
||||||
|
else:
|
||||||
|
w.set_error("%s: There was an error (%s)" % (self.name, status))
|
||||||
|
|
||||||
|
|
||||||
|
class GitDiff(Method):
|
||||||
|
'''diff the current file with the version in Git'''
|
||||||
|
def _execute(self, w, **vargs):
|
||||||
|
if not hasattr(w.buffer, 'path'):
|
||||||
|
w.set_error("Buffer has no corresponding file")
|
||||||
|
return
|
||||||
|
|
||||||
|
cmd = "git diff %r" % w.buffer.path
|
||||||
|
status, data = commands.getstatusoutput(cmd)
|
||||||
|
|
||||||
|
if status == 0:
|
||||||
|
if data:
|
||||||
|
w.application.data_buffer("*Diff*", data, switch_to=True, modename='diff')
|
||||||
|
w.set_error("Differences were found")
|
||||||
|
else:
|
||||||
|
w.set_error("No difference found")
|
||||||
|
else:
|
||||||
|
w.set_error("There was an error (%s)" % (status))
|
||||||
|
|
||||||
|
#class GitDiff2(Method):
|
||||||
|
# '''diff the current file with the version in SVN'''
|
||||||
|
# rev_regex = re.compile('^[0-9]+$')
|
||||||
|
# args = [Argument("revision", type=type(""), prompt="Old Revision: ")]
|
||||||
|
# def _execute(self, w, **vargs):
|
||||||
|
# if not hasattr(w.buffer, 'path'):
|
||||||
|
# w.set_error("Buffer has no corresponding file")
|
||||||
|
# return
|
||||||
|
#
|
||||||
|
# rev = vargs['revision']
|
||||||
|
# if not self.rev_regex.match(rev):
|
||||||
|
# w.set_error("Could not parse revision: %r" % rev)
|
||||||
|
# return
|
||||||
|
#
|
||||||
|
# cwd = os.getcwd() + os.path.sep
|
||||||
|
# path = w.buffer.path
|
||||||
|
# if path.startswith(cwd):
|
||||||
|
# path = path[len(cwd):]
|
||||||
|
#
|
||||||
|
# cmd = "git diff -r %s %r" % (rev, path)
|
||||||
|
# (status, data) = commands.getstatusoutput(cmd)
|
||||||
|
# status = status >> 8
|
||||||
|
#
|
||||||
|
# if data:
|
||||||
|
# w.application.data_buffer("*Diff*", data, switch_to=True, modename='diff')
|
||||||
|
# w.set_error("Differences were found")
|
||||||
|
# else:
|
||||||
|
# w.set_error("No difference found")
|
||||||
|
#class GitDiff3(Method):
|
||||||
|
# '''diff the current file with the version in SVN'''
|
||||||
|
# rev_regex = re.compile('^[0-9]+$')
|
||||||
|
# args = [Argument("revision1", type=type(""), prompt="Old Revision: "),
|
||||||
|
# Argument("revision2", type=type(""), prompt="New Revision: ")]
|
||||||
|
# def _execute(self, w, **vargs):
|
||||||
|
# if not hasattr(w.buffer, 'path'):
|
||||||
|
# w.set_error("Buffer has no corresponding file")
|
||||||
|
# return
|
||||||
|
#
|
||||||
|
# rev1 = vargs['revision1']
|
||||||
|
# if not self.rev_regex.match(rev1):
|
||||||
|
# w.set_error("Could not parse revision1: %r" % rev)
|
||||||
|
# return
|
||||||
|
#
|
||||||
|
# rev2 = vargs['revision2']
|
||||||
|
# if not self.rev_regex.match(rev2):
|
||||||
|
# w.set_error("Could not parse revision2: %r" % rev)
|
||||||
|
# return
|
||||||
|
#
|
||||||
|
# cwd = os.getcwd() + os.path.sep
|
||||||
|
# path = w.buffer.path
|
||||||
|
# if path.startswith(cwd):
|
||||||
|
# path = path[len(cwd):]
|
||||||
|
#
|
||||||
|
# cmd = "git diff -r %s:%s %r" % (rev1, rev2, path)
|
||||||
|
# (status, data) = commands.getstatusoutput(cmd)
|
||||||
|
# status = status >> 8
|
||||||
|
#
|
||||||
|
# if data:
|
||||||
|
# w.application.data_buffer("*Diff*", data, switch_to=True, modename='diff')
|
||||||
|
# w.set_error("Differences were found")
|
||||||
|
# else:
|
||||||
|
# w.set_error("No difference found")
|
||||||
|
|
||||||
|
class GitBlame(VcBlame):
|
||||||
|
'''show blame output for the current version in SVN'''
|
||||||
|
# rev, user, date, [time], [timezone], [date-str], content
|
||||||
|
num_fields = 3
|
||||||
|
line_re = re.compile(r'^([0-9a-f]+) \(([a-zA-Z0-9_]+|Not Committed Yet) +([-0-9]+) [:0-9]+ +[-\+]\d{4} +\d+\) (.*)\n$')
|
||||||
|
prefix_fmt = '[g:d:*]%*s [c:d:*]%-*s [b:d:*]%*s[d:d:*]'
|
||||||
|
pretest_err_msg = 'Git is not installed'
|
||||||
|
_is_method = True
|
||||||
|
def _filter(self, line):
|
||||||
|
m = self.line_re.match(line)
|
||||||
|
if not m:
|
||||||
|
raise VcException("couldn't parse %r" % line)
|
||||||
|
groups = m.groups()
|
||||||
|
fields = list(groups[:-1])
|
||||||
|
if fields[1] == 'Not Committed Yet':
|
||||||
|
fields[1] = ''
|
||||||
|
return {'fields': fields, 'content': groups[-1], 'tokens': []}
|
||||||
|
def _pretest(self):
|
||||||
|
return has_git
|
||||||
|
def _open_pipe(self, w, **vargs):
|
||||||
|
cmd = ("git", 'blame', w.buffer.path)
|
||||||
|
return Popen(cmd, stdin=PIPE, stdout=PIPE, stderr=PIPE)
|
||||||
|
|
||||||
|
#class GitBlame2(GitBlame):
|
||||||
|
# '''show file contents in SVN at revision'''
|
||||||
|
# args = [arg("revision", t=type(""), p="Revision: ", h="revision number")]
|
||||||
|
# def _open_pipe(self, w, **vargs):
|
||||||
|
# cmd = ("git", 'blame', '-v', '-r', vargs['revision'], w.buffer.path)
|
||||||
|
# return Popen(cmd, stdin=PIPE, stdout=PIPE, stderr=PIPE)
|
||||||
|
#
|
||||||
|
#class GitRevView(VcRevView):
|
||||||
|
# '''show file contents in SVN at date'''
|
||||||
|
# args = [arg("revision", t=type(""), p="Revision: ", h="revision number")]
|
||||||
|
# namebase = 'SVN'
|
||||||
|
# _is_method = True
|
||||||
|
# def _get_cmd(self, w, **vargs):
|
||||||
|
# path = self._get_path(w, **vargs)
|
||||||
|
# return ("git", 'cat', '-r', vargs['revision'], path)
|
12
method/vc.py
12
method/vc.py
|
@ -6,6 +6,17 @@ import lex
|
||||||
|
|
||||||
class VcException(Exception): pass
|
class VcException(Exception): pass
|
||||||
|
|
||||||
|
class VcBase(Method):
|
||||||
|
_is_method = False
|
||||||
|
def _get_path(self, w):
|
||||||
|
if not hasattr(w.buffer, 'path'):
|
||||||
|
raise VcException("buffer has no path")
|
||||||
|
cwd = os.getcwd() + os.path.sep
|
||||||
|
path = w.buffer.path
|
||||||
|
if path.startswith(cwd):
|
||||||
|
path = path[len(cwd):]
|
||||||
|
return path
|
||||||
|
|
||||||
class VcBlame(Method):
|
class VcBlame(Method):
|
||||||
_is_method = False
|
_is_method = False
|
||||||
line_re = None
|
line_re = None
|
||||||
|
@ -66,6 +77,7 @@ class VcBlame(Method):
|
||||||
groups, gsizes = self._build_groups(w, **vargs)
|
groups, gsizes = self._build_groups(w, **vargs)
|
||||||
except Exception, e:
|
except Exception, e:
|
||||||
w.set_error(str(e))
|
w.set_error(str(e))
|
||||||
|
return
|
||||||
|
|
||||||
data = ''.join(self._build_lines(groups, gsizes, w, **vargs))
|
data = ''.join(self._build_lines(groups, gsizes, w, **vargs))
|
||||||
w.application.color_data_buffer("*Blame*", data, switch_to=True)
|
w.application.color_data_buffer("*Blame*", data, switch_to=True)
|
||||||
|
|
Loading…
Reference in New Issue