From b0c442fe9221d1c9d8d3a8f301dbf48a83db62cd Mon Sep 17 00:00:00 2001 From: Denis Borzenko Date: Mon, 11 Jan 2016 22:23:55 +0300 Subject: [PATCH 1/8] "Track Remote Branch" menu item added; filter and strip branch names --- Main.sublime-menu | 1 + git/repo.py | 12 ++++++++++-- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/Main.sublime-menu b/Main.sublime-menu index 40c7d0b4..eb7647f1 100644 --- a/Main.sublime-menu +++ b/Main.sublime-menu @@ -88,6 +88,7 @@ ,{ "caption": "Init", "command": "git_init"} ,{ "caption": "Status...", "command": "git_status" } ,{ "caption": "Branches...", "command": "git_branch" } + ,{ "caption": "Track Remote Branch", "command": "git_track_remote_branch" } ,{ "caption": "Merge...", "command": "git_merge" } ,{ "caption": "See commit history...", "command": "git_commit_history"} ] diff --git a/git/repo.py b/git/repo.py index 303606b5..4c34959b 100644 --- a/git/repo.py +++ b/git/repo.py @@ -32,12 +32,18 @@ class GitBranchCommand(GitWindowCommand): may_change_files = True command_to_run_after_branch = ['checkout'] extra_flags = [] + filter_invalid_items = False + strip_items = False def run(self): self.run_command(['git', 'branch', '--no-color'] + self.extra_flags, self.branch_done) def branch_done(self, result): self.results = result.rstrip().split('\n') + if self.strip_items: + self.results = [item.strip() for item in self.results] + if self.filter_invalid_items: + self.results = [item for item in self.results if item.strip().find(' ') < 0] self.quick_panel(self.results, self.panel_done, sublime.MONOSPACE_FONT) @@ -80,8 +86,10 @@ def on_input(self, branchname): class GitTrackRemoteBranchCommand(GitBranchCommand): - command_to_run_after_branch = ['checkout', '-t'] - extra_flags = ['-r'] + command_to_run_after_branch = ['checkout', '-t'] + extra_flags = ['-r'] + filter_invalid_items = True + strip_items = True class GitNewTagCommand(GitWindowCommand): From 84b0eeebd494ee01e3d17b25e645b2cf9bcc0550 Mon Sep 17 00:00:00 2001 From: Denis Borzenko Date: Tue, 12 Jan 2016 17:32:01 +0300 Subject: [PATCH 2/8] git_diff_branch command implemented; command palette addendum and menu updated --- Default.sublime-commands | 9 +++++++ Main.sublime-menu | 2 ++ git/diff.py | 51 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 62 insertions(+) diff --git a/Default.sublime-commands b/Default.sublime-commands index 61bb55c5..9326b140 100644 --- a/Default.sublime-commands +++ b/Default.sublime-commands @@ -58,6 +58,10 @@ "caption": "Git: Diff Staged Files", "command": "git_diff_commit" } + ,{ + "caption": "Git: Diff Branch", + "command": "git_diff_branch" + } ,{ "caption": "Git: Diff Current File (Ignore Whitespace)", "command": "git_diff", @@ -73,6 +77,11 @@ "command": "git_diff_commit", "args": { "ignore_whitespace": true } } + ,{ + "caption": "Git: Diff Branch (Ignore Whitespace)", + "command": "git_diff_branch", + "args": { "ignore_whitespace": true } + } ,{ "caption": "Git: Diff Tool Current File", "command": "git_raw", "args": { "command": "git difftool", "append_current_file": true, "may_change_files": false } diff --git a/Main.sublime-menu b/Main.sublime-menu index eb7647f1..c9c2b9c9 100644 --- a/Main.sublime-menu +++ b/Main.sublime-menu @@ -43,6 +43,8 @@ ,{ "caption": "Diff (no whitespace)", "command": "git_diff_all", "args": { "ignore_whitespace": true } } ,{ "caption": "Diff Staged", "command": "git_diff_commit" } ,{ "caption": "Diff Staged (no whitespace)", "command": "git_diff_commit", "args": { "ignore_whitespace": true } } + ,{ "caption": "Diff Branch", "command": "git_diff_branch" } + ,{ "caption": "Diff Branch (Ignore Whitespace)", "command": "git_diff_branch", "args": { "ignore_whitespace": true } } ,{ "caption": "Diff Tool", "command": "git_raw", "args": { "command": "git difftool", "may_change_files": false } } ,{ "caption": "Reset Hard", "command": "git_reset_hard_head" } ,{ "caption": "-" } diff --git a/git/diff.py b/git/diff.py index 5abdc390..43cfd9c1 100644 --- a/git/diff.py +++ b/git/diff.py @@ -137,3 +137,54 @@ def on_path_confirmed(self, git_root_dir): new_view = v.window().open_file(full_path_file_name) do_when(lambda: not new_view.is_loading(), lambda: goto_xy(new_view, self.goto_line, self.column)) + + +class GitDiffBranch (GitWindowCommand): + ignore_whitespace = False + branches = [] + files = [] + + def run(self, edit = None, ignore_whitespace = False): + self.ignore_whitespace = ignore_whitespace; + self.run_command(['git', 'branch', '--no-color'], + self.panel_branch) + + def panel_branch(self, result): + self.branches = result.rstrip().split('\n') + self.branches = [item.strip() for item in self.branches + if not (item.startswith('*') or item.strip().find(' ') > -1)] + self.quick_panel(self.branches, self.panel_branch_done, + sublime.MONOSPACE_FONT) + + def panel_branch_done(self, picked = 0): + if 0 > picked < len(self.branches): + return + self.picked_branch = self.branches[picked] + self.run_command(['git', 'diff', '--name-status', self.picked_branch], + self.panel_file) + + def panel_file(self, result): + self.files = [['All', 'Compare all files']] + for item in result.rstrip().split('\n'): + self.files.append(item[1:].strip()) + self.quick_panel(self.files, self.panel_file_done, + sublime.MONOSPACE_FONT) + + def panel_file_done(self, picked = 0): + if 0 > picked < len(self.branches): + return + command = ['git', 'diff', '--cached', '--no-color', self.picked_branch] + if self.ignore_whitespace: + command.extend(('--ignore-all-space', '--ignore-blank-lines')) + if picked > 0: + command.extend(('--', self.files[picked])) + + self.run_command(command, self.diff_contents_done) + + def diff_contents_done(self, result): + if not result.strip(): + self.panel("No output") + return + s = sublime.load_settings("Git.sublime-settings") + syntax = s.get("diff_syntax", "Packages/Diff/Diff.tmLanguage") + self.scratch(result, title="Git Diff", syntax=syntax) From fee6aceddc8947700e0538c98d5d78a568161af3 Mon Sep 17 00:00:00 2001 From: Denis Borzenko Date: Tue, 12 Jan 2016 23:48:41 +0300 Subject: [PATCH 3/8] status symbol in filelist and "No changed files" --- git/diff.py | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/git/diff.py b/git/diff.py index 43cfd9c1..b9196f75 100644 --- a/git/diff.py +++ b/git/diff.py @@ -166,18 +166,23 @@ def panel_branch_done(self, picked = 0): def panel_file(self, result): self.files = [['All', 'Compare all files']] for item in result.rstrip().split('\n'): - self.files.append(item[1:].strip()) - self.quick_panel(self.files, self.panel_file_done, - sublime.MONOSPACE_FONT) + item = item.split('\t', 1)[::-1] + self.files.append(item) + + if (len(self.files) == 1): + self.panel("No changed files") + return + + self.quick_panel(self.files, self.panel_file_done, sublime.MONOSPACE_FONT) def panel_file_done(self, picked = 0): if 0 > picked < len(self.branches): return command = ['git', 'diff', '--cached', '--no-color', self.picked_branch] if self.ignore_whitespace: - command.extend(('--ignore-all-space', '--ignore-blank-lines')) + command += ['--ignore-all-space', '--ignore-blank-lines'] if picked > 0: - command.extend(('--', self.files[picked])) + command += ['--', self.files[picked][0]] self.run_command(command, self.diff_contents_done) From aa603f7422ba7c45db665b97189e789e2b7a9af4 Mon Sep 17 00:00:00 2001 From: Denis Borzenko Date: Fri, 19 Feb 2016 15:00:09 +0300 Subject: [PATCH 4/8] fixed comparing branches separate files (failed when call not from git toplevel) --- git/diff.py | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/git/diff.py b/git/diff.py index b9196f75..660721a4 100644 --- a/git/diff.py +++ b/git/diff.py @@ -143,6 +143,8 @@ class GitDiffBranch (GitWindowCommand): ignore_whitespace = False branches = [] files = [] + command = [] + picked_file = '' def run(self, edit = None, ignore_whitespace = False): self.ignore_whitespace = ignore_whitespace; @@ -181,9 +183,21 @@ def panel_file_done(self, picked = 0): command = ['git', 'diff', '--cached', '--no-color', self.picked_branch] if self.ignore_whitespace: command += ['--ignore-all-space', '--ignore-blank-lines'] - if picked > 0: - command += ['--', self.files[picked][0]] + if picked == 0: + self.run_command(command, self.diff_contents_done) + else: + self.picked_file = self.files[picked][0] + self.command = command + self.run_command(['git', 'rev-parse', '--show-toplevel'], self.show_toplevel_done) + + def show_toplevel_done(self, result): + result = result.strip() + if not result: + sublime.status_message("Can't retrieve git toplevel") + return + command = self.command + ['--', result.rstrip('/') + '/' + self.picked_file.lstrip('/')] + print(command, result, result.rstrip('/'), self.picked_file.lstrip('/')) self.run_command(command, self.diff_contents_done) def diff_contents_done(self, result): From 32ea9522624c2fb50466c7842060a26dfb1f26b4 Mon Sep 17 00:00:00 2001 From: Denis Borzenko Date: Fri, 19 Feb 2016 15:01:54 +0300 Subject: [PATCH 5/8] MOAR broken-data-workability (_make_text_safeish) --- git/__init__.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/git/__init__.py b/git/__init__.py index 003ed6a4..74275eb1 100644 --- a/git/__init__.py +++ b/git/__init__.py @@ -101,7 +101,10 @@ def _make_text_safeish(text, fallback_encoding, method='decode'): try: unitext = getattr(text, method)('utf-8') except (UnicodeEncodeError, UnicodeDecodeError): - unitext = getattr(text, method)(fallback_encoding) + try: + unitext = getattr(text, method)(fallback_encoding) + except (UnicodeEncodeError, UnicodeDecodeError): + unitext = str(text) except AttributeError: # strongly implies we're already unicode, but just in case let's cast # to string From 06e69369bf9d6fb144a40b8bc07d94fa7f3ab622 Mon Sep 17 00:00:00 2001 From: Denis Borzenko Date: Fri, 19 Feb 2016 15:06:02 +0300 Subject: [PATCH 6/8] sublime-project stored into root: i love this plugin %) --- .gitignore | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 56c6b572..8fb9cd82 100644 --- a/.gitignore +++ b/.gitignore @@ -2,4 +2,5 @@ *.tmLanguage.cache *.tmPreferences.cache .DS_Store -package-metadata.json \ No newline at end of file +package-metadata.json +*.sublime-project From 83a44a09ef84983697a782c06324f50c5633e3ba Mon Sep 17 00:00:00 2001 From: Denis Borzenko Date: Wed, 24 Feb 2016 14:08:59 +0300 Subject: [PATCH 7/8] Hide line numbers from diff view (scratch) --- git/__init__.py | 2 ++ git/diff.py | 6 +++--- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/git/__init__.py b/git/__init__.py index 74275eb1..d618e3e1 100644 --- a/git/__init__.py +++ b/git/__init__.py @@ -296,6 +296,8 @@ def scratch(self, output, title=False, position=None, **kwargs): self._output_to_view(scratch_file, output, **kwargs) scratch_file.set_read_only(True) scratch_file.settings().set('word_wrap', False) + if 'line_numbers' in kwargs: + scratch_file.settings().set('line_numbers', kwargs['line_numbers']) if position: sublime.set_timeout(lambda: scratch_file.set_viewport_position(position), 0) return scratch_file diff --git a/git/diff.py b/git/diff.py index 660721a4..c746c116 100644 --- a/git/diff.py +++ b/git/diff.py @@ -24,7 +24,7 @@ def diff_done(self, result): if s.get('diff_panel'): view = self.panel(result, syntax=syntax) else: - view = self.scratch(result, title="Git Diff", syntax=syntax) + view = self.scratch(result, title="Git Diff", syntax=syntax, line_numbers=False) # Store the git root directory in the view so we can resolve relative paths # when the user wants to navigate to the source file. @@ -44,7 +44,7 @@ def diff_done(self, result): return s = sublime.load_settings("Git.sublime-settings") syntax = s.get("diff_syntax", "Packages/Diff/Diff.tmLanguage") - self.scratch(result, title="Git Diff", syntax=syntax) + self.scratch(result, title="Git Diff", syntax=syntax, line_numbers=False) class GitDiffCommand(GitDiff, GitTextCommand): @@ -206,4 +206,4 @@ def diff_contents_done(self, result): return s = sublime.load_settings("Git.sublime-settings") syntax = s.get("diff_syntax", "Packages/Diff/Diff.tmLanguage") - self.scratch(result, title="Git Diff", syntax=syntax) + self.scratch(result, title="Git Diff", syntax=syntax, line_numbers=False) From dc425b3c6acb172260a58b619115f50b58796ae7 Mon Sep 17 00:00:00 2001 From: Denis Borzenko Date: Wed, 24 Feb 2016 15:24:31 +0300 Subject: [PATCH 8/8] line_numbers option is global now; GitDiffBranch extends GitDiffAllCommand and GitDiffBranch.diff_contents_done was removed --- Git.sublime-settings | 3 +++ git/__init__.py | 5 +++-- git/diff.py | 19 +++++-------------- 3 files changed, 11 insertions(+), 16 deletions(-) diff --git a/Git.sublime-settings b/Git.sublime-settings index 10bb9eee..98e4d93d 100644 --- a/Git.sublime-settings +++ b/Git.sublime-settings @@ -16,6 +16,9 @@ // use the panel for diff output, rather than a new scratch window (new tab) ,"diff_panel": false + // show line numbers in output views + ,"line_numbers": false + // If you'd rather have your status command open files instead of show you a // diff, set this to true. You can still do `Git: Status` followed by // 'Git: Diff Current File' to get a file diff diff --git a/git/__init__.py b/git/__init__.py index d618e3e1..1b9a4324 100644 --- a/git/__init__.py +++ b/git/__init__.py @@ -286,6 +286,9 @@ def _output_to_view(self, output_file, output, clear=False, 'output': output, 'clear': clear } + s = sublime.load_settings("Git.sublime-settings") + if (s.has('line_numbers')): + output_file.settings().set('line_numbers', s.get('line_numbers', False)) output_file.run_command('git_scratch_output', args) def scratch(self, output, title=False, position=None, **kwargs): @@ -296,8 +299,6 @@ def scratch(self, output, title=False, position=None, **kwargs): self._output_to_view(scratch_file, output, **kwargs) scratch_file.set_read_only(True) scratch_file.settings().set('word_wrap', False) - if 'line_numbers' in kwargs: - scratch_file.settings().set('line_numbers', kwargs['line_numbers']) if position: sublime.set_timeout(lambda: scratch_file.set_viewport_position(position), 0) return scratch_file diff --git a/git/diff.py b/git/diff.py index c746c116..0c9a2f3a 100644 --- a/git/diff.py +++ b/git/diff.py @@ -24,7 +24,7 @@ def diff_done(self, result): if s.get('diff_panel'): view = self.panel(result, syntax=syntax) else: - view = self.scratch(result, title="Git Diff", syntax=syntax, line_numbers=False) + view = self.scratch(result, title="Git Diff", syntax=syntax) # Store the git root directory in the view so we can resolve relative paths # when the user wants to navigate to the source file. @@ -42,9 +42,8 @@ def diff_done(self, result): if not result.strip(): self.panel("No output") return - s = sublime.load_settings("Git.sublime-settings") syntax = s.get("diff_syntax", "Packages/Diff/Diff.tmLanguage") - self.scratch(result, title="Git Diff", syntax=syntax, line_numbers=False) + self.scratch(result, title="Git Diff", syntax=syntax) class GitDiffCommand(GitDiff, GitTextCommand): @@ -139,7 +138,7 @@ def on_path_confirmed(self, git_root_dir): lambda: goto_xy(new_view, self.goto_line, self.column)) -class GitDiffBranch (GitWindowCommand): +class GitDiffBranch (GitDiffAllCommand): ignore_whitespace = False branches = [] files = [] @@ -185,7 +184,7 @@ def panel_file_done(self, picked = 0): command += ['--ignore-all-space', '--ignore-blank-lines'] if picked == 0: - self.run_command(command, self.diff_contents_done) + self.run_command(command, self.diff_done) else: self.picked_file = self.files[picked][0] self.command = command @@ -198,12 +197,4 @@ def show_toplevel_done(self, result): return command = self.command + ['--', result.rstrip('/') + '/' + self.picked_file.lstrip('/')] print(command, result, result.rstrip('/'), self.picked_file.lstrip('/')) - self.run_command(command, self.diff_contents_done) - - def diff_contents_done(self, result): - if not result.strip(): - self.panel("No output") - return - s = sublime.load_settings("Git.sublime-settings") - syntax = s.get("diff_syntax", "Packages/Diff/Diff.tmLanguage") - self.scratch(result, title="Git Diff", syntax=syntax, line_numbers=False) + self.run_command(command, self.diff_done)