From 514842ca773137c4e4951a0312636d0c2c82b852 Mon Sep 17 00:00:00 2001 From: joshaber Date: Tue, 19 Jan 2016 11:59:16 -0500 Subject: [PATCH 1/3] If we can't refresh a submodule, drop it. --- src/git-repository-async.js | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/src/git-repository-async.js b/src/git-repository-async.js index f40172c69..9828be14d 100644 --- a/src/git-repository-async.js +++ b/src/git-repository-async.js @@ -853,17 +853,26 @@ export default class GitRepositoryAsync { } for (const name in this.submodules) { - if (submoduleNames.indexOf(name) < 0) { - const repo = this.submodules[name] + const repo = this.submodules[name] + const gone = submoduleNames.indexOf(name) < 0 + if (gone) { repo.destroy() delete this.submodules[name] + } else { + try { + await repo.refreshStatus() + } catch (e) { + // If we error trying to refresh, then it probably means the submodule + // isn't actually a submodule. Libgit2 will report anything listed in + // .gitmodules as a submodule, but that's not necessarily accurate. So + // get rid of the submodule entry. + repo.destroy() + delete this.submodules[name] + } } } - const submoduleRepos = _.values(this.submodules) - await Promise.all(submoduleRepos.map(s => s.refreshStatus())) - - return submoduleRepos + return _.values(this.submodules) } // Get the status for the submodules in the repository. From 50c74499dcc96ba2f07d2af133712345a3f4aee9 Mon Sep 17 00:00:00 2001 From: joshaber Date: Tue, 19 Jan 2016 16:34:30 -0700 Subject: [PATCH 2/3] Link to the libgit2 issue. --- src/git-repository-async.js | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/git-repository-async.js b/src/git-repository-async.js index 9828be14d..9571f877d 100644 --- a/src/git-repository-async.js +++ b/src/git-repository-async.js @@ -862,10 +862,9 @@ export default class GitRepositoryAsync { try { await repo.refreshStatus() } catch (e) { - // If we error trying to refresh, then it probably means the submodule - // isn't actually a submodule. Libgit2 will report anything listed in - // .gitmodules as a submodule, but that's not necessarily accurate. So - // get rid of the submodule entry. + // libgit2 will sometimes report submodules that aren't actually valid + // (https://github.com/libgit2/libgit2/issues/3580). So check the + // validity of the submodules by removing any that fail. repo.destroy() delete this.submodules[name] } From 60c33f6bc937d6079f6b60b95afe6cf710cd18a5 Mon Sep 17 00:00:00 2001 From: joshaber Date: Tue, 19 Jan 2016 16:35:36 -0700 Subject: [PATCH 3/3] Open submodules directly instead of searching. --- src/git-repository-async.js | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/git-repository-async.js b/src/git-repository-async.js index 9571f877d..38792e02e 100644 --- a/src/git-repository-async.js +++ b/src/git-repository-async.js @@ -37,8 +37,11 @@ export default class GitRepositoryAsync { this.emitter = new Emitter() this.subscriptions = new CompositeDisposable() this.pathStatusCache = {} - // NB: This needs to happen before the following .openRepository call. + + // NB: These needs to happen before the following .openRepository call. this.openedPath = _path + this._openExactPath = options.openExactPath || false + this.repoPromise = this.openRepository() this.isCaseInsensitive = fs.isCaseInsensitive() this.upstream = {} @@ -848,7 +851,7 @@ export default class GitRepositoryAsync { const submodule = await Git.Submodule.lookup(repo, name) const absolutePath = path.join(repo.workdir(), submodule.path()) - const submoduleRepo = GitRepositoryAsync.open(absolutePath) + const submoduleRepo = GitRepositoryAsync.open(absolutePath, {openExactPath: true, refreshOnWindowFocus: false}) this.submodules[name] = submoduleRepo } @@ -977,7 +980,11 @@ export default class GitRepositoryAsync { // // Returns the new {NodeGit.Repository}. openRepository () { - return Git.Repository.openExt(this.openedPath, 0, '') + if (this._openExactPath) { + return Git.Repository.open(this.openedPath) + } else { + return Git.Repository.openExt(this.openedPath, 0, '') + } } // Section: Private