Clean up all old worktrees
This commit is contained in:
parent
10af97f51d
commit
5cc7160985
|
|
@ -1175,22 +1175,38 @@ func dirIsEmpty(dir string) (bool, error) {
|
||||||
return len(dirents) == 0, nil
|
return len(dirents) == 0, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func removeDirContents(dir string, log *logging.Logger) error {
|
// removeDirContents iterated the specified dir and removes all contents,
|
||||||
|
// except entries which are specifically excepted.
|
||||||
|
func removeDirContents(dir string, log *logging.Logger, except ...string) error {
|
||||||
dirents, err := os.ReadDir(dir)
|
dirents, err := os.ReadDir(dir)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
exceptMap := map[string]bool{}
|
||||||
|
for _, x := range except {
|
||||||
|
exceptMap[x] = true
|
||||||
|
}
|
||||||
|
|
||||||
|
// Save errors until the end.
|
||||||
|
var errs multiError
|
||||||
for _, fi := range dirents {
|
for _, fi := range dirents {
|
||||||
p := filepath.Join(dir, fi.Name())
|
name := fi.Name()
|
||||||
|
if exceptMap[name] {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
p := filepath.Join(dir, name)
|
||||||
if log != nil {
|
if log != nil {
|
||||||
log.V(3).Info("removing path recursively", "path", p, "isDir", fi.IsDir())
|
log.V(3).Info("removing path recursively", "path", p, "isDir", fi.IsDir())
|
||||||
}
|
}
|
||||||
if err := os.RemoveAll(p); err != nil {
|
if err := os.RemoveAll(p); err != nil {
|
||||||
return err
|
errs = append(errs, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if len(errs) != 0 {
|
||||||
|
return errs
|
||||||
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1261,7 +1277,7 @@ func (git *repoSync) createWorktree(ctx context.Context, hash string) (worktree,
|
||||||
}
|
}
|
||||||
|
|
||||||
git.log.V(0).Info("adding worktree", "path", worktree.Path(), "hash", hash)
|
git.log.V(0).Info("adding worktree", "path", worktree.Path(), "hash", hash)
|
||||||
_, err := git.run.Run(ctx, git.root, nil, git.cmd, "worktree", "add", "--detach", worktree.Path(), hash, "--no-checkout")
|
_, err := git.run.Run(ctx, git.root, nil, git.cmd, "worktree", "add", "--force", "--detach", worktree.Path(), hash, "--no-checkout")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
|
@ -1366,17 +1382,18 @@ func (git *repoSync) configureWorktree(ctx context.Context, worktree worktree) e
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// cleanup removes old worktrees and runs git's garbage collection.
|
// cleanup removes old worktrees and runs git's garbage collection. The
|
||||||
|
// specified worktree is preserved.
|
||||||
func (git *repoSync) cleanup(ctx context.Context, worktree worktree) error {
|
func (git *repoSync) cleanup(ctx context.Context, worktree worktree) error {
|
||||||
// Save errors until the end.
|
// Save errors until the end.
|
||||||
var cleanupErrs multiError
|
var cleanupErrs multiError
|
||||||
|
|
||||||
// Clean up previous worktree.
|
// Clean up previous worktree(s).
|
||||||
// TODO: list and clean up all old worktrees
|
if err := removeDirContents(git.worktreeFor("").path(), git.log, worktree.hash()); err != nil {
|
||||||
if worktree != "" {
|
cleanupErrs = append(cleanupErrs, err)
|
||||||
if err := git.cleanupWorktree(ctx, worktree); err != nil {
|
}
|
||||||
cleanupErrs = append(cleanupErrs, err)
|
if _, err := git.run.Run(ctx, git.root, nil, git.cmd, "worktree", "prune", "--verbose"); err != nil {
|
||||||
}
|
cleanupErrs = append(cleanupErrs, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Expire old refs.
|
// Expire old refs.
|
||||||
|
|
@ -1608,8 +1625,8 @@ func (git *repoSync) SyncRepo(ctx context.Context, refreshCreds func(context.Con
|
||||||
if currentHash == remoteHash {
|
if currentHash == remoteHash {
|
||||||
currentWorktree = ""
|
currentWorktree = ""
|
||||||
}
|
}
|
||||||
if err := git.cleanup(ctx, currentWorktree); err != nil {
|
if err := git.cleanup(ctx, newWorktree); err != nil {
|
||||||
git.log.Error(err, "git cleanup failed", "oldWorktree", currentWorktree)
|
git.log.Error(err, "git cleanup failed", "newWorktree", newWorktree)
|
||||||
}
|
}
|
||||||
|
|
||||||
return changed, remoteHash, nil
|
return changed, remoteHash, nil
|
||||||
|
|
|
||||||
|
|
@ -557,6 +557,10 @@ function e2e::worktree_cleanup() {
|
||||||
SHA=$(git -C "$REPO" rev-list -n1 HEAD)
|
SHA=$(git -C "$REPO" rev-list -n1 HEAD)
|
||||||
git -C "$REPO" worktree add -q "$ROOT/.worktrees/$SHA" -b e2e --no-checkout
|
git -C "$REPO" worktree add -q "$ROOT/.worktrees/$SHA" -b e2e --no-checkout
|
||||||
|
|
||||||
|
# add some garbage
|
||||||
|
mkdir -p "$ROOT/.worktrees/not_a_hash/subdir"
|
||||||
|
touch "$ROOT/.worktrees/not_a_directory"
|
||||||
|
|
||||||
# resume time
|
# resume time
|
||||||
docker ps --filter label="git-sync-e2e=$RUNID" --format="{{.ID}}" \
|
docker ps --filter label="git-sync-e2e=$RUNID" --format="{{.ID}}" \
|
||||||
| while read CTR; do
|
| while read CTR; do
|
||||||
|
|
@ -567,6 +571,9 @@ function e2e::worktree_cleanup() {
|
||||||
assert_file_exists "$ROOT"/link/file2
|
assert_file_exists "$ROOT"/link/file2
|
||||||
assert_file_eq "$ROOT"/link/file2 "$FUNCNAME-ok"
|
assert_file_eq "$ROOT"/link/file2 "$FUNCNAME-ok"
|
||||||
assert_metric_eq "${METRIC_GOOD_SYNC_COUNT}" 2
|
assert_metric_eq "${METRIC_GOOD_SYNC_COUNT}" 2
|
||||||
|
assert_file_absent "$ROOT/.worktrees/$SHA"
|
||||||
|
assert_file_absent "$ROOT/.worktrees/not_a_hash"
|
||||||
|
assert_file_absent "$ROOT/.worktrees/not_a_directory"
|
||||||
}
|
}
|
||||||
|
|
||||||
##############################################
|
##############################################
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue