From d1c194ce66859e6ba5fe1b2c5c3f07437ff564a2 Mon Sep 17 00:00:00 2001 From: Alex Dunmow Date: Wed, 3 Jun 2026 07:07:10 +0800 Subject: [PATCH] fix(cli): archive working tree (via stash create) so --allow-dirty publishes uncommitted plugin.mod --- cmd/ninja/internal/archive/archive.go | 27 +++++++++++++++++++++------ 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/cmd/ninja/internal/archive/archive.go b/cmd/ninja/internal/archive/archive.go index 158a5ac..ceb5d45 100644 --- a/cmd/ninja/internal/archive/archive.go +++ b/cmd/ninja/internal/archive/archive.go @@ -5,18 +5,33 @@ import ( "fmt" "io" "os/exec" + "strings" "github.com/klauspost/compress/zstd" ) -// BuildSourceArchive runs `git archive --format=tar HEAD` in repoDir and -// compresses the result with zstd. Returns the compressed bytes. +// BuildSourceArchive captures the working tree as `tar.zst` bytes. // -// Only tracked files at HEAD are included. .gitignored files that were -// never tracked are excluded. Tracked-then-gitignored files are still -// included — callers may warn separately. +// When the working tree is clean it archives HEAD. When it's dirty +// (modified or staged tracked files), it archives a temporary stash +// object so the dirty state is what ships — callers that want +// HEAD-only behaviour should reject dirty trees before calling. +// Untracked files are never included regardless of state. func BuildSourceArchive(repoDir string) ([]byte, error) { - cmd := exec.Command("git", "archive", "--format=tar", "HEAD") + stashCmd := exec.Command("git", "stash", "create") + stashCmd.Dir = repoDir + var stashOut, stashErr bytes.Buffer + stashCmd.Stdout = &stashOut + stashCmd.Stderr = &stashErr + if err := stashCmd.Run(); err != nil { + return nil, fmt.Errorf("git stash create: %v: %s", err, stashErr.String()) + } + treeish := "HEAD" + if sha := strings.TrimSpace(stashOut.String()); sha != "" { + treeish = sha + } + + cmd := exec.Command("git", "archive", "--format=tar", treeish) cmd.Dir = repoDir var tarOut, stderr bytes.Buffer cmd.Stdout = &tarOut