1 from __future__
import division
, absolute_import
, unicode_literals
11 from .interaction
import Interaction
12 from .widgets
import completion
13 from .widgets
import editremotes
14 from .widgets
.browse
import BrowseBranch
15 from .widgets
.selectcommits
import select_commits
16 from .widgets
.selectcommits
import select_commits_and_output
19 def delete_branch(context
):
20 """Launch the 'Delete Branch' dialog."""
21 icon
= icons
.discard()
22 branch
= choose_branch(context
, N_('Delete Branch'), N_('Delete'), icon
=icon
)
25 cmds
.do(cmds
.DeleteBranch
, context
, branch
)
28 def delete_remote_branch(context
):
29 """Launch the 'Delete Remote Branch' dialog."""
30 remote_branch
= choose_remote_branch(
31 context
, N_('Delete Remote Branch'), N_('Delete'), icon
=icons
.discard()
35 remote
, branch
= gitcmds
.parse_remote_branch(remote_branch
)
37 cmds
.do(cmds
.DeleteRemoteBranch
, context
, remote
, branch
)
40 def browse_current(context
):
41 """Launch the 'Browse Current Branch' dialog."""
42 branch
= gitcmds
.current_branch(context
)
43 BrowseBranch
.browse(context
, branch
)
46 def browse_other(context
):
47 """Prompt for a branch and inspect content at that point in time."""
48 # Prompt for a branch to browse
49 branch
= choose_ref(context
, N_('Browse Commits...'), N_('Browse'))
52 BrowseBranch
.browse(context
, branch
)
55 def checkout_branch(context
):
56 """Launch the 'Checkout Branch' dialog."""
57 branch
= choose_potential_branch(context
, N_('Checkout Branch'), N_('Checkout'))
60 cmds
.do(cmds
.CheckoutBranch
, context
, branch
)
63 def cherry_pick(context
):
64 """Launch the 'Cherry-Pick' dialog."""
65 revs
, summaries
= gitcmds
.log_helper(context
, all
=True)
66 commits
= select_commits(
67 context
, N_('Cherry-Pick Commit'), revs
, summaries
, multiselect
=False
71 cmds
.do(cmds
.CherryPick
, context
, commits
)
74 def new_repo(context
):
75 """Prompt for a new directory and create a new Git repository
77 :returns str: repository path or None if no repository was created.
81 path
= qtutils
.opendir_dialog(N_('New Repository...'), core
.getcwd())
84 # Avoid needlessly calling `git init`.
85 if git
.is_git_repository(path
):
86 # We could prompt here and confirm that they really didn't
87 # mean to open an existing repository, but I think
88 # treating it like an "Open" is a sensible DWIM answer.
91 status
, out
, err
= git
.init(path
)
95 title
= N_('Error Creating Repository')
96 Interaction
.command_error(title
, 'git init', status
, out
, err
)
100 def open_new_repo(context
):
101 dirname
= new_repo(context
)
104 cmds
.do(cmds
.OpenRepo
, context
, dirname
)
107 def new_bare_repo(context
):
109 repo
= prompt_for_new_bare_repo()
113 ok
= cmds
.do(cmds
.NewBareRepo
, context
, repo
)
116 # Add a new remote pointing to the bare repo
117 parent
= qtutils
.active_window()
118 add_remote
= editremotes
.add_remote(
119 context
, parent
, name
=os
.path
.basename(repo
), url
=repo
, readonly_url
=True
127 def prompt_for_new_bare_repo():
128 path
= qtutils
.opendir_dialog(N_('Select Directory...'), core
.getcwd())
133 default
= os
.path
.basename(core
.getcwd())
134 if not default
.endswith('.git'):
137 name
, ok
= qtutils
.prompt(
138 N_('Enter a name for the new bare repo'),
139 title
=N_('New Bare Repository...'),
142 if not name
or not ok
:
144 if not name
.endswith('.git'):
146 repo
= os
.path
.join(path
, name
)
148 Interaction
.critical(N_('Error'), N_('"%s" already exists') % repo
)
155 def export_patches(context
):
156 """Run 'git format-patch' on a list of commits."""
157 revs
, summaries
= gitcmds
.log_helper(context
)
158 to_export_and_output
= select_commits_and_output(
159 context
, N_('Export Patches'), revs
, summaries
161 if not to_export_and_output
['to_export']:
167 reversed(to_export_and_output
['to_export']),
169 to_export_and_output
['output'],
173 def diff_expression(context
):
174 """Diff using an arbitrary expression."""
175 tracked
= gitcmds
.tracked_branch(context
)
176 current
= gitcmds
.current_branch(context
)
177 if tracked
and current
:
178 ref
= tracked
+ '..' + current
180 ref
= '@{upstream}..'
181 difftool
.diff_expression(context
, qtutils
.active_window(), ref
)
184 def open_repo(context
):
185 model
= context
.model
186 dirname
= qtutils
.opendir_dialog(N_('Open Git Repository...'), model
.getcwd())
189 cmds
.do(cmds
.OpenRepo
, context
, dirname
)
192 def open_repo_in_new_window(context
):
193 """Spawn a new cola session."""
194 model
= context
.model
195 dirname
= qtutils
.opendir_dialog(N_('Open Git Repository...'), model
.getcwd())
198 cmds
.do(cmds
.OpenNewRepo
, context
, dirname
)
201 def load_commitmsg(context
):
202 """Load a commit message from a file."""
203 model
= context
.model
204 filename
= qtutils
.open_file(N_('Load Commit Message'), directory
=model
.getcwd())
206 cmds
.do(cmds
.LoadCommitMessageFromFile
, context
, filename
)
209 def choose_from_dialog(get
, context
, title
, button_text
, default
, icon
=None):
210 parent
= qtutils
.active_window()
211 return get(context
, title
, button_text
, parent
, default
=default
, icon
=icon
)
214 def choose_ref(context
, title
, button_text
, default
=None, icon
=None):
215 return choose_from_dialog(
216 completion
.GitRefDialog
.get
, context
, title
, button_text
, default
, icon
=icon
220 def choose_branch(context
, title
, button_text
, default
=None, icon
=None):
221 return choose_from_dialog(
222 completion
.GitBranchDialog
.get
, context
, title
, button_text
, default
, icon
=icon
226 def choose_potential_branch(context
, title
, button_text
, default
=None, icon
=None):
227 return choose_from_dialog(
228 completion
.GitCheckoutBranchDialog
.get
,
237 def choose_remote_branch(context
, title
, button_text
, default
=None, icon
=None):
238 return choose_from_dialog(
239 completion
.GitRemoteBranchDialog
.get
,
248 def review_branch(context
):
249 """Diff against an arbitrary revision, branch, tag, etc."""
250 branch
= choose_ref(context
, N_('Select Branch to Review'), N_('Review'))
253 merge_base
= gitcmds
.merge_base_parent(context
, branch
)
254 difftool
.diff_commits(context
, qtutils
.active_window(), merge_base
, branch
)
257 def rename_branch(context
):
258 """Launch the 'Rename Branch' dialogs."""
259 branch
= choose_branch(context
, N_('Rename Existing Branch'), N_('Select'))
262 new_branch
= choose_branch(context
, N_('Enter New Branch Name'), N_('Rename'))
265 cmds
.do(cmds
.RenameBranch
, context
, branch
, new_branch
)
268 def reset_soft(context
):
269 title
= N_('Reset Branch (Soft)')
270 ok_text
= N_('Reset Branch')
271 ref
= choose_ref(context
, title
, ok_text
, default
='HEAD^')
273 cmds
.do(cmds
.ResetSoft
, context
, ref
)
276 def reset_mixed(context
):
277 title
= N_('Reset Branch and Stage (Mixed)')
278 ok_text
= N_('Reset')
279 ref
= choose_ref(context
, title
, ok_text
, default
='HEAD^')
281 cmds
.do(cmds
.ResetMixed
, context
, ref
)
284 def reset_keep(context
):
285 title
= N_('Reset All (Keep Unstaged Changes)')
286 ref
= choose_ref(context
, title
, N_('Reset and Restore'))
288 cmds
.do(cmds
.ResetKeep
, context
, ref
)
291 def reset_merge(context
):
292 title
= N_('Restore Worktree and Reset All (Merge)')
293 ok_text
= N_('Reset and Restore')
294 ref
= choose_ref(context
, title
, ok_text
, default
='HEAD^')
296 cmds
.do(cmds
.ResetMerge
, context
, ref
)
299 def reset_hard(context
):
300 title
= N_('Restore Worktree and Reset All (Hard)')
301 ok_text
= N_('Reset and Restore')
302 ref
= choose_ref(context
, title
, ok_text
, default
='HEAD^')
304 cmds
.do(cmds
.ResetHard
, context
, ref
)
307 def restore_worktree(context
):
308 title
= N_('Restore Worktree')
309 ok_text
= N_('Restore Worktree')
310 ref
= choose_ref(context
, title
, ok_text
, default
='HEAD^')
312 cmds
.do(cmds
.RestoreWorktree
, context
, ref
)
316 """Install the GUI-model interaction hooks"""
317 Interaction
.choose_ref
= staticmethod(choose_ref
)