Skip to content

Track executable bits in repository copy inputs - #31802

Open
dzbarsky wants to merge 3 commits into
bazelbuild:masterfrom
dzbarsky:codex/bazel-pr121-upstream
Open

dzbarsky wants to merge 3 commits into
bazelbuild:masterfrom
dzbarsky:codex/bazel-pr121-upstream

Conversation

@dzbarsky

@dzbarsky dzbarsky commented Oct 15, 2026 •

Copy link
Copy Markdown
Contributor

Depends on #31461.

repository_ctx.copy preserves executable bits, but its recorded inputs
currently only check file contents. Changing a source from 0644 to 0755 can
therefore reuse a stale, non-executable copy.

Include executable bits in FileStateValue comparisons, directory-tree
digests and copied-file records. Regular reads and watches still record only
contents. Old FILE records revalidate once; new content-only records use
FILE_CONTENTS, so affected module lockfiles need regeneration.

fmeum and others added 3 commits October 2, 2026 14:27
`copy(src, dst)` copies a single file into the repository (or the
working directory of a module extension) and preserves its executable
bit. On file systems that support it, the copy is created as a
copy-on-write clone of the source (`clonefile` on macOS,
`copy_file_range` on Linux), so it doesn't take up additional disk
space. The source is watched by default, which can be controlled via
`watch_src`.

Unlike a symlink to a file in the main repo or in another repo, a copy
doesn't prevent a reproducible repo from being stored in the local and
remote repo contents caches. Emulating a copy via
`ctx.file(dst, ctx.read(src))` loads the file into memory and loses the
executable bit.

Contrary to `symlink`, `copy` is also available on `module_ctx` since
it watches the source in the same way on all platforms and thus doesn't
result in platform-specific lockfiles.

Work towards bazelbuild#31434 and bazelbuild#31456.
`repository_ctx.copy` and `module_ctx.copy` now also accept a directory
as `src`. It is copied as if each file in it were copied individually:

* Symlinks to files and directories are followed, so the copy doesn't
  contain any symlinks.
* Existing files below `dst` are overwritten and all other files below
  `dst` are kept, which matches `extract`.
* Executable bits are preserved and the copied files are writable.

The source directory is watched in the same way as by
`repository_ctx.watch_tree`, which also follows symlinks. Symlink cycles,
dangling symlinks and overlapping `src` and `dst` are errors.
repository_ctx.copy preserves executable bits. Include executable bits
in regular FileStateValue comparisons, directory-tree digests and copied
file inputs so chmod invalidates cached copies. Keep ordinary reads and
watches content-only.

Use FILE_CONTENTS for content-only records and include the executable bit
in FILE records. Old FILE records revalidate once, including affected
module lockfiles.
@github-actions github-actions Bot added team-Performance Issues for Performance teams team-ExternalDeps External dependency handling, remote repositiories, WORKSPACE file. team-Core Skyframe, bazel query, BEP, options parsing, bazelrc awaiting-review PR is awaiting review from an assigned reviewer labels Oct 15, 2026

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

awaiting-review PR is awaiting review from an assigned reviewer team-Core Skyframe, bazel query, BEP, options parsing, bazelrc team-ExternalDeps External dependency handling, remote repositiories, WORKSPACE file. team-Performance Issues for Performance teams

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants