Skip to content

Support .gitattributes in subdirectories#335

Merged
edolstra merged 3 commits intomainfrom
eelcodolstra/nix-285-support-gitattributes-in-all-directories
Feb 5, 2026
Merged

Support .gitattributes in subdirectories#335
edolstra merged 3 commits intomainfrom
eelcodolstra/nix-285-support-gitattributes-in-all-directories

Conversation

@edolstra
Copy link
Collaborator

@edolstra edolstra commented Feb 4, 2026

Motivation

For performance, the Git backwards compatibility hack was only applied to repositories that had a .gitattributes in the root directory. However, there are real-world repos that have it in subdirectories, so drop that condition.

Context

Summary by CodeRabbit

  • Bug Fixes

    • Fixed an error message so expected vs. actual hash values display in the correct order.
  • Improvements

    • Simplified Git input fingerprinting to use a consistent hashing rule.
    • Broadened when updated Git export behavior applies to improve compatibility with legacy flows.
  • Tests

    • Updated Git fetch test fixtures and expectations for a reorganized repository layout and new hash results.

@coderabbitai
Copy link

coderabbitai bot commented Feb 4, 2026

📝 Walkthrough

Walkthrough

Fixes an error-message hash ordering, simplifies Git input fingerprinting by removing a .gitattributes presence check, relaxes when Nix 2.19 semantics apply for Git NAR-hash handling (with a legacy fallback), and moves test fixtures into a dir/ subdirectory with updated expectations.

Changes

Cohort / File(s) Summary
Error Message Formatting
src/libexpr/paths.cc
Swaps the two hash arguments in EvalState::mountInput error output so "expected" and "got" match the template.
Fingerprinting Logic Simplification
src/libfetchers/fetchers.cc
Removes .gitattributes existence branching; Git inputs now always use the store path hash for fingerprinting.
Git Semantics & NAR-hash Handling
src/libfetchers/git.cc
Uses runProgram in legacy submodule path, broadens nix219Compat gating (settings.nix219Compat && !options.smudgeLfs), computes/compares narHashNew when provided regardless of .gitattributes, and falls back to legacy accessor only if legacy nar hash matches.
Test Data & Expectations
tests/functional/fetchGit.sh
Moves test files and Git metadata into dir/; updates fetchTree, flake.lock expectations and NAR-hash values/messages to match new layout.

Sequence Diagram(s)

sequenceDiagram
    participant Tester
    participant Fetcher
    participant GitAccessor
    participant LegacyAccessor
    participant Store
    Tester->>Fetcher: request Git input
    Fetcher->>GitAccessor: construct accessor (nix219Compat? smudgeLfs?)
    GitAccessor->>Store: compute store path hash / narHashNew (if expected provided)
    Store-->>GitAccessor: narHashComputed
    GitAccessor->>GitAccessor: compare expectedNarHash vs narHashComputed
    alt match
        GitAccessor-->>Fetcher: return new accessor
    else mismatch
        GitAccessor->>LegacyAccessor: compute legacy nar hash
        alt legacy matches
            LegacyAccessor-->>Fetcher: return legacy accessor (fallback)
        else
            GitAccessor-->>Fetcher: return accessor with updated path/hash
        end
    end
    Fetcher-->>Tester: accessor returned
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Suggested labels

flake-regression-test

Suggested reviewers

  • grahamc
  • cole-h

Poem

🐰 I hopped through hashes, neat and quick,
Swapped their places with a tiny trick.
.gitattributes? I've let it go,
Tests now nest where small carrots grow,
A twitchy nose for tidy git.

🚥 Pre-merge checks | ✅ 2 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 25.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'Support .gitattributes in subdirectories' directly and accurately summarizes the main objective: extending .gitattributes support beyond repository root to subdirectories, which is the core change across all modified files.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch eelcodolstra/nix-285-support-gitattributes-in-all-directories

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions
Copy link

github-actions bot commented Feb 4, 2026

@github-actions github-actions bot temporarily deployed to pull request February 4, 2026 11:28 Inactive
For performance, the Git backwards compatibility hack was only applied
to repositories that had a .gitattributes in the root
directory. However, there are real-world repos that have it in
subdirectories, so drop that condition.
@edolstra edolstra force-pushed the eelcodolstra/nix-285-support-gitattributes-in-all-directories branch from 2e99ba0 to a1cf632 Compare February 4, 2026 14:10
@github-actions github-actions bot temporarily deployed to pull request February 4, 2026 14:14 Inactive
@edolstra edolstra added this pull request to the merge queue Feb 4, 2026
@github-merge-queue github-merge-queue bot removed this pull request from the merge queue due to failed status checks Feb 4, 2026
This was breaking a flake-regressions test and is a bug in general.
@edolstra edolstra enabled auto-merge February 5, 2026 10:53
@github-actions github-actions bot temporarily deployed to pull request February 5, 2026 10:55 Inactive
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/libfetchers/git.cc (1)

1000-1014: ⚠️ Potential issue | 🟡 Minor

Warn only when legacy semantics are actually used.
If expectedNarHash matches the modern hash, the code switches to the modern accessor but still logs “Using Nix 2.19 semantics…”, which is misleading.

Suggested minimal adjustment
-            warn("Using Nix 2.19 semantics to export Git repository '%s'.", input.to_string());
+            bool useLegacy = true;
             auto accessorModern = accessor;
             accessor = getLegacyGitAccessor(store, repoInfo, repoDir, rev, options);
             if (expectedNarHash) {
                 auto narHashLegacy =
                     fetchToStore2(settings, store, {accessor}, FetchMode::DryRun, input.getName()).second;
                 if (expectedNarHash != narHashLegacy) {
                     auto narHashModern =
                         fetchToStore2(settings, store, {accessorModern}, FetchMode::DryRun, input.getName()).second;
                     if (expectedNarHash == narHashModern)
-                        accessor = accessorModern;
+                        { accessor = accessorModern; useLegacy = false; }
                 }
             }
+            if (useLegacy)
+                warn("Using Nix 2.19 semantics to export Git repository '%s'.", input.to_string());

@edolstra edolstra added this pull request to the merge queue Feb 5, 2026
Merged via the queue into main with commit fc1d758 Feb 5, 2026
28 checks passed
@edolstra edolstra deleted the eelcodolstra/nix-285-support-gitattributes-in-all-directories branch February 5, 2026 11:32
@coderabbitai coderabbitai bot mentioned this pull request Feb 6, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants