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 process_args(args): if args.version: # Accept 'git cola --version' or 'git cola version' version.print_version() sys.exit(0) if args.git_path: # Adds git to the PATH. This is needed on Windows. path_entries = core.getenv('PATH', '').split(os.pathsep) path_entries.insert(0, os.path.dirname(core.decode(args.git_path))) compat.setenv('PATH', os.pathsep.join(path_entries)) # Bail out if --repo is not a directory repo = core.decode(args.repo) if repo.startswith('file:'): repo = repo[len('file:'):] repo = core.realpath(repo) if not core.isdir(repo): sys.stderr.write("fatal: '%s' is not a directory. " 'Consider supplying -r <path>.\n' % repo) sys.exit(-1) # We do everything relative to the repo root os.chdir(args.repo) return repo
def process_args(args): if args.version: # Accept 'git cola --version' or 'git cola version' version.print_version() sys.exit(0) # Handle session management restore_session(args) if args.git_path: # Adds git to the PATH. This is needed on Windows. path_entries = core.getenv('PATH', '').split(os.pathsep) path_entries.insert(0, os.path.dirname(core.decode(args.git_path))) compat.setenv('PATH', os.pathsep.join(path_entries)) # Bail out if --repo is not a directory repo = core.decode(args.repo) if repo.startswith('file:'): repo = repo[len('file:'):] repo = core.realpath(repo) if not core.isdir(repo): errmsg = N_('fatal: "%s" is not a directory. ' 'Please specify a correct --repo <path>.') % repo core.stderr(errmsg) sys.exit(-1) # We do everything relative to the repo root os.chdir(args.repo) return repo
def prepend_path(path): # Adds git to the PATH. This is needed on Windows. path = core.decode(path) path_entries = core.getenv('PATH', '').split(os.pathsep) if path not in path_entries: path_entries.insert(0, path) compat.setenv('PATH', os.pathsep.join(path_entries))
def process_args(args): if args.version: # Accept 'git cola --version' or 'git cola version' version.print_version() sys.exit(0) # Handle session management restore_session(args) if args.git_path: # Adds git to the PATH. This is needed on Windows. path_entries = core.getenv('PATH', '').split(os.pathsep) path_entries.insert(0, os.path.dirname(core.decode(args.git_path))) compat.setenv('PATH', os.pathsep.join(path_entries)) # Bail out if --repo is not a directory repo = core.decode(args.repo) if repo.startswith('file:'): repo = repo[len('file:'):] repo = core.realpath(repo) if not core.isdir(repo): errmsg = N_('fatal: "%s" is not a directory. ' 'Please specify --repo <path>.') % repo core.stderr(errmsg) sys.exit(-1) # We do everything relative to the repo root os.chdir(args.repo) return repo
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 __init__(self, context, parent=None): super(MainWindow, self).__init__(parent) self.context = context self.status = 1 self.editor = None default_title = '%s - git cola seqeuence editor' % core.getcwd() title = core.getenv('GIT_COLA_SEQ_EDITOR_TITLE', default_title) self.setWindowTitle(title) self.show_help_action = qtutils.add_action(self, N_('Show Help'), partial(show_help, context), hotkeys.QUESTION) self.menubar = QtWidgets.QMenuBar(self) self.help_menu = self.menubar.addMenu(N_('Help')) self.help_menu.addAction(self.show_help_action) self.setMenuBar(self.menubar) qtutils.add_close_action(self) self.init_state(context.settings, self.init_window_size)
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 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 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 config_home(*args): config = core.getenv('XDG_CONFIG_HOME', os.path.join(core.expanduser('~'), '.config')) return os.path.join(config, 'git-cola', *args)
def __init__(self, context, filename, parent=None): super(Editor, self).__init__(parent) self.widget_version = 1 self.status = 1 self.context = context self.filename = filename self.comment_char = comment_char = prefs.comment_char(context) self.cancel_action = core.getenv('GIT_COLA_SEQ_EDITOR_CANCEL_ACTION', 'abort') self.diff = diff.DiffWidget(context, self) self.tree = RebaseTreeWidget(context, comment_char, self) self.filewidget = filelist.FileWidget(context, self) self.setFocusProxy(self.tree) self.rebase_button = qtutils.create_button( text=core.getenv('GIT_COLA_SEQ_EDITOR_ACTION', N_('Rebase')), tooltip=N_('Accept changes and rebase\n' 'Shortcut: Ctrl+Enter'), icon=icons.ok(), default=True, ) self.extdiff_button = qtutils.create_button( text=N_('Launch Diff Tool'), tooltip=N_('Launch external diff tool\n' 'Shortcut: Ctrl+D'), ) self.extdiff_button.setEnabled(False) self.help_button = qtutils.create_button( text=N_('Help'), tooltip=N_('Show help\nShortcut: ?'), icon=icons.question()) self.cancel_button = qtutils.create_button( text=N_('Cancel'), tooltip=N_('Cancel rebase\nShortcut: Ctrl+Q'), icon=icons.close(), ) top = qtutils.splitter(Qt.Horizontal, self.tree, self.filewidget) top.setSizes([75, 25]) main_split = qtutils.splitter(Qt.Vertical, top, self.diff) main_split.setSizes([25, 75]) controls_layout = qtutils.hbox( defs.no_margin, defs.button_spacing, self.cancel_button, qtutils.STRETCH, self.help_button, self.extdiff_button, self.rebase_button, ) layout = qtutils.vbox(defs.no_margin, defs.spacing, main_split, controls_layout) self.setLayout(layout) self.action_rebase = qtutils.add_action(self, N_('Rebase'), self.rebase, hotkeys.CTRL_RETURN, hotkeys.CTRL_ENTER) self.tree.commits_selected.connect(self.commits_selected) self.tree.commits_selected.connect(self.filewidget.commits_selected) self.tree.commits_selected.connect(self.diff.commits_selected) self.tree.external_diff.connect(self.external_diff) self.filewidget.files_selected.connect(self.diff.files_selected) qtutils.connect_button(self.rebase_button, self.rebase) qtutils.connect_button(self.extdiff_button, self.external_diff) qtutils.connect_button(self.help_button, partial(show_help, context)) qtutils.connect_button(self.cancel_button, self.cancel)
from cola import git from cola import observable from cola.decorators import memoize from cola.git import STDOUT from cola.compat import ustr @memoize def instance(): """Return a static GitConfig instance.""" return GitConfig() _USER_CONFIG = core.expanduser(join('~', '.gitconfig')) _USER_XDG_CONFIG = core.expanduser( join(core.getenv('XDG_CONFIG_HOME', join('~', '.config')), 'git', 'config')) def _stat_info(): # Try /etc/gitconfig as a fallback for the system config paths = (('system', '/etc/gitconfig'), ('user', _USER_XDG_CONFIG), ('user', _USER_CONFIG), ('repo', git.instance().git_path('config'))) statinfo = [] for category, path in paths: try: statinfo.append((category, path, core.stat(path).st_mtime)) except OSError: continue return statinfo
from cola import core from cola import git from cola import observable from cola.decorators import memoize from cola.git import STDOUT @memoize def instance(): """Return a static GitConfig instance.""" return GitConfig() _USER_CONFIG = core.expanduser(join("~", ".gitconfig")) _USER_XDG_CONFIG = core.expanduser(join(core.getenv("XDG_CONFIG_HOME", join("~", ".config")), "git", "config")) def _stat_info(): # Try /etc/gitconfig as a fallback for the system config paths = ( ("system", "/etc/gitconfig"), ("user", _USER_XDG_CONFIG), ("user", _USER_CONFIG), ("repo", git.instance().git_path("config")), ) statinfo = [] for category, path in paths: try: statinfo.append((category, path, core.stat(path).st_mtime)) except OSError:
import functools import errno import os import sys import subprocess import threading from os.path import join from cola import core from cola.compat import ustr, PY3 from cola.decorators import memoize from cola.interaction import Interaction INDEX_LOCK = threading.Lock() GIT_COLA_TRACE = core.getenv('GIT_COLA_TRACE', '') STATUS = 0 STDOUT = 1 STDERR = 2 def dashify(s): return s.replace('_', '-') def is_git_dir(d): """From git's setup.c:is_git_directory().""" if (core.isdir(d) and core.isdir(join(d, 'objects')) and core.isdir(join(d, 'refs'))): headref = join(d, 'HEAD') return (core.isfile(headref)
def tmp_dir(): # Allow TMPDIR/TMP with a fallback to /tmp return core.getenv('TMP', core.getenv('TMPDIR', '/tmp'))
from cola import git from cola import observable from cola.decorators import memoize from cola.git import STDOUT from cola.compat import ustr BUILTIN_READER = os.environ.get('GIT_COLA_BUILTIN_CONFIG_READER', False) @memoize def instance(): """Return a static GitConfig instance.""" return GitConfig() _USER_CONFIG = core.expanduser(join('~', '.gitconfig')) _USER_XDG_CONFIG = core.expanduser( join(core.getenv('XDG_CONFIG_HOME', join('~', '.config')), 'git', 'config')) def _stat_info(): # Try /etc/gitconfig as a fallback for the system config paths = (('system', '/etc/gitconfig'), ('user', _USER_XDG_CONFIG), ('user', _USER_CONFIG), ('repo', git.instance().git_path('config'))) statinfo = [] for category, path in paths: try: statinfo.append((category, path, core.stat(path).st_mtime)) except OSError: continue return statinfo
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")
import functools import errno import os import sys import subprocess import threading from os.path import join from cola import core from cola.decorators import memoize from cola.interaction import Interaction INDEX_LOCK = threading.Lock() GIT_COLA_TRACE = core.getenv('GIT_COLA_TRACE', '') STATUS = 0 STDOUT = 1 STDERR = 2 def dashify(s): return s.replace('_', '-') def is_git_dir(d): """From git's setup.c:is_git_directory().""" if (core.isdir(d) and core.isdir(join(d, 'objects')) and core.isdir(join(d, 'refs'))): headref = join(d, 'HEAD') return (core.isfile(headref) or
import functools import errno import os import sys import subprocess import threading from os.path import join from cola import core from cola.compat import ustr, PY3 from cola.decorators import memoize from cola.interaction import Interaction INDEX_LOCK = threading.Lock() GIT_COLA_TRACE = core.getenv("GIT_COLA_TRACE", "") STATUS = 0 STDOUT = 1 STDERR = 2 def dashify(s): return s.replace("_", "-") def is_git_dir(d): """From git's setup.c:is_git_directory().""" if core.isdir(d) and core.isdir(join(d, "objects")) and core.isdir(join(d, "refs")): headref = join(d, "HEAD") return core.isfile(headref) or (core.islink(headref) and core.readlink(headref).startswith("refs"))
def config_home(*args): config = core.getenv("XDG_CONFIG_HOME", os.path.join(core.expanduser("~"), ".config")) return os.path.join(config, "git-cola", *args)