Skip to content

copier update prints a misleading warning on modern Git #2759

Description

@mhelvens

Describe the problem

During copier update, Worker._apply_update computes the update diff by running (via diff_cmd) roughly:

git diff-tree --unified=<N> HEAD <ref> --inter-hunk-context=-1

wrapped in try / except ProcessExecutionError (copier/_main.py:1516-1524 in 9.16.0; identical on master). If that command fails, Copier assumes the only possible cause is an outdated Git and prints:

Make sure Git >= 2.24 is installed to improve updates.

to stderr, then retries with --inter-hunk-context=0.

The problem: recent Git releases tightened validation of --inter-hunk-context to reject negative values, so --inter-hunk-context=-1 now errors with:

error: option `inter-hunk-context' expects a non-negative integer value with an optional k/m/g suffix

(exit 129). On an up-to-date Git the -1 probe therefore fails, the blanket except fires, and Copier advises the user to "install Git >= 2.24" — even though their Git is far newer than 2.24. The message isn't just noise, it points in the wrong direction: the trigger is Git being too new, not too old.

This is the inverse of #175 (2020), where genuinely old Git (2.17.1) rejected -1. The -1 sentinel is only valid in a middle window of Git versions — rejected below it, accepted in the middle, and rejected again by current Git. The blanket except ProcessExecutionError conflates "option unsupported (old Git)" with "value rejected (new Git)" and misreports the latter as the former.

Template

Not template-specific — any template triggers it. Minimal, deterministic demonstration of the exact command Copier's code runs (no template required):

$ git --version
git version 2.55.0
$ git diff-tree --unified=3 HEAD~1 HEAD --inter-hunk-context=-1 ; echo "exit=$?"
error: option `inter-hunk-context' expects a non-negative integer value with an optional k/m/g suffix
exit=129

The same command on Git 2.39.5 succeeds (exit 0). I confirmed the boundary only at those two points (2.39.5 accepts, 2.55.0 rejects); I did not bisect the exact release that re-introduced the restriction.

To Reproduce

  1. Use a Git new enough to reject a negative --inter-hunk-context (confirmed on 2.55.0).
  2. Run copier update on any project.
  3. Observe Make sure Git >= 2.24 is installed to improve updates. on stderr, despite Git being far newer than 2.24.

Logs

Make sure Git >= 2.24 is installed to improve updates.

Expected behavior

No misleading warning on a modern Git. Copier should either:

  • gate that warning on an actual Git-version check, so it only advises upgrading when Git is genuinely < 2.24; and/or
  • stop depending on the non-portable -1 sentinel — use a value Git accepts across versions to get the same "fuse all hunks" effect (e.g. a large finite --inter-hunk-context), or distinguish the "value rejected" error from "option unsupported".

Environment

  • Operating system: Linux
  • Distribution and version: Debian GNU/Linux 12 (bookworm), aarch64
  • Copier version: 9.16.0
  • Python version: CPython 3.11.2
  • Installation method: pipx+pypi

Additional context

Code pointer — copier/_main.py, Worker._apply_update, lines 1516–1524 (v9.16.0; identical on master):

try:
    diff = diff_cmd("--inter-hunk-context=-1")
except ProcessExecutionError:
    print(
        colors.warn
        | "Make sure Git >= 2.24 is installed to improve updates.",
        file=sys.stderr,
    )
    diff = diff_cmd("--inter-hunk-context=0")

Happy to send a PR if you'd like a particular approach.


AI disclosure: this report was researched and drafted by Claude Opus 4.8. I (@mhelvens) reviewed and double-checked the work before filing.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions