diff --git a/spec/git-spec.coffee b/spec/git-spec.coffee index 7d9e9bbd4..82e371146 100644 --- a/spec/git-spec.coffee +++ b/spec/git-spec.coffee @@ -289,6 +289,16 @@ describe "GitRepository", -> expect(repo.isStatusModified(status)).toBe true expect(repo.isStatusNew(status)).toBe false + it 'caches statuses that were looked up synchronously', -> + originalContent = 'undefined' + fs.writeFileSync(modifiedPath, 'making this path modified') + repo.getPathStatus('file.txt') + + fs.writeFileSync(modifiedPath, originalContent) + waitsForPromise -> repo.refreshStatus() + runs -> + expect(repo.isStatusModified(repo.getCachedPathStatus(modifiedPath))).toBeFalsy() + describe "buffer events", -> [editor] = [] diff --git a/src/git-repository.coffee b/src/git-repository.coffee index a04124b78..fcbc40830 100644 --- a/src/git-repository.coffee +++ b/src/git-repository.coffee @@ -166,12 +166,7 @@ class GitRepository # # Returns a {Disposable} on which `.dispose()` can be called to unsubscribe. onDidChangeStatuses: (callback) -> - @async.onDidChangeStatuses -> - # Defer the callback to the next tick so that we've reset - # `@statusesByPath` by the time it's called. Otherwise reads from within - # the callback could be inconsistent. - # See https://github.com/atom/atom/issues/11396 - process.nextTick callback + @emitter.on 'did-change-statuses', callback ### Section: Repository Details @@ -496,9 +491,27 @@ class GitRepository # # Returns a promise that resolves when the repository has been refreshed. refreshStatus: -> + statusesChanged = false + + # Listen for `did-change-statuses` so we know if something changed. But we + # need to wait to propagate it until after we've set the branch and cleared + # the `statusesByPath` cache. So just set a flag, and we'll emit the event + # after refresh is done. + subscription = @async.onDidChangeStatuses -> + subscription?.dispose() + subscription = null + + statusesChanged = true + asyncRefresh = @async.refreshStatus().then => - @statusesByPath = {} + subscription?.dispose() + subscription = null + @branch = @async?.branch + @statusesByPath = {} + + if statusesChanged + @emitter.emit 'did-change-statuses' syncRefresh = new Promise (resolve, reject) => @handlerPath ?= require.resolve('./repository-status-handler')