MCPcopy Create free account
hub / github.com/QodeXcli/QodeX / readCommits

Function readCommits

src/tools/git/release-notes.ts:149–179  ·  view source on GitHub ↗
(
  cwd: string,
  range: string,
  maxCommits: number,
  signal?: AbortSignal,
)

Source from the content-addressed store, hash-verified

147}
148
149async function readCommits(
150 cwd: string,
151 range: string,
152 maxCommits: number,
153 signal?: AbortSignal,
154): Promise<RawCommit[]> {
155 // Field separator NUL, record separator unit-separator (\x1f). Body comes last because
156 // it can contain newlines; we terminate each commit with \x1e (record separator).
157 const fmt = `%h%x00%ad%x00%an%x00%s%x00%b%x1e`;
158 const r = await git(['log', `-${maxCommits}`, '--date=short', '--no-merges', `--pretty=format:${fmt}`, range], { cwd, signal });
159 if (r.exitCode !== 0) {
160 // Unknown ref, etc — surface a clean error
161 const err = (r.stderr || r.stdout).trim();
162 throw new Error(err || `git log exited ${r.exitCode}`);
163 }
164 if (!r.stdout.trim()) return [];
165
166 return r.stdout.split('\x1e')
167 .map(rec => rec.replace(/^\n/, ''))
168 .filter(rec => rec.length > 0)
169 .map(rec => {
170 const [sha, date, author, subject, body] = rec.split('\x00');
171 return {
172 sha: sha!.trim(),
173 date: date!.trim(),
174 author: author!.trim(),
175 subject: subject!.trim(),
176 body: (body ?? '').trim(),
177 };
178 });
179}
180
181function deriveHeading(to: string): string {
182 if (to === 'HEAD' || !to) return 'Unreleased';

Callers 1

executeMethod · 0.85

Calls 1

gitFunction · 0.70

Tested by

no test coverage detected