Skip to content

RFC: allow long-lived branches to scope pre-push hook file set via STDLIB_DIFF_BASE #11724

@batpigandme

Description

@batpigandme

Description

This RFC proposes extending `tools/git/hooks/pre-push` to honor an optional `STDLIB_DIFF_BASE` environment variable that overrides the hook's current file-set computation.

Today, the `pre-push` hook computes the list of files to validate with:

```sh
git diff --cached "${remote}/${GIT_CURRENT_BRANCH}"
```

i.e. "everything in the current branch that the remote tracking ref doesn't have yet." For short-lived feature branches this is exactly right.

For long-lived branches (e.g. integration branches carrying catalog/docs/changelog work for weeks or months), this definition is wrong in a specific way: after every periodic `git merge develop` the hook sees all merged-in develop commits as "not yet pushed" and therefore tries to run lint / benchmarks / examples / tests against hundreds of files that already passed on `develop`. The validation is not only wasteful — it often fails locally (missing native deps for a package the maintainer never touched) and blocks pushing genuinely correct work.

The local workaround stdlib already supports is to scope Make targets to `develop...HEAD` (three-dot, merge-base-relative) and use the `FILES=`-scoped variants:

```sh
git diff --name-only develop...HEAD > /tmp/files.txt
make lint-files FILES="$(cat /tmp/files.txt | ...)"
```

This RFC proposes exposing the same knob to the hook so there is one source of truth for "which files belong to this branch's work":

```sh
diff_base="${STDLIB_DIFF_BASE:-${remote}/${GIT_CURRENT_BRANCH}}"
files="$(git diff --name-only "${diff_base}")"
```

A maintainer of a long-lived branch would then:

```sh
STDLIB_DIFF_BASE=develop...HEAD git push origin my-long-lived-branch
```

Default behavior is unchanged — if `STDLIB_DIFF_BASE` is unset, the hook computes the file set exactly as it does today.

Related Issues

Related to #11501 (worktree hook fix — same family of long-lived-branch hook friction).

Questions

  1. Is `STDLIB_DIFF_BASE` the right name? Alternatives: `STDLIB_HOOK_DIFF_BASE`, `STDLIB_PREPUSH_DIFF_BASE`. A generic `STDLIB_DIFF_BASE` is reusable across other hooks later (e.g. `pre-commit` for conflict-merge commits), but that generality may be more than is wanted right now.
  2. Should the variable be documented in `CONTRIBUTING.md`, in the hook source, or only in a dedicated long-lived-branch operations doc? The use case is narrow; over-promoting it could invite misuse on short-lived branches.
  3. Should the hook validate that the resolved `diff_base` is reachable and emit a clear error if not, or fall back to the default silently?

Other

Concretely the diff is small — roughly two lines at the top of the hook:

```diff

  • files=$(git diff --cached "${remote}/${GIT_CURRENT_BRANCH}" --name-only --diff-filter=d)
  • diff_base="${STDLIB_DIFF_BASE:-${remote}/${GIT_CURRENT_BRANCH}}"
  • files=$(git diff "${diff_base}" --name-only --diff-filter=d)
    ```

(exact invocation depends on whether `--cached` is desired when an explicit `STDLIB_DIFF_BASE` is passed; I'd expect not, since the three-dot form already implies "committed but not on base").

Checklist

  • I have read and understood the Code of Conduct.
  • Searched for existing issues and pull requests.
  • The issue name begins with `RFC:`.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions