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 _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): if len(args) != 1: self.Usage() 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(portable.stream2str(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) 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=stderr) print(file=stderr)
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 cmd = ['fetch', url, '--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 _Fetch(self): """Fetches a local copy of a superproject for the manifest based on |_remote_url|. Returns: True if fetch is successful, or False. """ if not os.path.exists(self._work_git): self._LogWarning(f'git fetch missing directory: {self._work_git}') return False if not git_require((2, 28, 0)): self._LogWarning( 'superproject requires a git version 2.28 or later') return False cmd = [ 'fetch', self._remote_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: self._LogWarning(f'git fetch call failed, command: git {cmd}, ' f'return code: {retval}, stderr: {p.stderr}') return False return True
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): self._LogWarning( f'git ls-tree missing directory: {self._work_git}') 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: self._LogWarning(f'git ls-tree call failed, command: git {cmd}, ' f'return code: {retval}, stderr: {p.stderr}') return data
def init(args): """Initializes repository""" man = load_manifest() for (name, project) in man.projects.iteritems(): logging.warn("Initializing project: %s" % name) clone_remote = man.remotes[project.from_remote] clone_url = clone_remote.fetch % name p = GitCommand( None, ["clone", "-o", project.from_remote, "-n", clone_url, project.dir]) p.Wait() repo = GitRepo(workdir_for_project(project)) if repo.command(["show-ref", "-q", "HEAD"]) != 0: # There is no HEAD (maybe origin/master doesnt exist) so check out the tracking # branch repo.check_command([ "checkout", "--track", "-b", project.tracking_branch, project.remote_refspec ]) else: repo.check_command(["checkout"]) ensure_remotes([]) fetch([]) checkout_branches([])
def _UserAgent(): global _user_agent if _user_agent is None: py_version = sys.version_info os_name = sys.platform if os_name == 'linux2': os_name = 'Linux' elif os_name == 'win32': os_name = 'Win32' elif os_name == 'cygwin': os_name = 'Cygwin' elif os_name == 'darwin': os_name = 'Darwin' p = GitCommand( None, ['describe', 'HEAD'], cwd = _MyRepoPath(), capture_stdout = True) if p.Wait() == 0: repo_version = p.stdout if len(repo_version) > 0 and repo_version[-1] == '\n': repo_version = repo_version[0:-1] if len(repo_version) > 0 and repo_version[0] == 'v': repo_version = repo_version[1:] else: repo_version = 'unknown' _user_agent = 'git-repo/%s (%s) git/%s Python/%d.%d.%d' % ( repo_version, os_name, '.'.join(map(str, git.version_tuple())), py_version[0], py_version[1], py_version[2]) return _user_agent
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 _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 _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 _gitPushTag(self, project, tag_name): p = GitCommand(project, ['push', self.remote_name, tag_name], capture_stdout = True, capture_stderr = True) if p.Wait() != 0: err_msg = p.stderr print("Could not push tag for ", project.name) print(err_msg, file=sys.stderr)
def Execute(self, opt, args): rc = 0 out = ChangelogColoring(self.manifest.manifestProject.config) out.redirect(sys.stdout) emails = {} if not opt.regex: projects = self.GetProjects(args) else: projects = self.FindProjects(args) if opt.subscribers is not None: self._ParseSubscribersList(opt.subscribers) else: self.pager = True for project in projects: log_format = '--pretty=format:<li><a href="https://android.googlesource.com/' + project.name + '/+/%h">%h : </a>%s</li>' cmd_args = [ 'log', '--abbrev-commit', '--no-merges', log_format, opt.revisions ] p = GitCommand(project, cmd_args, bare=False, capture_stdout=True, capture_stderr=True) if p.Wait() != 0: out.write("%s", p.stderr) out.nl() continue if len(p.stdout) != 0: proj_header = "<h2>Project: <a href='https://android.googlesource.com/%s'>%s</a></h2>" % ( project.name, project.relpath) out.project(proj_header) out.nl() out.write("%s", p.stdout) out.nl() out.flush() user_list = [] if project.relpath in self.subscribersList: user_list += self.subscribersList[project.relpath] if 'all' in self.subscribersList: user_list += self.subscribersList['all'] for user in user_list: if user not in emails: emails[user] = "" emails[ user] += proj_header + '</br>\n' + p.stdout + '</br>\n' rc = self._SendEmails(emails) sys.exit(rc)
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 _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: return p.stdout else: GitError("git config %s: %s" % (str(args), p.stderr))
def _do(self, *args): command = ['config', '--file', self.file] command.extend(args) p = GitCommand(None, command, capture_stdout=True, capture_stderr=True) if p.Wait() == 0: return p.stdout else: GitError('git config %s: %s' % (str(args), p.stderr))
def PruneHeads(self): """Prune any topic branches already merged into upstream. """ cb = self.CurrentBranch kill = [] left = self._allrefs for name in left.keys(): if name.startswith(R_HEADS): name = name[len(R_HEADS):] if cb is None or name != cb: kill.append(name) rev = self.GetRevisionId(left) if cb is not None \ and not self._revlist(HEAD + '...' + rev) \ and not self.IsDirty(consider_untracked = False): self.work_git.DetachHead(HEAD) kill.append(cb) if kill: old = self.bare_git.GetHead() if old is None: old = 'refs/heads/please_never_use_this_as_a_branch_name' try: self.bare_git.DetachHead(rev) b = ['branch', '-d'] b.extend(kill) b = GitCommand(self, b, bare=True, capture_stdout=True, capture_stderr=True) b.Wait() finally: self.bare_git.SetHead(old) left = self._allrefs for branch in kill: if (R_HEADS + branch) not in left: self.CleanPublishedCache() break if cb and cb not in kill: kill.append(cb) kill.sort() kept = [] for branch in kill: if (R_HEADS + branch) in left: branch = self.GetBranch(branch) base = branch.LocalMerge if not base: base = rev kept.append(ReviewableBranch(self, branch, base)) return kept
def _gitCreateBranch(self, project, branch_name, sha1): p = GitCommand(project, ['checkout', '-b', branch_name, sha1], capture_stdout = True, capture_stderr = True) if p.Wait(): err_msg = p.stderr print(project.name, err_msg, file=sys.stderr) return False else: return True;
def _gitRebaseCurrent(self, project, sha1): p = GitCommand(project,['rebase', sha1], capture_stdout = True, capture_stderr = True) if p.Wait(): err_msg = p.stderr print(project.name, err_msg, file=sys.stderr) return False else: return True;
def _gitRebaseOnto(self, project, dest_sha1, begin_sha1, end_sha1): p = GitCommand(project,['rebase', '--onto', dest_sha1, begin_sha1, end_sha1], capture_stdout = True, capture_stderr = True) if p.Wait(): err_msg = p.stderr print(project.name, err_msg, file=sys.stderr) return False else: return True;
def _gitCreateTag(self, project, tag_name, sha1): p = GitCommand(project, ['tag', tag_name, sha1], capture_stdout = True, capture_stderr = True) if p.Wait(): err_msg = p.stderr print(project.name, err_msg, file=sys.stderr) return False else: return True;
def _gitGetMergeBase(self, project, first_sha1, second_sha1): p = GitCommand(project, ['merge-base', first_sha1, second_sha1 ], capture_stdout = True, capture_stderr = True) if p.Wait() == 0: merge_base_sha1 = p.stdout.rstrip() return merge_base_sha1 else: err_msg = p.stderr print(project.name, err_msg, file=sys.stderr) return ""
def _gitGetExprSHA1(self, project, expr): p = GitCommand(project, ['rev-parse', expr], capture_stdout = True, capture_stderr = True) if p.Wait() == 0: sha1 = p.stdout.rstrip() return sha1 else: err_msg = p.stderr print(project.name, err_msg, file=sys.stderr) return ""
def _gitGetCurrentBranch(self, project): p = GitCommand(project, ['rev-parse', '--abbrev-ref', 'HEAD'], capture_stdout = True, capture_stderr = True) if p.Wait() == 0: current_branch = p.stdout.rstrip() return current_branch else: err_msg = p.stderr print(project.name, err_msg, file=sys.stderr) return ""
def LsOthers(self): p = GitCommand( self._project, ['ls-files', '-z', '--others', '--exclude-standard'], bare=False, capture_stdout=True, capture_stderr=True) if p.Wait() == 0: out = p.stdout if out: return out[:-1].split("\0") return []
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 _allRevisionIds(self): if self._revisionIds is None: a = dict() p = GitCommand(self.manifestProject, ['ls-files', '-z', '--stage'], capture_stdout=True) for line in p.process.stdout.read().split('\0')[:-1]: l_info, l_path = line.split('\t', 2) l_mode, l_id, l_stage = l_info.split(' ', 2) if l_mode == GITLINK and l_stage == '0': a[l_path] = l_id p.Wait() self._revisionIds = a return self._revisionIds
def DiffZ(self, name, *args): cmd = [name] cmd.append('-z') cmd.extend(args) p = GitCommand(self._project, cmd, bare=False, capture_stdout=True, capture_stderr=True) try: out = p.process.stdout.read() r = {} if out: out = iter(out[:-1].split('\0')) while out: try: info = out.next() path = out.next() except StopIteration: break class _Info(object): def __init__(self, path, omode, nmode, oid, nid, state): self.path = path self.src_path = None self.old_mode = omode self.new_mode = nmode self.old_id = oid self.new_id = nid if len(state) == 1: self.status = state self.level = None else: self.status = state[:1] self.level = state[1:] while self.level.startswith('0'): self.level = self.level[1:] info = info[1:].split(' ') info = _Info(path, *info) if info.status in ('R', 'C'): info.src_path = info.path info.path = out.next() r[info.path] = info return r finally: p.Wait()
def runner(*args): cmdv = [name] cmdv.extend(args) p = GitCommand(self._project, cmdv, bare=self._bare, capture_stdout=True, capture_stderr=True) if p.Wait() != 0: raise GitError('%s %s: %s' % (self._project.name, name, p.stderr)) r = p.stdout if r.endswith('\n') and r.index('\n') == len(r) - 1: return r[:-1] return r
def _do(self, *args): if self.file == self._SYSTEM_CONFIG: command = ['config', '--system', '--includes'] else: command = ['config', '--file', self.file, '--includes'] command.extend(args) p = GitCommand(None, command, capture_stdout=True, capture_stderr=True) if p.Wait() == 0: return p.stdout else: raise GitError('git config %s: %s' % (str(args), p.stderr))