4 from PyQt4
import QtGui
8 from cola
import difftool
9 from cola
import gitcmds
10 from cola
import qtutils
11 from cola
.git
import git
12 from cola
.i18n
import N_
13 from cola
.interaction
import Interaction
14 from cola
.models
import main
15 from cola
.widgets
import completion
16 from cola
.widgets
.browse
import BrowseDialog
17 from cola
.widgets
.selectcommits
import select_commits
22 """Launch the 'Delete Branch' dialog."""
23 branch
= choose_branch(N_('Delete Branch'), N_('Delete'))
26 cmds
.do(cmds
.DeleteBranch
, branch
)
29 def delete_remote_branch():
30 """Launch the 'Delete Remote Branch' dialog."""
31 branch
= choose_remote_branch(N_('Delete Remote Branch'), N_('Delete'))
34 rgx
= re
.compile(r
'^(?P<remote>[^/]+)/(?P<branch>.+)$')
35 match
= rgx
.match(branch
)
37 remote
= match
.group('remote')
38 branch
= match
.group('branch')
39 cmds
.do(cmds
.DeleteRemoteBranch
, remote
, branch
)
43 """Launch the 'Browse Current Branch' dialog."""
44 branch
= gitcmds
.current_branch()
45 BrowseDialog
.browse(branch
)
49 """Prompt for a branch and inspect content at that point in time."""
50 # Prompt for a branch to browse
51 branch
= choose_ref(N_('Browse Commits...'), N_('Browse'))
54 BrowseDialog
.browse(branch
)
57 def checkout_branch():
58 """Launch the 'Checkout Branch' dialog."""
59 branch
= choose_branch(N_('Checkout Branch'), N_('Checkout'))
62 cmds
.do(cmds
.CheckoutBranch
, branch
)
66 """Launch the 'Cherry-Pick' dialog."""
67 revs
, summaries
= gitcmds
.log_helper(all
=True)
68 commits
= select_commits(N_('Cherry-Pick Commit'),
69 revs
, summaries
, multiselect
=False)
72 cmds
.do(cmds
.CherryPick
, commits
)
76 """Prompt for a new directory and create a new Git repository
78 :returns str: repository path or None if no repository was created.
81 dlg
= QtGui
.QFileDialog()
82 dlg
.setFileMode(QtGui
.QFileDialog
.Directory
)
83 dlg
.setOption(QtGui
.QFileDialog
.ShowDirsOnly
)
86 if dlg
.exec_() != QtGui
.QFileDialog
.Accepted
:
88 paths
= dlg
.selectedFiles()
91 path
= unicode(paths
[0])
94 # Avoid needlessly calling `git init`.
95 if git
.is_git_dir(path
):
96 # We could prompt here and confirm that they really didn't
97 # mean to open an existing repository, but I think
98 # treating it like an "Open" is a sensible DWIM answer.
101 status
, out
, err
= core
.run_command(['git', 'init', path
])
105 title
= N_('Error Creating Repository')
106 msg
= (N_('"%(command)s" returned exit status %(status)d') %
107 dict(command
='git init %s' % path
, status
=status
))
108 details
= N_('Output:\n%s') % out
111 details
+= N_('Errors: %s') % err
112 qtutils
.critical(title
, msg
, details
)
120 cmds
.do(cmds
.OpenRepo
, dirname
)
123 def clone_repo(spawn
=True):
125 Present GUI controls for cloning a repository
127 A new cola session is invoked when 'spawn' is True.
130 url
, ok
= qtutils
.prompt(N_('Path or URL to clone (Env. $VARS okay)'))
131 url
= os
.path
.expandvars(url
)
132 if not ok
or not url
:
135 # Pick a suitable basename by parsing the URL
136 newurl
= url
.replace('\\', '/').rstrip('/')
137 default
= newurl
.rsplit('/', 1)[-1]
138 if default
== '.git':
139 # The end of the URL is /.git, so assume it's a file path
140 default
= os
.path
.basename(os
.path
.dirname(newurl
))
141 if default
.endswith('.git'):
142 # The URL points to a bare repo
143 default
= default
[:-4]
145 # The URL is the current repo
146 default
= os
.path
.basename(core
.getcwd())
150 Interaction
.information(
152 N_('Could not parse Git URL: "%s"') % url
)
153 Interaction
.log(N_('Could not parse Git URL: "%s"') % url
)
156 # Prompt the user for a directory to use as the parent directory
157 msg
= N_('Select a parent directory for the new clone')
158 dirname
= qtutils
.opendir_dialog(msg
, main
.model().getcwd())
162 destdir
= os
.path
.join(dirname
, default
)
164 if core
.exists(destdir
):
165 # An existing path can be specified
166 msg
= (N_('"%s" already exists, cola will create a new directory') %
168 Interaction
.information('Directory Exists', msg
)
170 # Make sure the new destdir doesn't exist
171 while core
.exists(destdir
):
172 destdir
= olddestdir
+ str(count
)
174 if cmds
.do(cmds
.Clone
, url
, destdir
, spawn
=spawn
):
179 def export_patches():
180 """Run 'git format-patch' on a list of commits."""
181 revs
, summaries
= gitcmds
.log_helper()
182 to_export
= select_commits(N_('Export Patches'), revs
, summaries
)
187 cmds
.do(cmds
.FormatPatch
, to_export
, 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 """Spawn a new cola session."""
203 dirname
= qtutils
.opendir_dialog(N_('Open Git Repository...'),
204 main
.model().getcwd())
207 cmds
.do(cmds
.OpenRepo
, dirname
)
210 def load_commitmsg():
211 """Load a commit message from a file."""
212 filename
= qtutils
.open_file(N_('Load Commit Message'),
213 directory
=main
.model().getcwd())
215 cmds
.do(cmds
.LoadCommitMessageFromFile
, filename
)
218 def choose_from_dialog(get
, title
, button_text
, default
):
219 parent
= qtutils
.active_window()
220 return get(title
, button_text
, parent
, default
=default
)
223 def choose_ref(title
, button_text
, default
=None):
224 return choose_from_dialog(completion
.GitRefDialog
.get
,
225 title
, button_text
, default
)
228 def choose_branch(title
, button_text
, default
=None):
229 return choose_from_dialog(completion
.GitBranchDialog
.get
,
230 title
, button_text
, default
)
233 def choose_remote_branch(title
, button_text
, default
=None):
234 return choose_from_dialog(completion
.GitRemoteBranchDialog
.get
,
235 title
, button_text
, default
)
239 """Diff against an arbitrary revision, branch, tag, etc."""
240 branch
= choose_ref(N_('Select Branch to Review'), N_('Review'))
243 merge_base
= gitcmds
.merge_base_parent(branch
)
244 difftool
.diff_commits(qtutils
.active_window(), merge_base
, branch
)