Unstable store hash when using subdirectory as a flake input #586

Open
opened 2024-11-28 05:40:27 +00:00 by aidalgol · 4 comments

Describe the bug

UPDATE: The subtree is irrelevant. See followup comment.

If you use a git subtree path as a flake input, the flake input gets updated with a different store hash every time you run any flake command.

Steps To Reproduce

  1. Create a local git repo foo with a bare flake.nix file.

    1. $ mkdir foo && cd foo
    2. Write flake.nix
    {
      inputs = {
        nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable";
      };
    
      outputs =
        {
          ...
        }:
        {
          # empty flake
        };
    }
    
    1. $ nix flake lock && git init && git add . && git commit -m 'Initial commit'
  2. Create another local git repo with a flake.nix that contains foo as a subtree

    1. $ mkdir ../bar && cd ../bar
    2. $ cp ../foo/flake.nix .
    3. $ nix flake lock && git init && git add . && git commit -m 'Initial commit'
    4. $ git remote add foo-local /path/to/foo/
    5. $ git subtree add --prefix=foo foo-local main
    6. Add an input for foo to flake.nix
    {
      inputs = {
        nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable";
        foo = {
          url = "./foo";
          inputs.nixpkgs.follows = "nixpkgs";
        };
      };
    
      outputs =
        {
          ...
        }:
        {
          # empty flake
        };
    }
    
  3. Run nix flake lock to add the new input to flake.lock

  4. Run nix flake lock again and see that the flake input for foo gets updated despite no changes having been made since the last nix flake lock run.

bar on  main [!]
❯ nix flake lock
warning: Git tree '/path/to/bar' is dirty
warning: updating lock file '/path/to/bar/flake.lock':
• Added input 'foo':
'path:/nix/store/0pdg0vlb2l09fxwd7y4nadxa934l612j-source/foo?lastModified=1&narHash=sha256-XwqfbIh9%2BoKGz88UjXkAPPWacw87kul9GeCeQg6jIBo%3D' (1970-01-01)
• Added input 'foo/nixpkgs':
follows 'nixpkgs'
warning: Git tree '/path/to/bar' is dirty

bar on  main [!]
❯ nix flake lock
warning: Git tree '/path/to/bar' is dirty
warning: updating lock file '/path/to/bar/flake.lock':
• Updated input 'foo':
'path:/nix/store/0pdg0vlb2l09fxwd7y4nadxa934l612j-source/foo?lastModified=1&narHash=sha256-XwqfbIh9%2BoKGz88UjXkAPPWacw87kul9GeCeQg6jIBo%3D' (1970-01-01)
→ 'path:/nix/store/a6d42jbbhfl2j6ssfbidad0n5rx70jpq-source/foo?lastModified=1&narHash=sha256-XwqfbIh9%2BoKGz88UjXkAPPWacw87kul9GeCeQg6jIBo%3D' (1970-01-01)
warning: Git tree '/path/to/bar' is dirty

Note that the store hash changes, but the narHash stays the same.

Expected behavior

The lock file should not be updated when the subtree has not been changed.

nix --version output

  nix (Lix, like Nix) 2.91.1

Additional context

The reason for doing this is to use as an input a flake that has no central repository.

## Describe the bug **UPDATE**: The subtree is irrelevant. See [followup comment](https://git.lix.systems/lix-project/lix/issues/586#issuecomment-7379). If you use a git subtree path as a flake input, the flake input gets updated with a different store hash every time you run any flake command. ## Steps To Reproduce 1. Create a local git repo `foo` with a bare `flake.nix` file. 1. `$ mkdir foo && cd foo` 2. Write `flake.nix` ```nix { inputs = { nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable"; }; outputs = { ... }: { # empty flake }; } ``` 3. `$ nix flake lock && git init && git add . && git commit -m 'Initial commit'` 2. Create another local git repo with a `flake.nix` that contains `foo` as a subtree 1. `$ mkdir ../bar && cd ../bar` 2. `$ cp ../foo/flake.nix .` 3. `$ nix flake lock && git init && git add . && git commit -m 'Initial commit'` 4. `$ git remote add foo-local /path/to/foo/` 5. `$ git subtree add --prefix=foo foo-local main` 6. Add an input for `foo` to `flake.nix` ```nix { inputs = { nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable"; foo = { url = "./foo"; inputs.nixpkgs.follows = "nixpkgs"; }; }; outputs = { ... }: { # empty flake }; } ``` 3. Run `nix flake lock` to add the new input to `flake.lock` 4. Run `nix flake lock` again and see that the flake input for `foo` gets updated despite no changes having been made since the last `nix flake lock` run. ```console bar on  main [!] ❯ nix flake lock warning: Git tree '/path/to/bar' is dirty warning: updating lock file '/path/to/bar/flake.lock': • Added input 'foo': 'path:/nix/store/0pdg0vlb2l09fxwd7y4nadxa934l612j-source/foo?lastModified=1&narHash=sha256-XwqfbIh9%2BoKGz88UjXkAPPWacw87kul9GeCeQg6jIBo%3D' (1970-01-01) • Added input 'foo/nixpkgs': follows 'nixpkgs' warning: Git tree '/path/to/bar' is dirty bar on  main [!] ❯ nix flake lock warning: Git tree '/path/to/bar' is dirty warning: updating lock file '/path/to/bar/flake.lock': • Updated input 'foo': 'path:/nix/store/0pdg0vlb2l09fxwd7y4nadxa934l612j-source/foo?lastModified=1&narHash=sha256-XwqfbIh9%2BoKGz88UjXkAPPWacw87kul9GeCeQg6jIBo%3D' (1970-01-01) → 'path:/nix/store/a6d42jbbhfl2j6ssfbidad0n5rx70jpq-source/foo?lastModified=1&narHash=sha256-XwqfbIh9%2BoKGz88UjXkAPPWacw87kul9GeCeQg6jIBo%3D' (1970-01-01) warning: Git tree '/path/to/bar' is dirty ``` Note that the store hash changes, but the `narHash` stays the same. ## Expected behavior The lock file should not be updated when the subtree has not been changed. ## `nix --version` output ```console nix (Lix, like Nix) 2.91.1 ``` ## Additional context The reason for doing this is to use as an input a flake that has no central repository.
Owner

Hmmm. That's super weird that the paths are changing while maintaining the same nar hash (i think those should be output-addressed store paths so that ought to be impossible). I think the immediate fix to your issue here is possibly using a git input type (but I'm not sure; subdirectory flakes are incredibly broken and I forget the one syntax that actually works).

I'm also wondering to what extent the git repo being created after locking the flake has any influence (probably not, but maybe?).

This should get tested on 2.18 to see if it's a regression also.

Hmmm. That's super weird that the paths are changing while maintaining the same nar hash (i *think* those should be output-addressed store paths so that ought to be impossible). I think the immediate fix to your issue here is possibly using a git input type (but I'm not sure; subdirectory flakes are incredibly broken and I forget the one syntax that actually works). I'm also wondering to what extent the git repo being created after locking the flake has any influence (probably not, but maybe?). This should get tested on 2.18 to see if it's a regression also.
Author

Tested against Nix 2.18 from nixpkgs and the same thing happens, so not a regression in Lix.

❯ nix --version
nix (Nix) 2.18.9

Tried again with Lix (same version as in original report) but locking the flake after creating the initial git commit, and got the same issue.

I could not figure out a git input type that would work with a subdirectory path.

Tested against Nix 2.18 from nixpkgs and the same thing happens, so not a regression in Lix. ```console ❯ nix --version nix (Nix) 2.18.9 ``` Tried again with Lix (same version as in original report) but locking the flake _after_ creating the initial git commit, and got the same issue. I could not figure out a `git` input type that would work with a subdirectory path.
Author

I did some more monkeying around, and found that the issue has nothing to do with subtrees. If you have a subdirectory flake in the same repo, you get the same unstable-store-hash issue.

bar
├── flake.lock
├── flake.nix
└── foo
    ├── flake.lock
    └── flake.nix

Same contents of each flake.nix files as in the original issue description. The flake input foo in the flake bar is updated every time you run any nix flake command, even if you change nothing.

I did some more monkeying around, and found that the issue has nothing to do with subtrees. If you have a subdirectory flake in the same repo, you get the same unstable-store-hash issue. ```console bar ├── flake.lock ├── flake.nix └── foo ├── flake.lock └── flake.nix ``` Same contents of each `flake.nix` files as in the original issue description. The flake input `foo` in the flake `bar` is updated every time you run any `nix flake` command, even if you change nothing.
aidalgol changed title from Unstable store hash when using git subtree as a flake input to Unstable store hash when using subdirectory as a flake input 2024-11-29 05:24:25 +00:00
Author

I could not figure out a git input type that would work with a subdirectory path.

https://discourse.nixos.org/t/get-nix-flake-to-include-git-submodule/30324/18

The answer appears to be "git+file:foo". This also works with submodules.

> I could not figure out a `git` input type that would work with a subdirectory path. https://discourse.nixos.org/t/get-nix-flake-to-include-git-submodule/30324/18 The answer appears to be `"git+file:foo"`. This also works with submodules.
Sign in to join this conversation.
No milestone
No project
No assignees
2 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: lix-project/lix#586
No description provided.