From ef581c93f391919b35b903b93af45f33d90de15d Mon Sep 17 00:00:00 2001 From: tv Date: Fri, 13 Nov 2026 20:27:48 +0000 Subject: populate: keep URLs, refs, and names from being taken for options A git source's url and ref are strings, and git clone, git remote, and git fetch took ones starting with - for options, e.g. --upload-pack, which runs a command where the repository is local. They come after -- now, and so does a pass source's name for git log and pass show. git-ref-option gives a ref that git fetch would take for --upload-pack. --- CHANGELOG.md | 2 ++ pkgs/populate/src/sh.rs | 17 +++++++++-------- tests/scenarios.nix | 23 +++++++++++++++++++++++ 3 files changed, 34 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index af40bb0..7f5f2c4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,8 @@ as JSON. The store gets one program for each version of krops, instead of a script for each set of arguments. `pkgs.populate`, `writeDeploy`, and the other functions keep their arguments. +- Git can't take a `git` source's `url` or `ref`, or a `pass` source's + `name`, for an option. - `git` sources with a branch or tag as `ref` follow it: populate fetches the branch or tag on every run, and resets the work tree to what it fetched. diff --git a/pkgs/populate/src/sh.rs b/pkgs/populate/src/sh.rs index 8282370..ce42e12 100644 --- a/pkgs/populate/src/sh.rs +++ b/pkgs/populate/src/sh.rs @@ -352,24 +352,25 @@ if ! test -e "$path"; then if test -n "$shallow"; then git init "$path" else - git clone --recurse-submodules "$url" "$path" + git clone --recurse-submodules -- "$url" "$path" fi fi cd "$path" if ! origin=$(git config remote.origin.url); then - git remote add origin "$url" + git remote add -- origin "$url" elif test "$origin" != "$url"; then - git remote set-url origin "$url" + git remote set-url -- origin "$url" fi # A commit, given by its hash or a prefix thereof, gets fetched only if the -# work tree lacks it, unless fetchAlways is set. A branch or tag gets +# work tree lacks it, unless fetchAlways is set. After --, a ref can't be +# taken for an option. A branch or tag gets # fetched on every run, so the work tree follows it: resetting to its name # would reset to a local branch, which fetching doesn't move. fetch() { if test -n "$shallow"; then - git fetch --depth=1 origin "$1" + git fetch --depth=1 origin -- "$1" else - git fetch origin "$1" + git fetch origin -- "$1" fi } fetch_commit() { @@ -418,7 +419,7 @@ pub mod local { dir=$1 name=$2 if test -e "$dir"/.git; then printf '%s %s\n' "$name" "$( - git -C "$dir" log -1 --format=%H "$name" + git -C "$dir" log -1 --format=%H -- "$name" find "$dir"/"$name" -type l -exec realpath {} + | sort | xargs -r -n 1 git -C "$dir" log -1 --format=%H @@ -446,7 +447,7 @@ while read -r gpg_path; do pass_name=$name/$rel_name pass_out=$PWD/$rel_name mkdir -p "$(dirname "$pass_out")" - PASSWORD_STORE_DIR=$dir pass show "$pass_name" > "$pass_out" + PASSWORD_STORE_DIR=$dir pass show -- "$pass_name" > "$pass_out" if [ -n "$pass_date" ]; then touch -d "$pass_date" "$pass_out" fi diff --git a/tests/scenarios.nix b/tests/scenarios.nix index 14a2c91..85b481e 100644 --- a/tests/scenarios.nix +++ b/tests/scenarios.nix @@ -2105,6 +2105,29 @@ assert !(krops.isLocalTarget (targets.remote "/")); } ]; })) + # A ref that git fetch would take for an option: --upload-pack runs a + # command where the repository is local. + (s "git-ref-option" (let + elsewhere = "/var/krops-elsewhere"; + in { + isolate = true; + prepare = '' + rm -fR ${elsewhere} + git clone -q --bare ${gitUrl} ${elsewhere}/repo.git + ''; + phases = [ + { + sources.x.git = { + url = "${elsewhere}/repo.git"; + ref = "--upload-pack=touch ${elsewhere}/ran; git-upload-pack"; + }; + expect.fail = "invalid refspec"; + check = '' + test ! -e ${elsewhere}/ran || fail "the ref ran a command" + ''; + } + ]; + })) # A file in populate's state replaced by a symlink to a file outside. (s "state-key" (let sources.x.flake-input = { -- cgit v1.3.1