In my node application I'm using child_process.spawn to query information from the current repository
I've built a small function to return a promise which resolves with the response from the command:
const spawn = require('child_process').spawn;
const gitExec = command => (
new Promise((resolve, reject) => {
const thread = spawn('git', command);
const stdOut = [];
const stdErr = [];
thread.stdout.on('data', (data) => {
stdOut.push(data.toString('utf8'));
});
thread.stderr.on('data', (data) => {
stdErr.push(data.toString('utf8'));
});
thread.on('close', () => {
if (stdErr.length) {
reject(stdErr.join(''));
return;
}
resolve(stdOut.join());
});
})
);
module.exports = gitExec;
Calling git branch
works just as expected:
gitExec(['branch'])
.then((branchInfo) => {
console.log(branchInfo);
})
(as expected) results in
* develop
feature/forever
feature/sourceconfig
feature/testing
master
From my understanding this proves the method I'm using to actually be working.
When calling git shortlog -sn
the spawned process "hangs" and does not resolve in anything
gitExec(['shortlog', '-sn'])
.then((shortlogInfo) => {
console.log(shortlogInfo);
})
Calling git shortlog -sn
via commandline i geht the expected result:
154 Andreas Gack
89 Some other dude
6 Whoever else
using spawnSync (while changing my gitExec function to acommodate the syncronous approach) returns an object as documented - so the process seems to actually exit - but the relevant props of the object output
stdout
and stderr
are all empty.
The status
of the object is 0
which indicates the command to execute successfully
I've read about having to redefine the maxBuffer
in the spawn options, but neither setting it to a (ridiculously) high value nor a very small value does make a difference in the syncronous or asynchronous approach.
Setting the shell
option to true
also does not make a difference in all of the above scenarios.
The issue occurrs on my Win10x64 as well as on MacOs running node v6.9.x or 7.x
Also calling the alias git log --pretty=short
does not provide a result
git shortlog -sn
via child_process.spawn?I somehow think the two commands git branch
and git shortlog
internally handle their output in a different way.
I'd be happy to create an issue on their github page, but I actually don't know how to identify the actual root-cause of that problem.
Any further input is much appreciated!
git shortlog
thinks it needs to read something from stdin
thats why the whole process hangs. To work around that, you can pass stdin
from the main process in as an option and pipe everything else as usual. Then it should run.
const spawn = require('child_process').spawn;
const gitExec = command => (
new Promise((resolve, reject) => {
const thread = spawn('git', command, { stdio: ['inherit', 'pipe', 'pipe'] });
const stdOut = [];
const stdErr = [];
thread.stdout.on('data', (data) => {
stdOut.push(data.toString('utf8'));
});
thread.stderr.on('data', (data) => {
stdErr.push(data.toString('utf8'));
});
thread.on('close', () => {
if (stdErr.length) {
reject(stdErr.join(''));
return;
}
resolve(stdOut.join());
});
})
);
module.exports = gitExec;
Perhaps some more context from the git documentation:
If no revisions are passed on the command line and either standard input is not a terminal or there is no current branch, git shortlog will output a summary of the log read from standard input, without reference to the current repository.
Which is the case when spawning a child process. So it expects something gets passed in via stdin
. By setting stdin
to the main process git shortlog
is aware of the terminal and therefor will run.