5 from cola
import gitcmds
6 from cola
import qtutils
7 from cola
import signals
8 from cola
.git
import git
9 from cola
.widgets
.browse
import BrowseDialog
10 from cola
.widgets
.combodlg
import ComboDialog
13 def install_command_wrapper():
14 wrapper
= CommandWrapper()
15 cola
.factory().add_command_wrapper(wrapper
)
18 class CommandWrapper(object):
21 signals
.confirm
: qtutils
.confirm
,
22 signals
.critical
: qtutils
.critical
,
23 signals
.information
: qtutils
.information
,
24 signals
.question
: qtutils
.question
,
28 def choose_from_combo(title
, items
):
29 """Quickly choose an item from a list using a combo box"""
30 return ComboDialog(qtutils
.active_window(), title
=title
, items
=items
).selected()
33 def slot_with_parent(fn
, parent
):
34 """Return an argument-less method for calling fn(parent=parent)
36 :param fn: - Function reference, must accept 'parent' as a keyword
37 :param parent: - Qt parent widget
46 """Launch the 'Delete Branch' dialog."""
47 branch
= choose_from_combo('Delete Branch',
48 cola
.model().local_branches
)
51 cola
.notifier().broadcast(signals
.delete_branch
, branch
)
55 """Diff against an arbitrary revision, branch, tag, etc."""
56 branch
= choose_from_combo('Select Branch, Tag, or Commit-ish',
58 cola
.model().all_branches() +
62 cola
.notifier().broadcast(signals
.diff_mode
, branch
)
66 """Launch the 'Browse Current Branch' dialog."""
67 branch
= gitcmds
.current_branch()
68 BrowseDialog
.browse(branch
)
72 """Prompt for a branch and inspect content at that point in time."""
73 # Prompt for a branch to browse
74 branch
= choose_from_combo('Browse Revision...', gitcmds
.all_refs())
77 BrowseDialog
.browse(branch
)
80 def checkout_branch():
81 """Launch the 'Checkout Branch' dialog."""
82 branch
= choose_from_combo('Checkout Branch',
83 cola
.model().local_branches
)
86 cola
.notifier().broadcast(signals
.checkout_branch
, branch
)
90 """Launch the 'Cherry-Pick' dialog."""
91 from cola
.controllers
.selectcommits
import select_commits
93 revs
, summaries
= gitcmds
.log_helper(all
=True)
94 commits
= select_commits('Cherry-Pick Commit',
95 revs
, summaries
, multiselect
=False)
98 cola
.notifier().broadcast(signals
.cherry_pick
, commits
)
101 def clone_repo(spawn
=True):
103 Present GUI controls for cloning a repository
105 A new cola session is invoked when 'spawn' is True.
108 url
, ok
= qtutils
.prompt('Path or URL to clone (Env. $VARS okay)')
109 url
= os
.path
.expandvars(core
.encode(url
))
110 if not ok
or not url
:
113 # Pick a suitable basename by parsing the URL
114 newurl
= url
.replace('\\', '/')
115 default
= newurl
.rsplit('/', 1)[-1]
116 if default
== '.git':
117 # The end of the URL is /.git, so assume it's a file path
118 default
= os
.path
.basename(os
.path
.dirname(newurl
))
119 if default
.endswith('.git'):
120 # The URL points to a bare repo
121 default
= default
[:-4]
123 # The URL is the current repo
124 default
= os
.path
.basename(os
.getcwd())
128 cola
.notifier().broadcast(signals
.information
,
130 'Could not parse: "%s"' % url
)
131 qtutils
.log(1, 'Oops, could not parse git url: "%s"' % url
)
134 # Prompt the user for a directory to use as the parent directory
135 msg
= 'Select a parent directory for the new clone'
136 dirname
= qtutils
.opendir_dialog(msg
, cola
.model().getcwd())
140 dirname
= core
.decode(dirname
)
141 destdir
= os
.path
.join(dirname
, core
.decode(default
))
143 if os
.path
.exists(destdir
):
144 # An existing path can be specified
145 msg
= ('"%s" already exists, cola will create a new directory' %
147 cola
.notifier().broadcast(signals
.information
,
148 'Directory Exists', msg
)
150 # Make sure the new destdir doesn't exist
151 while os
.path
.exists(destdir
):
152 destdir
= olddestdir
+ str(count
)
154 cola
.notifier().broadcast(signals
.clone
, core
.decode(url
), destdir
,
159 def export_patches():
160 """Run 'git format-patch' on a list of commits."""
161 from cola
.controllers
.selectcommits
import select_commits
163 revs
, summaries
= gitcmds
.log_helper()
164 to_export
= select_commits('Export Patches', revs
, summaries
)
169 cola
.notifier().broadcast(signals
.format_patch
, to_export
, revs
)
173 """Launches a diff against a branch."""
174 branch
= choose_from_combo('Select Branch, Tag, or Commit-ish',
176 cola
.model().all_branches() +
180 files
= gitcmds
.diff_filenames(branch
)
182 qtutils
.critical('No Differences',
183 'No differences found for "%s"' % branch
)
185 filename
= BrowseDialog
.select_file_from_list(files
)
188 cola
.notifier().broadcast(signals
.branch_mode
, branch
, filename
)
191 def diff_expression():
192 """Diff using an arbitrary expression."""
193 expr
= choose_from_combo('Enter Diff Expression',
194 cola
.model().all_branches() +
198 cola
.notifier().broadcast(signals
.diff_expr_mode
, expr
)
202 """Called when Search -> Grep's right-click 'goto' action."""
203 filename
, line_number
, contents
= line
.split(':', 2)
204 filename
= core
.encode(filename
)
205 cola
.notifier().broadcast(signals
.edit
, [filename
], line_number
=line_number
)
209 """Prompt and use 'git grep' to find the content."""
210 # This should be a command in cola.cmds.
211 txt
, ok
= qtutils
.prompt('grep')
214 cola
.notifier().broadcast(signals
.grep
, txt
)
218 """Spawn a new cola session."""
219 dirname
= qtutils
.opendir_dialog('Open Git Repository...',
220 cola
.model().getcwd())
223 cola
.notifier().broadcast(signals
.open_repo
, dirname
)
226 def load_commitmsg():
227 """Load a commit message from a file."""
228 filename
= qtutils
.open_dialog('Load Commit Message...',
229 cola
.model().getcwd())
231 cola
.notifier().broadcast(signals
.load_commit_message
, filename
)
235 """Rebase onto a branch."""
236 branch
= choose_from_combo('Rebase Branch',
237 cola
.model().all_branches())
241 status
, output
= git
.rebase(branch
, with_stderr
=True, with_status
=True)
242 qtutils
.log(status
, output
)
246 """Diff against an arbitrary revision, branch, tag, etc."""
247 branch
= choose_from_combo('Select Branch, Tag, or Commit-ish',
248 cola
.model().all_branches() +
252 cola
.notifier().broadcast(signals
.review_branch_mode
, branch
)
256 """Launch the 'fetch' remote dialog."""
257 from cola
.controllers
.remote
import remote_action
259 return remote_action('fetch')
263 """Launch the 'push' remote dialog."""
264 from cola
.controllers
.remote
import remote_action
266 return remote_action('push')
270 """Launch the 'pull' remote dialog."""
271 from cola
.controllers
.remote
import remote_action
273 return remote_action('pull')