def setUp(self, commit=True): TmpPathTestCase.setUp(self) self.initialize_repo() if commit: self.commit_files() git.current().set_worktree(core.getcwd()) gitcfg.current().reset() gitcmds.reset()
def set_worktree(self, worktree): self.git.set_worktree(worktree) is_valid = self.git.is_valid() if is_valid: cwd = self.git.getcwd() self.project = os.path.basename(cwd) self.set_directory(cwd) core.chdir(cwd) gitcfg.current().reset() return is_valid
def start(): global _thread cfg = gitcfg.current() if not cfg.get('cola.inotify', True): msg = N_('inotify is disabled because "cola.inotify" is false') Interaction.log(msg) return if not AVAILABLE: if utils.is_win32(): msg = N_('file notification: disabled\n' 'Note: install pywin32 to enable.\n') elif utils.is_linux(): msg = N_('inotify: disabled\n' 'Note: install python-pyinotify to enable inotify.\n') else: return if utils.is_debian(): msg += N_('On Debian-based systems ' 'try: sudo apt-get install python-pyinotify') Interaction.log(msg) return # Start the notification thread _thread = GitNotifier() _thread.start() if utils.is_win32(): msg = N_('File notification enabled.') else: msg = N_('inotify enabled.') Interaction.log(msg)
def read(self): """Read dictionary words""" paths = [] words = self.dictwords cracklib = self.cracklib propernames = self.propernames cfg = gitcfg.current() cfg_dictionary = cfg.get('cola.dictionary', None) if cracklib and os.path.exists(cracklib): paths.append((cracklib, True)) elif words and os.path.exists(words): paths.append((words, True)) if propernames and os.path.exists(propernames): paths.append((propernames, False)) if cfg_dictionary and os.path.exists(cfg_dictionary): paths.append((cfg_dictionary, False)) for (path, title) in paths: try: with open(path, 'r') as f: for word in f: word = core.decode(word.rstrip()) yield word if title: yield word.title() except IOError: pass return
def __init__(self, model, filename='', cached=True, reverse=False, diff_source=None): self._idx = -1 self._diffs = [] self._diff_spans = [] self._diff_offsets = [] self._ranges = [] self.config = gitcfg.current() self.head = model.head self.amending = model.amending() self.start = None self.end = None self.offset = None self.diff_sel = [] self.selected = [] self.filename = filename self.diff_source = diff_source or DiffSource() if cached: reverse = True header, diff = self.diff_source.get(self.head, self.amending, filename, cached, reverse=False) if reverse: header, _ = self.diff_source.get(self.head, self.amending, filename, cached, reverse=True) self.model = model self.fwd_diff = diff self.header = header self.parse_diff(diff, reverse)
def start(): global _thread cfg = gitcfg.current() if not cfg.get('cola.inotify', True): msg = N_('inotify is disabled because "cola.inotify" is false') Interaction.log(msg) return if not AVAILABLE: if utils.is_win32(): msg = N_('file notification: disabled\n' 'Note: install pywin32 to enable.\n') elif utils.is_linux(): msg = N_('inotify: disabled\n' 'Note: install python-pyinotify to enable inotify.\n') else: return if utils.is_debian(): msg += N_('On Debian-based systems ' 'try: sudo aptitude install python-pyinotify') Interaction.log(msg) return # Start the notification thread _thread = GitNotifier() _thread.start() if utils.is_win32(): msg = N_('File notification enabled.') else: msg = N_('inotify enabled.') Interaction.log(msg)
def __init__(self, path, parent, runtask): qtutils.Task.__init__(self, parent) self.path = path self._parent = parent self._runtask = runtask self._cfg = gitcfg.current() self._data = {}
def toggle_check_spelling(self, enabled): spellcheck = self.description.spellcheck if enabled and not self.spellcheck_initialized: # Add our name to the dictionary self.spellcheck_initialized = True cfg = gitcfg.current() user_name = cfg.get('user.name') if user_name: for part in user_name.split(): spellcheck.add_word(part) # Add our email address to the dictionary user_email = cfg.get('user.email') if user_email: for part in user_email.split('@'): for elt in part.split('.'): spellcheck.add_word(elt) # git jargon spellcheck.add_word('Acked') spellcheck.add_word('Signed') spellcheck.add_word('Closes') spellcheck.add_word('Fixes') self.description.highlighter.enable(enabled)
def do(self): parser = DiffParser(self.model.filename, self.model.diff_text) if self.has_selection: patch = parser.generate_patch(self.first_line_idx, self.last_line_idx, reverse=self.reverse) else: patch = parser.generate_hunk_patch(self.first_line_idx, reverse=self.reverse) if patch is None: return cfg = gitcfg.current() tmp_path = utils.tmp_filename('patch') try: core.write(tmp_path, patch, encoding=cfg.file_encoding(self.model.filename)) if self.apply_to_worktree: status, out, err = self.model.apply_diff_to_worktree(tmp_path) else: status, out, err = self.model.apply_diff(tmp_path) finally: os.unlink(tmp_path) Interaction.log_status(status, out, err) self.model.update_file_status(update_index=True)
def new_model(app, repo, prompt=False, settings=None): model = main.model() valid = False if not prompt: valid = model.set_worktree(repo) if not valid: # We are not currently in a git repository so we need to find one. # Before prompting the user for a repostiory, check if they've # configured a default repository and attempt to use it. default_repo = gitcfg.current().get('cola.defaultrepo') if default_repo: valid = model.set_worktree(default_repo) while not valid: # If we've gotten into this loop then that means that neither the # current directory nor the default repository were available. # Prompt the user for a repository. startup_dlg = startup.StartupDialog(app.activeWindow(), settings=settings) gitdir = startup_dlg.find_git_repo() if not gitdir: sys.exit(EX_NOINPUT) valid = model.set_worktree(gitdir) return model
def new_model(app, repo, prompt=False, settings=None): model = main.model() valid = False if not prompt: valid = model.set_worktree(repo) if not valid: # We are not currently in a git repository so we need to find one. # Before prompting the user for a repostiory, check if they've # configured a default repository and attempt to use it. default_repo = gitcfg.current().get('cola.defaultrepo') if default_repo: valid = model.set_worktree(default_repo) while not valid: # If we've gotten into this loop then that means that neither the # current directory nor the default repository were available. # Prompt the user for a repository. startup_dlg = startup.StartupDialog(app.activeWindow(), settings=settings) gitdir = startup_dlg.find_git_repo() if not gitdir: sys.exit(EX_NOINPUT) valid = model.set_worktree(gitdir) # Finally, go to the root of the git repo os.chdir(model.git.worktree()) return model
def local_merge(): """Provides a dialog for merging branches""" model = main.model() cfg = gitcfg.current() view = MergeView(cfg, model, qtutils.active_window()) view.show() view.raise_() return view
def __init__(self, model, parent, source='user'): QtGui.QWidget.__init__(self, parent) self.model = model self.config_to_widget = {} self.widget_to_config = {} self.source = source self.config = gitcfg.current() self.defaults = {} self.setLayout(QtGui.QFormLayout())
def __init__(self): Command.__init__(self) cfg = gitcfg.current() diff_context = cfg.get("diff.context", 3) diff = self.model.git.diff( self.model.head, unified=diff_context, no_ext_diff=True, no_color=True, M=True, stat=True )[STDOUT] self.new_diff_text = diff self.new_mode = self.model.mode_worktree
def diff_text_for(self, filename): cfg = gitcfg.current() size = cfg.get('cola.readsize', 1024 * 2) try: result = core.read(filename, size=size) except: result = '' if len(result) == size: result += '...' return result
def __init__(self, doc, *args, **kwargs): QtGui.QSyntaxHighlighter.__init__(self, doc) cfg = gitcfg.current() self.color_text = RGB(cfg.color('text', '030303')) self.color_add = RGB(cfg.color('add', 'd2ffe4')) self.color_remove = RGB(cfg.color('remove', 'fee0e4')) self.color_header = RGB(cfg.color('header', 'bbbbbb')) self._rules = [] self.enabled = True self.generate_rules()
def diff_text_for(self, filename): cfg = gitcfg.current() size = cfg.get("cola.readsize", 1024 * 2) try: result = core.read(filename, size=size, encoding="utf-8", errors="ignore") except: result = "" if len(result) == size: result += "..." return result
def signoff(self): try: import pwd user = pwd.getpwuid(os.getuid()).pw_name except ImportError: user = os.getenv('USER', N_('unknown')) cfg = gitcfg.current() name = cfg.get('user.name', user) email = cfg.get('user.email', '%s@%s' % (user, core.node())) return '\nSigned-off-by: %s <%s>' % (name, email)
def rebase_start(self): cfg = gitcfg.current() if not cfg.get("rebase.autostash", False): if self.model.staged or self.model.unmerged or self.model.modified: Interaction.information(N_("Unable to rebase"), N_("You cannot rebase with uncommitted changes.")) return upstream = guicmds.choose_ref(N_("Select New Upstream"), N_("Interactive Rebase"), default="@{upstream}") if not upstream: return self.model.is_rebasing = True self._update_callback() cmds.do(cmds.Rebase, upstream=upstream)
def diff_helper(commit=None, ref=None, endref=None, filename=None, cached=True, head=None, amending=False, with_diff_header=False, suppress_header=True, reverse=False, git=git): "Invokes git diff on a filepath." if commit: ref, endref = commit + '^', commit argv = [] if ref and endref: argv.append('%s..%s' % (ref, endref)) elif ref: for r in utils.shell_split(ref.strip()): argv.append(r) elif head and amending and cached: argv.append(head) encoding = None if filename: argv.append('--') if type(filename) is list: argv.extend(filename) else: argv.append(filename) cfg = gitcfg.current() encoding = cfg.file_encoding(filename) if filename is not None: deleted = cached and not core.exists(filename) else: deleted = False status, out, err = git.diff(R=reverse, M=True, cached=cached, _encoding=encoding, *argv, **common_diff_opts()) if status != 0: # git init if with_diff_header: return ('', '') else: return '' return extract_diff_header(status, deleted, with_diff_header, suppress_header, out)
def signoff(self): try: import pwd user = pwd.getpwuid(os.getuid()).pw_name except ImportError: user = os.getenv("USER", N_("unknown")) cfg = gitcfg.current() name = cfg.get("user.name", user) email = cfg.get("user.email", "%s@%s" % (user, core.node())) return "\nSigned-off-by: %s <%s>" % (name, email)
def diff_text_for(self, filename): cfg = gitcfg.current() size = cfg.get('cola.readsize', 1024 * 2) try: result = core.read(filename, size=size, encoding='utf-8', errors='ignore') except: result = '' if len(result) == size: result += '...' return result
def __init__(self): Command.__init__(self) cfg = gitcfg.current() diff_context = cfg.get('diff.context', 3) diff = self.model.git.diff(self.model.head, unified=diff_context, no_ext_diff=True, no_color=True, M=True, stat=True)[STDOUT] self.new_diff_text = diff self.new_mode = self.model.mode_worktree
def diff_helper(commit=None, ref=None, endref=None, filename=None, cached=True, head=None, amending=False, with_diff_header=False, suppress_header=True, reverse=False, git=git): "Invokes git diff on a filepath." if commit: ref, endref = commit+'^', commit argv = [] if ref and endref: argv.append('%s..%s' % (ref, endref)) elif ref: for r in utils.shell_split(ref.strip()): argv.append(r) elif head and amending and cached: argv.append(head) encoding = None if filename: argv.append('--') if type(filename) is list: argv.extend(filename) else: argv.append(filename) cfg = gitcfg.current() encoding = cfg.file_encoding(filename) if filename is not None: deleted = cached and not core.exists(filename) else: deleted = False status, out, err = git.diff(R=reverse, M=True, cached=cached, _encoding=encoding, *argv, **common_diff_opts()) if status != 0: # git init if with_diff_header: return ('', '') else: return '' return extract_diff_header(status, deleted, with_diff_header, suppress_header, out)
def do(self): git = self.model.git old_worktree = git.worktree() if not self.model.set_worktree(self.repo_path): self.model.set_worktree(old_worktree) return new_worktree = git.worktree() core.chdir(new_worktree) self.model.set_directory(self.repo_path) cfg = gitcfg.current() cfg.reset() inotify.stop() inotify.start() self.model.update_status()
def application_init(args, update=False): """Parses the command-line arguments and starts git-cola """ # Ensure that we're working in a valid git repository. # If not, try to find one. When found, chdir there. setup_environment() process_args(args) app = new_application(args) model = new_model(app, args.repo, prompt=args.prompt) if update: model.update_status() cfg = gitcfg.current() return ApplicationContext(args, app, cfg, model)
def common_diff_opts(config=None): if config is None: config = gitcfg.current() submodule = version.check('diff-submodule', version.git_version()) opts = { 'patience': True, 'submodule': submodule, 'no_color': True, 'no_ext_diff': True, 'unified': config.get('gui.diffcontext', 3), '_raw': True, } opts.update(_diff_overrides) return opts
def do(self): s = selection.selection() if s.unmerged: paths = s.unmerged if utils.is_win32(): core.fork(['git', 'mergetool', '--no-prompt', '--'] + paths) else: cfg = gitcfg.current() cmd = cfg.terminal() argv = utils.shell_split(cmd) argv.extend(['git', 'mergetool', '--no-prompt', '--']) argv.extend(paths) core.fork(argv) else: difftool.run()
def rebase_start(self): cfg = gitcfg.current() if not cfg.get('rebase.autostash', False): if self.model.staged or self.model.unmerged or self.model.modified: Interaction.information( N_('Unable to rebase'), N_('You cannot rebase with uncommitted changes.')) return upstream = guicmds.choose_ref(N_('Select New Upstream'), N_('Interactive Rebase'), default='@{upstream}') if not upstream: return self.model.is_rebasing = True self._update_callback() cmds.do(cmds.Rebase, upstream=upstream)
def __init__(self, doc, whitespace=True): QtGui.QSyntaxHighlighter.__init__(self, doc) self.whitespace = whitespace self.enabled = True cfg = gitcfg.current() self.color_text = RGB(cfg.color("text", "030303")) self.color_add = RGB(cfg.color("add", "d2ffe4")) self.color_remove = RGB(cfg.color("remove", "fee0e4")) self.color_header = RGB(cfg.color("header", "bbbbbb")) self.diff_header_fmt = make_format(fg=self.color_header) self.bold_diff_header_fmt = make_format(fg=self.color_header, bold=True) self.diff_add_fmt = make_format(fg=self.color_text, bg=self.color_add) self.diff_remove_fmt = make_format(fg=self.color_text, bg=self.color_remove) self.bad_whitespace_fmt = make_format(bg=Qt.red)
def tracked_branch(branch=None, config=None): """Return the remote branch associated with 'branch'.""" if config is None: config = gitcfg.current() if branch is None: branch = current_branch() if branch is None: return None remote = config.get('branch.%s.remote' % branch) if not remote: return None merge_ref = config.get('branch.%s.merge' % branch) if not merge_ref: return None refs_heads = 'refs/heads/' if merge_ref.startswith(refs_heads): return remote + '/' + merge_ref[len(refs_heads):] return None
def __init__(self, doc, whitespace=True): QtGui.QSyntaxHighlighter.__init__(self, doc) self.whitespace = whitespace self.enabled = True cfg = gitcfg.current() self.color_text = RGB(cfg.color('text', '030303')) self.color_add = RGB(cfg.color('add', 'd2ffe4')) self.color_remove = RGB(cfg.color('remove', 'fee0e4')) self.color_header = RGB(cfg.color('header', 'bbbbbb')) self.diff_header_fmt = make_format(fg=self.color_header) self.bold_diff_header_fmt = make_format(fg=self.color_header, bold=True) self.diff_add_fmt = make_format(fg=self.color_text, bg=self.color_add) self.diff_remove_fmt = make_format(fg=self.color_text, bg=self.color_remove) self.bad_whitespace_fmt = make_format(bg=Qt.red)
def _create_instance(): thread_class = None cfg = gitcfg.current() if not cfg.get('cola.inotify', True): msg = N_('File system change monitoring: disabled because' ' "cola.inotify" is false.\n') Interaction.log(msg) elif AVAILABLE == 'inotify': thread_class = _InotifyThread elif AVAILABLE == 'pywin32': thread_class = _Win32Thread else: if utils.is_win32(): msg = N_('File system change monitoring: disabled because pywin32' ' is not installed.\n') Interaction.log(msg) elif utils.is_linux(): msg = N_('File system change monitoring: disabled because libc' ' does not support the inotify system calls.\n') Interaction.log(msg) return _Monitor(thread_class)
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
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 setUp(self): helper.GitRepositoryTestCase.setUp(self) self.config = gitcfg.current()
def event(self, e): if e.type() == QtCore.QEvent.ApplicationActivate: cfg = gitcfg.current() if cfg.get('cola.refreshonfocus', False): cmds.do(cmds.Refresh) return QtGui.QApplication.event(self, e)
def save_state(self, settings=None): if settings is None: settings = Settings() settings.load() if gitcfg.current().get('cola.savewindowsettings', True): settings.save_gui_state(self)
def default_remote(config=None): """Return the remote tracked by the current branch.""" if config is None: config = gitcfg.current() return config.get('branch.%s.remote' % current_branch())