| 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136 | 1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
6
6
6
6
6
6
4
6
6
6
6
6
6
31
6
20
20
6
6
20
12
12
8
6
6
1
1
1
1
1
1
1
1
1
1
| var check = require('check-types');
var moment = require('moment');
var spawn = require('child_process').spawn;
var path = require('path');
var getGitRootFolder = require('./repoRoot').getGitRootFolder;
// returns commits in reverse chronological order
function gitLog(filename, commits, cb, err, rootFolder) {
Iif (err) {
throw err;
}
check.verify.string(filename, 'missing filename');
check.verify.positiveNumber(commits, 'invalid number of commits', commits);
check.verify.fn(cb, 'callback should be a function');
// use -n <number> to limit history
// oe --since <date>
// var args = ['log', '--no-decorate', '-n ' + commits];
var args = ['log', '--name-status', '-n ' + commits];
Eif (filename) {
check.verify.string(rootFolder, 'could not find git root folder');
rootFolder = rootFolder.trim();
rootFolder = rootFolder.replace(/\//g, '\\');
console.log('filename', filename);
console.log('repo root folder', rootFolder);
var workingFolder = process.cwd();
console.log('working folder', workingFolder);
var relativePath = path.relative(workingFolder, filename);
// var repoPath = path.relative(rootFolder, filename);
args.push(relativePath);
}
console.log('git log command', args);
var git = spawn('git', args);
commits = [];
git.stdout.setEncoding('utf-8');
git.stdout.on('data', function (data) {
data.trim();
// console.log('git data\n', data);
var separatedData = data.split('\ncommit ');
separatedData = separatedData.filter(function (str) {
str.trim();
return str && str !== '\n';
});
var info = separatedData.map(parseCommit);
commits = commits.concat(info);
});
git.stderr.setEncoding('utf-8');
git.stderr.on('data', function (data) {
throw new Error('Could not get git log for\n' + filename +
'\n' + data);
});
git.on('exit', function () {
console.log('returning', commits.length, 'commits');
cb(commits);
});
}
function parseCommit(data) {
check.verify.string(data, 'null commit data');
data = data.trim();
// console.log('parsing commit\n', data);
var lines = data.split('\n');
console.assert(lines.length > 3, 'invalid commit\n', data);
// console.log('commit lines\n', lines);
var commitLine = lines[0].trim();
if (commitLine.indexOf('commit ') === 0) {
commitLine = commitLine.substr('commit '.length);
}
var authorLine = lines[1].split(':')[1].trim();
var dateLine = lines[2];
dateLine = dateLine.substr(dateLine.indexOf(':') + 1);
dateLine = dateLine.trim();
// console.log(dateLine);
lines.splice(0, 3);
lines = lines.filter(function (str) {
return str;
});
lines = lines.map(function (str) {
str = str.trim();
return str;
});
var files = [];
lines = lines.filter(function (str) {
// console.log('checking line', str);
if (str.indexOf('M') === 0 ||
str.indexOf('A') === 0 ||
str.indexOf('D') === 0) {
files.push({
name: str.substr(1).trim(),
status: str[0]
});
return false;
} else {
return true;
}
});
var description = lines.join('\n');
return {
commit: '' + commitLine.trim(),
author: authorLine.trim(),
date: moment(dateLine),
description: description.trim(),
files: files
};
}
function getGitLog(filename, commits, cb) {
Eif (filename) {
check.verify.string(filename, 'expected filename');
filename = path.resolve(filename);
console.log('fetching', commits, 'history for', filename);
}
commits = commits || 30;
check.verify.positiveNumber(commits, 'invalid max number of commits', commits);
check.verify.fn(cb, 'expect callback function, not', cb);
getGitRootFolder(gitLog.bind(null, filename, commits, cb));
}
module.exports = {
getGitLog: getGitLog,
parseCommit: parseCommit
};
|