5 from cStringIO
import StringIO
10 from cola
import errors
11 from cola
import gitcfg
12 from cola
import gitcmds
13 from cola
import utils
14 from cola
import signals
15 from cola
import cmdfactory
16 from cola
import difftool
17 from cola
.diffparse
import DiffParser
18 from cola
.models
import selection
20 _notifier
= cola
.notifier()
21 _factory
= cmdfactory
.factory()
22 _config
= gitcfg
.instance()
25 class BaseCommand(object):
26 """Base class for all commands; provides the command pattern"""
30 def is_undoable(self
):
31 """Can this be undone?"""
35 """Return this command's name."""
36 return self
.__class
__.__name
__
39 raise NotImplementedError('%s.do() is unimplemented' % self
.name())
42 raise NotImplementedError('%s.undo() is unimplemented' % self
.name())
45 class Command(BaseCommand
):
46 """Base class for commands that modify the main model"""
48 """Initialize the command and stash away values for use in do()"""
49 # These are commonly used so let's make it easier to write new commands.
50 BaseCommand
.__init
__(self
)
51 self
.model
= cola
.model()
53 self
.old_diff_text
= self
.model
.diff_text
54 self
.old_filename
= self
.model
.filename
55 self
.old_mode
= self
.model
.mode
56 self
.old_head
= self
.model
.head
58 self
.new_diff_text
= self
.old_diff_text
59 self
.new_filename
= self
.old_filename
60 self
.new_head
= self
.old_head
61 self
.new_mode
= self
.old_mode
64 """Perform the operation."""
65 self
.model
.set_diff_text(self
.new_diff_text
)
66 self
.model
.set_filename(self
.new_filename
)
67 self
.model
.set_head(self
.new_head
)
68 self
.model
.set_mode(self
.new_mode
)
71 """Undo the operation."""
72 self
.model
.set_diff_text(self
.old_diff_text
)
73 self
.model
.set_filename(self
.old_filename
)
74 self
.model
.set_head(self
.old_head
)
75 self
.model
.set_mode(self
.old_mode
)
78 class AmendMode(Command
):
79 """Try to amend a commit."""
80 def __init__(self
, amend
):
81 Command
.__init
__(self
)
85 self
.old_commitmsg
= self
.model
.commitmsg
88 self
.new_mode
= self
.model
.mode_amend
89 self
.new_head
= 'HEAD^'
90 self
.new_commitmsg
= self
.model
.prev_commitmsg()
92 # else, amend unchecked, regular commit
93 self
.new_mode
= self
.model
.mode_none
94 self
.new_head
= 'HEAD'
95 self
.new_diff_text
= ''
96 self
.new_commitmsg
= self
.model
.commitmsg
97 # If we're going back into new-commit-mode then search the
98 # undo stack for a previous amend-commit-mode and grab the
99 # commit message at that point in time.
100 if not _factory
.undostack
:
102 undo_count
= len(_factory
.undostack
)
103 for i
in xrange(undo_count
):
104 # Find the latest AmendMode command
105 idx
= undo_count
- i
- 1
106 cmdobj
= _factory
.undostack
[idx
]
107 if type(cmdobj
) is not AmendMode
:
110 self
.new_commitmsg
= cmdobj
.old_commitmsg
114 """Leave/enter amend mode."""
115 """Attempt to enter amend mode. Do not allow this when merging."""
117 if os
.path
.exists(self
.model
.git
.git_path('MERGE_HEAD')):
119 _notifier
.broadcast(signals
.amend
, False)
120 _factory
.prompt_user(signals
.information
,
122 'You are in the middle of a merge.\n'
123 'You cannot amend while merging.')
126 _notifier
.broadcast(signals
.amend
, self
.amending
)
127 self
.model
.set_commitmsg(self
.new_commitmsg
)
129 self
.model
.update_file_status()
134 self
.model
.set_commitmsg(self
.old_commitmsg
)
136 self
.model
.update_file_status()
139 class ApplyDiffSelection(Command
):
140 def __init__(self
, staged
, selected
, offset
, selection
, apply_to_worktree
):
141 Command
.__init
__(self
)
143 self
.selected
= selected
145 self
.selection
= selection
146 self
.apply_to_worktree
= apply_to_worktree
149 if self
.model
.mode
== self
.model
.mode_branch
:
150 # We're applying changes from a different branch!
151 parser
= DiffParser(self
.model
,
152 filename
=self
.model
.filename
,
154 branch
=self
.model
.head
)
156 parser
.process_diff_selection(self
.selected
,
159 apply_to_worktree
=True)
161 # The normal worktree vs index scenario
162 parser
= DiffParser(self
.model
,
163 filename
=self
.model
.filename
,
165 reverse
=self
.apply_to_worktree
)
167 parser
.process_diff_selection(self
.selected
,
171 self
.apply_to_worktree
)
172 _notifier
.broadcast(signals
.log_cmd
, status
, output
)
173 # Redo the diff to show changes
175 diffcmd
= DiffStaged([self
.model
.filename
])
177 diffcmd
= Diff([self
.model
.filename
])
179 self
.model
.update_file_status()
182 class ApplyPatches(Command
):
183 def __init__(self
, patches
):
184 Command
.__init
__(self
)
186 self
.patches
= patches
190 num_patches
= len(self
.patches
)
191 orig_head
= self
.model
.git
.rev_parse('HEAD')
193 for idx
, patch
in enumerate(self
.patches
):
194 status
, output
= self
.model
.git
.am(patch
,
197 # Log the git-am command
198 _notifier
.broadcast(signals
.log_cmd
, status
, output
)
201 diff
= self
.model
.git
.diff('HEAD^!', stat
=True)
202 diff_text
+= 'Patch %d/%d - ' % (idx
+1, num_patches
)
203 diff_text
+= '%s:\n%s\n\n' % (os
.path
.basename(patch
), diff
)
205 diff_text
+= 'Summary:\n'
206 diff_text
+= self
.model
.git
.diff(orig_head
, stat
=True)
209 self
.model
.set_diff_text(diff_text
)
211 self
.model
.update_file_status()
213 _factory
.prompt_user(signals
.information
,
215 '%d patch(es) applied:\n\n%s' %
217 '\n'.join(map(os
.path
.basename
, self
.patches
))))
220 class HeadChangeCommand(Command
):
221 """Changes the model's current head."""
222 def __init__(self
, treeish
):
223 Command
.__init
__(self
)
224 self
.new_head
= treeish
225 self
.new_diff_text
= ''
229 self
.model
.update_file_status()
232 class BranchMode(HeadChangeCommand
):
233 """Enter into diff-branch mode."""
234 def __init__(self
, treeish
, filename
):
235 HeadChangeCommand
.__init
__(self
, treeish
)
236 self
.old_filename
= self
.model
.filename
237 self
.new_filename
= filename
238 self
.new_mode
= self
.model
.mode_branch
239 self
.new_diff_text
= gitcmds
.diff_helper(filename
=filename
,
243 class Checkout(Command
):
245 A command object for git-checkout.
247 'argv' is handed off directly to git.
250 def __init__(self
, argv
, checkout_branch
=False):
251 Command
.__init
__(self
)
253 self
.checkout_branch
= checkout_branch
254 self
.new_diff_text
= ''
257 status
, output
= self
.model
.git
.checkout(with_stderr
=True,
258 with_status
=True, *self
.argv
)
259 _notifier
.broadcast(signals
.log_cmd
, status
, output
)
260 if self
.checkout_branch
:
261 self
.model
.update_status()
263 self
.model
.update_file_status()
266 class CheckoutBranch(Checkout
):
267 """Checkout a branch."""
268 def __init__(self
, branch
, checkout_branch
=True):
269 Checkout
.__init
__(self
, [branch
])
272 class CherryPick(Command
):
273 """Cherry pick commits into the current branch."""
274 def __init__(self
, commits
):
275 Command
.__init
__(self
)
276 self
.commits
= commits
279 self
.model
.cherry_pick_list(self
.commits
)
280 self
.model
.update_file_status()
283 class ResetMode(Command
):
284 """Reset the mode and clear the model's diff text."""
286 Command
.__init
__(self
)
287 self
.new_mode
= self
.model
.mode_none
288 self
.new_head
= 'HEAD'
289 self
.new_diff_text
= ''
293 self
.model
.update_file_status()
296 class Commit(ResetMode
):
297 """Attempt to create a new commit."""
298 def __init__(self
, amend
, msg
):
299 ResetMode
.__init
__(self
)
301 self
.msg
= core
.encode(msg
)
302 self
.old_commitmsg
= self
.model
.commitmsg
303 self
.new_commitmsg
= ''
306 status
, output
= self
.model
.commit_with_msg(self
.msg
, amend
=self
.amend
)
309 self
.model
.set_commitmsg(self
.new_commitmsg
)
312 title
= 'Commit failed: '
313 _notifier
.broadcast(signals
.log_cmd
, status
, title
+output
)
316 class Ignore(Command
):
317 """Add files to .gitignore"""
318 def __init__(self
, filenames
):
319 Command
.__init
__(self
)
320 self
.filenames
= filenames
324 for fname
in self
.filenames
:
325 new_additions
= new_additions
+ fname
+ '\n'
326 for_status
= new_additions
328 if '.gitignore' in gitcmds
.all_files():
329 current_list
= utils
.slurp('.gitignore')
330 new_additions
= new_additions
+ current_list
331 utils
.write('.gitignore', new_additions
)
332 _notifier
.broadcast(signals
.log_cmd
,
334 'Added to .gitignore:\n%s' % for_status
)
335 self
.model
.update_file_status()
338 class Delete(Command
):
339 """Simply delete files."""
340 def __init__(self
, filenames
):
341 Command
.__init
__(self
)
342 self
.filenames
= filenames
343 # We could git-hash-object stuff and provide undo-ability
347 for filename
in self
.filenames
:
353 _factory
.prompt_user(signals
.information
,
355 'Deleting "%s" failed.' % filename
)
357 self
.model
.update_file_status()
359 class DeleteBranch(Command
):
360 """Delete a git branch."""
361 def __init__(self
, branch
):
362 Command
.__init
__(self
)
366 status
, output
= self
.model
.delete_branch(self
.branch
)
368 if output
.startswith('error:'):
369 output
= 'E' + output
[1:]
372 _notifier
.broadcast(signals
.log_cmd
, status
, title
+ output
)
376 """Perform a diff and set the model's current text."""
377 def __init__(self
, filenames
, cached
=False):
378 Command
.__init
__(self
)
379 # Guard against the list of files being empty
384 cached
= not self
.model
.read_only()
385 opts
= dict(ref
=self
.model
.head
)
387 self
.new_filename
= filenames
[0]
388 self
.old_filename
= self
.model
.filename
389 if not self
.model
.read_only():
390 if self
.model
.mode
!= self
.model
.mode_amend
:
391 self
.new_mode
= self
.model
.mode_worktree
392 self
.new_diff_text
= gitcmds
.diff_helper(filename
=self
.new_filename
,
393 cached
=cached
, **opts
)
396 class DiffMode(HeadChangeCommand
):
397 """Enter diff mode and clear the model's diff text."""
398 def __init__(self
, treeish
):
399 HeadChangeCommand
.__init
__(self
, treeish
)
400 self
.new_mode
= self
.model
.mode_diff
403 class DiffExprMode(HeadChangeCommand
):
404 """Enter diff-expr mode and clear the model's diff text."""
405 def __init__(self
, treeish
):
406 HeadChangeCommand
.__init
__(self
, treeish
)
407 self
.new_mode
= self
.model
.mode_diff_expr
410 class Diffstat(Command
):
411 """Perform a diffstat and set the model's diff text."""
413 Command
.__init
__(self
)
414 diff
= self
.model
.git
.diff(self
.model
.head
,
415 unified
=_config
.get('diff.context', 3),
419 self
.new_diff_text
= core
.decode(diff
)
420 self
.new_mode
= self
.model
.mode_worktree
423 class DiffStaged(Diff
):
424 """Perform a staged diff on a file."""
425 def __init__(self
, filenames
):
426 Diff
.__init
__(self
, filenames
, cached
=True)
427 if not self
.model
.read_only():
428 if self
.model
.mode
!= self
.model
.mode_amend
:
429 self
.new_mode
= self
.model
.mode_index
432 class DiffStagedSummary(Command
):
434 Command
.__init
__(self
)
435 cached
= not self
.model
.read_only()
436 diff
= self
.model
.git
.diff(self
.model
.head
,
439 patch_with_stat
=True,
441 self
.new_diff_text
= core
.decode(diff
)
442 if not self
.model
.read_only():
443 if self
.model
.mode
!= self
.model
.mode_amend
:
444 self
.new_mode
= self
.model
.mode_index
447 class Difftool(Command
):
448 """Run git-difftool limited by path."""
449 def __init__(self
, staged
, filenames
):
450 Command
.__init
__(self
)
452 self
.filenames
= filenames
455 if not self
.filenames
:
458 if self
.staged
and not self
.model
.read_only():
459 args
.append('--cached')
460 if self
.model
.head
!= 'HEAD':
461 args
.append(self
.model
.head
)
463 args
.extend(self
.filenames
)
464 difftool
.launch(args
)
468 """Edit a file using the configured gui.editor."""
469 def __init__(self
, filenames
, line_number
=None):
470 Command
.__init
__(self
)
471 self
.filenames
= filenames
472 self
.line_number
= line_number
475 filename
= self
.filenames
[0]
476 if not os
.path
.exists(filename
):
478 editor
= self
.model
.editor()
479 if 'vi' in editor
and self
.line_number
:
480 utils
.fork([editor
, filename
, '+'+self
.line_number
])
482 utils
.fork([editor
, filename
])
485 class FormatPatch(Command
):
486 """Output a patch series given all revisions and a selected subset."""
487 def __init__(self
, to_export
, revs
):
488 Command
.__init
__(self
)
489 self
.to_export
= to_export
493 status
, output
= gitcmds
.format_patchsets(self
.to_export
, self
.revs
)
494 _notifier
.broadcast(signals
.log_cmd
, status
, output
)
497 class GrepMode(Command
):
498 def __init__(self
, txt
):
499 """Perform a git-grep."""
500 Command
.__init
__(self
)
501 self
.new_mode
= self
.model
.mode_grep
502 self
.new_diff_text
= core
.decode(self
.model
.git
.grep(txt
, n
=True))
505 class LoadCommitMessage(Command
):
506 """Loads a commit message from a path."""
507 def __init__(self
, path
):
508 Command
.__init
__(self
)
511 self
.old_commitmsg
= self
.model
.commitmsg
512 self
.old_directory
= self
.model
.directory
516 if not path
or not os
.path
.isfile(path
):
517 raise errors
.UsageError('Error: cannot find commit template',
518 '%s: No such file or directory.' % path
)
519 self
.model
.set_directory(os
.path
.dirname(path
))
520 self
.model
.set_commitmsg(utils
.slurp(path
))
523 self
.model
.set_commitmsg(self
.old_commitmsg
)
524 self
.model
.set_directory(self
.old_directory
)
527 class LoadCommitTemplate(LoadCommitMessage
):
528 """Loads the commit message template specified by commit.template."""
530 LoadCommitMessage
.__init
__(self
, _config
.get('commit.template'))
533 if self
.path
is None:
534 raise errors
.UsageError('Error: unconfigured commit template',
535 'A commit template has not been configured.\n'
536 'Use "git config" to define "commit.template"\n'
537 'so that it points to a commit template.')
538 return LoadCommitMessage
.do(self
)
541 class LoadPreviousMessage(Command
):
542 """Try to amend a commit."""
543 def __init__(self
, sha1
):
544 Command
.__init
__(self
)
546 self
.old_commitmsg
= self
.model
.commitmsg
547 self
.new_commitmsg
= self
.model
.prev_commitmsg(sha1
)
551 self
.model
.set_commitmsg(self
.new_commitmsg
)
554 self
.model
.set_commitmsg(self
.old_commitmsg
)
557 class Mergetool(Command
):
558 """Launch git-mergetool on a list of paths."""
559 def __init__(self
, paths
):
560 Command
.__init
__(self
)
566 utils
.fork(['git', 'mergetool', '--no-prompt', '--'] + self
.paths
)
569 class OpenRepo(Command
):
570 """Launches git-cola on a repo."""
571 def __init__(self
, dirname
):
572 Command
.__init
__(self
)
573 self
.new_directory
= dirname
576 self
.model
.set_directory(self
.new_directory
)
577 utils
.fork([sys
.executable
, sys
.argv
[0], '--repo', self
.new_directory
])
580 class Clone(Command
):
581 """Clones a repository and optionally spawns a new cola session."""
582 def __init__(self
, url
, destdir
, spawn
=True):
583 Command
.__init
__(self
)
585 self
.new_directory
= destdir
589 self
.model
.git
.clone(self
.url
, self
.new_directory
,
590 with_stderr
=True, with_status
=True)
592 utils
.fork(['python', sys
.argv
[0], '--repo', self
.new_directory
])
597 class Rescan(Command
):
598 """Rescans for changes."""
600 self
.model
.update_status(update_index
=True)
603 class ReviewBranchMode(Command
):
604 """Enter into review-branch mode."""
605 def __init__(self
, branch
):
606 Command
.__init
__(self
)
607 self
.new_mode
= self
.model
.mode_review
608 self
.new_head
= gitcmds
.merge_base_parent(branch
)
609 self
.new_diff_text
= ''
613 self
.model
.update_status()
616 class RunConfigAction(Command
):
617 """Run a user-configured action, typically from the "Tools" menu"""
618 def __init__(self
, name
):
619 Command
.__init
__(self
)
621 self
.model
= cola
.model()
624 for env
in ('FILENAME', 'REVISION', 'ARGS'):
631 opts
= _config
.get_guitool_opts(self
.name
)
632 cmd
= opts
.get('cmd')
633 if 'title' not in opts
:
636 if 'prompt' not in opts
or opts
.get('prompt') is True:
637 prompt
= i18n
.gettext('Are you sure you want to run %s?') % cmd
638 opts
['prompt'] = prompt
640 if opts
.get('needsfile'):
641 filename
= selection
.filename()
643 _factory
.prompt_user(signals
.information
,
644 'Please select a file',
645 '"%s" requires a selected file' % cmd
)
647 os
.environ
['FILENAME'] = filename
649 if opts
.get('revprompt') or opts
.get('argprompt'):
651 ok
= _factory
.prompt_user(signals
.run_config_action
, cmd
, opts
)
654 rev
= opts
.get('revision')
655 args
= opts
.get('args')
656 if opts
.get('revprompt') and not rev
:
657 msg
= ('Invalid revision:\n\n'
658 'Revision expression is empty')
660 _factory
.prompt_user(signals
.information
, title
, msg
)
664 elif opts
.get('confirm'):
665 title
= os
.path
.expandvars(opts
.get('title'))
666 prompt
= os
.path
.expandvars(opts
.get('prompt'))
667 if not _factory
.prompt_user(signals
.question
, title
, prompt
):
670 os
.environ
['REVISION'] = rev
672 os
.environ
['ARGS'] = args
673 title
= os
.path
.expandvars(cmd
)
674 _notifier
.broadcast(signals
.log_cmd
, 0, 'running: ' + title
)
675 cmd
= ['sh', '-c', cmd
]
677 if opts
.get('noconsole'):
678 status
, out
, err
= utils
.run_command(cmd
, flag_error
=False)
680 status
, out
, err
= _factory
.prompt_user(signals
.run_command
,
683 _notifier
.broadcast(signals
.log_cmd
, status
,
684 'stdout: %s\nstatus: %s\nstderr: %s' %
685 (out
.rstrip(), status
, err
.rstrip()))
687 if not opts
.get('norescan'):
688 self
.model
.update_status()
692 class SetDiffText(Command
):
693 def __init__(self
, text
):
694 Command
.__init
__(self
)
696 self
.new_diff_text
= text
699 class ShowUntracked(Command
):
700 """Show an untracked file."""
701 # We don't actually do anything other than set the mode right now.
702 # TODO check the mimetype for the file and handle things
704 def __init__(self
, filenames
):
705 Command
.__init
__(self
)
706 self
.new_mode
= self
.model
.mode_worktree
707 # TODO new_diff_text = utils.file_preview(filenames[0])
710 class SignOff(Command
):
712 Command
.__init
__(self
)
714 self
.old_commitmsg
= self
.model
.commitmsg
717 signoff
= self
.signoff()
718 if signoff
in self
.model
.commitmsg
:
720 self
.model
.set_commitmsg(self
.model
.commitmsg
+ '\n' + signoff
)
723 self
.model
.set_commitmsg(self
.old_commitmsg
)
728 user
= pwd
.getpwuid(os
.getuid()).pw_name
730 user
= os
.getenv('USER', 'unknown')
732 name
= _config
.get('user.name', user
)
733 email
= _config
.get('user.email', '%s@%s' % (user
, platform
.node()))
734 return '\nSigned-off-by: %s <%s>' % (name
, email
)
737 class Stage(Command
):
738 """Stage a set of paths."""
739 def __init__(self
, paths
):
740 Command
.__init
__(self
)
744 msg
= 'Staging: %s' % (', '.join(self
.paths
))
745 _notifier
.broadcast(signals
.log_cmd
, 0, msg
)
746 self
.model
.stage_paths(self
.paths
)
749 class StageModified(Stage
):
750 """Stage all modified files."""
752 Stage
.__init
__(self
, None)
753 self
.paths
= self
.model
.modified
756 class StageUntracked(Stage
):
757 """Stage all untracked files."""
759 Stage
.__init
__(self
, None)
760 self
.paths
= self
.model
.untracked
764 """Create a tag object."""
765 def __init__(self
, name
, revision
, sign
=False, message
=''):
766 Command
.__init
__(self
)
768 self
._message
= core
.encode(message
)
769 self
._revision
= revision
773 log_msg
= 'Tagging: "%s" as "%s"' % (self
._revision
, self
._name
)
776 opts
['F'] = self
.model
.tmp_filename()
777 utils
.write(opts
['F'], self
._message
)
780 log_msg
+= ', GPG-signed'
782 status
, output
= self
.model
.git
.tag(self
._name
,
788 opts
['a'] = bool(self
._message
)
789 status
, output
= self
.model
.git
.tag(self
._name
,
798 log_msg
+= '\nOutput:\n%s' % output
800 _notifier
.broadcast(signals
.log_cmd
, status
, log_msg
)
802 self
.model
.update_status()
805 class Unstage(Command
):
806 """Unstage a set of paths."""
807 def __init__(self
, paths
):
808 Command
.__init
__(self
)
812 msg
= 'Unstaging: %s' % (', '.join(self
.paths
))
813 _notifier
.broadcast(signals
.log_cmd
, 0, msg
)
814 self
.model
.unstage_paths(self
.paths
)
817 class UnstageAll(Command
):
818 """Unstage all files; resets the index."""
820 self
.model
.unstage_all()
823 class UnstageSelected(Unstage
):
824 """Unstage selected files."""
826 Unstage
.__init
__(self
, cola
.selection_model().staged
)
829 class UntrackedSummary(Command
):
830 """List possible .gitignore rules as the diff text."""
832 Command
.__init
__(self
)
833 untracked
= self
.model
.untracked
834 suffix
= len(untracked
) > 1 and 's' or ''
836 io
.write('# %s untracked file%s\n' % (len(untracked
), suffix
))
838 io
.write('# possible .gitignore rule%s:\n' % suffix
)
840 io
.write('/'+core
.encode(u
))
841 self
.new_diff_text
= core
.decode(io
.getvalue())
844 class UpdateStatus(Command
):
845 """Update the status of a list of files."""
846 def __init__(self
, files
):
847 Command
.__init
__(self
)
851 self
.model
.update_status_of_files(self
.files
)
854 class VisualizeAll(Command
):
855 """Visualize all branches."""
857 browser
= self
.model
.history_browser()
858 utils
.fork([browser
, '--all'])
861 class VisualizeCurrent(Command
):
862 """Visualize all branches."""
864 browser
= self
.model
.history_browser()
865 utils
.fork([browser
, self
.model
.currentbranch
])
868 class VisualizePaths(Command
):
869 """Path-limited visualization."""
870 def __init__(self
, paths
):
871 Command
.__init
__(self
)
872 browser
= self
.model
.history_browser()
874 self
.argv
= [browser
] + paths
876 self
.argv
= [browser
]
879 utils
.fork(self
.argv
)
882 visualize_revision
= 'visualize_revision'
884 class VisualizeRevision(Command
):
885 """Visualize a specific revision."""
886 def __init__(self
, revision
, paths
=None):
887 Command
.__init
__(self
)
888 self
.revision
= revision
892 argv
= [self
.model
.history_browser()]
894 argv
.append(self
.revision
)
897 argv
.extend(self
.paths
)
903 Register signal mappings with the factory.
905 These commands are automatically created and run when
906 their corresponding signal is broadcast by the notifier.
909 signal_to_command_map
= {
910 signals
.amend_mode
: AmendMode
,
911 signals
.apply_diff_selection
: ApplyDiffSelection
,
912 signals
.apply_patches
: ApplyPatches
,
913 signals
.branch_mode
: BranchMode
,
914 signals
.clone
: Clone
,
915 signals
.checkout
: Checkout
,
916 signals
.checkout_branch
: CheckoutBranch
,
917 signals
.cherry_pick
: CherryPick
,
918 signals
.commit
: Commit
,
919 signals
.delete
: Delete
,
920 signals
.delete_branch
: DeleteBranch
,
922 signals
.diff_mode
: DiffMode
,
923 signals
.diff_expr_mode
: DiffExprMode
,
924 signals
.diff_staged
: DiffStaged
,
925 signals
.diffstat
: Diffstat
,
926 signals
.difftool
: Difftool
,
928 signals
.format_patch
: FormatPatch
,
929 signals
.grep
: GrepMode
,
930 signals
.ignore
: Ignore
,
931 signals
.load_commit_message
: LoadCommitMessage
,
932 signals
.load_commit_template
: LoadCommitTemplate
,
933 signals
.load_previous_message
: LoadPreviousMessage
,
934 signals
.modified_summary
: Diffstat
,
935 signals
.mergetool
: Mergetool
,
936 signals
.open_repo
: OpenRepo
,
937 signals
.rescan
: Rescan
,
938 signals
.reset_mode
: ResetMode
,
939 signals
.review_branch_mode
: ReviewBranchMode
,
940 signals
.run_config_action
: RunConfigAction
,
941 signals
.set_diff_text
: SetDiffText
,
942 signals
.show_untracked
: ShowUntracked
,
943 signals
.signoff
: SignOff
,
944 signals
.stage
: Stage
,
945 signals
.stage_modified
: StageModified
,
946 signals
.stage_untracked
: StageUntracked
,
947 signals
.staged_summary
: DiffStagedSummary
,
949 signals
.unstage
: Unstage
,
950 signals
.unstage_all
: UnstageAll
,
951 signals
.unstage_selected
: UnstageSelected
,
952 signals
.untracked_summary
: UntrackedSummary
,
953 signals
.update_status
: UpdateStatus
,
954 signals
.visualize_all
: VisualizeAll
,
955 signals
.visualize_current
: VisualizeCurrent
,
956 signals
.visualize_paths
: VisualizePaths
,
957 signals
.visualize_revision
: VisualizeRevision
,
960 for signal
, cmd
in signal_to_command_map
.iteritems():
961 _factory
.add_global_command(signal
, cmd
)