def _GetEventTargetPath(self): """Get the 'trace2.eventtarget' path from git configuration. Returns: path: git config's 'trace2.eventtarget' path if it exists, or None """ path = None cmd = ['config', '--get', 'trace2.eventtarget'] # TODO(https://crbug.com/gerrit/13706): Use GitConfig when it supports # system git config variables. p = GitCommand(None, cmd, capture_stdout=True, capture_stderr=True, bare=True) retval = p.Wait() if retval == 0: # Strip trailing carriage-return in path. path = p.stdout.rstrip('\n') elif retval != 1: # `git config --get` is documented to produce an exit status of `1` if # the requested variable is not present in the configuration. Report any # other return value as an error. print( "repo: error: 'git config --get' call failed with return code: %r, stderr: %r" % (retval, p.stderr), file=sys.stderr) return path
def _LsTree(self): """Gets the commit ids for all projects. Works only in git repositories. Returns: data: data returned from 'git ls-tree ...' instead of None. """ if not os.path.exists(self._work_git): print('git ls-tree missing drectory: %s' % self._work_git, file=sys.stderr) return None data = None branch = 'HEAD' if not self._branch else self._branch cmd = ['ls-tree', '-z', '-r', branch] p = GitCommand(None, cmd, cwd=self._work_git, capture_stdout=True, capture_stderr=True) retval = p.Wait() if retval == 0: data = p.stdout else: print('repo: error: git ls-tree call failed with return code: %r, stderr: %r' % ( retval, p.stderr), file=sys.stderr) return data
def _Fetch(self, url): """Fetches a local copy of a superproject for the manifest based on url. Args: url: superproject's url. Returns: True if fetch is successful, or False. """ if not os.path.exists(self._work_git): print('git fetch missing drectory: %s' % self._work_git, file=sys.stderr) return False if not git_require((2, 28, 0)): print('superproject requires a git version 2.28 or later', file=sys.stderr) return False cmd = ['fetch', url, '--depth', '1', '--force', '--no-tags', '--filter', 'blob:none'] if self._branch: cmd += [self._branch + ':' + self._branch] p = GitCommand(None, cmd, cwd=self._work_git, capture_stdout=True, capture_stderr=True) retval = p.Wait() if retval: print('repo: error: git fetch call failed with return code: %r, stderr: %r' % (retval, p.stderr), file=sys.stderr) return False return True
def _ExecuteOne(self, cmd_argv, project): """Process one project.""" try: p = GitCommand(project, cmd_argv, bare=False, capture_stdout=True, capture_stderr=True) except GitError as e: return (project, -1, None, str(e)) return (project, p.Wait(), p.stdout, p.stderr)
def _do(self, *args): command = ['config', '--file', self.file, '--includes'] command.extend(args) p = GitCommand(None, command, capture_stdout=True, capture_stderr=True) if p.Wait() == 0: ret = p.stdout if isinstance(ret, bytes): ret = ret.decode('utf-8') return ret else: GitError('git config %s: %s' % (str(args), p.stderr))
def _Init(self): """Sets up a local Git repository to get a copy of a superproject. Returns: True if initialization is successful, or False. """ if not os.path.exists(self._superproject_path): os.mkdir(self._superproject_path) if not self._quiet and not os.path.exists(self._work_git): print('%s: Performing initial setup for superproject; this might take ' 'several minutes.' % self._work_git) cmd = ['init', '--bare', self._work_git_name] p = GitCommand(None, cmd, cwd=self._superproject_path, capture_stdout=True, capture_stderr=True) retval = p.Wait() if retval: print('repo: error: git init call failed with return code: %r, stderr: %r' % (retval, p.stderr), file=sys.stderr) return False return True
def _GetMergeBranch(self, project): p = GitCommand(project, ['rev-parse', '--abbrev-ref', 'HEAD'], capture_stdout=True, capture_stderr=True) p.Wait() local_branch = p.stdout.strip() p = GitCommand(project, ['config', '--get', 'branch.%s.merge' % local_branch], capture_stdout=True, capture_stderr=True) p.Wait() merge_branch = p.stdout.strip() return merge_branch
def Execute(self, opt, args): reference = args[0] p = GitCommand(None, ['rev-parse', '--verify', reference], capture_stdout=True, capture_stderr=True) if p.Wait() != 0: print(p.stderr, file=sys.stderr) sys.exit(1) sha1 = p.stdout.strip() p = GitCommand(None, ['cat-file', 'commit', sha1], capture_stdout=True) if p.Wait() != 0: print("error: Failed to retrieve old commit message", file=sys.stderr) sys.exit(1) old_msg = self._StripHeader(p.stdout) p = GitCommand(None, ['cherry-pick', sha1], capture_stdout=True, capture_stderr=True) status = p.Wait() print(p.stdout, file=sys.stdout) print(p.stderr, file=sys.stderr) if status == 0: # The cherry-pick was applied correctly. We just need to edit the # commit message. new_msg = self._Reformat(old_msg, sha1) p = GitCommand(None, ['commit', '--amend', '-F', '-'], provide_stdin=True, capture_stdout=True, capture_stderr=True) p.stdin.write(new_msg) p.stdin.close() if p.Wait() != 0: print("error: Failed to update commit message", file=sys.stderr) sys.exit(1) else: print('NOTE: When committing (please see above) and editing the commit ' 'message, please remove the old Change-Id-line and add:') print(self._GetReference(sha1), file=sys.stderr) print(file=sys.stderr)
def Execute(self, opt, args): out = GrepColoring(self.manifest.manifestProject.config) cmd_argv = ['grep'] if out.is_on: cmd_argv.append('--color') cmd_argv.extend(getattr(opt, 'cmd_argv', [])) if '-e' not in cmd_argv: if not args: self.Usage() cmd_argv.append('-e') cmd_argv.append(args[0]) args = args[1:] projects = self.GetProjects(args) full_name = False if len(projects) > 1: cmd_argv.append('--full-name') full_name = True have_rev = False if opt.revision: if '--cached' in cmd_argv: print('fatal: cannot combine --cached and --revision', file=sys.stderr) sys.exit(1) have_rev = True cmd_argv.extend(opt.revision) cmd_argv.append('--') git_failed = False bad_rev = False have_match = False for project in projects: try: p = GitCommand(project, cmd_argv, bare=False, capture_stdout=True, capture_stderr=True) except GitError as e: git_failed = True out.project('--- project %s ---' % project.relpath) out.nl() out.fail('%s', str(e)) out.nl() continue if p.Wait() != 0: # no results # if p.stderr: if have_rev and 'fatal: ambiguous argument' in p.stderr: bad_rev = True else: out.project('--- project %s ---' % project.relpath) out.nl() out.fail('%s', p.stderr.strip()) out.nl() continue have_match = True # We cut the last element, to avoid a blank line. # r = p.stdout.split('\n') r = r[0:-1] if have_rev and full_name: for line in r: rev, line = line.split(':', 1) out.write("%s", rev) out.write(':') out.project(project.relpath) out.write('/') out.write("%s", line) out.nl() elif full_name: for line in r: out.project(project.relpath) out.write('/') out.write("%s", line) out.nl() else: for line in r: print(line) if git_failed: sys.exit(1) elif have_match: sys.exit(0) elif have_rev and bad_rev: for r in opt.revision: print("error: can't search revision %s" % r, file=sys.stderr) sys.exit(1) else: sys.exit(1)
def Execute(self, opt, args): all_projects = self.GetProjects(args) one_project = len(all_projects) == 1 if opt.interactive and not one_project: print('error: interactive rebase not supported with multiple projects', file=sys.stderr) if len(args) == 1: print('note: project %s is mapped to more than one path' % (args[0],), file=sys.stderr) return 1 # Setup the common git rebase args that we use for all projects. common_args = ['rebase'] if opt.whitespace: common_args.append('--whitespace=%s' % opt.whitespace) if opt.quiet: common_args.append('--quiet') if opt.force_rebase: common_args.append('--force-rebase') if not opt.ff: common_args.append('--no-ff') if opt.autosquash: common_args.append('--autosquash') if opt.interactive: common_args.append('-i') config = self.manifest.manifestProject.config out = RebaseColoring(config) out.redirect(sys.stdout) ret = 0 for project in all_projects: if ret and opt.fail_fast: break cb = project.CurrentBranch if not cb: if one_project: print("error: project %s has a detached HEAD" % project.relpath, file=sys.stderr) return 1 # ignore branches with detatched HEADs continue upbranch = project.GetBranch(cb) if not upbranch.LocalMerge: if one_project: print("error: project %s does not track any remote branches" % project.relpath, file=sys.stderr) return 1 # ignore branches without remotes continue args = common_args[:] if opt.onto_manifest: args.append('--onto') args.append(project.revisionExpr) args.append(upbranch.LocalMerge) out.project('project %s: rebasing %s -> %s', project.relpath, cb, upbranch.LocalMerge) out.nl() out.flush() needs_stash = False if opt.auto_stash: stash_args = ["update-index", "--refresh", "-q"] if GitCommand(project, stash_args).Wait() != 0: needs_stash = True # Dirty index, requires stash... stash_args = ["stash"] if GitCommand(project, stash_args).Wait() != 0: ret += 1 continue if GitCommand(project, args).Wait() != 0: ret += 1 continue if needs_stash: stash_args.append('pop') stash_args.append('--quiet') if GitCommand(project, stash_args).Wait() != 0: ret += 1 if ret: out.fail('%i projects had errors', ret) out.nl() return ret
def _AddI(project): p = GitCommand(project, ['add', '--interactive'], bare=False) p.Wait()