5 from cola
import difftool
6 from cola
import gitcmds
8 from cola
import qtutils
9 from cola
import signals
10 from cola
.git
import git
11 from cola
.widgets
.browse
import BrowseDialog
12 from cola
.widgets
.combodlg
import ComboDialog
13 from cola
.widgets
.selectcommits
import select_commits
16 def install_command_wrapper():
17 wrapper
= CommandWrapper()
18 cola
.factory().add_command_wrapper(wrapper
)
21 class CommandWrapper(object):
24 signals
.confirm
: qtutils
.confirm
,
25 signals
.critical
: qtutils
.critical
,
26 signals
.information
: qtutils
.information
,
27 signals
.question
: qtutils
.question
,
31 def choose_from_combo(title
, items
):
32 """Quickly choose an item from a list using a combo box"""
33 return ComboDialog(qtutils
.active_window(), title
=title
, items
=items
).selected()
36 def slot_with_parent(fn
, parent
):
37 """Return an argument-less method for calling fn(parent=parent)
39 :param fn: - Function reference, must accept 'parent' as a keyword
40 :param parent: - Qt parent widget
49 """Launch the 'Delete Branch' dialog."""
50 branch
= choose_from_combo('Delete Branch',
51 cola
.model().local_branches
)
54 cola
.notifier().broadcast(signals
.delete_branch
, branch
)
58 """Diff an arbitrary revision against the worktree"""
59 ref
= choose_ref('Select Revision to Diff', 'Diff', pre
=['HEAD^'])
62 difftool
.diff_commits(qtutils
.active_window(), ref
, None)
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 revs
, summaries
= gitcmds
.log_helper(all
=True)
92 commits
= select_commits('Cherry-Pick Commit',
93 revs
, summaries
, multiselect
=False)
96 cola
.notifier().broadcast(signals
.cherry_pick
, commits
)
99 def clone_repo(spawn
=True):
101 Present GUI controls for cloning a repository
103 A new cola session is invoked when 'spawn' is True.
106 url
, ok
= qtutils
.prompt('Path or URL to clone (Env. $VARS okay)')
107 url
= os
.path
.expandvars(core
.encode(url
))
108 if not ok
or not url
:
111 # Pick a suitable basename by parsing the URL
112 newurl
= url
.replace('\\', '/')
113 default
= newurl
.rsplit('/', 1)[-1]
114 if default
== '.git':
115 # The end of the URL is /.git, so assume it's a file path
116 default
= os
.path
.basename(os
.path
.dirname(newurl
))
117 if default
.endswith('.git'):
118 # The URL points to a bare repo
119 default
= default
[:-4]
121 # The URL is the current repo
122 default
= os
.path
.basename(os
.getcwd())
126 cola
.notifier().broadcast(signals
.information
,
128 'Could not parse: "%s"' % url
)
129 qtutils
.log(1, 'Oops, could not parse git url: "%s"' % url
)
132 # Prompt the user for a directory to use as the parent directory
133 msg
= 'Select a parent directory for the new clone'
134 dirname
= qtutils
.opendir_dialog(msg
, cola
.model().getcwd())
138 dirname
= core
.decode(dirname
)
139 destdir
= os
.path
.join(dirname
, core
.decode(default
))
141 if os
.path
.exists(destdir
):
142 # An existing path can be specified
143 msg
= ('"%s" already exists, cola will create a new directory' %
145 cola
.notifier().broadcast(signals
.information
,
146 'Directory Exists', msg
)
148 # Make sure the new destdir doesn't exist
149 while os
.path
.exists(destdir
):
150 destdir
= olddestdir
+ str(count
)
152 cola
.notifier().broadcast(signals
.clone
, core
.decode(url
), destdir
,
157 def export_patches():
158 """Run 'git format-patch' on a list of commits."""
159 revs
, summaries
= gitcmds
.log_helper()
160 to_export
= select_commits('Export Patches', revs
, summaries
)
165 cola
.notifier().broadcast(signals
.format_patch
, to_export
, revs
)
168 def diff_expression():
169 """Diff using an arbitrary expression."""
170 expr
= choose_from_combo('Enter Diff Expression',
171 cola
.model().all_branches() +
175 cola
.notifier().broadcast(signals
.diff_expr_mode
, expr
)
179 """Called when Search -> Grep's right-click 'goto' action."""
180 filename
, line_number
, contents
= line
.split(':', 2)
181 filename
= core
.encode(filename
)
182 cola
.notifier().broadcast(signals
.edit
, [filename
], line_number
=line_number
)
186 """Prompt and use 'git grep' to find the content."""
187 # This should be a command in cola.cmds.
188 txt
, ok
= qtutils
.prompt('grep')
191 cola
.notifier().broadcast(signals
.grep
, txt
)
195 """Spawn a new cola session."""
196 dirname
= qtutils
.opendir_dialog('Open Git Repository...',
197 cola
.model().getcwd())
200 cola
.notifier().broadcast(signals
.open_repo
, dirname
)
203 def load_commitmsg():
204 """Load a commit message from a file."""
205 filename
= qtutils
.open_dialog('Load Commit Message...',
206 cola
.model().getcwd())
208 cola
.notifier().broadcast(signals
.load_commit_message
, filename
)
212 """Rebase onto a branch."""
213 branch
= choose_from_combo('Rebase Branch',
214 cola
.model().all_branches())
218 status
, output
= git
.rebase(branch
, with_stderr
=True, with_status
=True)
219 qtutils
.log(status
, output
)
222 def choose_ref(title
, button_text
, pre
=None):
225 provider
= qt
.GitRefProvider(pre
=pre
)
226 parent
= qtutils
.active_window()
227 return qt
.GitRefDialog
.ref(title
, button_text
, parent
, provider
=provider
)
231 """Diff against an arbitrary revision, branch, tag, etc."""
232 branch
= choose_ref('Select Branch to Review', 'Review')
235 merge_base
= gitcmds
.merge_base_parent(branch
)
236 difftool
.diff_commits(qtutils
.active_window(), merge_base
, branch
)