@howlil/ez-agents 2.0.0 → 2.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -21
- package/README.md +93 -93
- package/agents/ez-plan-checker.md +2 -2
- package/agents/ez-research-synthesizer.md +1 -1
- package/agents/ez-ui-researcher.md +1 -1
- package/agents/ez-verifier.md +1 -1
- package/bin/install.js +132 -132
- package/get-shit-done/bin/lib/assistant-adapter.cjs +205 -205
- package/get-shit-done/bin/lib/audit-exec.cjs +150 -150
- package/get-shit-done/bin/lib/auth.cjs +175 -175
- package/get-shit-done/bin/lib/circuit-breaker.cjs +118 -118
- package/get-shit-done/bin/lib/commands.cjs +666 -666
- package/get-shit-done/bin/lib/config.cjs +183 -183
- package/get-shit-done/bin/lib/core.cjs +495 -495
- package/get-shit-done/bin/lib/file-lock.cjs +236 -236
- package/get-shit-done/bin/lib/frontmatter.cjs +299 -299
- package/get-shit-done/bin/lib/fs-utils.cjs +153 -153
- package/get-shit-done/bin/lib/git-utils.cjs +203 -203
- package/get-shit-done/bin/lib/health-check.cjs +163 -163
- package/get-shit-done/bin/lib/index.cjs +113 -113
- package/get-shit-done/bin/lib/init.cjs +710 -710
- package/get-shit-done/bin/lib/logger.cjs +117 -117
- package/get-shit-done/bin/lib/milestone.cjs +241 -241
- package/get-shit-done/bin/lib/model-provider.cjs +146 -146
- package/get-shit-done/bin/lib/phase.cjs +908 -908
- package/get-shit-done/bin/lib/retry.cjs +119 -119
- package/get-shit-done/bin/lib/roadmap.cjs +305 -305
- package/get-shit-done/bin/lib/safe-exec.cjs +128 -128
- package/get-shit-done/bin/lib/safe-path.cjs +130 -130
- package/get-shit-done/bin/lib/state.cjs +721 -721
- package/get-shit-done/bin/lib/temp-file.cjs +239 -239
- package/get-shit-done/bin/lib/template.cjs +222 -222
- package/get-shit-done/bin/lib/test-file-lock.cjs +112 -112
- package/get-shit-done/bin/lib/test-graceful.cjs +93 -93
- package/get-shit-done/bin/lib/test-logger.cjs +60 -60
- package/get-shit-done/bin/lib/test-safe-exec.cjs +38 -38
- package/get-shit-done/bin/lib/test-safe-path.cjs +33 -33
- package/get-shit-done/bin/lib/test-temp-file.cjs +125 -125
- package/get-shit-done/bin/lib/timeout-exec.cjs +62 -62
- package/get-shit-done/bin/lib/verify.cjs +820 -820
- package/get-shit-done/references/checkpoints.md +776 -776
- package/get-shit-done/references/questioning.md +162 -162
- package/get-shit-done/references/tdd.md +263 -263
- package/get-shit-done/templates/codebase/concerns.md +310 -310
- package/get-shit-done/templates/codebase/conventions.md +307 -307
- package/get-shit-done/templates/codebase/integrations.md +280 -280
- package/get-shit-done/templates/codebase/stack.md +186 -186
- package/get-shit-done/templates/codebase/testing.md +480 -480
- package/get-shit-done/templates/config.json +37 -37
- package/get-shit-done/templates/continue-here.md +78 -78
- package/get-shit-done/templates/milestone-archive.md +123 -123
- package/get-shit-done/templates/milestone.md +115 -115
- package/get-shit-done/templates/requirements.md +231 -231
- package/get-shit-done/templates/research-project/ARCHITECTURE.md +204 -204
- package/get-shit-done/templates/research-project/FEATURES.md +147 -147
- package/get-shit-done/templates/research-project/PITFALLS.md +200 -200
- package/get-shit-done/templates/research-project/STACK.md +120 -120
- package/get-shit-done/templates/research-project/SUMMARY.md +170 -170
- package/get-shit-done/templates/retrospective.md +54 -54
- package/get-shit-done/templates/roadmap.md +202 -202
- package/get-shit-done/templates/summary-minimal.md +41 -41
- package/get-shit-done/templates/summary-standard.md +48 -48
- package/get-shit-done/templates/summary.md +248 -248
- package/get-shit-done/templates/user-setup.md +311 -311
- package/get-shit-done/templates/verification-report.md +322 -322
- package/get-shit-done/workflows/add-phase.md +112 -112
- package/get-shit-done/workflows/add-tests.md +351 -351
- package/get-shit-done/workflows/add-todo.md +158 -158
- package/get-shit-done/workflows/audit-milestone.md +332 -332
- package/get-shit-done/workflows/autonomous.md +743 -743
- package/get-shit-done/workflows/check-todos.md +177 -177
- package/get-shit-done/workflows/cleanup.md +152 -152
- package/get-shit-done/workflows/complete-milestone.md +766 -766
- package/get-shit-done/workflows/diagnose-issues.md +219 -219
- package/get-shit-done/workflows/discovery-phase.md +289 -289
- package/get-shit-done/workflows/discuss-phase.md +762 -762
- package/get-shit-done/workflows/execute-phase.md +468 -468
- package/get-shit-done/workflows/execute-plan.md +483 -483
- package/get-shit-done/workflows/health.md +159 -159
- package/get-shit-done/workflows/help.md +492 -492
- package/get-shit-done/workflows/insert-phase.md +130 -130
- package/get-shit-done/workflows/list-phase-assumptions.md +178 -178
- package/get-shit-done/workflows/map-codebase.md +316 -316
- package/get-shit-done/workflows/new-milestone.md +384 -384
- package/get-shit-done/workflows/new-project.md +1111 -1111
- package/get-shit-done/workflows/node-repair.md +92 -92
- package/get-shit-done/workflows/pause-work.md +122 -122
- package/get-shit-done/workflows/plan-milestone-gaps.md +274 -274
- package/get-shit-done/workflows/plan-phase.md +651 -651
- package/get-shit-done/workflows/progress.md +382 -382
- package/get-shit-done/workflows/quick.md +610 -610
- package/get-shit-done/workflows/remove-phase.md +155 -155
- package/get-shit-done/workflows/research-phase.md +74 -74
- package/get-shit-done/workflows/resume-project.md +307 -307
- package/get-shit-done/workflows/set-profile.md +81 -81
- package/get-shit-done/workflows/settings.md +242 -242
- package/get-shit-done/workflows/stats.md +57 -57
- package/get-shit-done/workflows/transition.md +544 -544
- package/get-shit-done/workflows/ui-phase.md +290 -290
- package/get-shit-done/workflows/ui-review.md +157 -157
- package/get-shit-done/workflows/update.md +320 -320
- package/get-shit-done/workflows/validate-phase.md +167 -167
- package/get-shit-done/workflows/verify-phase.md +243 -243
- package/package.json +1 -1
- package/scripts/build-hooks.js +43 -43
- package/scripts/run-tests.cjs +29 -29
|
@@ -1,203 +1,203 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* GSD Git Utils — Safe git operations with atomic commits
|
|
5
|
-
*
|
|
6
|
-
* Provides:
|
|
7
|
-
* - Atomic commits with validation
|
|
8
|
-
* - Branch creation and management
|
|
9
|
-
* - Safe git operations using execFile
|
|
10
|
-
* - Error handling with recovery suggestions
|
|
11
|
-
*
|
|
12
|
-
* Usage:
|
|
13
|
-
* const GitUtils = require('./git-utils.cjs');
|
|
14
|
-
* const git = new GitUtils(process.cwd());
|
|
15
|
-
* await git.commitAtomic('feat: add feature', ['file1.js']);
|
|
16
|
-
*/
|
|
17
|
-
|
|
18
|
-
const { execFile } = require('child_process');
|
|
19
|
-
const { promisify } = require('util');
|
|
20
|
-
const execFileAsync = promisify(execFile);
|
|
21
|
-
const Logger = require('./logger.cjs');
|
|
22
|
-
const logger = new Logger();
|
|
23
|
-
|
|
24
|
-
class GitUtils {
|
|
25
|
-
constructor(cwd) {
|
|
26
|
-
this.cwd = cwd || process.cwd();
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
/**
|
|
30
|
-
* Execute git command safely
|
|
31
|
-
*/
|
|
32
|
-
async exec(args, options = {}) {
|
|
33
|
-
const { timeout = 30000 } = options;
|
|
34
|
-
|
|
35
|
-
try {
|
|
36
|
-
const { stdout, stderr } = await execFileAsync('git', args, {
|
|
37
|
-
cwd: this.cwd,
|
|
38
|
-
encoding: 'utf-8',
|
|
39
|
-
timeout,
|
|
40
|
-
maxBuffer: 10 * 1024 * 1024
|
|
41
|
-
});
|
|
42
|
-
|
|
43
|
-
logger.debug('Git command executed', { args, stdout_length: stdout?.length });
|
|
44
|
-
|
|
45
|
-
return { stdout: stdout?.trim(), stderr: stderr?.trim() };
|
|
46
|
-
} catch (err) {
|
|
47
|
-
logger.error('Git command failed', { args, error: err.message });
|
|
48
|
-
throw err;
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
/**
|
|
53
|
-
* Check if directory is a git repo
|
|
54
|
-
*/
|
|
55
|
-
async isGitRepo() {
|
|
56
|
-
try {
|
|
57
|
-
await this.exec(['rev-parse', '--git-dir']);
|
|
58
|
-
return true;
|
|
59
|
-
} catch {
|
|
60
|
-
return false;
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
/**
|
|
65
|
-
* Get current branch name
|
|
66
|
-
*/
|
|
67
|
-
async getCurrentBranch() {
|
|
68
|
-
const { stdout } = await this.exec(['rev-parse', '--abbrev-ref', 'HEAD']);
|
|
69
|
-
return stdout;
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
/**
|
|
73
|
-
* Get git status (porcelain format)
|
|
74
|
-
*/
|
|
75
|
-
async getStatus() {
|
|
76
|
-
const { stdout } = await this.exec(['status', '--porcelain']);
|
|
77
|
-
return stdout.split('\n').filter(line => line.trim());
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
/**
|
|
81
|
-
* Check if there are uncommitted changes
|
|
82
|
-
*/
|
|
83
|
-
async hasChanges() {
|
|
84
|
-
const status = await this.getStatus();
|
|
85
|
-
return status.length > 0;
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
/**
|
|
89
|
-
* Stage files for commit
|
|
90
|
-
*/
|
|
91
|
-
async add(files) {
|
|
92
|
-
if (!Array.isArray(files)) files = [files];
|
|
93
|
-
await this.exec(['add', ...files]);
|
|
94
|
-
logger.info('Files staged', { files });
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
/**
|
|
98
|
-
* Add all changes
|
|
99
|
-
*/
|
|
100
|
-
async addAll() {
|
|
101
|
-
await this.exec(['add', '-A']);
|
|
102
|
-
logger.info('All files staged');
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
/**
|
|
106
|
-
* Create atomic commit with validation
|
|
107
|
-
*/
|
|
108
|
-
async commitAtomic(message, files = []) {
|
|
109
|
-
// Stage files if provided
|
|
110
|
-
if (files.length > 0) {
|
|
111
|
-
await this.add(files);
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
// Validate commit message format (conventional commits)
|
|
115
|
-
const conventionalPattern = /^(feat|fix|docs|chore|test|refactor|style|perf)(\([^)]+\))?:\s.+/;
|
|
116
|
-
if (!conventionalPattern.test(message)) {
|
|
117
|
-
logger.warn('Commit message may not follow conventional commits', { message });
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
// Create commit
|
|
121
|
-
await this.exec(['commit', '-m', message]);
|
|
122
|
-
|
|
123
|
-
// Get commit hash
|
|
124
|
-
const { stdout } = await this.exec(['rev-parse', '--short', 'HEAD']);
|
|
125
|
-
|
|
126
|
-
logger.info('Commit created', { hash: stdout, message });
|
|
127
|
-
|
|
128
|
-
return stdout;
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
/**
|
|
132
|
-
* Create new branch
|
|
133
|
-
*/
|
|
134
|
-
async createBranch(name, from = 'HEAD') {
|
|
135
|
-
await this.exec(['checkout', '-b', name, from]);
|
|
136
|
-
logger.info('Branch created', { name, from });
|
|
137
|
-
return name;
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
/**
|
|
141
|
-
* Switch to branch
|
|
142
|
-
*/
|
|
143
|
-
async checkout(branch) {
|
|
144
|
-
await this.exec(['checkout', branch]);
|
|
145
|
-
logger.info('Checked out branch', { branch });
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
/**
|
|
149
|
-
* Merge branch
|
|
150
|
-
*/
|
|
151
|
-
async mergeBranch(branch, squash = false) {
|
|
152
|
-
const args = squash ? ['merge', '--squash', branch] : ['merge', branch];
|
|
153
|
-
await this.exec(args);
|
|
154
|
-
logger.info('Branch merged', { branch, squash });
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
/**
|
|
158
|
-
* Create tag
|
|
159
|
-
*/
|
|
160
|
-
async tagRelease(version, message = '') {
|
|
161
|
-
const args = ['-a', version, '-m', message || `Release ${version}`];
|
|
162
|
-
await this.exec(['tag', ...args]);
|
|
163
|
-
logger.info('Tag created', { version });
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
/**
|
|
167
|
-
* Push to remote
|
|
168
|
-
*/
|
|
169
|
-
async push(remote = 'origin', branch = null) {
|
|
170
|
-
const args = ['push', remote];
|
|
171
|
-
if (branch) args.push(branch);
|
|
172
|
-
await this.exec(args);
|
|
173
|
-
logger.info('Pushed to remote', { remote, branch });
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
/**
|
|
177
|
-
* Pull from remote
|
|
178
|
-
*/
|
|
179
|
-
async pull(remote = 'origin', branch = null) {
|
|
180
|
-
const args = ['pull', remote];
|
|
181
|
-
if (branch) args.push(branch);
|
|
182
|
-
await this.exec(args);
|
|
183
|
-
logger.info('Pulled from remote', { remote, branch });
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
/**
|
|
187
|
-
* Get recent commits
|
|
188
|
-
*/
|
|
189
|
-
async getCommits(count = 5) {
|
|
190
|
-
const { stdout } = await this.exec(['log', `-n${count}`, '--oneline']);
|
|
191
|
-
return stdout.split('\n');
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
/**
|
|
195
|
-
* Get diff between commits/branches
|
|
196
|
-
*/
|
|
197
|
-
async getDiff(from, to = 'HEAD') {
|
|
198
|
-
const { stdout } = await this.exec(['diff', `${from}..${to}`, '--stat']);
|
|
199
|
-
return stdout;
|
|
200
|
-
}
|
|
201
|
-
}
|
|
202
|
-
|
|
203
|
-
module.exports = GitUtils;
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* GSD Git Utils — Safe git operations with atomic commits
|
|
5
|
+
*
|
|
6
|
+
* Provides:
|
|
7
|
+
* - Atomic commits with validation
|
|
8
|
+
* - Branch creation and management
|
|
9
|
+
* - Safe git operations using execFile
|
|
10
|
+
* - Error handling with recovery suggestions
|
|
11
|
+
*
|
|
12
|
+
* Usage:
|
|
13
|
+
* const GitUtils = require('./git-utils.cjs');
|
|
14
|
+
* const git = new GitUtils(process.cwd());
|
|
15
|
+
* await git.commitAtomic('feat: add feature', ['file1.js']);
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
const { execFile } = require('child_process');
|
|
19
|
+
const { promisify } = require('util');
|
|
20
|
+
const execFileAsync = promisify(execFile);
|
|
21
|
+
const Logger = require('./logger.cjs');
|
|
22
|
+
const logger = new Logger();
|
|
23
|
+
|
|
24
|
+
class GitUtils {
|
|
25
|
+
constructor(cwd) {
|
|
26
|
+
this.cwd = cwd || process.cwd();
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Execute git command safely
|
|
31
|
+
*/
|
|
32
|
+
async exec(args, options = {}) {
|
|
33
|
+
const { timeout = 30000 } = options;
|
|
34
|
+
|
|
35
|
+
try {
|
|
36
|
+
const { stdout, stderr } = await execFileAsync('git', args, {
|
|
37
|
+
cwd: this.cwd,
|
|
38
|
+
encoding: 'utf-8',
|
|
39
|
+
timeout,
|
|
40
|
+
maxBuffer: 10 * 1024 * 1024
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
logger.debug('Git command executed', { args, stdout_length: stdout?.length });
|
|
44
|
+
|
|
45
|
+
return { stdout: stdout?.trim(), stderr: stderr?.trim() };
|
|
46
|
+
} catch (err) {
|
|
47
|
+
logger.error('Git command failed', { args, error: err.message });
|
|
48
|
+
throw err;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Check if directory is a git repo
|
|
54
|
+
*/
|
|
55
|
+
async isGitRepo() {
|
|
56
|
+
try {
|
|
57
|
+
await this.exec(['rev-parse', '--git-dir']);
|
|
58
|
+
return true;
|
|
59
|
+
} catch {
|
|
60
|
+
return false;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Get current branch name
|
|
66
|
+
*/
|
|
67
|
+
async getCurrentBranch() {
|
|
68
|
+
const { stdout } = await this.exec(['rev-parse', '--abbrev-ref', 'HEAD']);
|
|
69
|
+
return stdout;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Get git status (porcelain format)
|
|
74
|
+
*/
|
|
75
|
+
async getStatus() {
|
|
76
|
+
const { stdout } = await this.exec(['status', '--porcelain']);
|
|
77
|
+
return stdout.split('\n').filter(line => line.trim());
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Check if there are uncommitted changes
|
|
82
|
+
*/
|
|
83
|
+
async hasChanges() {
|
|
84
|
+
const status = await this.getStatus();
|
|
85
|
+
return status.length > 0;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* Stage files for commit
|
|
90
|
+
*/
|
|
91
|
+
async add(files) {
|
|
92
|
+
if (!Array.isArray(files)) files = [files];
|
|
93
|
+
await this.exec(['add', ...files]);
|
|
94
|
+
logger.info('Files staged', { files });
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* Add all changes
|
|
99
|
+
*/
|
|
100
|
+
async addAll() {
|
|
101
|
+
await this.exec(['add', '-A']);
|
|
102
|
+
logger.info('All files staged');
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Create atomic commit with validation
|
|
107
|
+
*/
|
|
108
|
+
async commitAtomic(message, files = []) {
|
|
109
|
+
// Stage files if provided
|
|
110
|
+
if (files.length > 0) {
|
|
111
|
+
await this.add(files);
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
// Validate commit message format (conventional commits)
|
|
115
|
+
const conventionalPattern = /^(feat|fix|docs|chore|test|refactor|style|perf)(\([^)]+\))?:\s.+/;
|
|
116
|
+
if (!conventionalPattern.test(message)) {
|
|
117
|
+
logger.warn('Commit message may not follow conventional commits', { message });
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
// Create commit
|
|
121
|
+
await this.exec(['commit', '-m', message]);
|
|
122
|
+
|
|
123
|
+
// Get commit hash
|
|
124
|
+
const { stdout } = await this.exec(['rev-parse', '--short', 'HEAD']);
|
|
125
|
+
|
|
126
|
+
logger.info('Commit created', { hash: stdout, message });
|
|
127
|
+
|
|
128
|
+
return stdout;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* Create new branch
|
|
133
|
+
*/
|
|
134
|
+
async createBranch(name, from = 'HEAD') {
|
|
135
|
+
await this.exec(['checkout', '-b', name, from]);
|
|
136
|
+
logger.info('Branch created', { name, from });
|
|
137
|
+
return name;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* Switch to branch
|
|
142
|
+
*/
|
|
143
|
+
async checkout(branch) {
|
|
144
|
+
await this.exec(['checkout', branch]);
|
|
145
|
+
logger.info('Checked out branch', { branch });
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
/**
|
|
149
|
+
* Merge branch
|
|
150
|
+
*/
|
|
151
|
+
async mergeBranch(branch, squash = false) {
|
|
152
|
+
const args = squash ? ['merge', '--squash', branch] : ['merge', branch];
|
|
153
|
+
await this.exec(args);
|
|
154
|
+
logger.info('Branch merged', { branch, squash });
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
/**
|
|
158
|
+
* Create tag
|
|
159
|
+
*/
|
|
160
|
+
async tagRelease(version, message = '') {
|
|
161
|
+
const args = ['-a', version, '-m', message || `Release ${version}`];
|
|
162
|
+
await this.exec(['tag', ...args]);
|
|
163
|
+
logger.info('Tag created', { version });
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
/**
|
|
167
|
+
* Push to remote
|
|
168
|
+
*/
|
|
169
|
+
async push(remote = 'origin', branch = null) {
|
|
170
|
+
const args = ['push', remote];
|
|
171
|
+
if (branch) args.push(branch);
|
|
172
|
+
await this.exec(args);
|
|
173
|
+
logger.info('Pushed to remote', { remote, branch });
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
/**
|
|
177
|
+
* Pull from remote
|
|
178
|
+
*/
|
|
179
|
+
async pull(remote = 'origin', branch = null) {
|
|
180
|
+
const args = ['pull', remote];
|
|
181
|
+
if (branch) args.push(branch);
|
|
182
|
+
await this.exec(args);
|
|
183
|
+
logger.info('Pulled from remote', { remote, branch });
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
/**
|
|
187
|
+
* Get recent commits
|
|
188
|
+
*/
|
|
189
|
+
async getCommits(count = 5) {
|
|
190
|
+
const { stdout } = await this.exec(['log', `-n${count}`, '--oneline']);
|
|
191
|
+
return stdout.split('\n');
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
/**
|
|
195
|
+
* Get diff between commits/branches
|
|
196
|
+
*/
|
|
197
|
+
async getDiff(from, to = 'HEAD') {
|
|
198
|
+
const { stdout } = await this.exec(['diff', `${from}..${to}`, '--stat']);
|
|
199
|
+
return stdout;
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
module.exports = GitUtils;
|