code: func pruneTaskGetRetainedWorktree(gitscanner *lfs.GitScanner, retainChan chan string, errorChan chan error, waitg *sync.WaitGroup, sem *semaphore.Weighted) {
  	defer waitg.Done()
  
  	// Retain other worktree HEADs too
  	// Working copy, branch & maybe commit is different but repo is shared
  	allWorktreeRefs, err := git.GetAllWorkTreeHEADs(cfg.LocalGitStorageDir())
  	if err != nil {
  		errorChan <- err
  		return
  	}
  	// Don't repeat any commits, worktrees are always on their own branches but
  	// may point to the same commit
  	commits := tools.NewStringSet()
  	// current HEAD is done elsewhere
  	headref, err := git.CurrentRef()
  	if err != nil {
  		errorChan <- err
  		return
  	}
  	commits.Add(headref.Sha)
  	for _, ref := range allWorktreeRefs {
  		if commits.Add(ref.Sha) {
  			// Worktree is on a different commit
  			waitg.Add(1)
  			// Don't need to 'cd' to worktree since we share same repo
  			go pruneTaskGetRetainedAtRef(gitscanner, ref.Sha, retainChan, errorChan, waitg, sem)
  		}
  	}
  }
docs: // Background task, must call waitg.Done() once at end