Dirty nixos-rebuild build --flake issues

Hey folks,

Just trying to understand the process. I think I want my workflow to be something like this:

nix fmt 
nixos-rebuild build --flake .#xps15 --impure
sudo nixos-rebuild switch --flake .#xps15 --impure 
git add . 
git commit

What I’m seeing though is the flake will not build properly unless I do the git add . first (you can see in the 2nd screenshot where I renamed a folder):

Now, if I do a git add . and repeat the command:

What’s the best practice for this? I hate committing something before I’ve confirmed it will even build.

You can try explicitly specifying the flake to be of type path. The default is git, which uses a git repository as its input that can be a local path, but can also be a URL.

nixos-rebuild build --flake path:.#xps15 --impure

Potentially, a relative path flake doesn’t work and you have to make the path absolute:

nixos-rebuild build --flake path:$PWD#xps15 --impure

The reason for this is that Nix Flakes do everything they can to be reproducible, so when you build a git flake, it uses the current git HEAD as the source (so the last commit) AFAIK (corrected by @noah, it’s actually the filesystem tree, but only tracked files), not the current content of the directory. This means that just with the git hash (which is what git flakes use for locking), the flake is fully reproducible.

With a path flake, it uses the NAR hash for locking, which ensures that a change in the flake directory is detected, but this does not allow reproducing the result unless you also have the full source in your store.

Another workaround you can use for this is with work-in-progress commits and the --amend flag:

# Before you start a "project"
git commit --allow-empty -m "WIP" # Create empty WIP commit

# After every change
nix fmt && 
git add . &&
git commit --amend --no-edit &&
nixos-rebuild build --flake .#xps15 --impure

# If it built successfully
sudo nixos-rebuild switch --flake .#xps15 --impure 

# Once you're happy
git commit --amend # Edit commit message
git push

I use aliases for amends because they’re really useful in general.

1 Like

Just to be clear, the “dirty” warning and the error are two different things. They’re related, but not the same.

The “Git tree is dirty” warning just tells you that the tree has been modified but not committed. If you are aware of this, then it doesn’t matter at all.

The error is because the file isn’t being tracked by git. This is a problem, but you can fix the error without committing (or even staging) your changes.

I use git add --intent-to-add my-untracked-file.nix to track it in the working tree. An easy shortcut is git add -A -N to track every file in the repo. It won’t stage anything, but it will make sure that git is aware of the files. This will get rid of the errors that you’re encountering.

If you want to get rid of the warning, you can adjust your Nix settings:

nix.extraOptions = ''
  experimental-features = nix-command flakes
  warn-dirty = false

git add does not commit anything.

The common practice is to git add anything required to the build.

I consider this suggestion harmfull, --intent-to-add gives your flake a view to the flake that is not in sync with what your next git commit would produce.

The real problem is --impure. You should try to get rid of it. Feel free to open a new thread.

1 Like