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 ref
= choose_ref('Enter Diff Expression', 'Diff')
173 difftool
.diff_expression(qtutils
.active_window(), ref
)
177 """Called when Search -> Grep's right-click 'goto' action."""
178 filename
, line_number
, contents
= line
.split(':', 2)
179 filename
= core
.encode(filename
)
180 cola
.notifier().broadcast(signals
.edit
, [filename
], line_number
=line_number
)
184 """Prompt and use 'git grep' to find the content."""
185 # This should be a command in cola.cmds.
186 txt
, ok
= qtutils
.prompt('grep')
189 cola
.notifier().broadcast(signals
.grep
, txt
)
193 """Spawn a new cola session."""
194 dirname
= qtutils
.opendir_dialog('Open Git Repository...',
195 cola
.model().getcwd())
198 cola
.notifier().broadcast(signals
.open_repo
, dirname
)
201 def load_commitmsg():
202 """Load a commit message from a file."""
203 filename
= qtutils
.open_dialog('Load Commit Message...',
204 cola
.model().getcwd())
206 cola
.notifier().broadcast(signals
.load_commit_message
, filename
)
210 """Rebase onto a branch."""
211 branch
= choose_from_combo('Rebase Branch',
212 cola
.model().all_branches())
216 status
, output
= git
.rebase(branch
, with_stderr
=True, with_status
=True)
217 qtutils
.log(status
, output
)
220 def choose_ref(title
, button_text
, pre
=None):
223 provider
= qt
.GitRefProvider(pre
=pre
)
224 parent
= qtutils
.active_window()
225 return qt
.GitRefDialog
.ref(title
, button_text
, parent
, provider
=provider
)
229 """Diff against an arbitrary revision, branch, tag, etc."""
230 branch
= choose_ref('Select Branch to Review', 'Review')
233 merge_base
= gitcmds
.merge_base_parent(branch
)
234 difftool
.diff_commits(qtutils
.active_window(), merge_base
, branch
)