widgets: do not set window modality without a parent
[git-cola.git] / bin / git-cola
blob3de494a34d6780696cb98f49902703716eedeb54
1 #!/usr/bin/env python
2 # -*- python-mode -*-
3 """git-cola: The highly caffeinated Git GUI
4 """
6 __copyright__ = """
7 Copyright (C) 2007, 2008, 2009, 2010, 2011, 2012, 2013
8 David Aguilar <davvid@gmail.com> and contributors
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License version 2 as
12 published by the Free Software Foundation.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 """
21 import os
22 import sys
23 import subprocess
24 from argparse import ArgumentParser
25 from os.path import abspath
26 from os.path import dirname
27 from os.path import realpath
30 def setup_environment():
31 """Provides access to the cola modules"""
32 # Try to detect where it is run from and set prefix and the search path.
33 # It is assumed that the user installed Cola using the --prefix= option
34 prefix = dirname(dirname(realpath(abspath(__file__))))
36 # Look for modules in the source or install trees
37 cola_mod = os.path.join(prefix, 'cola', '__init__.py')
38 if os.path.exists(cola_mod):
39 # Source tree
40 sys.path.insert(1, prefix)
41 else:
42 # Install tree
43 install_lib = os.path.join(prefix, 'share', 'git-cola', 'lib')
44 sys.path.insert(1, install_lib)
45 setup_environment()
47 from cola import core
48 from cola import cmds
49 from cola.app import add_common_arguments
50 from cola.app import application_init
51 from cola.app import application_start
54 def main():
55 # we're using argparse with subparser, but argparse
56 # does not allow us to assign a default subparser
57 # when none has been specified. We fake it by injecting
58 # 'cola' into the command-line so that parse_args()
59 # routes them to the 'cola' parser by default.
60 if (len(sys.argv) < 2 or
61 sys.argv[1].startswith('-') and
62 sys.argv[1] not in ('-h', '--help')):
63 sys.argv.insert(1, 'cola')
64 args = parse_args()
65 return args.func(args)
68 def parse_args():
69 parser = ArgumentParser()
70 subparser = parser.add_subparsers(title='valid commands')
72 add_cola_command(subparser)
73 add_archive_command(subparser)
74 add_branch_command(subparser)
75 add_browse_command(subparser)
76 add_config_command(subparser)
77 add_dag_command(subparser)
78 add_diff_command(subparser)
79 add_fetch_command(subparser)
80 add_grep_command(subparser)
81 add_merge_command(subparser)
82 add_pull_command(subparser)
83 add_push_command(subparser)
84 add_rebase_command(subparser)
85 add_remote_command(subparser)
86 add_search_command(subparser)
87 add_stash_command(subparser)
88 add_tag_command(subparser)
89 add_version_command(subparser)
91 return parser.parse_args()
94 def add_command(parent, name, description, func):
95 parser = parent.add_parser(name, help=description)
96 parser.set_defaults(func=func)
97 add_common_arguments(parser)
98 return parser
101 def add_cola_command(subparser):
102 parser = add_command(subparser, 'cola', 'start git-cola', cmd_cola)
103 parser.add_argument('--amend', default=False, action='store_true',
104 help='start in amend mode')
107 def add_archive_command(parent):
108 parser = add_command(parent, 'archive', 'save an archive', cmd_archive)
109 parser.add_argument('ref', metavar='<ref>', nargs='?', default=None,
110 help='SHA-1 to archive')
113 def add_branch_command(subparser):
114 add_command(subparser, 'branch', 'create a branch', cmd_branch)
117 def add_browse_command(subparser):
118 add_command(subparser, 'browse', 'browse repository', cmd_browse)
119 add_command(subparser, 'classic', 'browse repository', cmd_browse)
122 def add_config_command(subparser):
123 add_command(subparser, 'config', 'edit configuration', cmd_config)
126 def add_dag_command(subparser):
127 parser = add_command(subparser, 'dag', 'start git-dag', cmd_dag)
128 parser.add_argument('-c', '--count', metavar='<count>',
129 type=int, default=1000,
130 help='number of commits to display')
131 parser.add_argument('args', nargs='*', metavar='<args>',
132 help='git log arguments')
134 def add_diff_command(subparser):
135 parser = add_command(subparser, 'diff', 'view diffs', cmd_diff)
136 parser.add_argument('args', nargs='*', metavar='<args>',
137 help='git diff arguments')
140 def add_fetch_command(subparser):
141 add_command(subparser, 'fetch', 'fetch remotes', cmd_fetch)
144 def add_grep_command(subparser):
145 parser = add_command(subparser, 'grep', 'grep source', cmd_grep)
146 parser.add_argument('args', nargs='*', metavar='<args>',
147 help='git grep arguments')
149 def add_merge_command(subparser):
150 add_command(subparser, 'merge', 'merge branches', cmd_merge)
153 def add_pull_command(subparser):
154 parser = add_command(subparser, 'pull', 'pull remote branches', cmd_pull)
155 parser.add_argument('--rebase', default=False, action='store_true',
156 help='rebase local branch when pulling')
159 def add_push_command(subparser):
160 add_command(subparser, 'push', 'push remote branches', cmd_push)
163 def add_rebase_command(subparser):
164 parser = add_command(subparser, 'rebase', 'interactive rebase', cmd_rebase)
165 parser.add_argument('branch', metavar='<branch>',
166 help='New upstream branch')
169 def add_remote_command(subparser):
170 add_command(subparser, 'remote', 'edit remotes', cmd_remote)
173 def add_search_command(subparser):
174 add_command(subparser, 'search', 'search commits', cmd_search)
177 def add_stash_command(subparser):
178 add_command(subparser, 'stash', 'stash and unstash changes', cmd_stash)
181 def add_tag_command(subparser):
182 parser = add_command(subparser, 'tag', 'create tags', cmd_tag)
183 parser.add_argument('name', metavar='<name>', nargs='?', default=None,
184 help='tag name')
185 parser.add_argument('ref', metavar='<ref>', nargs='?', default=None,
186 help='SHA-1 to tag')
187 parser.add_argument('-s', '--sign', default=False, action='store_true',
188 help='annotated and GPG-signed tag')
190 def add_version_command(subparser):
191 parser = add_command(subparser, 'version', 'print the version', cmd_version)
192 parser.add_argument('--brief', action='store_true', default=False,
193 help='print the version number only')
195 # entry points
197 def cmd_cola(args):
198 context = application_init(args)
199 from cola.widgets.main import MainView
200 view = MainView(context.model)
201 if args.amend:
202 cmds.do(cmds.AmendMode, True)
203 return application_start(context, view)
206 def cmd_archive(args):
207 context = application_init(args, update=True)
208 if args.ref is None:
209 args.ref = context.model.currentbranch
211 from cola.widgets.archive import GitArchiveDialog
212 view = GitArchiveDialog(args.ref)
213 return application_start(context, view)
216 def cmd_branch(args):
217 context = application_init(args, update=True)
218 from cola.widgets.createbranch import create_new_branch
219 view = create_new_branch()
220 return application_start(context, view)
223 def cmd_browse(args):
224 context = application_init(args)
225 from cola.widgets.browse import worktree_browser
226 view = worktree_browser(update=False)
227 return application_start(context, view)
230 def cmd_config(args):
231 context = application_init(args)
232 from cola.widgets.prefs import preferences
233 view = preferences()
234 return application_start(context, view)
237 def cmd_dag(args):
238 context = application_init(args)
239 from cola.widgets.dag import git_dag
240 view = git_dag(context.model, args=args)
241 return application_start(context, view)
244 def cmd_diff(args):
245 context = application_init(args)
246 from cola.difftool import diff_expression
247 expr = subprocess.list2cmdline(map(core.decode, args.args))
248 view = diff_expression(None, expr, create_widget=True)
249 return application_start(context, view)
252 def cmd_fetch(args):
253 # TODO: the calls to update_status() can be done asynchronously
254 # by hooking into the message_updated notification.
255 context = application_init(args)
256 from cola.widgets import remote
257 context.model.update_status()
258 view = remote.fetch()
259 return application_start(context, view)
262 def cmd_grep(args):
263 context = application_init(args)
264 from cola.widgets import grep
265 text = subprocess.list2cmdline(map(core.decode, args.args))
266 view = grep.new_grep(text=text, parent=None)
267 return application_start(context, view)
270 def cmd_merge(args):
271 context = application_init(args, update=True)
272 from cola.widgets.merge import MergeView
273 view = MergeView(context.model, parent=None)
274 return application_start(context, view)
277 def cmd_version(args):
278 from cola import version
279 version.print_version(brief=args.brief)
280 return 0
283 def cmd_pull(args):
284 context = application_init(args, update=True)
285 from cola.widgets import remote
286 view = remote.pull()
287 if args.rebase:
288 view.set_rebase(True)
289 return application_start(context, view)
292 def cmd_push(args):
293 context = application_init(args, update=True)
294 from cola.widgets import remote
295 view = remote.push()
296 return application_start(context, view)
299 def cmd_rebase(args):
300 status, out, err = cmds.do(cmds.Rebase, args.branch)
301 if out:
302 core.stdout(out)
303 if err:
304 core.stderr(err)
305 return status
308 def cmd_remote(args):
309 context = application_init(args)
310 from cola.widgets import editremotes
311 view = editremotes.new_remote_editor()
312 return application_start(context, view)
315 def cmd_search(args):
316 context = application_init(args)
317 from cola.widgets.search import search
318 view = search()
319 return application_start(context, view)
322 def cmd_stash(args):
323 context = application_init(args)
324 from cola.widgets.stash import stash
325 view = stash()
326 return application_start(context, view)
329 def cmd_tag(args):
330 context = application_init(args)
331 from cola.widgets.createtag import new_create_tag
332 view = new_create_tag(name=args.name, ref=args.ref, sign=args.sign)
333 return application_start(context, view)
336 if __name__ == '__main__':
337 sys.exit(main())