diff --git a/common/vendor/__init__.py b/common/vendor/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/core/commands/blame.py b/core/commands/blame.py index d067bcd48..f2a05f5af 100644 --- a/core/commands/blame.py +++ b/core/commands/blame.py @@ -7,13 +7,13 @@ from ..git_command import GitCommand from ...common import util -from ..ui_mixins.quick_panel import PanelActionMixin +from ..ui_mixins.quick_panel import PanelActionMixin, show_log_panel BlamedLine = namedtuple("BlamedLine", ("contents", "commit_hash", "orig_lineno", "final_lineno")) NOT_COMMITED_HASH = "0000000000000000000000000000000000000000" -BLAME_TITLE = "BLAME: {}" +BLAME_TITLE = "BLAME: {}{}" class GsBlameCommand(PanelActionMixin, WindowCommand, GitCommand): @@ -27,36 +27,60 @@ class GsBlameCommand(PanelActionMixin, WindowCommand, GitCommand): ] @util.view.single_cursor_coords - def run(self, coords, file_path=None, repo_path=None): - self._coords = coords - self.__file_path = file_path or self.file_path + def run(self, coords, file_path=None, repo_path=None, commit_hash=None): + self.coords = coords + self._file_path = file_path or self.file_path self.__repo_path = repo_path or self.repo_path + self._commit_hash = commit_hash super().run() + def update_actions(self): + super().update_actions() + if self._commit_hash is None: + self.actions.insert(6, + ["pick_commit", "Pick a commit"]) + def blame(self, ignore_whitespace=True, option=None): view = self.window.new_file() view.set_syntax_file("Packages/GitSavvy/syntax/blame.sublime-syntax") view.settings().set("git_savvy.blame_view", True) view.settings().set("git_savvy.repo_path", self.__repo_path) - view.settings().set("git_savvy.file_path", self.__file_path) + view.settings().set("git_savvy.file_path", self._file_path) + view.settings().set("git_savvy.commit_hash", self._commit_hash) view.settings().set("word_wrap", False) view.settings().set("line_numbers", False) view.settings().set('indent_guide_options', []) - view.set_name(BLAME_TITLE.format(self.get_rel_path(self.__file_path))) + view.set_name( + BLAME_TITLE.format( + self.get_rel_path(self._file_path), + " at {}".format(self._commit_hash) if self._commit_hash else "" + ) + ) view.set_scratch(True) view.run_command("gs_blame_initialize_view", { - "coords": self._coords, + "coords": self.coords, "ignore_whitespace": '-w' if ignore_whitespace else None, - "detect_move_or_copy": option + "detect_move_or_copy": option, + "commit_hash": self._commit_hash }) + def pick_commit(self): + self._branch = None + show_log_panel(self.commit_generator(), self.picked_commit) + + def picked_commit(self, commit_hash): + self._commit_hash = commit_hash + super().run() + + class GsBlameInitializeViewCommand(TextCommand, GitCommand): - def run(self, edit, coords=None, ignore_whitespace=None, detect_move_or_copy=None): + def run(self, edit, coords=None, ignore_whitespace=None, detect_move_or_copy=None, commit_hash=None): content = self.get_content( ignore_whitespace=ignore_whitespace, - detect_move_or_copy=detect_move_or_copy + detect_move_or_copy=detect_move_or_copy, + commit_hash=commit_hash ) self.view.sel().clear() self.view.set_read_only(False) @@ -66,9 +90,9 @@ def run(self, edit, coords=None, ignore_whitespace=None, detect_move_or_copy=Non if coords is not None: self.scroll_to(coords) - def get_content(self, ignore_whitespace=None, detect_move_or_copy=None): + def get_content(self, ignore_whitespace=None, detect_move_or_copy=None, commit_hash=None): blame_porcelain = self.git( - "blame", "-p", ignore_whitespace, detect_move_or_copy, self.file_path + "blame", "-p", ignore_whitespace, detect_move_or_copy, commit_hash, self.file_path ) blame_porcelain = unicodedata.normalize('NFC', blame_porcelain) blamed_lines, commits = self.parse_blame(blame_porcelain.splitlines()) diff --git a/core/commands/log.py b/core/commands/log.py index 31594a67c..0eb791c83 100644 --- a/core/commands/log.py +++ b/core/commands/log.py @@ -20,28 +20,14 @@ class LogMixin(object): but the subclass must also inherit fro GitCommand (for the `git()` method) """ - _limit = 6000 - def run(self, *args, file_path=None, branch=None): self._file_path = file_path self._branch = branch sublime.set_timeout_async(self.run_async) def run_async(self): - show_log_panel(self.log_generator(), self.do_action, self._limit) - - def log_generator(self): - skip = 0 - while True: - logs = self.log(branch=self._branch, - file_path=self._file_path, - limit=self._limit, - skip=skip) - if not logs: - break - for l in logs: - yield l - skip = skip + self._limit + show_log_panel(self.commit_generator(), self.do_action) + def do_action(self, commit_hash): if hasattr(self, 'window'): @@ -166,6 +152,7 @@ def update_actions(self): super().update_actions() if self._file_path: self.actions.insert(1, ["show_file_at_commit", "Show file at commit"]) + self.actions.insert(2, ["blame_file_atcommit", "Blame file at commit"]) def show_commit(self): self.window.run_command("gs_show_commit", {"commit_hash": self._commit_hash}) @@ -203,3 +190,8 @@ def show_file_at_commit(self): self.window.run_command( "gs_show_file_at_commit", {"commit_hash": self._commit_hash, "filepath": self._file_path, "lang": lang}) + + def blame_file_atcommit(self): + self.window.run_command( + "gs_blame", + {"commit_hash": self._commit_hash, "file_path": self._file_path}) diff --git a/core/git_mixins/history.py b/core/git_mixins/history.py index 853d72258..0d4599691 100644 --- a/core/git_mixins/history.py +++ b/core/git_mixins/history.py @@ -63,6 +63,20 @@ def log(self, author=None, branch=None, file_path=None, start_end=None, cherry=N return entries + def commit_generator(self, limit = 6000): + # Generator for show_log_panel + skip = 0 + while True: + logs = self.log(branch=self._branch, + file_path=self._file_path, + limit=limit, + skip=skip) + if not logs: + break + for l in logs: + yield l + skip = skip + limit + def reflog(self, limit=6000, skip=None, all_branches=False): log_output = self.git( "reflog",