Skip to content

Commit 5400218

Browse files
author
steven
committed
Init
0 parents  commit 5400218

12 files changed

+447
-0
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
*.pyc

Context.sublime-menu

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
[
2+
{
3+
"id": "TortoiseGit",
4+
"caption": "TortoiseGit",
5+
"children": [
6+
{ "caption": "Status", "command": "git_status" },
7+
{ "caption": "Log", "command": "git_log" },
8+
{ "caption": "Diff", "command": "git_diff" },
9+
{ "caption": "Blame", "command": "git_blame" },
10+
{ "caption": "Pull", "command": "git_pull" },
11+
{ "caption": "Revert", "command": "git_revert" },
12+
{ "caption": "Commit...", "command": "git_commit" },
13+
{ "caption": "Commit repo...", "command": "git_commit_repo" },
14+
{ "caption": "Sync repo...", "command": "git_sync" }
15+
]
16+
}
17+
]

Default (Windows).sublime-keymap

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
[
2+
{
3+
"keys": ["alt+u"],
4+
"command": "git_pull"
5+
},
6+
{
7+
"keys": ["alt+c"],
8+
"command": "git_commit"
9+
},
10+
{
11+
"keys": ["alt+l"],
12+
"command": "git_log",
13+
"args": { "paths": [] }
14+
},
15+
{
16+
"keys": ["alt+shift+d"],
17+
"command": "git_diff"
18+
},
19+
{
20+
"keys": ["alt+shift+c"],
21+
"command": "git_commit_repo"
22+
},
23+
{
24+
"keys": ["alt+shift+u"],
25+
"command": "git_sync"
26+
}
27+
]

Main.sublime-menu

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
[
2+
{
3+
"id": "preferences",
4+
"children":
5+
[
6+
{
7+
"caption": "Package Settings",
8+
"id": "package-settings",
9+
"children":
10+
[
11+
{
12+
"caption": "TortoiseGit",
13+
"children":
14+
[
15+
{
16+
"caption": "Settings – Default",
17+
"command": "open_file",
18+
"args":
19+
{
20+
"file": "${packages}/TortoiseGit/TortoiseGit.sublime-settings"
21+
}
22+
},
23+
{
24+
"caption": "Settings – User",
25+
"command": "open_file",
26+
"args":
27+
{
28+
"file": "${packages}/User/TortoiseGit.sublime-settings"
29+
}
30+
},
31+
{ "caption": "-" },
32+
{
33+
"caption": "Key Bindings – Default",
34+
"command": "open_file",
35+
"args": {
36+
"file": "${packages}/TortoiseGit/Default (Windows).sublime-keymap",
37+
"platform": "Windows"
38+
}
39+
},
40+
{
41+
"caption": "Key Bindings – User",
42+
"command": "open_file",
43+
"args": {
44+
"file": "${packages}/User/Default (Windows).sublime-keymap",
45+
"platform": "Windows"
46+
}
47+
}
48+
]
49+
}
50+
]
51+
}
52+
]
53+
}
54+
]

README.md

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
# Sublime-TortoiseGit
2+
3+
A TortoiseGit Plugin for [Sublime Text](http://www.sublimetext.com).
4+
5+
## Usage
6+
7+
Install it using [Sublime Package Control](http://wbond.net/sublime_packages/package_control).
8+
9+
The default key bindings:
10+
- [alt+c] : commit current file.
11+
- [alt+u] : update current file.
12+
- [alt+l] : show current file log.
13+
14+
You can also call TortoiseGit commands when right-clicking folders or files in the side bar.
15+
16+
## Settings
17+
18+
If your TortoiseGitProc.exe path is not the default, please modify the path by selecting
19+
"Preferences -> Package Settings -> TortoiseGit -> Settings - User" in the menu.
20+
21+
The default setting is:
22+
23+
```
24+
{
25+
// Auto close update dialog when no errors, conflicts and merges
26+
"auto_close_pull_dialog": false,
27+
"tortoisegit_path": "C:\Program Files\TortoiseGit\bin\TortoiseGitProc.exe"
28+
}
29+
```
30+
31+
## Thanks
32+
33+
Thanks to the authors and contributors of the following repositories,
34+
from whom I got useful direction:
35+
36+
* https://github.com/dexbol/sublime-TortoiseSVN
37+
* https://github.com/fyneworks/sublime-TortoiseGIT
38+
* https://github.com/kemayo/sublime-text-git
39+
* https://github.com/ses4j/tgit-st3

Side Bar.sublime-menu

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
[
2+
{ "caption": "-" },
3+
{ "caption": "Log", "command": "git_log", "args": {"paths": []}},
4+
{ "caption": "Diff", "command": "git_diff", "args": {"paths": []}},
5+
{ "caption": "Pull", "command": "git_pull", "args": {"paths": []}},
6+
{ "caption": "Commit...", "command": "git_commit", "args": {"paths": []}},
7+
{ "caption": "Sync repo...", "command": "git_sync" },
8+
{ "caption": "-" }
9+
]

TortoiseGit.py

Lines changed: 233 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,233 @@
1+
import sublime
2+
import sublime_plugin
3+
import os
4+
import os.path
5+
import time
6+
import subprocess
7+
8+
git_root_cache = {}
9+
10+
11+
def git_root(directory):
12+
global git_root_cache
13+
14+
retval = False
15+
leaf_dir = directory
16+
17+
if leaf_dir in git_root_cache and git_root_cache[leaf_dir]['expires'] > time.time():
18+
return git_root_cache[leaf_dir]['retval']
19+
20+
while directory:
21+
if os.path.exists(os.path.join(directory, '.git')):
22+
retval = directory
23+
break
24+
parent = os.path.realpath(os.path.join(directory, os.path.pardir))
25+
if parent == directory:
26+
retval = False
27+
break
28+
directory = parent
29+
30+
git_root_cache[leaf_dir] = {
31+
'retval': retval,
32+
'expires': time.time() + 5
33+
}
34+
35+
return retval
36+
37+
38+
def is_git_controlled(directory):
39+
return bool(git_root(directory))
40+
41+
42+
def get_setting():
43+
return sublime.load_settings('TortoiseGit.sublime-settings')
44+
45+
46+
def run_tortoise_git_command(command, args, path, isHung=False):
47+
settings = get_setting()
48+
tortoisegit_path = settings.get('tortoisegit_path')
49+
50+
if tortoisegit_path is None or not os.path.isfile(tortoisegit_path):
51+
# sublime.error_message('can\'t find TortoiseGitProc.exe, please config setting file\n --sublime-TortoiseGit')
52+
# raise
53+
tortoisegit_path = 'TortoiseGitProc.exe'
54+
55+
# cmd = '"' + tortoisegit_path + '"' + ' /command:' + cmd + ' /path:"%s"' % dir
56+
cmd = u'{0} /command:"{1}" /path:"{2}" {3}'.format(
57+
tortoisegit_path,
58+
command,
59+
path,
60+
u' '.join(args))
61+
62+
# proce = subprocess.Popen(cmd, stdout=subprocess.PIPE)
63+
try:
64+
print('Running {0}'.format(cmd))
65+
with open(os.devnull, 'w') as devnull:
66+
proc = subprocess.Popen(
67+
cmd,
68+
stdin=devnull,
69+
stdout=subprocess.PIPE,
70+
stderr=subprocess.PIPE,
71+
shell=False,
72+
creationflags=subprocess.SW_HIDE
73+
)
74+
75+
# This is required, cause of ST must wait TortoiseGit update then revert
76+
# the file. Otherwise the file reverting occur before git pull, if the
77+
# file changed the file content in ST is older.
78+
if isHung:
79+
proc.communicate()
80+
except IOError as ex:
81+
sublime.error_message('Failed to execute command: {}'.format(str(ex)))
82+
raise
83+
84+
85+
class TortoiseGitCommand(sublime_plugin.WindowCommand):
86+
def is_enabled(self):
87+
return is_git_controlled(self._relevant_path())
88+
89+
def _active_line_number(self):
90+
view = self.window.active_view()
91+
if view:
92+
row, col = view.rowcol(view.sel()[0].begin())
93+
return row + 1
94+
else:
95+
return None
96+
97+
def _active_file_path(self):
98+
view = self.window.active_view()
99+
if view and view.file_name() and len(view.file_name()) > 0:
100+
return view.file_name()
101+
102+
def _active_repo_path(self):
103+
path = self._active_file_path()
104+
if not path:
105+
path = self.window.project_file_name()
106+
if not path:
107+
path = self.window.folders()[0]
108+
if path is None:
109+
return
110+
111+
root = git_root(path)
112+
113+
if root is False:
114+
return
115+
else:
116+
return root
117+
118+
def _active_file_or_repo_path(self):
119+
path = self._active_file_path()
120+
if path is not None:
121+
return path
122+
123+
# If no active file, then guess the repo.
124+
return self._active_repo_path()
125+
126+
# TODO
127+
# def _selected_dir(self, dirs):
128+
# if len(dirs):
129+
# return dirs[0]
130+
# else:
131+
# return
132+
133+
def _run_command(self, cmd, paths=[], args=[], isHung=False):
134+
arguments = []
135+
line_number = self._active_line_number()
136+
if line_number:
137+
# args.append('/line:{}'.format(line_number))
138+
arguments = args + ['/line:{}'.format(line_number)]
139+
140+
# TODO
141+
if len(paths):
142+
run_tortoise_git_command(cmd, arguments, paths[0])
143+
else:
144+
run_tortoise_git_command(cmd, arguments, self._relevant_path())
145+
146+
147+
class GitStatusCommand(TortoiseGitCommand):
148+
def run(self, paths=[]):
149+
self._run_command('repostatus', paths)
150+
151+
def _relevant_path(self):
152+
return self._active_file_or_repo_path()
153+
154+
155+
class GitLogCommand(TortoiseGitCommand):
156+
def run(self, paths=[]):
157+
self._run_command('log', paths)
158+
159+
def _relevant_path(self):
160+
return self._active_file_or_repo_path()
161+
162+
163+
class GitDiffCommand(TortoiseGitCommand):
164+
def run(self, paths=[]):
165+
self._run_command('diff', paths)
166+
167+
def _relevant_path(self):
168+
return self._active_file_or_repo_path()
169+
170+
171+
class GitCommitCommand(TortoiseGitCommand):
172+
def run(self, paths=[]):
173+
self._run_command('commit', paths)
174+
175+
def _relevant_path(self):
176+
return self._active_file_or_repo_path()
177+
178+
179+
class GitCommitRepoCommand(TortoiseGitCommand):
180+
def run(self):
181+
self._run_command('commit')
182+
183+
def _relevant_path(self):
184+
return self._active_repo_path()
185+
186+
187+
class GitSyncCommand(TortoiseGitCommand):
188+
def run(self):
189+
self._run_command('sync', [], [], True)
190+
191+
def _relevant_path(self):
192+
return self._active_repo_path()
193+
194+
195+
class GitBlameCommand(TortoiseGitCommand):
196+
def run(self):
197+
self._run_command('blame')
198+
199+
def _relevant_path(self):
200+
return self._active_file_path()
201+
202+
203+
class MutatingTortoiseGitCommand(TortoiseGitCommand):
204+
def run(self, cmd, paths=None, args=[]):
205+
self._run_command(cmd, paths, args, True)
206+
207+
self.view = sublime.active_window().active_view()
208+
row, col = self.view.rowcol(self.view.sel()[0].begin())
209+
self.lastLine = str(row + 1)
210+
sublime.set_timeout(self.revert, 100)
211+
212+
def _relevant_path(self):
213+
return self._active_file_or_repo_path()
214+
215+
def revert(self):
216+
self.view.run_command('revert')
217+
sublime.set_timeout(self.revertPoint, 600)
218+
219+
def revertPoint(self):
220+
self.view.window().run_command('goto_line', {'line': self.lastLine})
221+
222+
223+
class GitPullCommand(MutatingTortoiseGitCommand):
224+
def run(self, paths=[]):
225+
settings = get_setting()
226+
auto_close_dialog = settings.get('auto_close_pull_dialog')
227+
args = ['/closeonend:2'] if auto_close_dialog else []
228+
MutatingTortoiseGitCommand.run(self, 'pull', paths, args)
229+
230+
231+
class GitRevertCommand(MutatingTortoiseGitCommand):
232+
def run(self, paths=[]):
233+
MutatingTortoiseGitCommand.run(self, 'revert', paths)

TortoiseGit.sublime-commands

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
[
2+
{ "caption": "TortoiseGit: Status", "command": "git_status" },
3+
{ "caption": "TortoiseGit: Log", "command": "git_log" },
4+
{ "caption": "TortoiseGit: Diff", "command": "git_diff" },
5+
{ "caption": "TortoiseGit: Blame", "command": "git_blame" },
6+
{ "caption": "TortoiseGit: Pull", "command": "git_pull" },
7+
{ "caption": "TortoiseGit: Revert", "command": "git_revert" },
8+
{ "caption": "TortoiseGit: Commit...", "command": "git_commit" },
9+
{ "caption": "TortoiseGit: Commit repo...", "command": "git_commit_repo" },
10+
{ "caption": "TortoiseGit: Sync repo...", "command": "git_sync" }
11+
]

0 commit comments

Comments
 (0)