1 from __future__
import absolute_import
, division
, print_function
, unicode_literals
14 from .interaction
import Interaction
15 from .widgets
import completion
16 from .widgets
import editremotes
17 from .widgets
import switcher
18 from .widgets
.browse
import BrowseBranch
19 from .widgets
.selectcommits
import select_commits
20 from .widgets
.selectcommits
import select_commits_and_output
23 def delete_branch(context
):
24 """Launch the 'Delete Branch' dialog."""
25 icon
= icons
.discard()
26 branch
= choose_branch(context
, N_('Delete Branch'), N_('Delete'), icon
=icon
)
29 cmds
.do(cmds
.DeleteBranch
, context
, branch
)
32 def delete_remote_branch(context
):
33 """Launch the 'Delete Remote Branch' dialog."""
34 remote_branch
= choose_remote_branch(
35 context
, N_('Delete Remote Branch'), N_('Delete'), icon
=icons
.discard()
39 remote
, branch
= gitcmds
.parse_remote_branch(remote_branch
)
41 cmds
.do(cmds
.DeleteRemoteBranch
, context
, remote
, branch
)
44 def browse_current(context
):
45 """Launch the 'Browse Current Branch' dialog."""
46 branch
= gitcmds
.current_branch(context
)
47 BrowseBranch
.browse(context
, branch
)
50 def browse_other(context
):
51 """Prompt for a branch and inspect content at that point in time."""
52 # Prompt for a branch to browse
53 branch
= choose_ref(context
, N_('Browse Commits...'), N_('Browse'))
56 BrowseBranch
.browse(context
, branch
)
59 def checkout_branch(context
):
60 """Launch the 'Checkout Branch' dialog."""
61 branch
= choose_potential_branch(context
, N_('Checkout Branch'), N_('Checkout'))
64 cmds
.do(cmds
.CheckoutBranch
, context
, branch
)
67 def cherry_pick(context
):
68 """Launch the 'Cherry-Pick' dialog."""
69 revs
, summaries
= gitcmds
.log_helper(context
, all
=True)
70 commits
= select_commits(
71 context
, N_('Cherry-Pick Commit'), revs
, summaries
, multiselect
=False
75 cmds
.do(cmds
.CherryPick
, context
, commits
)
78 def new_repo(context
):
79 """Prompt for a new directory and create a new Git repository
81 :returns str: repository path or None if no repository was created.
85 path
= qtutils
.opendir_dialog(N_('New Repository...'), core
.getcwd())
88 # Avoid needlessly calling `git init`.
89 if git
.is_git_repository(path
):
90 # We could prompt here and confirm that they really didn't
91 # mean to open an existing repository, but I think
92 # treating it like an "Open" is a sensible DWIM answer.
95 status
, out
, err
= git
.init(path
)
99 title
= N_('Error Creating Repository')
100 Interaction
.command_error(title
, 'git init', status
, out
, err
)
104 def open_new_repo(context
):
105 dirname
= new_repo(context
)
108 cmds
.do(cmds
.OpenRepo
, context
, dirname
)
111 def new_bare_repo(context
):
113 repo
= prompt_for_new_bare_repo()
117 ok
= cmds
.do(cmds
.NewBareRepo
, context
, repo
)
120 # Add a new remote pointing to the bare repo
121 parent
= qtutils
.active_window()
122 add_remote
= editremotes
.add_remote(
123 context
, parent
, name
=os
.path
.basename(repo
), url
=repo
, readonly_url
=True
131 def prompt_for_new_bare_repo():
132 path
= qtutils
.opendir_dialog(N_('Select Directory...'), core
.getcwd())
137 default
= os
.path
.basename(core
.getcwd())
138 if not default
.endswith('.git'):
141 name
, ok
= qtutils
.prompt(
142 N_('Enter a name for the new bare repo'),
143 title
=N_('New Bare Repository...'),
146 if not name
or not ok
:
148 if not name
.endswith('.git'):
150 repo
= os
.path
.join(path
, name
)
152 Interaction
.critical(N_('Error'), N_('"%s" already exists') % repo
)
159 def export_patches(context
):
160 """Run 'git format-patch' on a list of commits."""
161 revs
, summaries
= gitcmds
.log_helper(context
)
162 to_export_and_output
= select_commits_and_output(
163 context
, N_('Export Patches'), revs
, summaries
165 if not to_export_and_output
['to_export']:
171 reversed(to_export_and_output
['to_export']),
173 to_export_and_output
['output'],
177 def diff_against_commit(context
):
178 """Diff against any commit and checkout changes using the Diff Editor"""
179 icon
= icons
.compare()
180 ref
= choose_ref(context
, N_('Diff Against Commit'), N_('Diff'), icon
=icon
)
183 cmds
.do(cmds
.DiffAgainstCommitMode
, context
, ref
)
186 def diff_expression(context
):
187 """Diff using an arbitrary expression."""
188 tracked
= gitcmds
.tracked_branch(context
)
189 current
= gitcmds
.current_branch(context
)
190 if tracked
and current
:
191 ref
= tracked
+ '..' + current
193 ref
= '@{upstream}..'
194 difftool
.diff_expression(context
, qtutils
.active_window(), ref
)
197 def open_repo(context
):
198 model
= context
.model
199 dirname
= qtutils
.opendir_dialog(N_('Open Git Repository'), model
.getcwd())
202 cmds
.do(cmds
.OpenRepo
, context
, dirname
)
205 def open_repo_in_new_window(context
):
206 """Spawn a new cola session."""
207 model
= context
.model
208 dirname
= qtutils
.opendir_dialog(N_('Open Git Repository'), model
.getcwd())
211 cmds
.do(cmds
.OpenNewRepo
, context
, dirname
)
214 def open_quick_repo_search(context
, parent
=None):
215 """Open a Quick Repository Search dialog"""
217 parent
= qtutils
.active_window()
218 settings
= context
.settings
219 items
= settings
.bookmarks
+ settings
.recent
223 default_repo
= cfg
.get('cola.defaultrepo')
225 entries
= QtGui
.QStandardItemModel()
227 normalize
= display
.normalize_path
228 star_icon
= icons
.star()
229 folder_icon
= icons
.folder()
232 key
= normalize(item
['path'])
237 if default_repo
== item
['path']:
242 entry
= switcher
.switcher_item(key
, icon
, name
)
243 entries
.appendRow(entry
)
246 title
= N_('Quick Open Repository')
247 place_holder
= N_('Search repositories by name...')
248 switcher
.switcher_inner_view(
252 place_holder
=place_holder
,
253 enter_action
=lambda entry
: cmds
.do(cmds
.OpenRepo
, context
, entry
.key
),
258 def load_commitmsg(context
):
259 """Load a commit message from a file."""
260 model
= context
.model
261 filename
= qtutils
.open_file(N_('Load Commit Message'), directory
=model
.getcwd())
263 cmds
.do(cmds
.LoadCommitMessageFromFile
, context
, filename
)
266 def choose_from_dialog(get
, context
, title
, button_text
, default
, icon
=None):
267 parent
= qtutils
.active_window()
268 return get(context
, title
, button_text
, parent
, default
=default
, icon
=icon
)
271 def choose_ref(context
, title
, button_text
, default
=None, icon
=None):
272 return choose_from_dialog(
273 completion
.GitRefDialog
.get
, context
, title
, button_text
, default
, icon
=icon
277 def choose_branch(context
, title
, button_text
, default
=None, icon
=None):
278 return choose_from_dialog(
279 completion
.GitBranchDialog
.get
, context
, title
, button_text
, default
, icon
=icon
283 def choose_potential_branch(context
, title
, button_text
, default
=None, icon
=None):
284 return choose_from_dialog(
285 completion
.GitCheckoutBranchDialog
.get
,
294 def choose_remote_branch(context
, title
, button_text
, default
=None, icon
=None):
295 return choose_from_dialog(
296 completion
.GitRemoteBranchDialog
.get
,
305 def review_branch(context
):
306 """Diff against an arbitrary revision, branch, tag, etc."""
307 branch
= choose_ref(context
, N_('Select Branch to Review'), N_('Review'))
310 merge_base
= gitcmds
.merge_base_parent(context
, branch
)
311 difftool
.diff_commits(context
, qtutils
.active_window(), merge_base
, branch
)
314 def rename_branch(context
):
315 """Launch the 'Rename Branch' dialogs."""
316 branch
= choose_branch(context
, N_('Rename Existing Branch'), N_('Select'))
319 new_branch
= choose_branch(context
, N_('Enter New Branch Name'), N_('Rename'))
322 cmds
.do(cmds
.RenameBranch
, context
, branch
, new_branch
)
325 def reset_soft(context
):
326 title
= N_('Reset Branch (Soft)')
327 ok_text
= N_('Reset Branch')
328 ref
= choose_ref(context
, title
, ok_text
, default
='HEAD^')
330 cmds
.do(cmds
.ResetSoft
, context
, ref
)
333 def reset_mixed(context
):
334 title
= N_('Reset Branch and Stage (Mixed)')
335 ok_text
= N_('Reset')
336 ref
= choose_ref(context
, title
, ok_text
, default
='HEAD^')
338 cmds
.do(cmds
.ResetMixed
, context
, ref
)
341 def reset_keep(context
):
342 title
= N_('Reset All (Keep Unstaged Changes)')
343 ref
= choose_ref(context
, title
, N_('Reset and Restore'))
345 cmds
.do(cmds
.ResetKeep
, context
, ref
)
348 def reset_merge(context
):
349 title
= N_('Restore Worktree and Reset All (Merge)')
350 ok_text
= N_('Reset and Restore')
351 ref
= choose_ref(context
, title
, ok_text
, default
='HEAD^')
353 cmds
.do(cmds
.ResetMerge
, context
, ref
)
356 def reset_hard(context
):
357 title
= N_('Restore Worktree and Reset All (Hard)')
358 ok_text
= N_('Reset and Restore')
359 ref
= choose_ref(context
, title
, ok_text
, default
='HEAD^')
361 cmds
.do(cmds
.ResetHard
, context
, ref
)
364 def restore_worktree(context
):
365 title
= N_('Restore Worktree')
366 ok_text
= N_('Restore Worktree')
367 ref
= choose_ref(context
, title
, ok_text
, default
='HEAD^')
369 cmds
.do(cmds
.RestoreWorktree
, context
, ref
)
373 """Install the GUI-model interaction hooks"""
374 Interaction
.choose_ref
= staticmethod(choose_ref
)