diff --git a/README.md b/README.md
index 45e21fc..11cfdb6 100644
--- a/README.md
+++ b/README.md
@@ -463,7 +463,7 @@ versions left: [docs/cleanup.md](docs/cleanup.md).
- `experimental-features = nix-command flakes` in `~/.config/nix/nix.conf`
if Nix was already there without flakes;
- `~/nix-config` (your configuration, a git repository, from the template
- with your user name filled into `flake.nix`; with `--clone` only until the
+ with your user name filled into `flake.nix`, locked and committed; with `--clone` only until the
clone replaces it) and the link `~/.config/home-manager` to it, unless that
exists or `--flake` is given (with `--flake
` or `--clone`, the link
to that directory unless it exists); uninstall removes the link, never
diff --git a/docs/cleanup.md b/docs/cleanup.md
index 057f1ef..e58d327 100644
--- a/docs/cleanup.md
+++ b/docs/cleanup.md
@@ -49,7 +49,10 @@ desktop can't reach it with its own environment) and uses the installed
with `GIT_TERMINAL_PROMPT=0`. "The unchanged template": `create_config`
writes the hash of the configuration's files (without `.git`) to
`.git/steam-frame-nix-template`; it must still match, with at most one
-commit. Any other directory is used as it is, `--ref` ignored. The template
+commit. `create_config` locks the template as `path:` (no "dirty" warning)
+and commits everything once, with the user's git identity or, missing
+that, `-c user.name= -c user.email=@localhost` for that commit
+only. Any other directory is used as it is, `--ref` ignored. The template
is created and activated only into an empty target without
`~/.config/home-manager`; with another configuration linked, git clones
with that one's helpers. The switch to an existing template is skipped when
diff --git a/install.sh b/install.sh
index 4fa1b10..5006788 100755
--- a/install.sh
+++ b/install.sh
@@ -362,11 +362,16 @@ create_config() { # dir [question]
set_let "$dir/flake.nix" system "$system"
info "user $USER_NAME, home $HOME, system $system"
- # Flakes in a git repository only see tracked files.
+ # Locked as a path (not the git repository: no "dirty" warning), then
+ # one commit, since flakes in a git repository only see tracked files.
+ nix flake lock "path:$dir"
git_any -C "$dir" init -q
git_any -C "$dir" add -A
- nix flake lock "$dir"
- git_any -C "$dir" add flake.lock
+ local id=() # the user's git identity, else one for this commit only
+ git_any -C "$dir" config user.name >/dev/null || id+=(-c "user.name=$USER_NAME")
+ git_any -C "$dir" config user.email >/dev/null || id+=(-c "user.email=$USER_NAME@localhost")
+ git_any -C "$dir" "${id[@]}" -c commit.gpgsign=false commit -q --no-verify \
+ -m "Configuration from the steam-frame-nix template"
config_hash "$dir" >"$dir/.git/$TEMPLATE_MARK"
link_config "$dir"
diff --git a/modules/cleanup/check.nix b/modules/cleanup/check.nix
index 07e99cd..9b58f41 100644
--- a/modules/cleanup/check.nix
+++ b/modules/cleanup/check.nix
@@ -356,7 +356,7 @@ pkgs.runCommand "cleanup-check" { nativeBuildInputs = [ cleanup pkgs.jq pkgs.git
"store info") ;;
"config show") echo "flakes nix-command" ;;
"flake init") cp -r --no-preserve=mode "$TEMPLATE_SRC"/. . ;;
- "flake lock") echo '{}' > "$3/flake.lock" ;;
+ "flake lock") [ "''${3#path:}" != "$3" ] || exit 1; echo '{}' > "''${3#path:}/flake.lock" ;;
"eval --impure") printf aarch64-linux ;;
*) echo "nix $*: not faked" >&2; exit 1 ;;
esac
@@ -378,6 +378,7 @@ pkgs.runCommand "cleanup-check" { nativeBuildInputs = [ cleanup pkgs.jq pkgs.git
inst() {
: > $LOG
(. $INSTALL; ASSUME_YES=1; curl() { :; }; install_nix() { echo "nix install"; }
+ unset GIT_AUTHOR_NAME GIT_AUTHOR_EMAIL GIT_COMMITTER_NAME GIT_COMMITTER_EMAIL
hm() {
echo "hm $*" | tee -a $LOG
if grep -qs 'credential.helper = "store"' "''${3%%#*}/home.nix"; then
@@ -416,7 +417,13 @@ pkgs.runCommand "cleanup-check" { nativeBuildInputs = [ cleanup pkgs.jq pkgs.git
has "$res" "hm switch --flake $HOME/nix-config#$(id -un) -b"
grep -q "steamFrame" $HOME/nix-config/home.nix || fail "no template"
[ -s $HOME/nix-config/.git/steam-frame-nix-template ] || fail "no template marker"
- ! $GIT -C $HOME/nix-config status --porcelain | grep -v '^A ' || fail "marker visible to git"
+ # one commit with everything (git has no identity here: the fallback)
+ [ -z "$($GIT -C $HOME/nix-config status --porcelain)" ] || fail "template repository not clean"
+ [ "$($GIT -C $HOME/nix-config rev-list --count HEAD)" = 1 ] || fail "template: not one commit"
+ [ "$($GIT -C $HOME/nix-config ls-files | sort | tr '\n' ' ')" = "flake.lock flake.nix home.nix " ] || fail "template: files"
+ [ "$($GIT -C $HOME/nix-config log -1 --format='%an <%ae>')" = "$(id -un) <$(id -un)@localhost>" ] || fail "template: identity"
+ [ -z "$($GIT config --global user.name)" ] || fail "global identity written"
+ sfn template_untouched $HOME/nix-config || fail "template marker doesn't match"
has "$res" "Your configuration: ~/nix-config (home.nix). After changing it, apply it with"
has "$res" "'home-manager switch' (from a terminal in the nested desktop"
for p in uncomment Konsole "install.sh status"; do hasnt "$res" "$p"; done
@@ -489,7 +496,10 @@ pkgs.runCommand "cleanup-check" { nativeBuildInputs = [ cleanup pkgs.jq pkgs.git
# a changed template is used as it is
rm -rf $HOME/nix-config $HOME/.config/home-manager $GH_LOGIN; nohelper
+ $GIT config --global user.name "A User"; $GIT config --global user.email a@example.org
inst --clone https://github.com/owner/private.git >/dev/null 2>&1 && fail "private repo cloned"
+ [ "$($GIT -C $HOME/nix-config log -1 --format='%an <%ae>')" = "A User " ] || fail "template: the user's identity"
+ $GIT config --global --unset user.name; $GIT config --global --unset user.email
echo "# mine" >> $HOME/nix-config/home.nix
res=$(inst --clone github:owner/config)
has "$res" "using it as it is (not cloning)"