Skip to content

Commit e15c7a9

Browse files
committed
Tighten up cleanup to be called once per loop
1 parent 451ac41 commit e15c7a9

File tree

1 file changed

+33
-25
lines changed

1 file changed

+33
-25
lines changed

cmd/git-sync/main.go

+33-25
Original file line numberDiff line numberDiff line change
@@ -953,12 +953,6 @@ func main() {
953953
start := time.Now()
954954
ctx, cancel := context.WithTimeout(context.Background(), *flSyncTimeout)
955955

956-
if git.staleTimeout > 0 {
957-
if err := git.cleanupStaleWorktrees(); err != nil {
958-
log.Error(err, "failed to clean up stale worktrees")
959-
}
960-
}
961-
962956
if changed, hash, err := git.SyncRepo(ctx, refreshCreds); err != nil {
963957
failCount++
964958
updateSyncMetrics(metricKeyError, start)
@@ -990,6 +984,11 @@ func main() {
990984
updateSyncMetrics(metricKeyNoOp, start)
991985
}
992986

987+
// Clean up old worktree(s) and run GC.
988+
if err := git.cleanup(ctx); err != nil {
989+
log.Error(err, "git cleanup failed")
990+
}
991+
993992
// Determine if git-sync should terminate for one of several reasons
994993
if *flOneTime {
995994
// Wait for hooks to complete at least once, if not nil, before
@@ -1272,19 +1271,27 @@ func (git *repoSync) initRepo(ctx context.Context) error {
12721271
return nil
12731272
}
12741273

1275-
func (git *repoSync) cleanupStaleWorktrees() error {
1274+
func (git *repoSync) removeStaleWorktrees() (int, error) {
12761275
currentWorktree, err := git.currentWorktree()
12771276
if err != nil {
1278-
return err
1277+
return 0, err
12791278
}
1279+
1280+
git.log.V(3).Info("cleaning up stale worktrees", "currentHash", currentWorktree.Hash())
1281+
1282+
count := 0
12801283
err = removeDirContentsIf(git.worktreeFor("").Path(), git.log, func(fi os.FileInfo) (bool, error) {
12811284
// delete files that are over the stale time out, and make sure to never delete the current worktree
1282-
return fi.Name() != currentWorktree.Hash() && time.Since(fi.ModTime()) > git.staleTimeout, nil
1285+
if fi.Name() != currentWorktree.Hash() && time.Since(fi.ModTime()) > git.staleTimeout {
1286+
count++
1287+
return true, nil
1288+
}
1289+
return false, nil
12831290
})
12841291
if err != nil {
1285-
return err
1292+
return 0, err
12861293
}
1287-
return nil
1294+
return count, nil
12881295
}
12891296

12901297
// sanityCheckRepo tries to make sure that the repo dir is a valid git repository.
@@ -1379,10 +1386,10 @@ func removeDirContentsIf(dir absPath, log *logging.Logger, fn func(fi os.FileInf
13791386
continue
13801387
}
13811388
if shouldDelete, err := fn(stat); err != nil {
1382-
log.Error(err, "failed to evaluate shouldDelete function, skipping", "path", p)
1389+
log.Error(err, "predicate function failed for path, skipping", "path", p)
13831390
continue
13841391
} else if !shouldDelete {
1385-
log.V(3).Info("skipping path that should not be removed", "path", p)
1392+
log.V(3).Info("skipping path", "path", p)
13861393
continue
13871394
}
13881395
if log != nil {
@@ -1431,8 +1438,8 @@ func (git *repoSync) publishSymlink(ctx context.Context, worktree worktree) erro
14311438
return nil
14321439
}
14331440

1434-
// cleanupWorktree is used to remove a worktree and its folder
1435-
func (git *repoSync) cleanupWorktree(ctx context.Context, worktree worktree) error {
1441+
// removeWorktree is used to remove a worktree and its folder
1442+
func (git *repoSync) removeWorktree(ctx context.Context, worktree worktree) error {
14361443
// Clean up worktree, if needed.
14371444
_, err := os.Stat(worktree.Path().String())
14381445
switch {
@@ -1461,7 +1468,7 @@ func (git *repoSync) createWorktree(ctx context.Context, hash string) (worktree,
14611468
// error'd without cleaning up. The next time thru the sync loop fails to
14621469
// create the worktree and bails out. This manifests as:
14631470
// "fatal: '/repo/root/nnnn' already exists"
1464-
if err := git.cleanupWorktree(ctx, worktree); err != nil {
1471+
if err := git.removeWorktree(ctx, worktree); err != nil {
14651472
return "", err
14661473
}
14671474

@@ -1568,8 +1575,11 @@ func (git *repoSync) cleanup(ctx context.Context) error {
15681575
var cleanupErrs multiError
15691576

15701577
// Clean up previous worktree(s).
1571-
if err := git.cleanupStaleWorktrees(); err != nil {
1578+
if n, err := git.removeStaleWorktrees(); err != nil {
15721579
cleanupErrs = append(cleanupErrs, err)
1580+
} else if n == 0 {
1581+
// We didn't clean up any worktrees, so the rest of this is moot.
1582+
return nil
15731583
}
15741584

15751585
// Let git know we don't need those old commits any more.
@@ -1752,7 +1762,7 @@ func (git *repoSync) SyncRepo(ctx context.Context, refreshCreds func(context.Con
17521762
if !git.sanityCheckWorktree(ctx, currentWorktree) {
17531763
// Sanity check failed, nuke it and start over.
17541764
git.log.V(0).Info("worktree failed checks or was empty", "path", currentWorktree)
1755-
if err := git.cleanupWorktree(ctx, currentWorktree); err != nil {
1765+
if err := git.removeWorktree(ctx, currentWorktree); err != nil {
17561766
return false, "", err
17571767
}
17581768
currentHash = ""
@@ -1806,11 +1816,10 @@ func (git *repoSync) SyncRepo(ctx context.Context, refreshCreds func(context.Con
18061816
return false, "", err
18071817
}
18081818
if currentWorktree != "" {
1809-
// Touch the old worktree -- which will make cleanupStaleWorktrees delete it in the future,
1810-
// if the stale timeout option is enabled
1819+
// Start the stale worktree removal timer.
18111820
err = touch(currentWorktree.Path())
18121821
if err != nil {
1813-
git.log.Error(err, "Couldn't change stale worktree mtime", "path", currentWorktree.Path())
1822+
git.log.Error(err, "can't change stale worktree mtime", "path", currentWorktree.Path())
18141823
}
18151824
}
18161825
}
@@ -1819,15 +1828,14 @@ func (git *repoSync) SyncRepo(ctx context.Context, refreshCreds func(context.Con
18191828
setRepoReady()
18201829
git.syncCount++
18211830

1822-
// Clean up old worktree(s) and run GC.
1831+
// Regular cleanup will happen in the outer loop, to catch stale
1832+
// worktrees.
1833+
18231834
if currentWorktree != git.worktreeFor(currentHash) {
18241835
// The old worktree might have come from a prior version, and so
18251836
// not get caught by the normal cleanup.
18261837
os.RemoveAll(currentWorktree.Path().String())
18271838
}
1828-
if err := git.cleanup(ctx); err != nil {
1829-
git.log.Error(err, "git cleanup failed", "newWorktree", newWorktree)
1830-
}
18311839
}
18321840

18331841
return changed, remoteHash, nil

0 commit comments

Comments
 (0)