Review feedback flagged that the resolved worktree path was trusted
without verifying it actually belongs to the repository. A stale
$GIT_DIR/gitdir pointer, or one pointing at a different repository,
could silently redirect status and restore into wrong directories.
core.worktree was also read from every config scope, so a global or
system setting would override discovery for every repository.
- verify the gitdir link in both directions: the .git entry the pointer
names must in turn reference this GIT_DIR
- prefer the worktree discovered at load time over core.worktree, and
read core.worktree from repository-local config only
- fall back to looking for bare sentinel files instead of the GIT_DIR
name, which inverted for bare repos named repo.git and linked worktrees
- compare worktree and GIT_DIR paths after resolving symlinks
- require the common-dir config to be a regular file before reading it
- separate restore pathspecs from options with "--"
- case-fold repository environment variable keys in the test helper for
Windows, and parallelize the new worktree tests
Signed-off-by: lakshit verma <vermalucky2004@gmail.com>
Worktree resolution chopped ".git" off the resolved GIT_DIR path, which
only works for the standard <repo>/.git layout. This breaks repositories
created with --separate-git-dir, misclassifies linked worktrees as bare
(so file restoration was silently skipped), and misclassifies bare
repositories named foo.git as non-bare. Linked worktrees could not even
be loaded because ensureNoCompatObjectFormat expects a config file that
only exists in the repository's common Git directory.
- add Repository.GetWorktree() resolving via $GIT_DIR/gitdir,
core.worktree, load-time discovery, then the standard layout;
validated so stale or malformed records fall through cleanly
- determine bareness via rev-parse --is-bare-repository instead of the
GIT_DIR name, exposed through the ErrNoWorktree sentinel
- read configuration from the common directory via $GIT_DIR/commondir
- route Status(), RestoreWorktree(), and post-propagation restore
through GetWorktree()
Fixes#1006
Signed-off-by: lakshit verma <vermalucky2004@gmail.com>
Restructure storage so gittuf verification can run over backends other
than the git binary (e.g. go-git):
- pkg/githash: concrete Git object hash, stdlib-only.
gitinterface.Hash aliases it.
- pkg/gitstore: the single Storer interface (24 methods) that all
storage consumers program against, plus the shared
ErrReferenceNotFound sentinel. *gitinterface.Repository satisfies it
structurally (compile-time asserted). Also defines ConfigKey, the
canonical type for the Git config settings gittuf reads.
- pkg/rsl (from internal/rsl): entry model, codec, and readers over
gitstore.Storer; zero gitinterface/sigstore dependencies. rsl.Hash
aliases githash.Hash; nil is the unset-Hash sentinel and IsZero
matches nil and empty as well as both format zeros (no
object-format-unaware ZeroHash). Entry commits (empty tree on the
RSL ref) are owned by the package; no storer adapter.
- internal/signerverifier/gitobject: verifies commit/tag signatures
over (payload, signature) bytes, Rekor URL as an option. The storage
half is Repository.GetObjectSignature. Removes sigstore, cosign, and
gitsign from gitinterface's dependency tree.
- internal/propagation: propagation workflow, moved off pkg/rsl's
public API (its tuf directive types are internal).
- internal/{attestations,cache,policy}: storage via gitstore.Storer;
tree writing via WriteTree(blobs, subtrees).
Breaking changes to pkg/gitinterface: Repository.VerifySignature and
the verification sentinels are removed (use gitobject.Verify);
ErrReferenceNotFound now aliases gitstore's. Repository.GetGitConfig
(which returned the whole config map) is replaced by
LookupConfig(gitstore.ConfigKey), returning a single setting's value.
Policy resolves the Rekor override from git config once per
verification and extracts signed payloads once per object instead of
per key attempt.
Assisted-by: Claude Opus 4.8 <noreply@anthropic.com>
Signed-off-by: Paulo Gomes <paulo@entire.io>
LoadRepository did os.Chdir(repositoryPath) to run 'git rev-parse
--git-dir', and Status/RestoreWorktree/tree-restore did the same to run
worktree-relative commands. os.Chdir is process-global; concurrent
LoadRepository calls for different paths could each resolve the wrong
gitDirPath.
Adds executor.withDir(dir) which sets cmd.Dir. LoadRepository now runs
'git rev-parse --absolute-git-dir' with cmd.Dir set to the repository
path (and EvalSymlinks the result to match prior behaviour). The
worktree commands use withDir(worktree).
TestLoadRepositoryConcurrent runs 20 pairs of LoadRepository for two
distinct repos in parallel under -race and asserts each gets its own
gitDirPath.
Signed-off-by: Andrew Nesbitt <andrewnez@gmail.com>