Skip to content

Inherited GIT_ICASE/GLOB/NOGLOB_PATHSPECS breaks every path-taking verb, and inherited GIT_QUARANTINE_PATH breaks every ref-updating verb: the environment overlay doesn't clear them #237

Open

Description

@matt-edmondson

What's wrong

RunCommandGitProcessRunner.EnvironmentOverlay (GitIntegration/Execution/RunCommandGitProcessRunner.cs:61-75) clears inherited variables that would override the library's own arguments, such as GIT_DIR, GIT_INDEX_FILE and GIT_DIFF_OPTS (#139). Two more groups of variables still get through, and each one breaks a whole class of verbs.

1. The global pathspec variables. GitCommandBuilder.BuildArguments adds --literal-pathspecs whenever a builder passes caller paths (GitIntegration/Builders/GitCommandBuilder.cs:154-157). That covers Add().ForPath, Diff/Patch/Log/RevList().ForPath, and always Unstage. Git will not combine the literal setting with any other global pathspec setting:

$ GIT_ICASE_PATHSPECS=1 git --literal-pathspecs add -- a.txt
fatal: global 'literal' pathspec setting is incompatible with all other global pathspec settings   (exit 128)

GIT_GLOB_PATHSPECS=1 and GIT_NOGLOB_PATHSPECS=1 fail the same way. Some users set GIT_ICASE_PATHSPECS in their shell profile on case-insensitive filesystems. For them, every path-filtered verb fails.

2. GIT_QUARANTINE_PATH. Git sets this for pre-receive and update hooks, and while it is set git refuses every ref update. A tool built on this library that runs from such a hook cannot commit, branch, tag, fetch or push:

fatal: ref updates forbidden inside quarantine environment

The overlay already clears GIT_OBJECT_DIRECTORY and GIT_ALTERNATE_OBJECT_DIRECTORIES, which are the other half of the quarantine environment.

Reproduced through the library (git 2.43, net10.0, HEAD 65984d7)

  • With GIT_ICASE_PATHSPECS=1 set, repo.Add().ForPath("b.txt").TryExecuteAsync() returns Success=False with the "incompatible with all other global pathspec settings" error.
  • With GIT_QUARANTINE_PATH=/tmp/x set and a file staged, repo.Commit("msg").TryExecuteAsync() returns Success=False with "ref updates forbidden inside quarantine environment".

Suggested fix / acceptance criteria

  • Add GIT_ICASE_PATHSPECS, GIT_GLOB_PATHSPECS, GIT_NOGLOB_PATHSPECS and GIT_QUARANTINE_PATH to EnvironmentOverlay with the value null.
    • Optionally add GIT_LITERAL_PATHSPECS as well, so builders that do not opt in behave the same whatever the parent set.
  • Extend the overlay's <remarks> to cover both groups.
  • Add tests to GitIntegration.Test/Integration/GitInheritedEnvironmentTests.cs using EnvironmentScope:
    • With GIT_ICASE_PATHSPECS=1, Add().ForPath(...) succeeds and stages exactly that file.
    • With GIT_QUARANTINE_PATH set, Commit(...) succeeds.

Activity

  1. matt-edmondson commented on Oct 17, 2026

    @matt-edmondson
    ContributorAuthor

    Triage

    Notes: The fix is four or five null entries in the overlay plus two EnvironmentScope tests. Including GIT_LITERAL_PATHSPECS is worth doing for consistency.


    Generated by Claude Code

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions