def GitSetRemoteRepo(url, directory, push_url=None, repo_name='origin', logger=None): """Sets the remotely tracked URL for a git repository. Args: url: Remote git URL to set. directory: Local git repository to set tracked repo for. push_url: If specified, uses a different URL for pushing. repo_name: set the URL for a particular remote repo name. """ git = GitCmd() try: log_tools.CheckCall(git + ['remote', 'set-url', repo_name, url], logger=logger, cwd=directory) except subprocess.CalledProcessError: # If setting the URL failed, repo_name may be new. Try adding the URL. log_tools.CheckCall(git + ['remote', 'add', repo_name, url], logger=logger, cwd=directory) if push_url: log_tools.CheckCall( git + ['remote', 'set-url', '--push', repo_name, push_url], logger=logger, cwd=directory)
def SyncGitRepo(self, package): """Sync the git repo for a package. Args: package: Package name to sync. """ PrintFlush('@@@BUILD_STEP sync %s@@@' % package) package_info = self._packages[package] url = package_info['git_url'] revision = package_info['git_revision'] destination = os.path.join(self._options.source, package) logging.info('Syncing %s...' % package) if self._options.reclone: file_tools.RemoveDirectoryIfPresent(destination) if sys.platform == 'win32': # On windows, we want to use the depot_tools version of git, which has # git.bat as an entry point. When running through the msys command # prompt, subprocess does not handle batch files. Explicitly invoking # cmd.exe to be sure we run the correct git in this case. git = ['cmd.exe', '/c', 'git.bat'] else: git = ['git'] if not os.path.exists(destination): logging.info('Cloning %s...' % package) log_tools.CheckCall(git + ['clone', '-n', url, destination]) if self._options.pinned: logging.info('Checking out pinned revision...') log_tools.CheckCall(git + ['fetch', '--all'], cwd=destination) log_tools.CheckCall(git + ['checkout', '-f', revision], cwd=destination) log_tools.CheckCall(git + ['clean', '-dffx'], cwd=destination) logging.info('Done syncing %s.' % package)
def runcmd(subst, command, stdout, **kwargs): check_call_kwargs = kwargs.copy() command = command[:] cwd = subst.SubstituteAbsPaths(check_call_kwargs.get('cwd', '.')) subst.SetCwd(cwd) check_call_kwargs['cwd'] = cwd # Extract paths from kwargs and add to the command environment. path_dirs = [] if 'path_dirs' in check_call_kwargs: path_dirs = [ subst.Substitute(dirname) for dirname in check_call_kwargs['path_dirs'] ] del check_call_kwargs['path_dirs'] check_call_kwargs['env'] = PlatformEnvironment(path_dirs) if isinstance(command, str): command = subst.Substitute(command) else: command = [subst.Substitute(arg) for arg in command] paths = check_call_kwargs['env']['PATH'].split(os.pathsep) command[0] = file_tools.Which(command[0], paths=paths) if stdout is not None: stdout = subst.SubstituteAbsPaths(stdout) log_tools.CheckCall(command, stdout=stdout, **check_call_kwargs)
def CleanGitWorkingDir(directory, path): """Clean a particular path of an existing git checkout. Args: directory: Directory where the git repo is currently checked out path: path to clean, relative to the repo directory """ log_tools.CheckCall(GitCmd() + ['clean', '-f', path], cwd=directory)
def CleanGitWorkingDir(directory, reset=False, path=None, logger=None): """Clean all or part of an existing git checkout. Args: directory: Directory where the git repo is currently checked out reset: If True, also reset the working directory to HEAD path: path to clean, relative to the repo directory. If None, clean the whole working directory """ repo_path = [path] if path else [] log_tools.CheckCall(GitCmd() + ['clean', '-dffx'] + repo_path, logger=logger, cwd=directory) if reset: log_tools.CheckCall(GitCmd() + ['reset', '--hard', 'HEAD'], logger=logger, cwd=directory)
def generatePatch(src_rev, dst_rev, suffix): src_prefix = '--src-prefix=' + basename + '/' dst_prefix = '--dst-prefix=' + basename + suffix + '/' patch_file = subst.SubstituteAbsPaths( path.join('%(output)s', basename + suffix + '.patch')) git_args = [ git_dir_flag, 'diff', '--patch-with-stat', '--ignore-space-at-eol', '--full-index', '--no-ext-diff', '--no-color', '--no-renames', '--no-textconv', '--text', src_prefix, dst_prefix, src_rev, dst_rev ] log_tools.CheckCall(repo_tools.GitCmd() + git_args, stdout=patch_file)
def SyncGitRepo(url, destination, revision, reclone=False, clean=False, pathspec=None): """Sync an individual git repo. Args: url: URL to sync destination: Directory to check out into. revision: Pinned revision to check out. If None, do not check out a pinned revision. reclone: If True, delete the destination directory and re-clone the repo. clean: If True, discard local changes and untracked files. Otherwise the checkout will fail if there are uncommitted changes. pathspec: If not None, add the path to the git checkout command, which causes it to just update the working tree without switching branches. """ if reclone: logging.debug('Clobbering source directory %s' % destination) file_tools.RemoveDirectoryIfPresent(destination) git = GitCmd() if not os.path.exists(destination) or len(os.listdir(destination)) == 0: logging.info('Cloning %s...' % url) log_tools.CheckCall(git + ['clone', '-n', url, destination]) if revision is not None: logging.info('Checking out pinned revision...') log_tools.CheckCall(git + ['fetch', '--all'], cwd=destination) checkout_flags = ['-f'] if clean else [] path = [pathspec] if pathspec else [] log_tools.CheckCall(git + ['checkout'] + checkout_flags + [revision] + path, cwd=destination) if clean: log_tools.CheckCall(git + ['clean', '-dffx'], cwd=destination)
def PopulateGitCache(cache_dir, url_list, logger=None): """Fetches a git repo that combines a list of git repos. This is an interface to the "git cache" command found within depot_tools. You can populate a cache directory then obtain the local cache url using GetGitCacheURL(). It is best to sync with the shared option so that the cloned repository shares the same git objects. Args: cache_dir: Local directory where git cache will be populated. url_list: List of URLs which cache_dir should be populated with. """ if url_list: file_tools.MakeDirectoryIfAbsent(cache_dir) git = GitCmd() for url in url_list: log_tools.CheckCall(git + ['cache', 'populate', '-c', '.', url], logger=logger, cwd=cache_dir)
def SyncGitRepo(url, destination, revision, reclone=False, pathspec=None, git_cache=None, push_url=None, logger=None): """Sync an individual git repo. Args: url: URL to sync destination: Directory to check out into. revision: Pinned revision to check out. If None, do not check out a pinned revision. reclone: If True, delete the destination directory and re-clone the repo. pathspec: If not None, add the path to the git checkout command, which causes it to just update the working tree without switching branches. git_cache: If set, assumes URL has been populated within the git cache directory specified and sets the fetch URL to be from the git_cache. """ if logger is None: logger = log_tools.GetConsoleLogger() if reclone: logger.debug('Clobbering source directory %s' % destination) file_tools.RemoveDirectoryIfPresent(destination) if git_cache: git_cache_url = GetGitCacheURL(git_cache, url) else: git_cache_url = None # If the destination is a git repository, validate the tracked origin. git_dir = os.path.join(destination, '.git') if os.path.exists(git_dir): if not IsURLInRemoteRepoList( url, destination, include_fetch=True, include_push=False): # If the git cache URL is being tracked instead of the fetch URL, we # can safely redirect it to the fetch URL instead. if git_cache_url and IsURLInRemoteRepoList(git_cache_url, destination, include_fetch=True, include_push=False): GitSetRemoteRepo(url, destination, push_url=push_url, logger=logger) else: logger.error('Git Repo (%s) does not track URL: %s', destination, url) raise InvalidRepoException(url, 'Could not sync git repo: %s', destination) # Make sure the push URL is set correctly as well. if not IsURLInRemoteRepoList( push_url, destination, include_fetch=False, include_push=True): GitSetRemoteRepo(url, destination, push_url=push_url) git = GitCmd() if not os.path.exists(git_dir): logger.info('Cloning %s...' % url) file_tools.MakeDirectoryIfAbsent(destination) clone_args = ['clone', '-n'] if git_cache_url: clone_args.extend(['--reference', git_cache_url]) log_tools.CheckCall(git + clone_args + [url, '.'], logger=logger, cwd=destination) if url != push_url: GitSetRemoteRepo(url, destination, push_url=push_url, logger=logger) # If a git cache URL is supplied, make sure it is setup as a git alternate. if git_cache_url: git_alternates = [git_cache_url] else: git_alternates = [] GitSetRepoAlternates(destination, git_alternates, append=False, logger=logger) if revision is not None: logger.info('Checking out pinned revision...') log_tools.CheckCall(git + ['fetch', '--all'], logger=logger, cwd=destination) path = [pathspec] if pathspec else [] log_tools.CheckCall(git + ['checkout', revision] + path, logger=logger, cwd=destination)