codiedev 0.7.3 → 0.7.4
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/dist/commands/reverseTicket.js +32 -11
- package/package.json +1 -1
|
@@ -36,6 +36,7 @@ function parseArgs(args) {
|
|
|
36
36
|
let base;
|
|
37
37
|
let forcedKey;
|
|
38
38
|
let noTruncate = false;
|
|
39
|
+
let dirty = false;
|
|
39
40
|
for (let i = 0; i < args.length; i++) {
|
|
40
41
|
const a = args[i];
|
|
41
42
|
if ((a === "--with" || a === "-w") && i + 1 < args.length) {
|
|
@@ -53,17 +54,20 @@ function parseArgs(args) {
|
|
|
53
54
|
else if (a === "--full") {
|
|
54
55
|
noTruncate = true;
|
|
55
56
|
}
|
|
57
|
+
else if (a === "--dirty") {
|
|
58
|
+
dirty = true;
|
|
59
|
+
}
|
|
56
60
|
else if (!a.startsWith("--") && !prUrl) {
|
|
57
61
|
prUrl = a;
|
|
58
62
|
}
|
|
59
63
|
}
|
|
60
|
-
return { prUrl, base, forcedKey, noTruncate };
|
|
64
|
+
return { prUrl, base, forcedKey, noTruncate, dirty };
|
|
61
65
|
}
|
|
62
66
|
async function runReverseTicket(args) {
|
|
63
|
-
const { prUrl, base, forcedKey, noTruncate } = parseArgs(args);
|
|
67
|
+
const { prUrl, base, forcedKey, noTruncate, dirty } = parseArgs(args);
|
|
64
68
|
// No PR URL → branch mode (mid-session, no PR exists yet).
|
|
65
69
|
if (!prUrl) {
|
|
66
|
-
return runBranchMode({ explicitBase: base, forcedKey });
|
|
70
|
+
return runBranchMode({ explicitBase: base, forcedKey, dirty });
|
|
67
71
|
}
|
|
68
72
|
const parsed = parsePrUrl(prUrl);
|
|
69
73
|
if (!parsed) {
|
|
@@ -237,22 +241,38 @@ async function runBranchMode(opts) {
|
|
|
237
241
|
}
|
|
238
242
|
};
|
|
239
243
|
const shQuote = (s) => `'${s.replace(/'/g, "'\\''")}'`;
|
|
240
|
-
//
|
|
241
|
-
//
|
|
242
|
-
|
|
244
|
+
// Default scope is committed-only — files and content reachable from HEAD,
|
|
245
|
+
// not from the working tree. Without `HEAD` as the second arg, `git diff
|
|
246
|
+
// <ref>` compares <ref> to the working tree, which silently rolls in
|
|
247
|
+
// uncommitted modifications and (via ls-files --others) untracked leftovers
|
|
248
|
+
// from prior branches. That produced audit-grade leaks where a one-commit
|
|
249
|
+
// copy-button branch generated a draft describing an unrelated auth rebrand
|
|
250
|
+
// that was sitting dirty in the working tree.
|
|
251
|
+
//
|
|
252
|
+
// --dirty re-enables the old behavior for the "ticket my current WIP"
|
|
253
|
+
// intent — explicit opt-in, since the user is asserting the dirty state is
|
|
254
|
+
// theirs and on-topic.
|
|
255
|
+
const includeDirty = opts.dirty === true;
|
|
256
|
+
const trackedRaw = git(`diff --name-only ${baseSha}${includeDirty ? "" : " HEAD"}`);
|
|
243
257
|
const trackedFiles = trackedRaw ? trackedRaw.split("\n").filter(Boolean) : [];
|
|
244
|
-
const untrackedRaw =
|
|
258
|
+
const untrackedRaw = includeDirty
|
|
259
|
+
? safeGit(() => git("ls-files --others --exclude-standard"))
|
|
260
|
+
: undefined;
|
|
245
261
|
const untrackedFiles = untrackedRaw
|
|
246
262
|
? untrackedRaw.split("\n").filter(Boolean)
|
|
247
263
|
: [];
|
|
248
264
|
const filesChanged = Array.from(new Set([...trackedFiles, ...untrackedFiles]));
|
|
249
265
|
if (filesChanged.length === 0) {
|
|
250
|
-
|
|
266
|
+
const scope = includeDirty ? "your working tree" : "HEAD";
|
|
267
|
+
console.error(`No changes detected between ${baseRef} and ${scope} on ${branch}.`);
|
|
268
|
+
if (!includeDirty) {
|
|
269
|
+
console.error("Pass --dirty to also include uncommitted + untracked changes.");
|
|
270
|
+
}
|
|
251
271
|
process.exit(1);
|
|
252
272
|
}
|
|
253
273
|
let stat = "";
|
|
254
274
|
try {
|
|
255
|
-
const trackedStat = git(`diff --stat=200 ${baseSha}`);
|
|
275
|
+
const trackedStat = git(`diff --stat=200 ${baseSha}${includeDirty ? "" : " HEAD"}`);
|
|
256
276
|
const untrackedStatLines = untrackedFiles.map((f) => {
|
|
257
277
|
const wc = shellTolerant(`wc -l < ${shQuote(f)}`);
|
|
258
278
|
const n = parseInt(wc.split(/\s+/)[0] || "0", 10) || 0;
|
|
@@ -269,9 +289,10 @@ async function runBranchMode(opts) {
|
|
|
269
289
|
let diff = "";
|
|
270
290
|
try {
|
|
271
291
|
const sourceTracked = trackedFiles.filter((f) => !isNoise(f));
|
|
292
|
+
const headRef = includeDirty ? "" : " HEAD";
|
|
272
293
|
const trackedDiff = sourceTracked.length > 0
|
|
273
|
-
? git(`diff ${baseSha} -- ${sourceTracked.map(shQuote).join(" ")}`)
|
|
274
|
-
: git(`diff ${baseSha}`);
|
|
294
|
+
? git(`diff ${baseSha}${headRef} -- ${sourceTracked.map(shQuote).join(" ")}`)
|
|
295
|
+
: git(`diff ${baseSha}${headRef}`);
|
|
275
296
|
const sourceUntracked = untrackedFiles.filter((f) => !isNoise(f));
|
|
276
297
|
const untrackedDiffs = sourceUntracked.map((f) => shellTolerant(`git diff --no-index --no-color -- /dev/null ${shQuote(f)}`));
|
|
277
298
|
diff = [trackedDiff, ...untrackedDiffs]
|
package/package.json
CHANGED