@@ -953,12 +953,6 @@ func main() {
953
953
start := time .Now ()
954
954
ctx , cancel := context .WithTimeout (context .Background (), * flSyncTimeout )
955
955
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
-
962
956
if changed , hash , err := git .SyncRepo (ctx , refreshCreds ); err != nil {
963
957
failCount ++
964
958
updateSyncMetrics (metricKeyError , start )
@@ -990,6 +984,11 @@ func main() {
990
984
updateSyncMetrics (metricKeyNoOp , start )
991
985
}
992
986
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
+
993
992
// Determine if git-sync should terminate for one of several reasons
994
993
if * flOneTime {
995
994
// Wait for hooks to complete at least once, if not nil, before
@@ -1272,19 +1271,27 @@ func (git *repoSync) initRepo(ctx context.Context) error {
1272
1271
return nil
1273
1272
}
1274
1273
1275
- func (git * repoSync ) cleanupStaleWorktrees () error {
1274
+ func (git * repoSync ) removeStaleWorktrees () ( int , error ) {
1276
1275
currentWorktree , err := git .currentWorktree ()
1277
1276
if err != nil {
1278
- return err
1277
+ return 0 , err
1279
1278
}
1279
+
1280
+ git .log .V (3 ).Info ("cleaning up stale worktrees" , "currentHash" , currentWorktree .Hash ())
1281
+
1282
+ count := 0
1280
1283
err = removeDirContentsIf (git .worktreeFor ("" ).Path (), git .log , func (fi os.FileInfo ) (bool , error ) {
1281
1284
// 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
1283
1290
})
1284
1291
if err != nil {
1285
- return err
1292
+ return 0 , err
1286
1293
}
1287
- return nil
1294
+ return count , nil
1288
1295
}
1289
1296
1290
1297
// 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
1379
1386
continue
1380
1387
}
1381
1388
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 )
1383
1390
continue
1384
1391
} 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 )
1386
1393
continue
1387
1394
}
1388
1395
if log != nil {
@@ -1431,8 +1438,8 @@ func (git *repoSync) publishSymlink(ctx context.Context, worktree worktree) erro
1431
1438
return nil
1432
1439
}
1433
1440
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 {
1436
1443
// Clean up worktree, if needed.
1437
1444
_ , err := os .Stat (worktree .Path ().String ())
1438
1445
switch {
@@ -1461,7 +1468,7 @@ func (git *repoSync) createWorktree(ctx context.Context, hash string) (worktree,
1461
1468
// error'd without cleaning up. The next time thru the sync loop fails to
1462
1469
// create the worktree and bails out. This manifests as:
1463
1470
// "fatal: '/repo/root/nnnn' already exists"
1464
- if err := git .cleanupWorktree (ctx , worktree ); err != nil {
1471
+ if err := git .removeWorktree (ctx , worktree ); err != nil {
1465
1472
return "" , err
1466
1473
}
1467
1474
@@ -1568,8 +1575,11 @@ func (git *repoSync) cleanup(ctx context.Context) error {
1568
1575
var cleanupErrs multiError
1569
1576
1570
1577
// Clean up previous worktree(s).
1571
- if err := git .cleanupStaleWorktrees (); err != nil {
1578
+ if n , err := git .removeStaleWorktrees (); err != nil {
1572
1579
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
1573
1583
}
1574
1584
1575
1585
// 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
1752
1762
if ! git .sanityCheckWorktree (ctx , currentWorktree ) {
1753
1763
// Sanity check failed, nuke it and start over.
1754
1764
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 {
1756
1766
return false , "" , err
1757
1767
}
1758
1768
currentHash = ""
@@ -1806,11 +1816,10 @@ func (git *repoSync) SyncRepo(ctx context.Context, refreshCreds func(context.Con
1806
1816
return false , "" , err
1807
1817
}
1808
1818
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.
1811
1820
err = touch (currentWorktree .Path ())
1812
1821
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 ())
1814
1823
}
1815
1824
}
1816
1825
}
@@ -1819,15 +1828,14 @@ func (git *repoSync) SyncRepo(ctx context.Context, refreshCreds func(context.Con
1819
1828
setRepoReady ()
1820
1829
git .syncCount ++
1821
1830
1822
- // Clean up old worktree(s) and run GC.
1831
+ // Regular cleanup will happen in the outer loop, to catch stale
1832
+ // worktrees.
1833
+
1823
1834
if currentWorktree != git .worktreeFor (currentHash ) {
1824
1835
// The old worktree might have come from a prior version, and so
1825
1836
// not get caught by the normal cleanup.
1826
1837
os .RemoveAll (currentWorktree .Path ().String ())
1827
1838
}
1828
- if err := git .cleanup (ctx ); err != nil {
1829
- git .log .Error (err , "git cleanup failed" , "newWorktree" , newWorktree )
1830
- }
1831
1839
}
1832
1840
1833
1841
return changed , remoteHash , nil
0 commit comments