1 from __future__
import division
, absolute_import
, unicode_literals
6 from PyQt4
import QtGui
10 from cola
import difftool
11 from cola
import gitcmds
12 from cola
import qtutils
13 from cola
.git
import git
14 from cola
.i18n
import N_
15 from cola
.interaction
import Interaction
16 from cola
.models
import main
17 from cola
.widgets
import completion
18 from cola
.widgets
.browse
import BrowseDialog
19 from cola
.widgets
.selectcommits
import select_commits
20 from cola
.compat
import ustr
24 """Launch the 'Delete Branch' dialog."""
25 branch
= choose_branch(N_('Delete Branch'), N_('Delete'))
28 cmds
.do(cmds
.DeleteBranch
, branch
)
31 def delete_remote_branch():
32 """Launch the 'Delete Remote Branch' dialog."""
33 branch
= choose_remote_branch(N_('Delete Remote Branch'), N_('Delete'))
36 rgx
= re
.compile(r
'^(?P<remote>[^/]+)/(?P<branch>.+)$')
37 match
= rgx
.match(branch
)
39 remote
= match
.group('remote')
40 branch
= match
.group('branch')
41 cmds
.do(cmds
.DeleteRemoteBranch
, remote
, branch
)
45 """Launch the 'Browse Current Branch' dialog."""
46 branch
= gitcmds
.current_branch()
47 BrowseDialog
.browse(branch
)
51 """Prompt for a branch and inspect content at that point in time."""
52 # Prompt for a branch to browse
53 branch
= choose_ref(N_('Browse Commits...'), N_('Browse'))
56 BrowseDialog
.browse(branch
)
59 def checkout_branch():
60 """Launch the 'Checkout Branch' dialog."""
61 branch
= choose_branch(N_('Checkout Branch'), N_('Checkout'))
64 cmds
.do(cmds
.CheckoutBranch
, branch
)
68 """Launch the 'Cherry-Pick' dialog."""
69 revs
, summaries
= gitcmds
.log_helper(all
=True)
70 commits
= select_commits(N_('Cherry-Pick Commit'),
71 revs
, summaries
, multiselect
=False)
74 cmds
.do(cmds
.CherryPick
, commits
)
78 """Prompt for a new directory and create a new Git repository
80 :returns str: repository path or None if no repository was created.
83 dlg
= QtGui
.QFileDialog()
84 dlg
.setFileMode(QtGui
.QFileDialog
.Directory
)
85 dlg
.setOption(QtGui
.QFileDialog
.ShowDirsOnly
)
88 if dlg
.exec_() != QtGui
.QFileDialog
.Accepted
:
90 paths
= dlg
.selectedFiles()
96 # Avoid needlessly calling `git init`.
97 if git
.is_git_dir(path
):
98 # We could prompt here and confirm that they really didn't
99 # mean to open an existing repository, but I think
100 # treating it like an "Open" is a sensible DWIM answer.
103 status
, out
, err
= core
.run_command(['git', 'init', path
])
107 title
= N_('Error Creating Repository')
108 msg
= (N_('"%(command)s" returned exit status %(status)d') %
109 dict(command
='git init %s' % path
, status
=status
))
110 details
= N_('Output:\n%s') % out
113 details
+= N_('Errors: %s') % err
114 qtutils
.critical(title
, msg
, details
)
122 cmds
.do(cmds
.OpenRepo
, dirname
)
125 def clone_repo(spawn
=True):
127 Present GUI controls for cloning a repository
129 A new cola session is invoked when 'spawn' is True.
132 url
, ok
= qtutils
.prompt(N_('Path or URL to clone (Env. $VARS okay)'))
133 url
= os
.path
.expandvars(url
)
134 if not ok
or not url
:
137 # Pick a suitable basename by parsing the URL
138 newurl
= url
.replace('\\', '/').rstrip('/')
139 default
= newurl
.rsplit('/', 1)[-1]
140 if default
== '.git':
141 # The end of the URL is /.git, so assume it's a file path
142 default
= os
.path
.basename(os
.path
.dirname(newurl
))
143 if default
.endswith('.git'):
144 # The URL points to a bare repo
145 default
= default
[:-4]
147 # The URL is the current repo
148 default
= os
.path
.basename(core
.getcwd())
152 Interaction
.information(
154 N_('Could not parse Git URL: "%s"') % url
)
155 Interaction
.log(N_('Could not parse Git URL: "%s"') % url
)
158 # Prompt the user for a directory to use as the parent directory
159 msg
= N_('Select a parent directory for the new clone')
160 dirname
= qtutils
.opendir_dialog(msg
, main
.model().getcwd())
164 destdir
= os
.path
.join(dirname
, default
)
166 if core
.exists(destdir
):
167 # An existing path can be specified
168 msg
= (N_('"%s" already exists, cola will create a new directory') %
170 Interaction
.information('Directory Exists', msg
)
172 # Make sure the new destdir doesn't exist
173 while core
.exists(destdir
):
174 destdir
= olddestdir
+ str(count
)
176 if cmds
.do(cmds
.Clone
, url
, destdir
, spawn
=spawn
):
181 def export_patches():
182 """Run 'git format-patch' on a list of commits."""
183 revs
, summaries
= gitcmds
.log_helper()
184 to_export
= select_commits(N_('Export Patches'), revs
, summaries
)
187 cmds
.do(cmds
.FormatPatch
, reversed(to_export
), reversed(revs
))
190 def diff_expression():
191 """Diff using an arbitrary expression."""
192 tracked
= gitcmds
.tracked_branch()
193 current
= gitcmds
.current_branch()
194 if tracked
and current
:
195 ref
= tracked
+ '..' + current
197 ref
= 'origin/master..'
198 difftool
.diff_expression(qtutils
.active_window(), ref
)
202 dirname
= qtutils
.opendir_dialog(N_('Open Git Repository...'),
203 main
.model().getcwd())
206 cmds
.do(cmds
.OpenRepo
, dirname
)
209 def open_repo_in_new_window():
210 """Spawn a new cola session."""
211 dirname
= qtutils
.opendir_dialog(N_('Open Git Repository...'),
212 main
.model().getcwd())
215 cmds
.do(cmds
.OpenNewRepo
, dirname
)
218 def load_commitmsg():
219 """Load a commit message from a file."""
220 filename
= qtutils
.open_file(N_('Load Commit Message'),
221 directory
=main
.model().getcwd())
223 cmds
.do(cmds
.LoadCommitMessageFromFile
, filename
)
226 def choose_from_dialog(get
, title
, button_text
, default
):
227 parent
= qtutils
.active_window()
228 return get(title
, button_text
, parent
, default
=default
)
231 def choose_ref(title
, button_text
, default
=None):
232 return choose_from_dialog(completion
.GitRefDialog
.get
,
233 title
, button_text
, default
)
236 def choose_branch(title
, button_text
, default
=None):
237 return choose_from_dialog(completion
.GitBranchDialog
.get
,
238 title
, button_text
, default
)
241 def choose_remote_branch(title
, button_text
, default
=None):
242 return choose_from_dialog(completion
.GitRemoteBranchDialog
.get
,
243 title
, button_text
, default
)
247 """Diff against an arbitrary revision, branch, tag, etc."""
248 branch
= choose_ref(N_('Select Branch to Review'), N_('Review'))
251 merge_base
= gitcmds
.merge_base_parent(branch
)
252 difftool
.diff_commits(qtutils
.active_window(), merge_base
, branch
)