diff options
author | Paulo Gomes <pjbgf@linux.com> | 2024-08-03 10:23:28 +0100 |
---|---|---|
committer | Paulo Gomes <pjbgf@linux.com> | 2024-08-03 10:25:23 +0100 |
commit | e2d6e8f264604b1b71dc2c958f7bdd44a90d029b (patch) | |
tree | 5212ed1117f4e655356ddd6fdf7fce5647267d52 /status.go | |
parent | 093134604cde84f51625efdcf5266a62cd5ab6e9 (diff) | |
download | go-git-e2d6e8f264604b1b71dc2c958f7bdd44a90d029b.tar.gz |
git: worktree, Add StatusWithOptions
The fix for #119 improves the Worktree.Status() behaviour by preloading
all existing files and setting their status to unmodified. Which makes it
more reliable when doing per file status verification, however breaks
backwards compatibility in two ways:
- Increased execution time and space: the preloading can be slow in
very large repositories and will increase memory usage when representing
the state.
- Behaviour: the previous behaviour returned a map with a small subset of
entries. The new behaviour will include a new entry for every file within
the repository.
This commit introduces reverts the change in the default behaviour, and
introduces StatusWithOptions so that users can opt-in the new option.
Signed-off-by: Paulo Gomes <pjbgf@linux.com>
Diffstat (limited to 'status.go')
-rw-r--r-- | status.go | 69 |
1 files changed, 69 insertions, 0 deletions
@@ -4,6 +4,9 @@ import ( "bytes" "fmt" "path/filepath" + + mindex "github.com/go-git/go-git/v5/utils/merkletrie/index" + "github.com/go-git/go-git/v5/utils/merkletrie/noder" ) // Status represents the current status of a Worktree. @@ -77,3 +80,69 @@ const ( Copied StatusCode = 'C' UpdatedButUnmerged StatusCode = 'U' ) + +// StatusStrategy defines the different types of strategies when processing +// the worktree status. +type StatusStrategy int + +const ( + // TODO: (V6) Review the default status strategy. + // TODO: (V6) Review the type used to represent Status, to enable lazy + // processing of statuses going direct to the backing filesystem. + defaultStatusStrategy = Empty + + // Empty starts its status map from empty. Missing entries for a given + // path means that the file is untracked. This causes a known issue (#119) + // whereby unmodified files can be incorrectly reported as untracked. + // + // This can be used when returning the changed state within a modified Worktree. + // For example, to check whether the current worktree is clean. + Empty StatusStrategy = 0 + // Preload goes through all existing nodes from the index and add them to the + // status map as unmodified. This is currently the most reliable strategy + // although it comes at a performance cost in large repositories. + // + // This method is recommended when fetching the status of unmodified files. + // For example, to confirm the status of a specific file that is either + // untracked or unmodified. + Preload StatusStrategy = 1 +) + +func (s StatusStrategy) new(w *Worktree) (Status, error) { + switch s { + case Preload: + return preloadStatus(w) + case Empty: + return make(Status), nil + } + return nil, fmt.Errorf("%w: %+v", ErrUnsupportedStatusStrategy, s) +} + +func preloadStatus(w *Worktree) (Status, error) { + idx, err := w.r.Storer.Index() + if err != nil { + return nil, err + } + + idxRoot := mindex.NewRootNode(idx) + nodes := []noder.Noder{idxRoot} + + status := make(Status) + for len(nodes) > 0 { + var node noder.Noder + node, nodes = nodes[0], nodes[1:] + if node.IsDir() { + children, err := node.Children() + if err != nil { + return nil, err + } + nodes = append(nodes, children...) + continue + } + fs := status.File(node.Name()) + fs.Worktree = Unmodified + fs.Staging = Unmodified + } + + return status, nil +} |