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 # The normal worktree vs index scenario
150 parser
= DiffParser(self
.model
,
151 filename
=self
.model
.filename
,
153 reverse
=self
.apply_to_worktree
)
155 parser
.process_diff_selection(self
.selected
,
158 apply_to_worktree
=self
.apply_to_worktree
)
159 _notifier
.broadcast(signals
.log_cmd
, status
, output
)
160 # Redo the diff to show changes
162 diffcmd
= DiffStaged([self
.model
.filename
])
164 diffcmd
= Diff([self
.model
.filename
])
166 self
.model
.update_file_status()
169 class ApplyPatches(Command
):
170 def __init__(self
, patches
):
171 Command
.__init
__(self
)
173 self
.patches
= patches
177 num_patches
= len(self
.patches
)
178 orig_head
= self
.model
.git
.rev_parse('HEAD')
180 for idx
, patch
in enumerate(self
.patches
):
181 status
, output
= self
.model
.git
.am(patch
,
184 # Log the git-am command
185 _notifier
.broadcast(signals
.log_cmd
, status
, output
)
188 diff
= self
.model
.git
.diff('HEAD^!', stat
=True)
189 diff_text
+= 'Patch %d/%d - ' % (idx
+1, num_patches
)
190 diff_text
+= '%s:\n%s\n\n' % (os
.path
.basename(patch
), diff
)
192 diff_text
+= 'Summary:\n'
193 diff_text
+= self
.model
.git
.diff(orig_head
, stat
=True)
196 self
.model
.set_diff_text(diff_text
)
198 self
.model
.update_file_status()
200 _factory
.prompt_user(signals
.information
,
202 '%d patch(es) applied:\n\n%s' %
204 '\n'.join(map(os
.path
.basename
, self
.patches
))))
207 class HeadChangeCommand(Command
):
208 """Changes the model's current head."""
209 def __init__(self
, treeish
):
210 Command
.__init
__(self
)
211 self
.new_head
= treeish
212 self
.new_diff_text
= ''
216 self
.model
.update_file_status()
219 class Checkout(Command
):
221 A command object for git-checkout.
223 'argv' is handed off directly to git.
226 def __init__(self
, argv
, checkout_branch
=False):
227 Command
.__init
__(self
)
229 self
.checkout_branch
= checkout_branch
230 self
.new_diff_text
= ''
233 status
, output
= self
.model
.git
.checkout(with_stderr
=True,
234 with_status
=True, *self
.argv
)
235 _notifier
.broadcast(signals
.log_cmd
, status
, output
)
236 if self
.checkout_branch
:
237 self
.model
.update_status()
239 self
.model
.update_file_status()
242 class CheckoutBranch(Checkout
):
243 """Checkout a branch."""
244 def __init__(self
, branch
, checkout_branch
=True):
245 Checkout
.__init
__(self
, [branch
])
248 class CherryPick(Command
):
249 """Cherry pick commits into the current branch."""
250 def __init__(self
, commits
):
251 Command
.__init
__(self
)
252 self
.commits
= commits
255 self
.model
.cherry_pick_list(self
.commits
)
256 self
.model
.update_file_status()
259 class ResetMode(Command
):
260 """Reset the mode and clear the model's diff text."""
262 Command
.__init
__(self
)
263 self
.new_mode
= self
.model
.mode_none
264 self
.new_head
= 'HEAD'
265 self
.new_diff_text
= ''
269 self
.model
.update_file_status()
272 class Commit(ResetMode
):
273 """Attempt to create a new commit."""
274 def __init__(self
, amend
, msg
):
275 ResetMode
.__init
__(self
)
277 self
.msg
= core
.encode(msg
)
278 self
.old_commitmsg
= self
.model
.commitmsg
279 self
.new_commitmsg
= ''
282 tmpfile
= utils
.tmp_filename('commit-message')
283 status
, output
= self
.model
.commit_with_msg(self
.msg
, tmpfile
, amend
=self
.amend
)
286 self
.model
.set_commitmsg(self
.new_commitmsg
)
289 title
= 'Commit failed: '
290 _notifier
.broadcast(signals
.log_cmd
, status
, title
+output
)
293 class Ignore(Command
):
294 """Add files to .gitignore"""
295 def __init__(self
, filenames
):
296 Command
.__init
__(self
)
297 self
.filenames
= filenames
301 for fname
in self
.filenames
:
302 new_additions
= new_additions
+ fname
+ '\n'
303 for_status
= new_additions
305 if os
.path
.exists('.gitignore'):
306 current_list
= utils
.slurp('.gitignore')
307 new_additions
= new_additions
+ current_list
308 utils
.write('.gitignore', new_additions
)
309 _notifier
.broadcast(signals
.log_cmd
,
311 'Added to .gitignore:\n%s' % for_status
)
312 self
.model
.update_file_status()
315 class Delete(Command
):
316 """Simply delete files."""
317 def __init__(self
, filenames
):
318 Command
.__init
__(self
)
319 self
.filenames
= filenames
320 # We could git-hash-object stuff and provide undo-ability
324 for filename
in self
.filenames
:
330 _factory
.prompt_user(signals
.information
,
332 'Deleting "%s" failed.' % filename
)
334 self
.model
.update_file_status()
336 class DeleteBranch(Command
):
337 """Delete a git branch."""
338 def __init__(self
, branch
):
339 Command
.__init
__(self
)
343 status
, output
= self
.model
.delete_branch(self
.branch
)
345 if output
.startswith('error:'):
346 output
= 'E' + output
[1:]
349 _notifier
.broadcast(signals
.log_cmd
, status
, title
+ output
)
353 """Perform a diff and set the model's current text."""
354 def __init__(self
, filenames
, cached
=False):
355 Command
.__init
__(self
)
356 # Guard against the list of files being empty
361 cached
= not self
.model
.read_only()
362 opts
= dict(ref
=self
.model
.head
)
364 self
.new_filename
= filenames
[0]
365 self
.old_filename
= self
.model
.filename
366 if not self
.model
.read_only():
367 if self
.model
.mode
!= self
.model
.mode_amend
:
368 self
.new_mode
= self
.model
.mode_worktree
369 self
.new_diff_text
= gitcmds
.diff_helper(filename
=self
.new_filename
,
370 cached
=cached
, **opts
)
373 class DiffMode(HeadChangeCommand
):
374 """Enter diff mode and clear the model's diff text."""
375 def __init__(self
, treeish
):
376 HeadChangeCommand
.__init
__(self
, treeish
)
377 self
.new_mode
= self
.model
.mode_diff
380 class DiffExprMode(HeadChangeCommand
):
381 """Enter diff-expr mode and clear the model's diff text."""
382 def __init__(self
, treeish
):
383 HeadChangeCommand
.__init
__(self
, treeish
)
384 self
.new_mode
= self
.model
.mode_diff_expr
387 class Diffstat(Command
):
388 """Perform a diffstat and set the model's diff text."""
390 Command
.__init
__(self
)
391 diff
= self
.model
.git
.diff(self
.model
.head
,
392 unified
=_config
.get('diff.context', 3),
396 self
.new_diff_text
= core
.decode(diff
)
397 if not self
.model
.read_only():
398 if self
.model
.mode
!= self
.model
.mode_amend
:
399 self
.new_mode
= self
.model
.mode_worktree
402 class DiffStaged(Diff
):
403 """Perform a staged diff on a file."""
404 def __init__(self
, filenames
):
405 Diff
.__init
__(self
, filenames
, cached
=True)
406 if not self
.model
.read_only():
407 if self
.model
.mode
!= self
.model
.mode_amend
:
408 self
.new_mode
= self
.model
.mode_index
411 class DiffStagedSummary(Command
):
413 Command
.__init
__(self
)
414 cached
= not self
.model
.read_only()
415 diff
= self
.model
.git
.diff(self
.model
.head
,
418 patch_with_stat
=True,
420 self
.new_diff_text
= core
.decode(diff
)
421 if not self
.model
.read_only():
422 if self
.model
.mode
!= self
.model
.mode_amend
:
423 self
.new_mode
= self
.model
.mode_index
426 class Difftool(Command
):
427 """Run git-difftool limited by path."""
428 def __init__(self
, staged
, filenames
):
429 Command
.__init
__(self
)
431 self
.filenames
= filenames
434 if not self
.filenames
:
437 if self
.staged
and not self
.model
.read_only():
438 args
.append('--cached')
439 if self
.model
.head
!= 'HEAD':
440 args
.append(self
.model
.head
)
442 args
.extend(self
.filenames
)
443 difftool
.launch(args
)
447 """Edit a file using the configured gui.editor."""
448 def __init__(self
, filenames
, line_number
=None):
449 Command
.__init
__(self
)
450 self
.filenames
= filenames
451 self
.line_number
= line_number
454 filename
= self
.filenames
[0]
455 if not os
.path
.exists(filename
):
457 editor
= self
.model
.editor()
458 if editor
== 'gvim' and self
.line_number
:
459 utils
.fork([editor
, filename
, '+'+self
.line_number
])
461 utils
.fork([editor
, filename
])
464 class FormatPatch(Command
):
465 """Output a patch series given all revisions and a selected subset."""
466 def __init__(self
, to_export
, revs
):
467 Command
.__init
__(self
)
468 self
.to_export
= to_export
472 status
, output
= gitcmds
.format_patchsets(self
.to_export
, self
.revs
)
473 _notifier
.broadcast(signals
.log_cmd
, status
, output
)
476 class GrepMode(Command
):
477 def __init__(self
, txt
):
478 """Perform a git-grep."""
479 Command
.__init
__(self
)
480 self
.new_mode
= self
.model
.mode_grep
481 self
.new_diff_text
= core
.decode(self
.model
.git
.grep(txt
, n
=True))
484 class LoadCommitMessage(Command
):
485 """Loads a commit message from a path."""
486 def __init__(self
, path
):
487 Command
.__init
__(self
)
490 self
.old_commitmsg
= self
.model
.commitmsg
491 self
.old_directory
= self
.model
.directory
495 if not path
or not os
.path
.isfile(path
):
496 raise errors
.UsageError('Error: cannot find commit template',
497 '%s: No such file or directory.' % path
)
498 self
.model
.set_directory(os
.path
.dirname(path
))
499 self
.model
.set_commitmsg(utils
.slurp(path
))
502 self
.model
.set_commitmsg(self
.old_commitmsg
)
503 self
.model
.set_directory(self
.old_directory
)
506 class LoadCommitTemplate(LoadCommitMessage
):
507 """Loads the commit message template specified by commit.template."""
509 LoadCommitMessage
.__init
__(self
, _config
.get('commit.template'))
512 if self
.path
is None:
513 raise errors
.UsageError('Error: unconfigured commit template',
514 'A commit template has not been configured.\n'
515 'Use "git config" to define "commit.template"\n'
516 'so that it points to a commit template.')
517 return LoadCommitMessage
.do(self
)
520 class LoadPreviousMessage(Command
):
521 """Try to amend a commit."""
522 def __init__(self
, sha1
):
523 Command
.__init
__(self
)
525 self
.old_commitmsg
= self
.model
.commitmsg
526 self
.new_commitmsg
= self
.model
.prev_commitmsg(sha1
)
530 self
.model
.set_commitmsg(self
.new_commitmsg
)
533 self
.model
.set_commitmsg(self
.old_commitmsg
)
536 class Mergetool(Command
):
537 """Launch git-mergetool on a list of paths."""
538 def __init__(self
, paths
):
539 Command
.__init
__(self
)
545 utils
.fork(['git', 'mergetool', '--no-prompt', '--'] + self
.paths
)
548 class OpenRepo(Command
):
549 """Launches git-cola on a repo."""
550 def __init__(self
, dirname
):
551 Command
.__init
__(self
)
552 self
.new_directory
= dirname
555 self
.model
.set_directory(self
.new_directory
)
556 utils
.fork([sys
.executable
, sys
.argv
[0], '--repo', self
.new_directory
])
559 class Clone(Command
):
560 """Clones a repository and optionally spawns a new cola session."""
561 def __init__(self
, url
, destdir
, spawn
=True):
562 Command
.__init
__(self
)
564 self
.new_directory
= destdir
568 self
.model
.git
.clone(self
.url
, self
.new_directory
,
569 with_stderr
=True, with_status
=True)
571 utils
.fork(['python', sys
.argv
[0], '--repo', self
.new_directory
])
576 class Rescan(Command
):
577 """Rescans for changes."""
579 self
.model
.update_status()
582 rescan_and_refresh
= 'rescan_and_refresh'
584 class RescanAndRefresh(Command
):
585 """Rescans for changes."""
587 self
.model
.update_status(update_index
=True)
590 class ReviewBranchMode(Command
):
591 """Enter into review-branch mode."""
592 def __init__(self
, branch
):
593 Command
.__init
__(self
)
594 self
.new_mode
= self
.model
.mode_review
595 self
.new_head
= gitcmds
.merge_base_parent(branch
)
596 self
.new_diff_text
= ''
600 self
.model
.update_status()
603 class RunConfigAction(Command
):
604 """Run a user-configured action, typically from the "Tools" menu"""
605 def __init__(self
, name
):
606 Command
.__init
__(self
)
608 self
.model
= cola
.model()
611 for env
in ('FILENAME', 'REVISION', 'ARGS'):
618 opts
= _config
.get_guitool_opts(self
.name
)
619 cmd
= opts
.get('cmd')
620 if 'title' not in opts
:
623 if 'prompt' not in opts
or opts
.get('prompt') is True:
624 prompt
= i18n
.gettext('Are you sure you want to run %s?') % cmd
625 opts
['prompt'] = prompt
627 if opts
.get('needsfile'):
628 filename
= selection
.filename()
630 _factory
.prompt_user(signals
.information
,
631 'Please select a file',
632 '"%s" requires a selected file' % cmd
)
634 os
.environ
['FILENAME'] = filename
636 if opts
.get('revprompt') or opts
.get('argprompt'):
638 ok
= _factory
.prompt_user(signals
.run_config_action
, cmd
, opts
)
641 rev
= opts
.get('revision')
642 args
= opts
.get('args')
643 if opts
.get('revprompt') and not rev
:
644 title
= 'Invalid Revision'
645 msg
= 'The revision expression cannot be empty.'
646 _factory
.prompt_user(signals
.critical
, title
, msg
)
650 elif opts
.get('confirm'):
651 title
= os
.path
.expandvars(opts
.get('title'))
652 prompt
= os
.path
.expandvars(opts
.get('prompt'))
653 if not _factory
.prompt_user(signals
.question
, title
, prompt
):
656 os
.environ
['REVISION'] = rev
658 os
.environ
['ARGS'] = args
659 title
= os
.path
.expandvars(cmd
)
660 _notifier
.broadcast(signals
.log_cmd
, 0, 'running: ' + title
)
661 cmd
= ['sh', '-c', cmd
]
663 if opts
.get('noconsole'):
664 status
, out
, err
= utils
.run_command(cmd
, flag_error
=False)
666 status
, out
, err
= _factory
.prompt_user(signals
.run_command
,
669 _notifier
.broadcast(signals
.log_cmd
, status
,
670 'stdout: %s\nstatus: %s\nstderr: %s' %
671 (out
.rstrip(), status
, err
.rstrip()))
673 if not opts
.get('norescan'):
674 self
.model
.update_status()
678 class SetDiffText(Command
):
679 def __init__(self
, text
):
680 Command
.__init
__(self
)
682 self
.new_diff_text
= text
685 class ShowUntracked(Command
):
686 """Show an untracked file."""
687 # We don't actually do anything other than set the mode right now.
688 # TODO check the mimetype for the file and handle things
690 def __init__(self
, filenames
):
691 Command
.__init
__(self
)
692 if not self
.model
.read_only():
693 if self
.model
.mode
!= self
.model
.mode_amend
:
694 self
.new_mode
= self
.model
.mode_untracked
695 # TODO new_diff_text = utils.file_preview(filenames[0])
698 class SignOff(Command
):
700 Command
.__init
__(self
)
702 self
.old_commitmsg
= self
.model
.commitmsg
705 signoff
= self
.signoff()
706 if signoff
in self
.model
.commitmsg
:
708 self
.model
.set_commitmsg(self
.model
.commitmsg
+ '\n' + signoff
)
711 self
.model
.set_commitmsg(self
.old_commitmsg
)
716 user
= pwd
.getpwuid(os
.getuid()).pw_name
718 user
= os
.getenv('USER', 'unknown')
720 name
= _config
.get('user.name', user
)
721 email
= _config
.get('user.email', '%s@%s' % (user
, platform
.node()))
722 return '\nSigned-off-by: %s <%s>' % (name
, email
)
725 class Stage(Command
):
726 """Stage a set of paths."""
727 def __init__(self
, paths
):
728 Command
.__init
__(self
)
732 msg
= 'Staging: %s' % (', '.join(self
.paths
))
733 _notifier
.broadcast(signals
.log_cmd
, 0, msg
)
734 self
.model
.stage_paths(self
.paths
)
737 class StageModified(Stage
):
738 """Stage all modified files."""
740 Stage
.__init
__(self
, None)
741 self
.paths
= self
.model
.modified
744 class StageUnmerged(Stage
):
745 """Stage all modified files."""
747 Stage
.__init
__(self
, None)
748 self
.paths
= self
.model
.unmerged
751 class StageUntracked(Stage
):
752 """Stage all untracked files."""
754 Stage
.__init
__(self
, None)
755 self
.paths
= self
.model
.untracked
759 """Create a tag object."""
760 def __init__(self
, name
, revision
, sign
=False, message
=''):
761 Command
.__init
__(self
)
763 self
._message
= core
.encode(message
)
764 self
._revision
= revision
768 log_msg
= 'Tagging: "%s" as "%s"' % (self
._revision
, self
._name
)
771 opts
['F'] = utils
.tmp_filename('tag-message')
772 utils
.write(opts
['F'], self
._message
)
775 log_msg
+= ', GPG-signed'
777 status
, output
= self
.model
.git
.tag(self
._name
,
783 opts
['a'] = bool(self
._message
)
784 status
, output
= self
.model
.git
.tag(self
._name
,
793 log_msg
+= '\nOutput:\n%s' % output
795 _notifier
.broadcast(signals
.log_cmd
, status
, log_msg
)
797 self
.model
.update_status()
800 class Unstage(Command
):
801 """Unstage a set of paths."""
802 def __init__(self
, paths
):
803 Command
.__init
__(self
)
807 msg
= 'Unstaging: %s' % (', '.join(self
.paths
))
808 _notifier
.broadcast(signals
.log_cmd
, 0, msg
)
809 self
.model
.unstage_paths(self
.paths
)
812 class UnstageAll(Command
):
813 """Unstage all files; resets the index."""
815 self
.model
.unstage_all()
818 class UnstageSelected(Unstage
):
819 """Unstage selected files."""
821 Unstage
.__init
__(self
, cola
.selection_model().staged
)
824 class UntrackedSummary(Command
):
825 """List possible .gitignore rules as the diff text."""
827 Command
.__init
__(self
)
828 untracked
= self
.model
.untracked
829 suffix
= len(untracked
) > 1 and 's' or ''
831 io
.write('# %s untracked file%s\n' % (len(untracked
), suffix
))
833 io
.write('# possible .gitignore rule%s:\n' % suffix
)
835 io
.write('/'+core
.encode(u
))
836 self
.new_diff_text
= core
.decode(io
.getvalue())
838 if not self
.model
.read_only():
839 if self
.model
.mode
!= self
.model
.mode_amend
:
840 self
.new_mode
= self
.model
.mode_untracked
843 class UpdateFileStatus(Command
):
844 """Rescans for changes."""
846 self
.model
.update_file_status()
849 class VisualizeAll(Command
):
850 """Visualize all branches."""
852 browser
= self
.model
.history_browser()
853 utils
.fork([browser
, '--all'])
856 class VisualizeCurrent(Command
):
857 """Visualize all branches."""
859 browser
= self
.model
.history_browser()
860 utils
.fork([browser
, self
.model
.currentbranch
])
863 class VisualizePaths(Command
):
864 """Path-limited visualization."""
865 def __init__(self
, paths
):
866 Command
.__init
__(self
)
867 browser
= self
.model
.history_browser()
869 self
.argv
= [browser
] + paths
871 self
.argv
= [browser
]
874 utils
.fork(self
.argv
)
877 visualize_revision
= 'visualize_revision'
879 class VisualizeRevision(Command
):
880 """Visualize a specific revision."""
881 def __init__(self
, revision
, paths
=None):
882 Command
.__init
__(self
)
883 self
.revision
= revision
887 argv
= [self
.model
.history_browser()]
889 argv
.append(self
.revision
)
892 argv
.extend(self
.paths
)
898 Register signal mappings with the factory.
900 These commands are automatically created and run when
901 their corresponding signal is broadcast by the notifier.
904 signal_to_command_map
= {
905 signals
.amend_mode
: AmendMode
,
906 signals
.apply_diff_selection
: ApplyDiffSelection
,
907 signals
.apply_patches
: ApplyPatches
,
908 signals
.clone
: Clone
,
909 signals
.checkout
: Checkout
,
910 signals
.checkout_branch
: CheckoutBranch
,
911 signals
.cherry_pick
: CherryPick
,
912 signals
.commit
: Commit
,
913 signals
.delete
: Delete
,
914 signals
.delete_branch
: DeleteBranch
,
916 signals
.diff_mode
: DiffMode
,
917 signals
.diff_expr_mode
: DiffExprMode
,
918 signals
.diff_staged
: DiffStaged
,
919 signals
.diffstat
: Diffstat
,
920 signals
.difftool
: Difftool
,
922 signals
.format_patch
: FormatPatch
,
923 signals
.grep
: GrepMode
,
924 signals
.ignore
: Ignore
,
925 signals
.load_commit_message
: LoadCommitMessage
,
926 signals
.load_commit_template
: LoadCommitTemplate
,
927 signals
.load_previous_message
: LoadPreviousMessage
,
928 signals
.modified_summary
: Diffstat
,
929 signals
.mergetool
: Mergetool
,
930 signals
.open_repo
: OpenRepo
,
931 signals
.rescan
: Rescan
,
932 signals
.rescan_and_refresh
: RescanAndRefresh
,
933 signals
.reset_mode
: ResetMode
,
934 signals
.review_branch_mode
: ReviewBranchMode
,
935 signals
.run_config_action
: RunConfigAction
,
936 signals
.set_diff_text
: SetDiffText
,
937 signals
.show_untracked
: ShowUntracked
,
938 signals
.signoff
: SignOff
,
939 signals
.stage
: Stage
,
940 signals
.stage_modified
: StageModified
,
941 signals
.stage_unmerged
: StageUnmerged
,
942 signals
.stage_untracked
: StageUntracked
,
943 signals
.staged_summary
: DiffStagedSummary
,
945 signals
.unstage
: Unstage
,
946 signals
.unstage_all
: UnstageAll
,
947 signals
.unstage_selected
: UnstageSelected
,
948 signals
.untracked_summary
: UntrackedSummary
,
949 signals
.update_file_status
: UpdateFileStatus
,
950 signals
.visualize_all
: VisualizeAll
,
951 signals
.visualize_current
: VisualizeCurrent
,
952 signals
.visualize_paths
: VisualizePaths
,
953 signals
.visualize_revision
: VisualizeRevision
,
956 for signal
, cmd
in signal_to_command_map
.iteritems():
957 _factory
.add_global_command(signal
, cmd
)