def find_base_commit_for_fixup(view, commit_line, commit_message): # type: (sublime.View, TextRange, str) -> Optional[str] dot = log_graph.dot_from_line(view, commit_line) if not dot: return None original_message = strip_fixup_or_squash_prefix(commit_message) target_dot = log_graph.find_matching_commit(view.id(), dot, original_message) if not target_dot: return None target_line = log_graph.line_from_pt(view, target_dot.pt) target_commit_hash = log_graph.extract_commit_hash(target_line.text) return target_commit_hash
def extract_symbol_from_graph(self, done): # type: (GsCommand, Kont) -> None view = get_view_for_command(self) if not view: return sel = log_graph.get_simple_selection(view) if sel is None: flash(view, "Only single cursors are supported.") return line = log_graph.line_from_pt(view, sel.b) info = log_graph.describe_graph_line(line.text, remotes=[]) if info is None: flash(view, "Not on a line with a commit.") return symbol = commitish_from_info(info) done(symbol)
def run(self): # type: () -> None view = self.window.active_view() if not view: return sel = log_graph.get_simple_selection(view) if sel is None: flash(view, "Only single cursors are supported.") return line = log_graph.line_from_pt(view, sel.b) info = log_graph.describe_graph_line(line.text, remotes=[]) if info is None: flash(view, "Not on a line with a commit.") return commit_hash = info["commit"] commitish = commitish_from_info(info) parent_commitish = "{}^".format(commitish) commit_message = commit_message_from_line(view, line) on_head = "HEAD" in info actions = [] # type: List[Tuple[str, Callable[[], None]]] if commit_message and is_fixup_or_squash_message(commit_message): base_commit = find_base_commit_for_fixup(view, line, commit_message) if base_commit: fixup_commit = Commit(commit_hash, commit_message) actions += [ ( "Apply fix to '{}'".format(base_commit) if is_fixup(fixup_commit) else "Squash with '{}'".format(base_commit), partial(self.apply_fixup, view, base_commit, [fixup_commit]) ) ] actions += [ ( "Re[W]ord commit message", partial(self.reword, view, commit_hash) ), ( "[E]dit commit", partial(self.edit, view, commit_hash) ), ( "Drop commit", partial(self.drop, view, commit_hash) ), SEPARATOR, ] # `HEAD^..HEAD` only selects one commit which is not enough # for autosquashing. if not on_head: head_info = log_graph.describe_head(view, []) good_head_name = ( "HEAD" if not head_info or head_info["HEAD"] == head_info["commit"] else head_info["HEAD"] ) actions += [ ( "Apply fixes and squashes {}..{}".format(parent_commitish, good_head_name), partial(self.autosquash, view, parent_commitish), ), ] actions += [ ( "[R]ebase from {} on interactive".format(parent_commitish), partial(self.rebase_interactive, view, parent_commitish) ), ( "Rebase {} --onto <branch>".format(parent_commitish), partial(self.rebase_onto, view, parent_commitish) ), ( "Rebase on <branch>", partial(self.rebase_on, view) ), ] def on_action_selection(index): if index == -1: return self.selected_index = index description, action = actions[index] action() self.window.show_quick_panel( [a[0] for a in actions], on_action_selection, flags=sublime.MONOSPACE_FONT, selected_index=self.selected_index, )