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',
63 difftool
.diff_commits(qtutils
.active_window(), ref
, None)
67 """Launch the 'Browse Current Branch' dialog."""
68 branch
= gitcmds
.current_branch()
69 BrowseDialog
.browse(branch
)
73 """Prompt for a branch and inspect content at that point in time."""
74 # Prompt for a branch to browse
75 branch
= choose_from_combo('Browse Revision...', gitcmds
.all_refs())
78 BrowseDialog
.browse(branch
)
81 def checkout_branch():
82 """Launch the 'Checkout Branch' dialog."""
83 branch
= choose_from_combo('Checkout Branch',
84 cola
.model().local_branches
)
87 cola
.notifier().broadcast(signals
.checkout_branch
, branch
)
91 """Launch the 'Cherry-Pick' dialog."""
92 revs
, summaries
= gitcmds
.log_helper(all
=True)
93 commits
= select_commits('Cherry-Pick Commit',
94 revs
, summaries
, multiselect
=False)
97 cola
.notifier().broadcast(signals
.cherry_pick
, commits
)
100 def clone_repo(spawn
=True):
102 Present GUI controls for cloning a repository
104 A new cola session is invoked when 'spawn' is True.
107 url
, ok
= qtutils
.prompt('Path or URL to clone (Env. $VARS okay)')
108 url
= os
.path
.expandvars(core
.encode(url
))
109 if not ok
or not url
:
112 # Pick a suitable basename by parsing the URL
113 newurl
= url
.replace('\\', '/')
114 default
= newurl
.rsplit('/', 1)[-1]
115 if default
== '.git':
116 # The end of the URL is /.git, so assume it's a file path
117 default
= os
.path
.basename(os
.path
.dirname(newurl
))
118 if default
.endswith('.git'):
119 # The URL points to a bare repo
120 default
= default
[:-4]
122 # The URL is the current repo
123 default
= os
.path
.basename(os
.getcwd())
127 cola
.notifier().broadcast(signals
.information
,
129 'Could not parse: "%s"' % url
)
130 qtutils
.log(1, 'Oops, could not parse git url: "%s"' % url
)
133 # Prompt the user for a directory to use as the parent directory
134 msg
= 'Select a parent directory for the new clone'
135 dirname
= qtutils
.opendir_dialog(msg
, cola
.model().getcwd())
139 dirname
= core
.decode(dirname
)
140 destdir
= os
.path
.join(dirname
, core
.decode(default
))
142 if os
.path
.exists(destdir
):
143 # An existing path can be specified
144 msg
= ('"%s" already exists, cola will create a new directory' %
146 cola
.notifier().broadcast(signals
.information
,
147 'Directory Exists', msg
)
149 # Make sure the new destdir doesn't exist
150 while os
.path
.exists(destdir
):
151 destdir
= olddestdir
+ str(count
)
153 cola
.notifier().broadcast(signals
.clone
, core
.decode(url
), destdir
,
158 def export_patches():
159 """Run 'git format-patch' on a list of commits."""
160 revs
, summaries
= gitcmds
.log_helper()
161 to_export
= select_commits('Export Patches', revs
, summaries
)
166 cola
.notifier().broadcast(signals
.format_patch
, to_export
, revs
)
169 def diff_expression():
170 """Diff using an arbitrary expression."""
171 tracked
= gitcmds
.tracked_branch()
172 current
= gitcmds
.current_branch()
173 if tracked
and current
:
174 default
= tracked
+ '..' + current
176 default
= 'origin/master..'
177 ref
= choose_ref('Enter Diff Expression', 'Diff',
181 difftool
.diff_expression(qtutils
.active_window(), ref
)
185 """Called when Search -> Grep's right-click 'goto' action."""
186 filename
, line_number
, contents
= line
.split(':', 2)
187 filename
= core
.encode(filename
)
188 cola
.notifier().broadcast(signals
.edit
, [filename
], line_number
=line_number
)
192 """Prompt and use 'git grep' to find the content."""
193 from cola
.widgets
.grep
import run_grep
195 widget
= run_grep(parent
=qtutils
.active_window())
202 """Spawn a new cola session."""
203 dirname
= qtutils
.opendir_dialog('Open Git Repository...',
204 cola
.model().getcwd())
207 cola
.notifier().broadcast(signals
.open_repo
, dirname
)
210 def load_commitmsg():
211 """Load a commit message from a file."""
212 filename
= qtutils
.open_dialog('Load Commit Message...',
213 cola
.model().getcwd())
215 cola
.notifier().broadcast(signals
.load_commit_message
, filename
)
219 """Rebase onto a branch."""
220 branch
= choose_from_combo('Rebase Branch',
221 cola
.model().all_branches())
225 status
, output
= git
.rebase(branch
, with_stderr
=True, with_status
=True)
226 qtutils
.log(status
, output
)
229 def choose_ref(title
, button_text
, default
=None):
230 parent
= qtutils
.active_window()
231 return qt
.GitRefDialog
.ref(title
, button_text
, parent
, default
=default
)
235 """Diff against an arbitrary revision, branch, tag, etc."""
236 branch
= choose_ref('Select Branch to Review', 'Review')
239 merge_base
= gitcmds
.merge_base_parent(branch
)
240 difftool
.diff_commits(qtutils
.active_window(), merge_base
, branch
)