def do(self): if self.index: args = ['apply', '--index', self.selection] else: args = ['apply', self.selection] status, output = git.stash(with_stderr=True, with_status=True, *args) Interaction.log_status(status, output, '')
def do(self): if self.keep_index: args = ['save', '--keep-index', self.stash_name] else: args = ['save', self.stash_name] status, output = git.stash(with_stderr=True, with_status=True, *args) Interaction.log_status(status, output, '')
def do(self): with GitXBaseContext( GIT_XBASE_TITLE=N_('Edit Rebase'), GIT_XBASE_ACTION=N_('Save')): status, out, err = self.model.git.rebase(edit_todo=True) Interaction.log_status(status, out, err) self.model.update_status()
def do(self): status, out, err = self.model.git.checkout(*self.argv) Interaction.log_status(status, out, err) if self.checkout_branch: self.model.update_status() else: self.model.update_file_status()
def do(self): diff_text = "" num_patches = len(self.patches) orig_head = self.model.git.rev_parse("HEAD")[STDOUT] for idx, patch in enumerate(self.patches): status, out, err = self.model.git.am(patch) # Log the git-am command Interaction.log_status(status, out, err) if num_patches > 1: diff = self.model.git.diff("HEAD^!", stat=True)[STDOUT] diff_text += N_("PATCH %(current)d/%(count)d") % dict(current=idx + 1, count=num_patches) diff_text += " - %s:\n%s\n\n" % (os.path.basename(patch), diff) diff_text += N_("Summary:") + "\n" diff_text += self.model.git.diff(orig_head, stat=True)[STDOUT] # Display a diffstat self.model.set_diff_text(diff_text) self.model.update_file_status() basenames = "\n".join([os.path.basename(p) for p in self.patches]) Interaction.information( N_("Patch(es) Applied"), (N_("%d patch(es) applied.") + "\n\n%s") % (len(self.patches), basenames) )
def do(self): log_msg = N_('Tagging "%(revision)s" as "%(name)s"') % dict(revision=self._revision, name=self._name) opts = {} try: if self._message: opts["F"] = utils.tmp_filename("tag-message") core.write(opts["F"], self._message) if self._sign: log_msg += " (%s)" % N_("GPG-signed") opts["s"] = True else: opts["a"] = bool(self._message) status, output, err = self.model.git.tag(self._name, self._revision, **opts) finally: if "F" in opts: os.unlink(opts["F"]) if output: log_msg += "\n" + (N_("Output: %s") % output) Interaction.log_status(status, log_msg, err) if status == 0: self.model.update_status() return (status, output, err)
def do(self): (status, out, err) = (1, "", "") with GitXBaseContext(GIT_XBASE_TITLE=N_("Rebase"), GIT_XBASE_ACTION=N_("Rebase")): status, out, err = self.model.git.rebase(skip=True) Interaction.log_status(status, out, err) self.model.update_status() return status, out, err
def do(self): diff_text = '' num_patches = len(self.patches) orig_head = self.model.git.rev_parse('HEAD')[STDOUT] for idx, patch in enumerate(self.patches): status, out, err = self.model.git.am(patch) # Log the git-am command Interaction.log_status(status, out, err) if num_patches > 1: diff = self.model.git.diff('HEAD^!', stat=True)[STDOUT] diff_text += (N_('PATCH %(current)d/%(count)d') % dict(current=idx+1, count=num_patches)) diff_text += ' - %s:\n%s\n\n' % (os.path.basename(patch), diff) diff_text += N_('Summary:') + '\n' diff_text += self.model.git.diff(orig_head, stat=True)[STDOUT] # Display a diffstat self.model.set_diff_text(diff_text) self.model.update_file_status() basenames = '\n'.join([os.path.basename(p) for p in self.patches]) Interaction.information( N_('Patch(es) Applied'), (N_('%d patch(es) applied.') + '\n\n%s') % (len(self.patches), basenames))
def do(self): if self.index: args = ['apply', '--index', self.selection] else: args = ['apply', self.selection] status, out, err = git.stash(*args) Interaction.log_status(status, out, err)
def do(self): log_msg = 'Tagging: "%s" as "%s"' % (self._revision, self._name) opts = {} if self._message: opts['F'] = utils.tmp_filename('tag-message') utils.write(opts['F'], self._message) if self._sign: log_msg += ', GPG-signed' opts['s'] = True status, output = self.model.git.tag(self._name, self._revision, with_status=True, with_stderr=True, **opts) else: opts['a'] = bool(self._message) status, output = self.model.git.tag(self._name, self._revision, with_status=True, with_stderr=True, **opts) if 'F' in opts: os.unlink(opts['F']) if output: log_msg += '\nOutput:\n%s' % output Interaction.log_status(status, log_msg, '') if status == 0: self.model.update_status()
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 do(self): diff_text = '' num_patches = len(self.patches) orig_head = self.model.git.rev_parse('HEAD') for idx, patch in enumerate(self.patches): status, output = self.model.git.am(patch, with_status=True, with_stderr=True) # Log the git-am command Interaction.log_status(status, output, '') if num_patches > 1: diff = self.model.git.diff('HEAD^!', stat=True) diff_text += 'Patch %d/%d - ' % (idx+1, num_patches) diff_text += '%s:\n%s\n\n' % (os.path.basename(patch), diff) diff_text += 'Summary:\n' diff_text += self.model.git.diff(orig_head, stat=True) # Display a diffstat self.model.set_diff_text(diff_text) self.model.update_file_status() Interaction.information( 'Patch(es) Applied', '%d patch(es) applied:\n\n%s' % (len(self.patches), '\n'.join(map(os.path.basename, self.patches))))
def do(self): status, output = self.model.git.checkout(with_stderr=True, with_status=True, *self.argv) Interaction.log_status(status, output, "") if self.checkout_branch: self.model.update_status() else: self.model.update_file_status()
def export_patch(self): widget = self.commit_list row, selected = qtutils.selected_row(widget) if not selected or len(self.results) < row: return revision = self.results[row][0] Interaction.log_status(*gitcmds.export_patchset(revision, revision))
def do(self): diff_text = "" num_patches = len(self.patches) orig_head = self.model.git.rev_parse("HEAD") for idx, patch in enumerate(self.patches): status, output = self.model.git.am(patch, with_status=True, with_stderr=True) # Log the git-am command Interaction.log_status(status, output, "") if num_patches > 1: diff = self.model.git.diff("HEAD^!", stat=True) diff_text += "Patch %d/%d - " % (idx + 1, num_patches) diff_text += "%s:\n%s\n\n" % (os.path.basename(patch), diff) diff_text += "Summary:\n" diff_text += self.model.git.diff(orig_head, stat=True) # Display a diffstat self.model.set_diff_text(diff_text) self.model.update_file_status() Interaction.information( "Patch(es) Applied", "%d patch(es) applied:\n\n%s" % (len(self.patches), "\n".join(map(os.path.basename, self.patches))), )
def do(self): # Create the commit message file msg = self.strip_comments(self.msg) tmpfile = utils.tmp_filename('commit-message') try: core.write(tmpfile, msg) # Run 'git commit' status, out, err = self.model.git.commit(F=tmpfile, v=True, gpg_sign=self.sign, amend=self.amend, no_verify=self.no_verify) finally: core.unlink(tmpfile) if status == 0: ResetMode.do(self) self.model.set_commitmsg(self.new_commitmsg) msg = N_('Created commit: %s') % out else: msg = N_('Commit failed: %s') % out Interaction.log_status(status, msg, err) return status, out, err
def cherry_pick(self): widget = self.commit_list row, selected = qtutils.selected_row(widget) if not selected or len(self.results) < row: return revision = self.results[row][0] Interaction.log_status(*git.cherry_pick(revision))
def do(self): log_msg = (N_('Tagging "%(revision)s" as "%(name)s"') % dict(revision=self._revision, name=self._name)) opts = {} if self._message: opts['F'] = utils.tmp_filename('tag-message') core.write(opts['F'], self._message) if self._sign: log_msg += ' (%s)' % N_('GPG-signed') opts['s'] = True status, output, err = self.model.git.tag(self._name, self._revision, **opts) else: opts['a'] = bool(self._message) status, output, err = self.model.git.tag(self._name, self._revision, **opts) if 'F' in opts: os.unlink(opts['F']) if output: log_msg += '\n' + (N_('Output: %s') % output) Interaction.log_status(status, log_msg, err) if status == 0: self.model.update_status()
def do(self): if self.keep_index: args = ['save', '--keep-index', self.stash_name] else: args = ['save', self.stash_name] status, out, err = git.stash(*args) Interaction.log_status(status, out, err)
def do(self): status, output = self.model.delete_branch(self.branch) title = "" if output.startswith("error:"): output = "E" + output[1:] else: title = "Info: " Interaction.log_status(status, title + output)
def do(self): status, output = self.model.delete_branch(self.branch) title = '' if output.startswith('error:'): output = 'E' + output[1:] else: title = 'Info: ' Interaction.log_status(status, title + output)
def rebase(): """Rebase onto a branch.""" branch = choose_ref(N_('Select New Base'), N_('Rebase')) if not branch: return #TODO cmd status, output = git.rebase(branch, with_stderr=True, with_status=True) Interaction.log_status(status, output, '')
def execute(command, _cwd=None, _decode=True, _encoding=None, _raw=False, _stdin=None, _stderr=subprocess.PIPE, _stdout=subprocess.PIPE): """ Execute a command and returns its output :param command: argument list to execute. :param _cwd: working directory, defaults to the current directory. :param _decode: whether to decode output, defaults to True. :param _encoding: default encoding, defaults to None (utf-8). :param _raw: do not strip trailing whitespace. :param _stdin: optional stdin filehandle. :returns (status, out, err): exit status, stdout, stderr """ # Allow the user to have the command executed in their working dir. if not _cwd: _cwd = core.getcwd() extra = {} if sys.platform == 'win32': command = map(replace_carot, command) extra['shell'] = True # Start the process # Guard against thread-unsafe .git/index.lock files INDEX_LOCK.acquire() status, out, err = core.run_command(command, cwd=_cwd, encoding=_encoding, stdin=_stdin, stdout=_stdout, stderr=_stderr, **extra) # Let the next thread in INDEX_LOCK.release() if not _raw and out is not None: out = out.rstrip('\n') cola_trace = GIT_COLA_TRACE if cola_trace == 'trace': msg = 'trace: ' + subprocess.list2cmdline(command) Interaction.log_status(status, msg, '') elif cola_trace == 'full': if out: core.stderr("%s -> %d: '%s' '%s'" % (' '.join(command), status, out, err)) else: core.stderr("%s -> %d" % (' '.join(command), status)) elif cola_trace: core.stderr(' '.join(command)) # Allow access to the command's status code return (status, out, err)
def rebase(): """Rebase onto a branch.""" branch = choose_from_combo(N_('Rebase Branch'), cola.model().all_branches()) if not branch: return #TODO cmd status, output = git.rebase(branch, with_stderr=True, with_status=True) Interaction.log_status(status, output, '')
def do(self): (status, out, err) = (1, '', '') with GitXBaseContext( GIT_XBASE_TITLE=N_('Rebase'), GIT_XBASE_ACTION=N_('Rebase')): status, out, err = self.model.git.rebase('--continue') Interaction.log_status(status, out, err) self.model.update_status() return status, out, err
def do(self): (status, out, err) = (1, "", "") args, kwargs = self.prepare_arguments() upstream_title = self.upstream or "@{upstream}" with GitXBaseContext(GIT_XBASE_TITLE=N_("Rebase onto %s") % upstream_title, GIT_XBASE_ACTION=N_("Rebase")): status, out, err = self.model.git.rebase(*args, **kwargs) Interaction.log_status(status, out, err) self.model.update_status() return status, out, err
def do(self): tmpfile = utils.tmp_filename('commit-message') status, output = self.model.commit_with_msg(self.msg, tmpfile, amend=self.amend) if status == 0: ResetMode.do(self) self.model.set_commitmsg(self.new_commitmsg) title = 'Commit: ' else: title = 'Commit failed: ' Interaction.log_status(status, title+output, '')
def do(self): if not self.filenames: return new_additions = '\n'.join(self.filenames) + '\n' for_status = new_additions if core.exists('.gitignore'): current_list = core.read('.gitignore') new_additions = current_list.rstrip() + '\n' + new_additions core.write('.gitignore', new_additions) Interaction.log_status(0, 'Added to .gitignore:\n%s' % for_status, '') self.model.update_file_status()
def do(self): if not self.filenames: return new_additions = "\n".join(self.filenames) + "\n" for_status = new_additions if core.exists(".gitignore"): current_list = core.read(".gitignore") new_additions = current_list.rstrip() + "\n" + new_additions core.write(".gitignore", new_additions) Interaction.log_status(0, "Added to .gitignore:\n%s" % for_status, "") self.model.update_file_status()
def do(self): tmpfile = utils.tmp_filename('commit-message') status, output = self.model.commit_with_msg(self.msg, tmpfile, amend=self.amend) if status == 0: ResetMode.do(self) self.model.set_commitmsg(self.new_commitmsg) msg = N_('Created commit: %s') % output else: msg = N_('Commit failed: %s') % output Interaction.log_status(status, msg, '') return status, output
def do(self): status, out, err = self.model.git.push(self.remote, self.branch, delete=True) Interaction.log_status(status, out, err) self.model.update_status() if status == 0: Interaction.information( N_('Remote Branch Deleted'), N_('"%(branch)s" has been deleted from "%(remote)s".') % dict(branch=self.branch, remote=self.remote)) else: command = 'git push' message = (N_('"%(command)s" returned exit status %(status)d') % dict(command=command, status=status)) Interaction.critical(N_('Error Deleting Remote Branch'), message, out + err)
def do(self): # The normal worktree vs index scenario parser = DiffParser(self.model, filename=self.model.filename, cached=self.staged, reverse=self.apply_to_worktree) status, output = \ parser.process_diff_selection(self.selected, self.offset, self.selection, apply_to_worktree=self.apply_to_worktree) Interaction.log_status(status, output, '') # Redo the diff to show changes if self.staged: diffcmd = DiffStaged([self.model.filename]) else: diffcmd = Diff([self.model.filename]) diffcmd.do() self.model.update_file_status()
def do(self): model = self.model ref = core.encode(model.ref) relpath = core.encode(model.relpath) cmd = ['git', 'show', '%s:%s' % (ref, relpath)] fp = open(core.encode(model.filename), 'wb') proc = utils.start_command(cmd, stdout=fp) out, err = proc.communicate() fp.close() status = proc.returncode msg = ('Saved "%s" from %s to "%s"' % (model.relpath, model.ref, model.filename)) Interaction.log_status(status, msg, '') Interaction.information( 'File Saved', 'File saved to "%s"' % model.filename)
def do(self): # Create the commit message file msg = self.strip_comments(self.msg) tmpfile = utils.tmp_filename('commit-message') core.write(tmpfile, msg) # Run 'git commit' status, out, err = self.model.git.commit(F=tmpfile, v=True, amend=self.amend) core.unlink(tmpfile) if status == 0: ResetMode.do(self) self.model.set_commitmsg(self.new_commitmsg) msg = N_('Created commit: %s') % out else: msg = N_('Commit failed: %s') % out Interaction.log_status(status, msg, err) return status, out, err
def do(self): branch = self.branch if not branch: return status = 1 out = '' err = '' extra = {} if self.capture_output: extra['_stderr'] = None extra['_stdout'] = None with GitXBaseContext(GIT_EDITOR=prefs.editor(), GIT_XBASE_TITLE=N_('Rebase onto %s') % branch, GIT_XBASE_ACTION=N_('Rebase')): status, out, err = self.model.git.rebase(branch, interactive=True, autosquash=True, **extra) Interaction.log_status(status, out, err) self.model.update_status() return status, out, err
def _initialize(self): """Iterate over git-ls-tree and create GitTreeItems.""" status, out, err = git.ls_tree('--full-tree', '-r', '-t', '-z', self.ref) if status != 0: Interaction.log_status(status, out, err) return if not out: return for line in out[:-1].split('\0'): # .....6 ...4 ......................................40 # 040000 tree c127cde9a0c644a3a8fef449a244f47d5272dfa6 relative # 100644 blob 139e42bf4acaa4927ec9be1ec55a252b97d3f1e2 relative/path objtype = line[7] relpath = line[6 + 1 + 4 + 1 + 40 + 1:] if objtype == 't': parent = self.dir_entries[utils.dirname(relpath)] self.add_directory(parent, relpath) elif objtype == 'b': self.add_file(relpath)
def launch(left=None, right=None, paths=None, left_take_parent=False, staged=False): """Launches 'git difftool' with given parameters""" difftool_args = ['git', 'difftool', '--no-prompt'] if staged: difftool_args.append('--cached') if left: if left_take_parent: # Check root commit (no parents and thus cannot execute '~') model = main.model() git = model.git status, out, err = git.rev_list(left, parents=True, n=1) Interaction.log_status(status, out, err) if status: raise OSError('git rev-list command failed') if len(out.split()) >= 2: # Commit has a parent, so we can take its child as requested left += '~' else: # No parent, assume it's the root commit, so we have to diff # against the empty tree. The empty tree is a built-in # git constant SHA1. The empty tree is a built-in Git SHA1. left = '4b825dc642cb6eb9a060e54bf8d69288fbee4904' difftool_args.append(left) if right: difftool_args.append(right) if paths: difftool_args.append('--') difftool_args.extend(paths) core.fork(difftool_args)
def do(self): status, out, err = self.model.git.rebase('--continue') Interaction.log_status(status, out, err) self.model.update_status()
def do(self): status, out, err = git.stash('drop', self.stash_sha1) Interaction.log_status(status, out, err)
def cherry_pick(self): revision = self.selected_revision() if revision is not None: Interaction.log_status(*git.cherry_pick(revision))
def do(self): with GitXBaseContext(GIT_XBASE_TITLE=N_('Edit Rebase'), GIT_XBASE_ACTION=N_('Save')): status, out, err = self.model.git.rebase(edit_todo=True) Interaction.log_status(status, out, err) self.model.update_status()
def do(self): status, out, err = gitcmds.format_patchsets(self.to_export, self.revs) Interaction.log_status(status, out, err)
def export_patch(self): revision = self.selected_revision() if revision is not None: Interaction.log_status( *gitcmds.export_patchset(revision, revision))
def do(self): status, out, err = self.model.delete_branch(self.branch) Interaction.log_status(status, out, err)
def do(self): status, out, err = self.model.rename_branch(self.branch, self.new_branch) Interaction.log_status(status, out, err)
def do(self): for env in ('FILENAME', 'REVISION', 'ARGS'): try: compat.unsetenv(env) except KeyError: pass rev = None args = None cfg = gitcfg.current() opts = cfg.get_guitool_opts(self.action_name) cmd = opts.get('cmd') if 'title' not in opts: opts['title'] = cmd if 'prompt' not in opts or opts.get('prompt') is True: prompt = N_('Run "%s"?') % cmd opts['prompt'] = prompt if opts.get('needsfile'): filename = selection.filename() if not filename: Interaction.information( N_('Please select a file'), N_('"%s" requires a selected file.') % cmd) return False compat.setenv('FILENAME', filename) if opts.get('revprompt') or opts.get('argprompt'): while True: ok = Interaction.confirm_config_action(cmd, opts) if not ok: return False rev = opts.get('revision') args = opts.get('args') if opts.get('revprompt') and not rev: title = N_('Invalid Revision') msg = N_('The revision expression cannot be empty.') Interaction.critical(title, msg) continue break elif opts.get('confirm'): title = os.path.expandvars(opts.get('title')) prompt = os.path.expandvars(opts.get('prompt')) if Interaction.question(title, prompt): return if rev: compat.setenv('REVISION', rev) if args: compat.setenv('ARGS', args) title = os.path.expandvars(cmd) Interaction.log(N_('Running command: %s') % title) cmd = ['sh', '-c', cmd] if opts.get('background'): core.fork(cmd) status, out, err = (0, '', '') elif opts.get('noconsole'): status, out, err = core.run_command(cmd) else: status, out, err = Interaction.run_command(title, cmd) Interaction.log_status(status, out and (N_('Output: %s') % out) or '', err and (N_('Errors: %s') % err) or '') if not opts.get('background') and not opts.get('norescan'): self.model.update_status() return status
def do(self): msg = N_('Untracking: %s') % (', '.join(self.paths)) Interaction.log(msg) with CommandDisabled(UpdateFileStatus): status, out, err = self.model.untrack_paths(self.paths) Interaction.log_status(status, out, err)
def do(self): status, out, err = self.model.git.rebase(abort=True) Interaction.log_status(status, out, err) self.model.update_status()
count += 1 continue INDEX_LOCK.release() raise except: INDEX_LOCK.release() raise # Let the next thread in INDEX_LOCK.release() output = with_stderr and (out+err) or out if not with_raw_output: output = output.rstrip('\n') if cola_trace == 'trace': msg = 'trace: ' + subprocess.list2cmdline(command) Interaction.log_status(status, msg, '') elif cola_trace == 'full': if output: print "%s -> %d: '%s'" % (command, status, output) else: print "%s -> %d" % (command, status) elif cola_trace: print ' '.join(command) # Allow access to the command's status code if with_status: return (status, output) else: return output def transform_kwargs(self, **kwargs):
def thread_command(self, status, out, err): Interaction.log_status(status, out, err)
def do(self): for env in ('FILENAME', 'REVISION', 'ARGS'): try: compat.unsetenv(env) except KeyError: pass rev = None args = None opts = _config.get_guitool_opts(self.name) cmd = opts.get('cmd') if 'title' not in opts: opts['title'] = cmd if 'prompt' not in opts or opts.get('prompt') is True: prompt = i18n.gettext('Are you sure you want to run %s?') % cmd opts['prompt'] = prompt if opts.get('needsfile'): filename = selection.filename() if not filename: Interaction.information('Please select a file', '"%s" requires a selected file' % cmd) return False compat.putenv('FILENAME', filename) if opts.get('revprompt') or opts.get('argprompt'): while True: ok = Interaction.confirm_config_action(cmd, opts) if not ok: return False rev = opts.get('revision') args = opts.get('args') if opts.get('revprompt') and not rev: title = 'Invalid Revision' msg = 'The revision expression cannot be empty.' Interaction.critical(title, msg) continue break elif opts.get('confirm'): title = os.path.expandvars(opts.get('title')) prompt = os.path.expandvars(opts.get('prompt')) if Interaction.question(title, prompt): return if rev: compat.putenv('REVISION', rev) if args: compat.putenv('ARGS', args) title = os.path.expandvars(cmd) Interaction.log('running: ' + title) cmd = ['sh', '-c', cmd] if opts.get('noconsole'): status, out, err = utils.run_command(cmd) else: status, out, err = Interaction.run_command(title, cmd) Interaction.log_status(status, out and 'stdout: %s' % out, err and 'stderr: %s' % err) if not opts.get('norescan'): self.model.update_status() return status
def do(self): msg = 'Untracking: %s' % (', '.join(self.paths)) Interaction.log(msg) status, out = self.model.untrack_paths(self.paths) Interaction.log_status(status, out, '')
def do(self): status, output = git.stash('drop', self.stash_sha1, with_stderr=True, with_status=True) Interaction.log_status(status, output, '')
def execute(command, _cwd=None, _decode=True, _encoding=None, _raw=False, _stdin=None, _stderr=subprocess.PIPE, _stdout=subprocess.PIPE): """ Execute a command and returns its output :param command: argument list to execute. :param _cwd: working directory, defaults to the current directory. :param _decode: whether to decode output, defaults to True. :param _encoding: default encoding, defaults to None (utf-8). :param _raw: do not strip trailing whitespace. :param _stdin: optional stdin filehandle. :returns (status, out, err): exit status, stdout, stderr """ # Allow the user to have the command executed in their working dir. if not _cwd: _cwd = core.getcwd() extra = {} if sys.platform == 'win32': # If git-cola is invoked on Windows using "start pythonw git-cola", # a console window will briefly flash on the screen each time # git-cola invokes git, which is very annoying. The code below # prevents this by ensuring that any window will be hidden. startupinfo = subprocess.STARTUPINFO() startupinfo.dwFlags = subprocess.STARTF_USESHOWWINDOW startupinfo.wShowWindow = subprocess.SW_HIDE extra['startupinfo'] = startupinfo if hasattr(os, 'setsid'): # SSH uses the SSH_ASKPASS variable only if the process is really # detached from the TTY (stdin redirection and setting the # SSH_ASKPASS environment variable is not enough). To detach a # process from the console it should fork and call os.setsid(). extra['preexec_fn'] = os.setsid # Start the process # Guard against thread-unsafe .git/index.lock files INDEX_LOCK.acquire() status, out, err = core.run_command(command, cwd=_cwd, encoding=_encoding, stdin=_stdin, stdout=_stdout, stderr=_stderr, **extra) # Let the next thread in INDEX_LOCK.release() if not _raw and out is not None: out = out.rstrip('\n') cola_trace = GIT_COLA_TRACE if cola_trace == 'trace': msg = 'trace: ' + subprocess.list2cmdline(command) Interaction.log_status(status, msg, '') elif cola_trace == 'full': if out or err: core.stderr("%s -> %d: '%s' '%s'" % (' '.join(command), status, out, err)) else: core.stderr("%s -> %d" % (' '.join(command), status)) elif cola_trace: core.stderr(' '.join(command)) # Allow access to the command's status code return (status, out, err)