diff --git a/tools/build_defs/repo/git.bzl b/tools/build_defs/repo/git.bzl index 020b3acc6f19e8..d85a9d6e7e06ed 100644 --- a/tools/build_defs/repo/git.bzl +++ b/tools/build_defs/repo/git.bzl @@ -14,30 +14,39 @@ """Rules for cloning external git repositories.""" def _clone_or_update(ctx): - if (ctx.attr.verbose): - print('git.bzl: Cloning or updating repository %s using strip_prefix of [%s]' % - (ctx.name, ctx.attr.strip_prefix if ctx.attr.strip_prefix else 'None')) if ((not ctx.attr.tag and not ctx.attr.commit) or (ctx.attr.tag and ctx.attr.commit)): fail('Exactly one of commit and tag must be provided') + shallow = '' if ctx.attr.commit: ref = ctx.attr.commit else: ref = 'tags/' + ctx.attr.tag + shallow = '--depth=1' directory=str(ctx.path('.')) if ctx.attr.strip_prefix: directory = directory + "-tmp" + if ctx.attr.shallow_since: + if ctx.attr.tag: + fail('shallow_since not allowed if a tag is specified; --depth=1 will be used for tags') + shallow='--shallow-since=%s' % ctx.attr.shallow_since + if (ctx.attr.verbose): + print('git.bzl: Cloning or updating%s repository %s using strip_prefix of [%s]' % + (' (%s)' % shallow if shallow else '', + ctx.name, + ctx.attr.strip_prefix if ctx.attr.strip_prefix else 'None', + )) bash_exe = ctx.os.environ["BAZEL_SH"] if "BAZEL_SH" in ctx.os.environ else "bash" st = ctx.execute([bash_exe, '-c', """ set -ex ( cd {working_dir} && if ! ( cd '{dir_link}' && [[ "$(git rev-parse --git-dir)" == '.git' ]] ) >/dev/null 2>&1; then rm -rf '{directory}' '{dir_link}' - git clone '{remote}' '{directory}' + git clone {shallow} '{remote}' '{directory}' fi cd '{directory}' - git reset --hard {ref} || (git fetch origin {ref}:{ref} && git reset --hard {ref}) + git reset --hard {ref} || (git fetch {shallow} origin {ref}:{ref} && git reset --hard {ref}) git clean -xdf ) """.format( working_dir=ctx.path('.').dirname, @@ -45,6 +54,7 @@ set -ex directory=directory, remote=ctx.attr.remote, ref=ref, + shallow=shallow, )]) if st.return_code: @@ -86,6 +96,7 @@ def _git_repository_implementation(ctx): _common_attrs = { 'remote': attr.string(mandatory=True), 'commit': attr.string(default=''), + 'shallow_since': attr.string(default=''), 'tag': attr.string(default=''), 'init_submodules': attr.bool(default=False), 'verbose': attr.bool(default=False), @@ -124,6 +135,12 @@ Args: commit: specific commit to be checked out Either tag or commit must be specified. + shallow_since: an optional date, not after the specified commit; the + argument is not allowed if a tag is specified (which allows cloning + with depth 1). Setting such a date close to the specified commit + allows for a more shallow clone of the repository, saving bandwith and + wall-clock time. + init_submodules: Whether to clone submodules in the repository. remote: The URI of the remote Git repository. @@ -152,6 +169,11 @@ Args: commit: specific commit to be checked out Either tag or commit must be specified. + shallow_since: an optional date, not after the specified commit; the + argument is not allowed if a tag is specified (which allows cloning + with depth 1). Setting such a date close to the specified commit + allows for a more shallow clone of the repository, saving bandwith and + wall-clock time. strip_prefix: A directory prefix to strip from the extracted files. """