widgets: rename 'file' to 'filelist'
[git-cola.git] / bin / git-cola
blob26d3d778aa2bc1f9518420a7e6d282d10888798f
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.app import add_common_arguments
48 from cola.app import application_init
49 from cola.app import application_start
51 # NOTE: these must be imported *after* cola.app.
52 # PyQt4 may not be available until after cola.app has gotten a chance to
53 # install the homebrew modules in sys.path.
54 from cola import core
55 from cola import cmds
58 def main():
59 # we're using argparse with subparser, but argparse
60 # does not allow us to assign a default subparser
61 # when none has been specified. We fake it by injecting
62 # 'cola' into the command-line so that parse_args()
63 # routes them to the 'cola' parser by default.
64 if (len(sys.argv) < 2 or
65 sys.argv[1].startswith('-') and
66 sys.argv[1] not in ('-h', '--help')):
67 sys.argv.insert(1, 'cola')
68 args = parse_args()
69 return args.func(args)
72 def parse_args():
73 parser = ArgumentParser()
74 subparser = parser.add_subparsers(title='valid commands')
76 add_cola_command(subparser)
77 add_am_command(subparser)
78 add_archive_command(subparser)
79 add_branch_command(subparser)
80 add_browse_command(subparser)
81 add_config_command(subparser)
82 add_dag_command(subparser)
83 add_diff_command(subparser)
84 add_fetch_command(subparser)
85 add_grep_command(subparser)
86 add_merge_command(subparser)
87 add_pull_command(subparser)
88 add_push_command(subparser)
89 add_rebase_command(subparser)
90 add_remote_command(subparser)
91 add_search_command(subparser)
92 add_stash_command(subparser)
93 add_tag_command(subparser)
94 add_version_command(subparser)
96 return parser.parse_args()
99 def add_command(parent, name, description, func):
100 parser = parent.add_parser(name, help=description)
101 parser.set_defaults(func=func)
102 add_common_arguments(parser)
103 return parser
106 def add_cola_command(subparser):
107 parser = add_command(subparser, 'cola', 'start git-cola', cmd_cola)
108 parser.add_argument('--amend', default=False, action='store_true',
109 help='start in amend mode')
112 def add_am_command(parent):
113 parser = add_command(parent, 'am', 'apply patches using "git am"', cmd_am)
114 parser.add_argument('patches', metavar='<patches>', nargs='*',
115 help='patches to apply')
118 def add_archive_command(parent):
119 parser = add_command(parent, 'archive', 'save an archive', cmd_archive)
120 parser.add_argument('ref', metavar='<ref>', nargs='?', default=None,
121 help='SHA-1 to archive')
124 def add_branch_command(subparser):
125 add_command(subparser, 'branch', 'create a branch', cmd_branch)
128 def add_browse_command(subparser):
129 add_command(subparser, 'browse', 'browse repository', cmd_browse)
130 add_command(subparser, 'classic', 'browse repository', cmd_browse)
133 def add_config_command(subparser):
134 add_command(subparser, 'config', 'edit configuration', cmd_config)
137 def add_dag_command(subparser):
138 parser = add_command(subparser, 'dag', 'start git-dag', cmd_dag)
139 parser.add_argument('-c', '--count', metavar='<count>',
140 type=int, default=1000,
141 help='number of commits to display')
142 parser.add_argument('args', nargs='*', metavar='<args>',
143 help='git log arguments')
145 def add_diff_command(subparser):
146 parser = add_command(subparser, 'diff', 'view diffs', cmd_diff)
147 parser.add_argument('args', nargs='*', metavar='<args>',
148 help='git diff arguments')
151 def add_fetch_command(subparser):
152 add_command(subparser, 'fetch', 'fetch remotes', cmd_fetch)
155 def add_grep_command(subparser):
156 parser = add_command(subparser, 'grep', 'grep source', cmd_grep)
157 parser.add_argument('args', nargs='*', metavar='<args>',
158 help='git grep arguments')
160 def add_merge_command(subparser):
161 add_command(subparser, 'merge', 'merge branches', cmd_merge)
164 def add_pull_command(subparser):
165 parser = add_command(subparser, 'pull', 'pull remote branches', cmd_pull)
166 parser.add_argument('--rebase', default=False, action='store_true',
167 help='rebase local branch when pulling')
170 def add_push_command(subparser):
171 add_command(subparser, 'push', 'push remote branches', cmd_push)
174 def add_rebase_command(subparser):
175 parser = add_command(subparser, 'rebase', 'interactive rebase', cmd_rebase)
176 parser.add_argument('branch', metavar='<branch>',
177 help='New upstream branch')
180 def add_remote_command(subparser):
181 add_command(subparser, 'remote', 'edit remotes', cmd_remote)
184 def add_search_command(subparser):
185 add_command(subparser, 'search', 'search commits', cmd_search)
188 def add_stash_command(subparser):
189 add_command(subparser, 'stash', 'stash and unstash changes', cmd_stash)
192 def add_tag_command(subparser):
193 parser = add_command(subparser, 'tag', 'create tags', cmd_tag)
194 parser.add_argument('name', metavar='<name>', nargs='?', default=None,
195 help='tag name')
196 parser.add_argument('ref', metavar='<ref>', nargs='?', default=None,
197 help='SHA-1 to tag')
198 parser.add_argument('-s', '--sign', default=False, action='store_true',
199 help='annotated and GPG-signed tag')
201 def add_version_command(subparser):
202 parser = add_command(subparser, 'version', 'print the version', cmd_version)
203 parser.add_argument('--brief', action='store_true', default=False,
204 help='print the version number only')
206 # entry points
208 def cmd_cola(args):
209 context = application_init(args)
210 from cola.widgets.main import MainView
211 view = MainView(context.model)
212 if args.amend:
213 cmds.do(cmds.AmendMode, True)
214 return application_start(context, view)
217 def cmd_am(args):
218 context = application_init(args)
219 from cola.widgets.patch import new_apply_patches
220 view = new_apply_patches(patches=args.patches)
221 return application_start(context, view)
224 def cmd_archive(args):
225 context = application_init(args, update=True)
226 if args.ref is None:
227 args.ref = context.model.currentbranch
229 from cola.widgets.archive import GitArchiveDialog
230 view = GitArchiveDialog(args.ref)
231 return application_start(context, view)
234 def cmd_branch(args):
235 context = application_init(args, update=True)
236 from cola.widgets.createbranch import create_new_branch
237 view = create_new_branch()
238 return application_start(context, view)
241 def cmd_browse(args):
242 context = application_init(args)
243 from cola.widgets.browse import worktree_browser
244 view = worktree_browser(update=False)
245 return application_start(context, view)
248 def cmd_config(args):
249 context = application_init(args)
250 from cola.widgets.prefs import preferences
251 view = preferences()
252 return application_start(context, view)
255 def cmd_dag(args):
256 context = application_init(args)
257 from cola.widgets.dag import git_dag
258 view = git_dag(context.model, args=args)
259 return application_start(context, view)
262 def cmd_diff(args):
263 context = application_init(args)
264 from cola.difftool import diff_expression
265 expr = subprocess.list2cmdline(map(core.decode, args.args))
266 view = diff_expression(None, expr, create_widget=True)
267 return application_start(context, view)
270 def cmd_fetch(args):
271 # TODO: the calls to update_status() can be done asynchronously
272 # by hooking into the message_updated notification.
273 context = application_init(args)
274 from cola.widgets import remote
275 context.model.update_status()
276 view = remote.fetch()
277 return application_start(context, view)
280 def cmd_grep(args):
281 context = application_init(args)
282 from cola.widgets import grep
283 text = subprocess.list2cmdline(map(core.decode, args.args))
284 view = grep.new_grep(text=text, parent=None)
285 return application_start(context, view)
288 def cmd_merge(args):
289 context = application_init(args, update=True)
290 from cola.widgets.merge import MergeView
291 view = MergeView(context.model, parent=None)
292 return application_start(context, view)
295 def cmd_version(args):
296 from cola import version
297 version.print_version(brief=args.brief)
298 return 0
301 def cmd_pull(args):
302 context = application_init(args, update=True)
303 from cola.widgets import remote
304 view = remote.pull()
305 if args.rebase:
306 view.set_rebase(True)
307 return application_start(context, view)
310 def cmd_push(args):
311 context = application_init(args, update=True)
312 from cola.widgets import remote
313 view = remote.push()
314 return application_start(context, view)
317 def cmd_rebase(args):
318 status, out, err = cmds.do(cmds.Rebase, args.branch, capture_output=False)
319 if out:
320 core.stdout(out)
321 if err:
322 core.stderr(err)
323 return status
326 def cmd_remote(args):
327 context = application_init(args)
328 from cola.widgets import editremotes
329 view = editremotes.new_remote_editor()
330 return application_start(context, view)
333 def cmd_search(args):
334 context = application_init(args)
335 from cola.widgets.search import search
336 view = search()
337 return application_start(context, view)
340 def cmd_stash(args):
341 context = application_init(args)
342 from cola.widgets.stash import stash
343 view = stash()
344 return application_start(context, view)
347 def cmd_tag(args):
348 context = application_init(args)
349 from cola.widgets.createtag import new_create_tag
350 view = new_create_tag(name=args.name, ref=args.ref, sign=args.sign)
351 return application_start(context, view)
354 if __name__ == '__main__':
355 sys.exit(main())