diff --git a/server/events/working_dir.go b/server/events/working_dir.go index c3ebe56e80..33bb7a8826 100644 --- a/server/events/working_dir.go +++ b/server/events/working_dir.go @@ -96,6 +96,13 @@ type FileWorkspace struct { // multiple dirs of the same repo without deleting existing plans. func (w *FileWorkspace) Clone(logger logging.SimpleLogging, headRepo models.Repo, p models.PullRequest, workspace string) (string, bool, error) { cloneDir := w.cloneDir(p.BaseRepo, p, workspace) + + // Unconditionally wait for the clone lock here, if anyone else is doing any clone + // operation in this directory, we wait for it to finish before we check anything. + value, _ := cloneLocks.LoadOrStore(cloneDir, new(sync.Mutex)) + mutex := value.(*sync.Mutex) + mutex.Lock() + defer mutex.Unlock() defer func() { w.CheckForUpstreamChanges = false }() c := wrappedGitContext{cloneDir, headRepo, p} @@ -217,15 +224,6 @@ func (w *FileWorkspace) HasDiverged(logger logging.SimpleLogging, cloneDir strin } func (w *FileWorkspace) forceClone(logger logging.SimpleLogging, c wrappedGitContext) error { - value, _ := cloneLocks.LoadOrStore(c.dir, new(sync.Mutex)) - mutex := value.(*sync.Mutex) - - defer mutex.Unlock() - if locked := mutex.TryLock(); !locked { - mutex.Lock() - return nil - } - err := os.RemoveAll(c.dir) if err != nil { return errors.Wrapf(err, "deleting dir '%s' before cloning", c.dir) @@ -280,15 +278,6 @@ func (w *FileWorkspace) forceClone(logger logging.SimpleLogging, c wrappedGitCon // There is a new upstream update that we need, and we want to update to it // without deleting any existing plans func (w *FileWorkspace) mergeAgain(logger logging.SimpleLogging, c wrappedGitContext) error { - value, _ := cloneLocks.LoadOrStore(c.dir, new(sync.Mutex)) - mutex := value.(*sync.Mutex) - - defer mutex.Unlock() - if locked := mutex.TryLock(); !locked { - mutex.Lock() - return nil - } - // Reset branch as if it was cloned again if err := w.wrappedGit(logger, c, "reset", "--hard", fmt.Sprintf("refs/remotes/origin/%s", c.pr.BaseBranch)); err != nil { return err