def __init__(self, monitor): _BaseThread.__init__(self, monitor) self._worktree = self._transform_path(core.abspath(git.worktree())) self._worktree_watch = None self._git_dir = self._transform_path(core.abspath(git.git_dir())) self._git_dir_watch = None self._stop_event_lock = Lock() self._stop_event = None
def __init__(self, monitor, refs_only): _BaseThread.__init__(self, monitor, refs_only) self._worktree = self._transform_path(core.abspath(git.getcwd())) self._worktree_watch = None self._git_dir = self._transform_path(core.abspath(git.git_path())) self._git_dir_watch = None self._stop_event_lock = Lock() self._stop_event = None
def contextMenuEvent(self, event): """Create the context menu for the diff display.""" menu = QtGui.QMenu(self) s = selection.selection() if self.model.stageable(): if s.modified and s.modified[0] in main.model().submodules: action = menu.addAction(qtutils.icon('add.svg'), cmds.Stage.name(), cmds.run(cmds.Stage, s.modified)) action.setShortcut(cmds.Stage.SHORTCUT) menu.addAction(qtutils.git_icon(), N_('Launch git-cola'), cmds.run(cmds.OpenRepo, core.abspath(s.modified[0]))) elif s.modified: action = menu.addAction(qtutils.icon('add.svg'), N_('Stage Section'), self.stage_section) action.setShortcut(Qt.Key_H) menu.addAction(self.action_stage_selection) menu.addSeparator() menu.addAction(qtutils.icon('undo.svg'), N_('Revert Section...'), self.revert_section) menu.addAction(self.action_revert_selection) if self.model.unstageable(): if s.staged and s.staged[0] in main.model().submodules: action = menu.addAction(qtutils.icon('remove.svg'), cmds.Unstage.name(), cmds.do(cmds.Unstage, s.staged)) action.setShortcut(cmds.Unstage.SHORTCUT) menu.addAction(qtutils.git_icon(), N_('Launch git-cola'), cmds.do(cmds.OpenRepo, core.abspath(s.staged[0]))) elif s.staged: action = menu.addAction(qtutils.icon('remove.svg'), N_('Unstage Section'), self.unstage_section) action.setShortcut(Qt.Key_H) menu.addAction(self.action_unstage_selection) if self.model.stageable() or self.model.unstageable(): menu.addSeparator() menu.addAction(self.launch_editor) menu.addAction(self.launch_difftool) menu.addSeparator() action = menu.addAction(qtutils.icon('edit-copy.svg'), N_('Copy'), self.copy) action.setShortcut(QtGui.QKeySequence.Copy) action = menu.addAction(qtutils.icon('edit-select-all.svg'), N_('Select All'), self.selectAll) action.setShortcut(QtGui.QKeySequence.SelectAll) menu.exec_(self.mapToGlobal(event.pos()))
def __init__(self, monitor, refs_only): _BaseThread.__init__(self, monitor, refs_only) if refs_only: worktree = None else: worktree = git.worktree() if worktree is not None: worktree = self._transform_path(core.abspath(worktree)) self._worktree = worktree self._worktree_watch = None self._git_dir = self._transform_path(core.abspath(git.git_path())) self._git_dir_watch = None self._stop_event_lock = Lock() self._stop_event = None
def copy_path(filename, absolute=True): """Copy a filename to the clipboard""" if filename is None: return if absolute: filename = core.abspath(filename) set_clipboard(filename)
def setup_environment(): # Spoof an X11 display for SSH os.environ.setdefault('DISPLAY', ':0') # Setup the path so that git finds us when we run 'git cola' path_entries = core.getenv('PATH', '').split(os.pathsep) bindir = os.path.dirname(core.abspath(__file__)) path_entries.insert(0, bindir) path = os.pathsep.join(path_entries) compat.setenv('PATH', path) # We don't ever want a pager compat.setenv('GIT_PAGER', '') # Setup *SSH_ASKPASS git_askpass = core.getenv('GIT_ASKPASS') ssh_askpass = core.getenv('SSH_ASKPASS') if git_askpass: askpass = git_askpass elif ssh_askpass: askpass = ssh_askpass elif sys.platform == 'darwin': askpass = resources.share('bin', 'ssh-askpass-darwin') else: askpass = resources.share('bin', 'ssh-askpass') compat.setenv('GIT_ASKPASS', askpass) compat.setenv('SSH_ASKPASS', askpass) # --- >8 --- >8 --- # Git v1.7.10 Release Notes # ========================= # # Compatibility Notes # ------------------- # # * From this release on, the "git merge" command in an interactive # session will start an editor when it automatically resolves the # merge for the user to explain the resulting commit, just like the # "git commit" command does when it wasn't given a commit message. # # If you have a script that runs "git merge" and keeps its standard # input and output attached to the user's terminal, and if you do not # want the user to explain the resulting merge commits, you can # export GIT_MERGE_AUTOEDIT environment variable set to "no", like # this: # # #!/bin/sh # GIT_MERGE_AUTOEDIT=no # export GIT_MERGE_AUTOEDIT # # to disable this behavior (if you want your users to explain their # merge commits, you do not have to do anything). Alternatively, you # can give the "--no-edit" option to individual invocations of the # "git merge" command if you know everybody who uses your script has # Git v1.7.8 or newer. # --- >8 --- >8 --- # Longer-term: Use `git merge --no-commit` so that we always # have a chance to explain our merges. compat.setenv('GIT_MERGE_AUTOEDIT', 'no')
def mimedata_from_paths(paths): """Return mimedata with a list of absolute path URLs""" abspaths = [core.abspath(path) for path in paths] urls = [QtCore.QUrl.fromLocalFile(path) for path in abspaths] unicode_urls = [core.decode(bytes(url.toEncoded().data())) for url in urls] raw_text = core.encode('\r\n'.join(unicode_urls) + '\r\n') text = QtCore.QByteArray(raw_text) mimedata = QtCore.QMimeData() mimedata.setUrls(urls) mimedata.setData('text/plain', text) mimedata.setData('UTF8_STRING', text) mimedata.setData('COMPOUND_TEXT', text) mimedata.setData('TEXT', text) mimedata.setData('STRING', text) mimedata.setData('text/plain;charset=utf-8', text) # The text/x-moz-list format is raw text encoded in utf-16. # Failure to encode prevents gnome-terminal from getting the right paths. moz_text = subprocess.list2cmdline(abspaths) moz_text = core.encode(moz_text, encoding='utf-16') mimedata.setData('text/x-moz-url', moz_text) return mimedata
def __init__(self, monitor): _BaseThread.__init__(self, monitor) self._worktree = core.abspath(git.worktree()) self._git_dir = git.git_dir() self._lock = Lock() self._inotify_fd = None self._pipe_r = None self._pipe_w = None self._worktree_wds = set() self._worktree_wd_map = {} self._git_dir_wds = set() self._git_dir_wd_map = {}
def worktree(self): if self._worktree: return self._worktree self.git_dir() if self._git_dir: curdir = self._git_dir else: curdir = core.getcwd() if is_git_dir(join(curdir, '.git')): return curdir # Handle bare repositories if (len(os.path.basename(curdir)) > 4 and curdir.endswith('.git')): return curdir if 'GIT_WORK_TREE' in os.environ: self._worktree = core.getenv('GIT_WORK_TREE') if not self._worktree or not core.isdir(self._worktree): if self._git_dir: gitparent = join(core.abspath(self._git_dir), '..') self._worktree = core.abspath(gitparent) self.set_cwd(self._worktree) return self._worktree
def git_dir(self): if self.is_valid(): return self._git_dir if 'GIT_DIR' in os.environ: self._git_dir = core.getenv('GIT_DIR') if self._git_dir: curpath = core.abspath(self._git_dir) else: curpath = core.abspath(core.getcwd()) # Search for a .git directory while curpath: if is_git_dir(curpath): self._git_dir = curpath break gitpath = join(curpath, '.git') if is_git_dir(gitpath): self._git_dir = gitpath break curpath, dummy = os.path.split(curpath) if not dummy: break self._git_file_path = read_git_file(self._git_dir) return self._git_dir
def _create_staged_submodule_context_menu(self, menu, s): menu.addAction(icons.cola(), N_("Launch git-cola"), cmds.run(cmds.OpenRepo, core.abspath(s.staged[0]))) menu.addAction(self.launch_editor_action) menu.addSeparator() action = menu.addAction(icons.remove(), N_("Unstage Selected"), cmds.run(cmds.Unstage, self.staged())) action.setShortcut(hotkeys.STAGE_SELECTION) menu.addSeparator() menu.addAction(self.copy_path_action) menu.addAction(self.copy_relpath_action) menu.addAction(self.view_history_action) return menu
def worktree(self): if self._worktree: return self._worktree self.git_dir() if self._git_dir: curdir = self._git_dir else: curdir = core.getcwd() if is_git_dir(join(curdir, ".git")): return curdir # Handle bare repositories if len(os.path.basename(curdir)) > 4 and curdir.endswith(".git"): return curdir if "GIT_WORK_TREE" in os.environ: self._worktree = core.getenv("GIT_WORK_TREE") if not self._worktree or not core.isdir(self._worktree): if self._git_dir: gitparent = join(core.abspath(self._git_dir), "..") self._worktree = core.abspath(gitparent) self.set_cwd(self._worktree) return self._worktree
def _create_staged_submodule_context_menu(self, menu, s): menu.addAction(qtutils.git_icon(), N_('Launch git-cola'), cmds.run(cmds.OpenRepo, core.abspath(s.staged[0]))) menu.addAction(self.launch_editor) menu.addSeparator() action = menu.addAction(qtutils.icon('remove.svg'), N_('Unstage Selected'), cmds.run(cmds.Unstage, self.staged())) action.setShortcut(cmds.Unstage.SHORTCUT) menu.addSeparator() menu.addAction(self.copy_path_action) return menu
def _create_staged_submodule_context_menu(self, menu, s): menu.addAction(qtutils.git_icon(), N_('Launch git-cola'), cmds.run(cmds.OpenRepo, core.abspath(s.staged[0]))) menu.addAction(self.launch_editor) menu.addSeparator() action = menu.addAction( qtutils.icon('remove.svg'), N_('Unstage Selected'), cmds.run(cmds.Unstage, self.staged())) action.setShortcut(cmds.Unstage.SHORTCUT) menu.addSeparator() menu.addAction(self.copy_path_action) return menu
def cmd_cola(args): status_filter = args.status_filter if status_filter: status_filter = core.abspath(status_filter) context = application_init(args) from cola.widgets.main import MainView view = MainView(context.model, settings=args.settings) if args.amend: cmds.do(cmds.AmendMode, True) if status_filter: view.set_filter(core.relpath(status_filter)) return application_start(context, view)
def _create_staged_submodule_context_menu(self, menu, s): menu.addAction(icons.cola(), N_('Launch git-cola'), cmds.run(cmds.OpenRepo, core.abspath(s.staged[0]))) menu.addAction(self.launch_editor_action) menu.addSeparator() action = menu.addAction(icons.remove(), N_('Unstage Selected'), cmds.run(cmds.Unstage, self.staged())) action.setShortcut(hotkeys.STAGE_SELECTION) menu.addSeparator() menu.addAction(self.copy_path_action) menu.addAction(self.copy_relpath_action) menu.addAction(self.view_history_action) return menu
def _create_modified_submodule_context_menu(self, menu, s): menu.addAction(qtutils.git_icon(), N_('Launch git-cola'), cmds.run(cmds.OpenRepo, core.abspath(s.modified[0]))) menu.addAction(self.launch_editor_action) if self.m.stageable(): menu.addSeparator() action = menu.addAction(qtutils.icon('add.svg'), N_('Stage Selected'), cmds.run(cmds.Stage, self.unstaged())) action.setShortcut(cmds.Stage.SHORTCUT) menu.addSeparator() menu.addAction(self.copy_path_action) menu.addAction(self.copy_relpath_action) return menu
def _read_git_head(head, default='master', git=git): """Pure-python .git/HEAD reader""" # Legacy .git/HEAD symlinks if core.islink(head): refs_heads = core.realpath(git.git_path('refs', 'heads')) path = core.abspath(head).replace('\\', '/') if path.startswith(refs_heads + '/'): return path[len(refs_heads)+1:] # Common .git/HEAD "ref: refs/heads/master" file elif core.isfile(head): data = core.read(head).rstrip() ref_prefix = 'ref: ' if data.startswith(ref_prefix): return data[len(ref_prefix):] # Detached head return data return default
def _read_git_head(head, default='master', git=git): """Pure-python .git/HEAD reader""" # Legacy .git/HEAD symlinks if core.islink(head): refs_heads = core.realpath(git.git_path('refs', 'heads')) path = core.abspath(head).replace('\\', '/') if path.startswith(refs_heads + '/'): return path[len(refs_heads) + 1:] # Common .git/HEAD "ref: refs/heads/master" file elif core.isfile(head): data = core.read(head).rstrip() ref_prefix = 'ref: ' if data.startswith(ref_prefix): return data[len(ref_prefix):] # Detached head return data return default
def __init__(self, monitor, refs_only): _BaseThread.__init__(self, monitor, refs_only) if refs_only: worktree = None else: worktree = git.worktree() if worktree is not None: worktree = core.abspath(worktree) self._worktree = worktree self._git_dir = git.git_path() self._lock = Lock() self._inotify_fd = None self._pipe_r = None self._pipe_w = None self._worktree_wds = set() self._worktree_wd_map = {} self._git_dir_wds = set() self._git_dir_wd_map = {} self._git_dir_wd = None
def _read_git_head(head, default="master", git=git): """Pure-python .git/HEAD reader""" # Legacy .git/HEAD symlinks if core.islink(head): refs_heads = core.realpath(git.git_path("refs", "heads")) path = core.abspath(head).replace("\\", "/") if path.startswith(refs_heads + "/"): return path[len(refs_heads) + 1 :] # Common .git/HEAD "ref: refs/heads/master" file elif core.isfile(head): data = core.read(head).rstrip() ref_prefix = "ref: " if data.startswith(ref_prefix): return data[len(ref_prefix) :] # Detached head return data return default
def find_git_directory(curpath): """Perform Git repository discovery """ paths = Paths(git_dir=core.getenv('GIT_DIR'), worktree=core.getenv('GIT_WORKTREE'), git_file=None) ceiling_dirs = set() ceiling = core.getenv('GIT_CEILING_DIRECTORIES') if ceiling: ceiling_dirs.update([x for x in ceiling.split(':') if x]) if not paths.git_dir or not paths.worktree: if curpath: curpath = core.abspath(curpath) # Search for a .git directory while curpath: if curpath in ceiling_dirs: break if is_git_dir(curpath): paths.git_dir = curpath if os.path.basename(curpath) == '.git': paths.worktree = os.path.dirname(curpath) break gitpath = join(curpath, '.git') if is_git_dir(gitpath): paths.git_dir = gitpath paths.worktree = curpath break curpath, dummy = os.path.split(curpath) if not dummy: break git_dir_path = read_git_file(paths.git_dir) if git_dir_path: paths.git_file = paths.git_dir paths.git_dir = git_dir_path return paths
def mimedata_from_paths(paths): """Return mimedata with a list of absolute path URLs""" abspaths = [core.abspath(path) for path in paths] urls = [QtCore.QUrl.fromLocalFile(path) for path in abspaths] mimedata = QtCore.QMimeData() mimedata.setUrls(urls) # The text/x-moz-list format is always included by Qt, and doing # mimedata.removeFormat('text/x-moz-url') has no effect. # C.f. http://www.qtcentre.org/threads/44643-Dragging-text-uri-list-Qt-inserts-garbage # # gnome-terminal expects utf-16 encoded text, but other terminals, # e.g. terminator, prefer utf-8, so allow cola.dragencoding # to override the default. paths_text = subprocess.list2cmdline(abspaths) encoding = gitcfg.current().get('cola.dragencoding', 'utf-16') moz_text = core.encode(paths_text, encoding=encoding) mimedata.setData('text/x-moz-url', moz_text) return mimedata
def mimedata_from_paths(paths): """Return mimedata with a list of absolute path URLs""" abspaths = [core.abspath(path) for path in paths] urls = [QtCore.QUrl.fromLocalFile(path) for path in abspaths] mimedata = QtCore.QMimeData() mimedata.setUrls(urls) # The text/x-moz-list format is always included by Qt, and doing # mimedata.removeFormat('text/x-moz-url') has no effect. # C.f. http://www.qtcentre.org/threads/44643-Dragging-text-uri-list-Qt-inserts-garbage # # gnome-terminal expects utf-16 encoded text, but other terminals, # e.g. terminator, prefer utf-8, so allow cola.dragencoding # to override the default. paths_text = core.list2cmdline(abspaths) encoding = gitcfg.current().get('cola.dragencoding', 'utf-16') moz_text = core.encode(paths_text, encoding=encoding) mimedata.setData('text/x-moz-url', moz_text) return mimedata
"""Provides the prefix() function for finding cola resources""" from __future__ import division, absolute_import, unicode_literals import os import webbrowser from os.path import dirname from cola import core _modpath = core.abspath(__file__) if os.path.join('share', 'git-cola', 'lib') in _modpath: # this is the release tree # __file__ = '$prefix/share/git-cola/lib/cola/__file__.py' _lib_dir = dirname(dirname(_modpath)) _prefix = dirname(dirname(dirname(_lib_dir))) elif os.path.join('pkgs', 'cola') in _modpath: # Windows release tree # __file__ = $installdir/pkgs/cola/resources.py _prefix = dirname(dirname(dirname(_modpath))) else: # this is the source tree # __file__ = '$prefix/cola/__file__.py' _prefix = dirname(dirname(_modpath)) def prefix(*args): """Return a path relative to cola's installation prefix""" return os.path.join(_prefix, *args) def doc(*args):
def mimedata_from_paths(paths): """Return mimedata with a list of absolute path URLs""" urls = [QtCore.QUrl(core.abspath(path)) for path in paths] mimedata = QtCore.QMimeData() mimedata.setUrls(urls) return mimedata
def contextMenuEvent(self, event): """Create the context menu for the diff display.""" menu = QtGui.QMenu(self) s = selection.selection() filename = selection.filename() if self.model.stageable() or self.model.unstageable(): if self.model.stageable(): self.stage_or_unstage.setText(N_('Stage')) else: self.stage_or_unstage.setText(N_('Unstage')) menu.addAction(self.stage_or_unstage) if s.modified and self.model.stageable(): if s.modified[0] in main.model().submodules: action = menu.addAction(icons.add(), cmds.Stage.name(), cmds.run(cmds.Stage, s.modified)) action.setShortcut(hotkeys.STAGE_SELECTION) menu.addAction(icons.cola(), N_('Launch git-cola'), cmds.run(cmds.OpenRepo, core.abspath(s.modified[0]))) elif s.modified[0] not in main.model().unstaged_deleted: if self.has_selection(): apply_text = N_('Stage Selected Lines') revert_text = N_('Revert Selected Lines...') else: apply_text = N_('Stage Diff Hunk') revert_text = N_('Revert Diff Hunk...') self.action_apply_selection.setText(apply_text) self.action_apply_selection.setIcon(icons.add()) self.action_revert_selection.setText(revert_text) menu.addAction(self.action_apply_selection) menu.addAction(self.action_revert_selection) if s.staged and self.model.unstageable(): if s.staged[0] in main.model().submodules: action = menu.addAction(icons.remove(), cmds.Unstage.name(), cmds.do(cmds.Unstage, s.staged)) action.setShortcut(hotkeys.STAGE_SELECTION) menu.addAction(icons.cola(), N_('Launch git-cola'), cmds.do(cmds.OpenRepo, core.abspath(s.staged[0]))) elif s.staged[0] not in main.model().staged_deleted: if self.has_selection(): apply_text = N_('Unstage Selected Lines') else: apply_text = N_('Unstage Diff Hunk') self.action_apply_selection.setText(apply_text) self.action_apply_selection.setIcon(icons.remove()) menu.addAction(self.action_apply_selection) if self.model.stageable() or self.model.unstageable(): # Do not show the "edit" action when the file does not exist. # Untracked files exist by definition. if filename and core.exists(filename): menu.addSeparator() menu.addAction(self.launch_editor) # Removed files can still be diffed. menu.addAction(self.launch_difftool) # Add the Previous/Next File actions, which improves discoverability # of their associated shortcuts menu.addSeparator() menu.addAction(self.move_up) menu.addAction(self.move_down) menu.addSeparator() action = menu.addAction(icons.copy(), N_('Copy'), self.copy) action.setShortcut(QtGui.QKeySequence.Copy) action = menu.addAction(icons.select_all(), N_('Select All'), self.selectAll) action.setShortcut(QtGui.QKeySequence.SelectAll) menu.exec_(self.mapToGlobal(event.pos()))
"""Provides the prefix() function for finding cola resources""" from __future__ import division, absolute_import, unicode_literals import os import webbrowser from os.path import dirname from cola import core _modpath = core.abspath(__file__) if os.path.join('share', 'git-cola', 'lib') in _modpath: # this is the release tree # __file__ = '$prefix/share/git-cola/lib/cola/__file__.py' _lib_dir = dirname(dirname(_modpath)) _prefix = dirname(dirname(dirname(_lib_dir))) else: # this is the source tree # __file__ = '$prefix/cola/__file__.py' _prefix = dirname(dirname(_modpath)) def prefix(*args): """Return a path relative to cola's installation prefix""" return os.path.join(_prefix, *args) def doc(*args): """Return a path relative to cola's /usr/share/doc/ directory""" return os.path.join(_prefix, 'share', 'doc', 'git-cola', *args)
def contextMenuEvent(self, event): """Create the context menu for the diff display.""" menu = QtGui.QMenu(self) s = selection.selection() filename = selection.filename() if self.model.stageable() and s.modified: if s.modified[0] in main.model().submodules: action = menu.addAction(qtutils.icon('add.svg'), cmds.Stage.name(), cmds.run(cmds.Stage, s.modified)) action.setShortcut(cmds.Stage.SHORTCUT) menu.addAction(qtutils.git_icon(), N_('Launch git-cola'), cmds.run(cmds.OpenRepo, core.abspath(s.modified[0]))) else: if self.has_selection(): apply_text = N_('Stage Selected Lines') revert_text = N_('Revert Selected Lines...') else: apply_text = N_('Stage Diff Hunk') revert_text = N_('Revert Diff Hunk...') self.action_apply_selection.setText(apply_text) self.action_apply_selection.setIcon(qtutils.icon('add.svg')) self.action_revert_selection.setText(revert_text) menu.addAction(self.action_apply_selection) menu.addAction(self.action_revert_selection) if self.model.unstageable(): if s.staged and s.staged[0] in main.model().submodules: action = menu.addAction(qtutils.icon('remove.svg'), cmds.Unstage.name(), cmds.do(cmds.Unstage, s.staged)) action.setShortcut(cmds.Unstage.SHORTCUT) menu.addAction(qtutils.git_icon(), N_('Launch git-cola'), cmds.do(cmds.OpenRepo, core.abspath(s.staged[0]))) elif s.staged: if self.has_selection(): apply_text = N_('Unstage Selected Lines') else: apply_text = N_('Unstage Diff Hunk') self.action_apply_selection.setText(apply_text) self.action_apply_selection.setIcon(qtutils.icon('remove.svg')) menu.addAction(self.action_apply_selection) if self.model.stageable() or self.model.unstageable(): # Do not show the "edit" action when the file does not exist. # Untracked files exist by definition. if filename and core.exists(filename): menu.addSeparator() menu.addAction(self.launch_editor) # Removed files can still be diffed. menu.addAction(self.launch_difftool) menu.addSeparator() action = menu.addAction(qtutils.icon('edit-copy.svg'), N_('Copy'), self.copy) action.setShortcut(QtGui.QKeySequence.Copy) action = menu.addAction(qtutils.icon('edit-select-all.svg'), N_('Select All'), self.selectAll) action.setShortcut(QtGui.QKeySequence.SelectAll) menu.exec_(self.mapToGlobal(event.pos()))
def contextMenuEvent(self, event): """Create the context menu for the diff display.""" menu = QtGui.QMenu(self) s = selection.selection() filename = selection.filename() if self.model.stageable() or self.model.unstageable(): if self.model.stageable(): self.stage_or_unstage.setText(N_('Stage')) else: self.stage_or_unstage.setText(N_('Unstage')) menu.addAction(self.stage_or_unstage) if s.modified and self.model.stageable(): if s.modified[0] in main.model().submodules: action = menu.addAction(icons.add(), cmds.Stage.name(), cmds.run(cmds.Stage, s.modified)) action.setShortcut(hotkeys.STAGE_SELECTION) menu.addAction( icons.cola(), N_('Launch git-cola'), cmds.run(cmds.OpenRepo, core.abspath(s.modified[0]))) elif s.modified[0] not in main.model().unstaged_deleted: if self.has_selection(): apply_text = N_('Stage Selected Lines') revert_text = N_('Revert Selected Lines...') else: apply_text = N_('Stage Diff Hunk') revert_text = N_('Revert Diff Hunk...') self.action_apply_selection.setText(apply_text) self.action_apply_selection.setIcon(icons.add()) self.action_revert_selection.setText(revert_text) menu.addAction(self.action_apply_selection) menu.addAction(self.action_revert_selection) if s.staged and self.model.unstageable(): if s.staged[0] in main.model().submodules: action = menu.addAction(icons.remove(), cmds.Unstage.name(), cmds.do(cmds.Unstage, s.staged)) action.setShortcut(hotkeys.STAGE_SELECTION) menu.addAction( icons.cola(), N_('Launch git-cola'), cmds.do(cmds.OpenRepo, core.abspath(s.staged[0]))) elif s.staged[0] not in main.model().staged_deleted: if self.has_selection(): apply_text = N_('Unstage Selected Lines') else: apply_text = N_('Unstage Diff Hunk') self.action_apply_selection.setText(apply_text) self.action_apply_selection.setIcon(icons.remove()) menu.addAction(self.action_apply_selection) if self.model.stageable() or self.model.unstageable(): # Do not show the "edit" action when the file does not exist. # Untracked files exist by definition. if filename and core.exists(filename): menu.addSeparator() menu.addAction(self.launch_editor) # Removed files can still be diffed. menu.addAction(self.launch_difftool) # Add the Previous/Next File actions, which improves discoverability # of their associated shortcuts menu.addSeparator() menu.addAction(self.move_up) menu.addAction(self.move_down) menu.addSeparator() action = menu.addAction(icons.copy(), N_('Copy'), self.copy) action.setShortcut(QtGui.QKeySequence.Copy) action = menu.addAction(icons.select_all(), N_('Select All'), self.selectAll) action.setShortcut(QtGui.QKeySequence.SelectAll) menu.exec_(self.mapToGlobal(event.pos()))
def setup_environment(): # Allow Ctrl-C to exit signal.signal(signal.SIGINT, signal.SIG_DFL) # Session management wants an absolute path when restarting sys.argv[0] = core.abspath(sys.argv[0]) # Spoof an X11 display for SSH os.environ.setdefault("DISPLAY", ":0") if not core.getenv("SHELL", ""): for shell in ("/bin/zsh", "/bin/bash", "/bin/sh"): if os.path.exists(shell): compat.setenv("SHELL", shell) break # Setup the path so that git finds us when we run 'git cola' path_entries = core.getenv("PATH", "").split(os.pathsep) bindir = os.path.dirname(core.abspath(__file__)) path_entries.insert(0, bindir) path = os.pathsep.join(path_entries) compat.setenv("PATH", path) # We don't ever want a pager compat.setenv("GIT_PAGER", "") # Setup *SSH_ASKPASS git_askpass = core.getenv("GIT_ASKPASS") ssh_askpass = core.getenv("SSH_ASKPASS") if git_askpass: askpass = git_askpass elif ssh_askpass: askpass = ssh_askpass elif sys.platform == "darwin": askpass = resources.share("bin", "ssh-askpass-darwin") else: askpass = resources.share("bin", "ssh-askpass") compat.setenv("GIT_ASKPASS", askpass) compat.setenv("SSH_ASKPASS", askpass) # --- >8 --- >8 --- # Git v1.7.10 Release Notes # ========================= # # Compatibility Notes # ------------------- # # * From this release on, the "git merge" command in an interactive # session will start an editor when it automatically resolves the # merge for the user to explain the resulting commit, just like the # "git commit" command does when it wasn't given a commit message. # # If you have a script that runs "git merge" and keeps its standard # input and output attached to the user's terminal, and if you do not # want the user to explain the resulting merge commits, you can # export GIT_MERGE_AUTOEDIT environment variable set to "no", like # this: # # #!/bin/sh # GIT_MERGE_AUTOEDIT=no # export GIT_MERGE_AUTOEDIT # # to disable this behavior (if you want your users to explain their # merge commits, you do not have to do anything). Alternatively, you # can give the "--no-edit" option to individual invocations of the # "git merge" command if you know everybody who uses your script has # Git v1.7.8 or newer. # --- >8 --- >8 --- # Longer-term: Use `git merge --no-commit` so that we always # have a chance to explain our merges. compat.setenv("GIT_MERGE_AUTOEDIT", "no")
def git_dir(self): if not self.paths.git_dir: path = core.abspath(core.getcwd()) self._find_git_directory(path) return self.paths.git_dir
def worktree(self): if not self.paths.worktree: path = core.abspath(core.getcwd()) self._find_git_directory(path) return self.paths.worktree
def contextMenuEvent(self, event): """Create the context menu for the diff display.""" menu = QtGui.QMenu(self) s = selection.selection() filename = selection.filename() if s.modified and self.model.stageable(): if s.modified[0] in main.model().submodules: action = menu.addAction(qtutils.icon('add.svg'), cmds.Stage.name(), cmds.run(cmds.Stage, s.modified)) action.setShortcut(cmds.Stage.SHORTCUT) menu.addAction( qtutils.git_icon(), N_('Launch git-cola'), cmds.run(cmds.OpenRepo, core.abspath(s.modified[0]))) elif s.modified[0] not in main.model().unstaged_deleted: if self.has_selection(): apply_text = N_('Stage Selected Lines') revert_text = N_('Revert Selected Lines...') else: apply_text = N_('Stage Diff Hunk') revert_text = N_('Revert Diff Hunk...') self.action_apply_selection.setText(apply_text) self.action_apply_selection.setIcon(qtutils.icon('add.svg')) self.action_revert_selection.setText(revert_text) menu.addAction(self.action_apply_selection) menu.addAction(self.action_revert_selection) if s.staged and self.model.unstageable(): if s.staged[0] in main.model().submodules: action = menu.addAction(qtutils.icon('remove.svg'), cmds.Unstage.name(), cmds.do(cmds.Unstage, s.staged)) action.setShortcut(cmds.Unstage.SHORTCUT) menu.addAction( qtutils.git_icon(), N_('Launch git-cola'), cmds.do(cmds.OpenRepo, core.abspath(s.staged[0]))) elif s.staged[0] not in main.model().staged_deleted: if self.has_selection(): apply_text = N_('Unstage Selected Lines') else: apply_text = N_('Unstage Diff Hunk') self.action_apply_selection.setText(apply_text) self.action_apply_selection.setIcon(qtutils.icon('remove.svg')) menu.addAction(self.action_apply_selection) if self.model.stageable() or self.model.unstageable(): # Do not show the "edit" action when the file does not exist. # Untracked files exist by definition. if filename and core.exists(filename): menu.addSeparator() menu.addAction(self.launch_editor) # Removed files can still be diffed. menu.addAction(self.launch_difftool) menu.addSeparator() action = menu.addAction(qtutils.icon('edit-copy.svg'), N_('Copy'), self.copy) action.setShortcut(QtGui.QKeySequence.Copy) action = menu.addAction(qtutils.icon('edit-select-all.svg'), N_('Select All'), self.selectAll) action.setShortcut(QtGui.QKeySequence.SelectAll) menu.exec_(self.mapToGlobal(event.pos()))