Description
I was trying to use nodegit to do a recursive clone, but was getting crashes left and right and couldn't figure out what was going on. I've found a workaround, but wanted to report the crash here.
As far as I can tell, if I used Submodule.foreach
to iterate over the submodules and then call submodule.update
, nodegit crashes the node process, and I get an error message popup that looks like this:
Microsoft Visual C++ Runtime Library
Assertion failed!
Program: ...re\node_modules\nodegit\build\Release\nodegit.node
File: ..\..\vendor\libgit2\src\repository.c
Line: 2111
Expression: repo && id
For information on how your program can cause an assertion failure, see the Visual C++ documentation on asserts.
( Here's a link to an image of the screenshot: https://dl.dropboxusercontent.com/u/108847970/nodegit-crash-screenshot.png )
These's are the versions I'm running:
- Windows 10 (x64)
- nodejs 4.2.3 (x64)
- nodegit 0.11.5
Here's some sample code that reproduces the issue for me:
var path = require("path");
var mkdirp = require("mkdirp");
var rimraf = require("rimraf");
var git = require("nodegit");
var reposPath = path.join(__dirname, "cloned-repos");
var repoPath = path.join(reposPath, "electron");
var cloneUrl = "https://github.com/atom/electron";
rimraf(reposPath, function (err) {
if (err) {
throw err;
}
mkdirp(reposPath, function (err) {
if (err) {
throw err;
}
console.log("Cloning '" + cloneUrl + "'...");
git.Clone.clone(cloneUrl, repoPath, new git.CloneOptions()).then(function () {
console.log("Cloned successfully!");
git.Repository.open(repoPath)
.then(function(repo) {
var p = Promise.resolve();
git.Submodule.foreach(repo, function(submodule) {
var name = submodule.name();
console.log("Found submodule: " + name);
p = p.then(
function() {
return new Promise(function(resolve, reject) {
submodule.init(1).then(
function() {
console.log("Init success on " + name);
submodule.update(1, new git.SubmoduleUpdateOptions()).then(
function () {
console.log("Update success on " + name);
resolve();
},
reject
);
}, reject
);
});
}
)
}).then(
function() {
console.log("Foreach is done.");
p.then(
function() {
console.log("Everything is done.");
},
function(error) {
console.error(error);
}
)
}
);
});
}, function (error) {
console.error(error);
});
});
});
The workaround I discovered was that if I switch to using Repository.getSubmoduleNames
and Submodule.lookup
instead of Submodule.foreach
, everything seems to work just fine.
Here's the sample code for that:
var path = require("path");
var mkdirp = require("mkdirp");
var rimraf = require("rimraf");
var git = require("nodegit");
var reposPath = path.join(__dirname, "cloned-repos");
var repoPath = path.join(reposPath, "electron");
var cloneUrl = "https://github.com/atom/electron";
rimraf(reposPath, function (err) {
if (err) {
throw err;
}
mkdirp(reposPath, function (err) {
if (err) {
throw err;
}
console.log("Cloning '" + cloneUrl + "'...");
git.Clone.clone(cloneUrl, repoPath, new git.CloneOptions()).then(function () {
console.log("Cloned successfully!");
git.Repository.open(repoPath)
.then(function(repo) {
repo.getSubmoduleNames().then(
function(names) {
console.log("Found the following submodules:");
console.log(names);
var p = Promise.resolve();
names.forEach(function(name) {
p = p.then(
function() {
return new Promise(function(resolve, reject) {
git.Submodule.lookup(repo, name).then(
function (submodule) {
submodule.init(1).then(
function() {
console.log("Init success on " + name);
submodule.update(1, new git.SubmoduleUpdateOptions()).then(
function () {
console.log("Update success on " + name);
resolve();
},
reject
);
}, reject
);
}, reject
);
});
}
)
});
return p;
}
).then(
function() {
console.log("Done!");
},
function(error) {
console.error(error);
}
);
});
}, function (error) {
console.error(error);
});
});
});
A zip of the files used in the above examples (including my compiled version of nodegit) is available here if that helps at all: https://dl.dropboxusercontent.com/u/108847970/nodegit-foreach-failure.zip
I had screen other crashes in the past when I was using Submodule.foreach
as well, but I had never been able to identify the cause as being that specific function. Now I think that it was.
I would try to track down this issue to the source myself, but I have no idea where to even start on debugging this kind of thing 😛
Let me know if I can provide any other additional information.