def system_date(datestring): m = re.match(r"^(.+)([+-]\d\d:?\d\d)$", datestring) if m: # Time zone included; we parse it ourselves, since "date" # would convert it to the local time zone. (ds, z) = m.groups() try: t = Run("date", "+%Y-%m-%d-%H-%M-%S", "-d", ds ).output_one_line() except RunException: return None else: # Time zone not included; we ask "date" to provide it for us. try: d = Run("date", "+%Y-%m-%d-%H-%M-%S_%z", "-d", datestring ).output_one_line() except RunException: return None (t, z) = d.split("_") year, month, day, hour, minute, second = [int(x) for x in t.split("-")] try: return datetime(year, month, day, hour, minute, second, tzinfo=TimeZone(z)) except ValueError: raise DateException(datestring, "date")
def func(parser, options, args): if options.clear: if (options.diff or options.number or options.full or options.graphical): parser.error('cannot combine --clear with other options') elif args: parser.error('cannot combine --clear with patch arguments') if options.graphical: for o in ['diff', 'number', 'full']: if getattr(options, o): parser.error('cannot combine --graphical and --%s' % o) stack = directory.repository.get_stack(options.branch) patches = parse_patches(args, list(stack.patchorder.all)) logref = log.log_ref(stack.name) try: logcommit = stack.repository.refs.get(logref) except KeyError: out.info('Log is empty') return if options.clear: log.delete_log(stack.repository, stack.name) return stacklog = log.get_log_entry(stack.repository, logref, logcommit) pathlim = [os.path.join('patches', pn) for pn in patches] if options.graphical: cmd = ['gitk', stacklog.simplified.sha1, '--'] + pathlim # Discard the exit codes generated by SIGINT, SIGKILL, and SIGTERM. Run(*cmd).returns([0, -2, -9, -15]).run() else: show_log(stacklog.simplified, pathlim, options.number, options.full, options.diff)
def default(cls): path = environ_get('GIT_WORK_TREE', None) if not path: path = Run('git', 'rev-parse', '--show-toplevel').output_one_line() return cls(path)
def _is_inside_worktree(self): return Run('git', 'rev-parse', '--is-inside-work-tree').output_one_line() == 'true'
def get_colorbool(self, name, stdout_is_tty): """Invoke 'git config --get-colorbool' and return the result.""" return Run('git', 'config', '--get-colorbool', name, stdout_is_tty).output_one_line()
def set(self, name, value): Run('git', 'config', name, value).run() self._cache[name] = value
def rename_section(self, from_name, to_name): """Rename a section in the config file. Silently do nothing if the section doesn't exist.""" Run('git', 'config', '--rename-section', from_name, to_name ).returns([0, 1, 128]).run() self._cache.clear()
def __init__(self, *cmd): """Initialise the Run object and insert the 'git' command name. """ Run.__init__(self, 'git', *cmd)
def clone(remote, local): """Clone a remote repository using 'git clone'.""" Run('git', 'clone', remote, local).run()
def _git_status(): out = Run('git', 'status').output_lines() # strip out git's "instruction" lines, such as '(use "git add <file>..." to update' return [line for line in out if '(use' not in line]
def diffstat(diff): """Return the diffstat of the supplied diff.""" return Run('git', 'apply', '--stat', '--summary').raw_input(diff).raw_output()
def _git_diff(): return Run('git', 'diff').output_lines()
def run_in_cwd(self, args): return Run(*args).env(self.env)
def run(self, args, env=()): return Run(*args).env(add_dict(self.env, env)).cwd(self._worktree.directory)
def run(self, args, env=()): return Run(*args).env(add_dict(self.env, env))
def add_trailer(message, trailer, name, email): trailer_line = '%s: %s <%s>' % (trailer, name, email) return Run('git', 'interpret-trailers', '--trailer', trailer_line).raw_input(message).raw_output()
def diffstat(diff): """Return the diffstat of the supplied diff.""" return (Run('git', 'apply', '--stat', '--summary').encoding( None).raw_input(diff).decoding('utf-8').raw_output())
def shortlog(patches): log = ''.join(Run('git', 'log', '--pretty=short', p.get_top(), '^%s' % p.get_bottom()).raw_output() for p in patches) return Run('git', 'shortlog').raw_input(log).raw_output()
def __send_message_sendmail(sendmail, msg_bytes): """Send the message using the sendmail command. """ cmd = sendmail.split() Run(*cmd).encoding(None).raw_input(msg_bytes).discard_output()
def git_dir(self): try: return Run('git', 'rev-parse', '--git-dir' ).discard_stderr().output_one_line() except RunException: raise DirectoryException('No git repository found')
def __pick_commit(stack, ref_stack, iw, commit, patchname, options): """Pick a commit.""" repository = stack.repository if options.name: patchname = options.name elif patchname and options.revert: patchname = 'revert-' + patchname if patchname: patchname = find_patch_name(patchname, stack.patches.exists) else: patchname = make_patch_name(commit.data.message_str, stack.patches.exists) if options.parent: parent = git_commit(options.parent, repository, ref_stack.name) else: parent = commit.data.parent if not options.revert: bottom = parent top = commit else: bottom = commit top = parent if options.fold: out.start('Folding commit %s' % commit.sha1) diff = repository.diff_tree(bottom.data.tree, top.data.tree, pathlimits=options.file) if diff: try: # try a direct git apply first iw.apply(diff, quiet=True) except MergeException: if options.file: out.done('conflict(s)') out.error('%s does not apply cleanly' % patchname) return STGIT_CONFLICT else: try: iw.merge( bottom.data.tree, stack.head.data.tree, top.data.tree, ) except MergeConflictException as e: out.done('%s conflicts' % len(e.conflicts)) out.error('%s does not apply cleanly' % patchname, *e.conflicts) return STGIT_CONFLICT out.done() else: out.done('no changes') return STGIT_SUCCESS elif options.update: files = [ fn1 for _, _, _, _, _, fn1, fn2 in repository.diff_tree_files( stack.top.data.parent.data.tree, stack.top.data.tree) ] diff = repository.diff_tree(bottom.data.tree, top.data.tree, pathlimits=files) out.start('Updating with commit %s' % commit.sha1) try: iw.apply(diff, quiet=True) except MergeException: out.done('conflict(s)') out.error('%s does not apply cleanly' % patchname) return STGIT_CONFLICT else: out.done() return STGIT_SUCCESS else: author = commit.data.author message = commit.data.message_str if options.revert: author = Person.author() if message: lines = message.splitlines() subject = lines[0] body = '\n'.join(lines[2:]) else: subject = commit.sha1 body = '' message = 'Revert "%s"\n\nThis reverts commit %s.\n\n%s\n' % ( subject, commit.sha1, body, ) elif options.expose: fmt = config.get('stgit.pick.expose-format') message = Run('git', 'show', '--no-patch', '--pretty=' + fmt, commit.sha1).raw_output() message = message.rstrip() + '\n' out.start('Importing commit %s' % commit.sha1) new_commit = repository.commit( CommitData( tree=top.data.tree, parents=[bottom], message=message, author=author, )) trans = StackTransaction( stack, 'pick %s from %s' % (patchname, ref_stack.name)) trans.patches[patchname] = new_commit trans.unapplied.append(patchname) if not options.unapplied: try: trans.push_patch(patchname, iw, allow_interactive=True) except TransactionHalted: pass retval = trans.run(iw, print_current_patch=False) if retval == STGIT_CONFLICT: out.done('conflict(s)') elif stack.patches.get(patchname).is_empty(): out.done('empty patch') else: out.done() return retval
def is_inside_git_dir(self): return {'true': True, 'false': False}[ Run('git', 'rev-parse', '--is-inside-git-dir').output_one_line() ]
def remove_section(self, name): """Remove a section in the config file. Silently do nothing if the section doesn't exist.""" Run('git', 'config', '--remove-section', name ).returns([0, 1, 128]).discard_stderr().discard_output() self._cache.clear()
def is_inside_worktree(self): return {'true': True, 'false': False}[ Run('git', 'rev-parse', '--is-inside-work-tree').output_one_line() ]
def unset(self, name): Run('git', 'config', '--unset', name).run() self._cache[name] = [None]
def default(cls): """Return the default repository.""" try: return cls(Run('git', 'rev-parse', '--git-dir').output_one_line()) except RunException: raise RepositoryException('Cannot find git repository')
def _get_git_dir(self): try: return Run('git', 'rev-parse', '--git-dir').discard_stderr().output_one_line() except RunException: return None
def run_in_cwd(self, args): return Run(*args).env(add_dict(self.env, self.env_in_cwd))
def cd_to_topdir(self): worktree_top = Run( 'git', 'rev-parse', '--show-cdup').discard_stderr().raw_output().rstrip() if worktree_top: os.chdir(worktree_top)