(summary?: string)
| 142 | // Scope gate — same contract as write() above. |
| 143 | { |
| 144 | const denial = checkWriteScope(abs); |
| 145 | if (denial) { |
| 146 | logger.info('Scope gate refused delete', { txnId: this.id, path: abs }); |
| 147 | throw new Error(denial); |
| 148 | } |
| 149 | } |
| 150 | const content = await fs.readFile(abs, 'utf-8'); |
| 151 | const hash = hashContent(content); |
| 152 | await this.journal.storeBlob(hash, content); |
| 153 | |
| 154 | await fs.unlink(abs); |
| 155 | |
| 156 | this.ops.push({ |
| 157 | operation: 'delete', |
| 158 | path: abs, |
| 159 | beforeHash: hash, |
| 160 | afterHash: null, |
| 161 | beforeContent: content, |
| 162 | }); |
| 163 | } |
| 164 | |
| 165 | async commit(summary?: string): Promise<string | null> { |
| 166 | this.ensureOpen(); |
| 167 | if (this.ops.length === 0) { |
| 168 | this.status = 'committed'; |
| 169 | return null; |
| 170 | } |
| 171 | |
| 172 | // Try git commit — categorize failures. |
| 173 | let gitStatus: 'committed' | 'skipped-not-a-repo' | 'skipped-gitignored' | 'failed' = 'skipped-not-a-repo'; |
| 174 | let gitFailReason: string | null = null; |
| 175 | try { |
| 176 | const git = simpleGit(process.cwd()); |
| 177 | const isRepo = await git.checkIsRepo(); |
| 178 | if (isRepo) { |
| 179 | const relPaths = this.ops.map(o => path.relative(process.cwd(), o.path)); |
| 180 | |
| 181 | // Filter out paths that are ignored — git add will refuse them and abort the whole add. |
| 182 | const trackable: string[] = []; |
| 183 | const ignored: string[] = []; |
| 184 | try { |
| 185 | // simple-git checkIgnore returns paths that ARE ignored |
| 186 | const ignoredPaths = await git.checkIgnore(relPaths); |
| 187 | for (const p of relPaths) { |
| 188 | if (ignoredPaths.includes(p)) ignored.push(p); |
| 189 | else trackable.push(p); |
| 190 | } |
| 191 | } catch { |
| 192 | // If checkIgnore fails for any reason, attempt to add everything |
| 193 | trackable.push(...relPaths); |
| 194 | } |
| 195 | |
| 196 | if (ignored.length > 0) { |
| 197 | logger.warn('Git: some files are gitignored, transaction journal still tracks them', { |
| 198 | ignored, |
| 199 | txnId: this.id, |
| 200 | }); |
| 201 | gitFailReason = `Gitignored (not in git): ${ignored.join(', ')}`; |
nothing calls this directly
no test coverage detected