Skip to content

Commit 4eb4304

Browse files
committed
Merge branch 'master' into patch-1
2 parents 4c5d6ac + dadeb95 commit 4eb4304

File tree

3 files changed

+63
-52
lines changed

3 files changed

+63
-52
lines changed

.github/ISSUE_TEMPLATE.md

Lines changed: 0 additions & 2 deletions
This file was deleted.

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ Small plugin to parse git blame and add a view to show the user and datetime of
1010

1111
View on [packagecontrol.io](https://packagecontrol.io/packages/Git%20blame)
1212

13+
This package was originally created by [@psykzz](https://github.com/psykzz) and is now maintained by [@frou](https://github.com/frou)
14+
1315

1416
## Usage
1517

git-blame.py

Lines changed: 61 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
import re
55
import functools
66
import subprocess
7-
from subprocess import check_output as shell
87

98
PHANTOM_KEY_ALL = 'git-blame-all'
109
SETTING_PHANTOM_ALL_DISPLAYED = 'git-blame-all-displayed'
@@ -115,20 +114,15 @@ def __init__(self, view):
115114

116115
@functools.lru_cache(128, False)
117116
def get_blame(self, line, path):
118-
try:
119-
return shell(
120-
["git", "blame", "--minimal", "-w", "-L {0},{0}".format(line), os.path.basename(path)],
121-
cwd=os.path.dirname(os.path.realpath(path)),
122-
startupinfo=si,
123-
stderr=subprocess.STDOUT
124-
)
125-
except subprocess.CalledProcessError as e:
126-
print("Git blame: git error {}:\n{}".format(e.returncode, e.output.decode("UTF-8")))
127-
except Exception as e:
128-
print("Git blame: Unexpected error:", e)
117+
return subprocess.check_output(
118+
["git", "blame", "--minimal", "-w", "-L {0},{0}".format(line), os.path.basename(path)],
119+
cwd=os.path.dirname(os.path.realpath(path)),
120+
startupinfo=si,
121+
stderr=subprocess.STDOUT
122+
).decode("utf-8")
129123

130124
def parse_blame(self, blame):
131-
sha, file_path, user, date, time, tz_offset, *_ = blame.decode('utf-8').split()
125+
sha, file_path, user, date, time, tz_offset, *_ = blame.split()
132126

133127
# Was part of the inital commit so no updates
134128
if file_path[0] == '(':
@@ -145,14 +139,12 @@ def parse_blame(self, blame):
145139
return(sha, user[1:], date, time)
146140

147141
def get_commit(self, sha, path):
148-
try:
149-
return shell(
150-
["git", "show", sha],
151-
cwd=os.path.dirname(os.path.realpath(path)),
152-
startupinfo=si
153-
)
154-
except Exception as e:
155-
return
142+
return subprocess.check_output(
143+
["git", "show", sha],
144+
cwd=os.path.dirname(os.path.realpath(path)),
145+
startupinfo=si,
146+
stderr=subprocess.STDOUT
147+
).decode('utf-8')
156148

157149
def on_phantom_close(self, href):
158150
href_parts = href.split('-')
@@ -170,7 +162,12 @@ def on_phantom_close(self, href):
170162
sublime.set_clipboard(sha)
171163
sublime.status_message('Git SHA copied to clipboard')
172164
elif intent == "show":
173-
desc = self.get_commit(sha, self.view.file_name()).decode('utf-8')
165+
try:
166+
desc = self.get_commit(sha, self.view.file_name())
167+
except Exception as e:
168+
communicate_error(e)
169+
return
170+
174171
buf = self.view.window().new_file()
175172
buf.run_command('insert_commit_description', {'desc': desc, 'scratch_view_name': 'commit ' + sha})
176173
else:
@@ -179,8 +176,7 @@ def on_phantom_close(self, href):
179176
self.view.erase_phantoms('git-blame')
180177

181178
def run(self, edit):
182-
if self.view.is_dirty():
183-
sublime.status_message("The file needs to be saved for git blame.")
179+
if not view_is_suitable(self.view):
184180
return
185181

186182
phantoms = []
@@ -196,12 +192,14 @@ def run(self, edit):
196192
line = self.view.line(region)
197193
(row, col) = self.view.rowcol(region.begin())
198194
full_path = self.view.file_name()
199-
result = self.get_blame(int(row) + 1, full_path)
200-
if not result:
201-
# Unable to get blame
195+
196+
try:
197+
blame_output = self.get_blame(int(row) + 1, full_path)
198+
except Exception as e:
199+
communicate_error(e)
202200
return
203201

204-
sha, user, date, time = self.parse_blame(result)
202+
sha, user, date, time = self.parse_blame(blame_output)
205203

206204
body = template_one.format(sha=sha, user=user, date=date, time=time, stylesheet=stylesheet_one)
207205

@@ -221,8 +219,7 @@ def __init__(self, view):
221219
self.pattern = None
222220

223221
def run(self, edit):
224-
if self.view.is_dirty():
225-
sublime.status_message("The file needs to be saved for git blame.")
222+
if not view_is_suitable(self.view):
226223
return
227224

228225
self.view.erase_phantoms(PHANTOM_KEY_ALL)
@@ -234,12 +231,13 @@ def run(self, edit):
234231
self.view.settings().set(SETTING_PHANTOM_ALL_DISPLAYED, False)
235232
return
236233

237-
blame_lines = self.get_blame_lines(self.view.file_name())
238-
239-
if not blame_lines:
234+
try:
235+
blame_output = self.get_blame(self.view.file_name())
236+
except Exception as e:
237+
communicate_error(e)
240238
return
241239

242-
for l in blame_lines:
240+
for l in blame_output.splitlines():
243241
parsed = self.parse_blame(l)
244242
if not parsed:
245243
continue
@@ -264,23 +262,14 @@ def run(self, edit):
264262
# Bring the phantoms into view without the user needing to manually scroll left.
265263
self.view.set_viewport_position((0.0, self.view.viewport_position()[1]))
266264

267-
def get_blame_lines(self, path):
268-
'''Run `git blame` and get the output lines.
269-
'''
270-
try:
265+
def get_blame(self, path):
266+
return subprocess.check_output(
271267
# The option --show-name is necessary to force file name display.
272-
command = ["git", "blame", "--show-name", "--minimal", "-w", os.path.basename(path)]
273-
output = shell(
274-
command,
275-
cwd=os.path.dirname(os.path.realpath(path)),
276-
startupinfo=si,
277-
stderr=subprocess.STDOUT
278-
)
279-
return output.decode("UTF-8").splitlines()
280-
except subprocess.CalledProcessError as e:
281-
print("Git blame: git error {}:\n{}".format(e.returncode, e.output.decode("UTF-8")))
282-
except Exception as e:
283-
print("Git blame: Unexpected error:", e)
268+
["git", "blame", "--show-name", "--minimal", "-w", os.path.basename(path)],
269+
cwd=os.path.dirname(os.path.realpath(path)),
270+
startupinfo=si,
271+
stderr=subprocess.STDOUT
272+
).decode("utf-8")
284273

285274
def parse_blame(self, blame):
286275
'''Parses git blame output.
@@ -372,3 +361,25 @@ def run(self, edit, desc, scratch_view_name):
372361
view.set_syntax_file('Packages/Diff/Diff.sublime-syntax')
373362
view.insert(edit, 0, desc)
374363
view.set_name(scratch_view_name)
364+
365+
366+
def view_is_suitable(view):
367+
ok = view.file_name() and not view.is_dirty()
368+
if not ok:
369+
communicate_error("Please save file changes to disk first.")
370+
return ok
371+
372+
373+
def communicate_error(e, modal=True):
374+
user_msg = "st3-gitblame:\n\n{}".format(e)
375+
if isinstance(e, subprocess.CalledProcessError):
376+
user_msg += "\n\n{}".format(e.output.decode("utf-8"))
377+
378+
print()
379+
if modal:
380+
sublime.error_message(user_msg)
381+
else:
382+
sublime.status_message(user_msg)
383+
# Unlike with the error dialog, a status message is not automatically
384+
# persisted in the console too.
385+
print(user_msg)

0 commit comments

Comments
 (0)