@quonfig/cli 0.0.33 → 0.0.35
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/README.md +39 -36
- package/dist/commands/migrate.js +17 -10
- package/dist/commands/pull.d.ts +1 -0
- package/dist/commands/pull.js +42 -2
- package/dist/commands/push.js +24 -1
- package/dist/migrate/local-write.d.ts +19 -2
- package/dist/migrate/local-write.js +102 -4
- package/dist/migrate/migration-report.d.ts +3 -0
- package/dist/migrate/migration-report.js +3 -0
- package/dist/migrate/push-to-cloud.d.ts +4 -1
- package/dist/migrate/push-to-cloud.js +9 -44
- package/dist/migrate/sources/launch/translate.d.ts +16 -0
- package/dist/migrate/sources/launch/translate.js +112 -5
- package/dist/push/run-push.d.ts +17 -0
- package/dist/push/run-push.js +30 -0
- package/dist/util/clone-and-stack-push.d.ts +6 -2
- package/dist/util/clone-and-stack-push.js +9 -2
- package/dist/util/git-ops.d.ts +40 -0
- package/dist/util/git-ops.js +82 -0
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/oclif.manifest.json +7 -1
- package/package.json +1 -1
package/dist/util/git-ops.js
CHANGED
|
@@ -222,6 +222,41 @@ export const canFastForward = async (dir) => {
|
|
|
222
222
|
return false;
|
|
223
223
|
}
|
|
224
224
|
};
|
|
225
|
+
/**
|
|
226
|
+
* Returns true iff origin/main is NOT an ancestor of the local HEAD —
|
|
227
|
+
* covering both "local strictly behind" and "diverged" in one boolean.
|
|
228
|
+
*
|
|
229
|
+
* Used by the clone-path stale-HEAD guard in `qfg push` (qfg-fboj):
|
|
230
|
+
* either of those two states would otherwise produce a `HEAD..origin/main`
|
|
231
|
+
* diff that ships REVERSAL deltas to the server, silently undoing
|
|
232
|
+
* remote-newer commits. Both must refuse.
|
|
233
|
+
*
|
|
234
|
+
* Returns false on any git failure (no `origin/main` ref yet, no `.git/`,
|
|
235
|
+
* etc.) so the caller falls through to its other guards rather than
|
|
236
|
+
* aborting on an opaque error.
|
|
237
|
+
*/
|
|
238
|
+
export const isLocalBehindOrDivergedFromRemote = async (dir) => {
|
|
239
|
+
try {
|
|
240
|
+
const { stdout: localSha } = await runGit(['-C', dir, 'rev-parse', 'HEAD']);
|
|
241
|
+
const { stdout: remoteSha } = await runGit(['-C', dir, 'rev-parse', 'origin/main']);
|
|
242
|
+
const local = localSha.trim();
|
|
243
|
+
const remote = remoteSha.trim();
|
|
244
|
+
if (local === remote)
|
|
245
|
+
return false;
|
|
246
|
+
try {
|
|
247
|
+
// exit 0 → remote is an ancestor of local → local is strictly ahead, fine.
|
|
248
|
+
await runGit(['-C', dir, 'merge-base', '--is-ancestor', remote, local]);
|
|
249
|
+
return false;
|
|
250
|
+
}
|
|
251
|
+
catch {
|
|
252
|
+
// non-zero exit → remote is NOT an ancestor → behind or diverged.
|
|
253
|
+
return true;
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
catch {
|
|
257
|
+
return false;
|
|
258
|
+
}
|
|
259
|
+
};
|
|
225
260
|
/**
|
|
226
261
|
* Returns true if local has commits not reachable from origin/main (diverged).
|
|
227
262
|
*/
|
|
@@ -310,3 +345,50 @@ export const hasAtLeastOneCommit = async (dir) => {
|
|
|
310
345
|
* Get the URL stripped of credentials for display purposes.
|
|
311
346
|
*/
|
|
312
347
|
export const displayUrl = (url) => redactToken(url);
|
|
348
|
+
/**
|
|
349
|
+
* `git pull --rebase origin main`. Replays local commits on top of the
|
|
350
|
+
* remote tip. On conflicts, leaves the repo in rebase-in-progress state
|
|
351
|
+
* with `<<<<<<<` / `=======` / `>>>>>>>` markers planted by git so the
|
|
352
|
+
* user can resolve via standard git tools (`git rebase --continue` /
|
|
353
|
+
* `git rebase --abort`).
|
|
354
|
+
*
|
|
355
|
+
* Caller is responsible for surfacing recovery instructions; this function
|
|
356
|
+
* only reports the outcome.
|
|
357
|
+
*/
|
|
358
|
+
export const gitPullRebase = async (dir) => {
|
|
359
|
+
// Count local-only commits BEFORE the rebase so the success path can
|
|
360
|
+
// tell the user how many got moved. After a clean rebase, origin/main
|
|
361
|
+
// is the merge-base and ahead-count == commits-rebased.
|
|
362
|
+
let commitsRebased = 0;
|
|
363
|
+
try {
|
|
364
|
+
const { stdout } = await runGit(['-C', dir, 'rev-list', '--count', 'origin/main..HEAD']);
|
|
365
|
+
commitsRebased = Number.parseInt(stdout.trim(), 10) || 0;
|
|
366
|
+
}
|
|
367
|
+
catch {
|
|
368
|
+
// Non-fatal — counting is for UX, not correctness.
|
|
369
|
+
}
|
|
370
|
+
try {
|
|
371
|
+
await runGit(['-C', dir, 'pull', '--rebase', 'origin', 'main']);
|
|
372
|
+
return { kind: 'clean', commitsRebased };
|
|
373
|
+
}
|
|
374
|
+
catch (err) {
|
|
375
|
+
// Distinguish "rebase paused on conflicts" from "rebase never started".
|
|
376
|
+
// Conflicts: `diff --diff-filter=U` lists the unmerged paths and
|
|
377
|
+
// `.git/rebase-merge/` is present.
|
|
378
|
+
try {
|
|
379
|
+
const { stdout } = await runGit(['-C', dir, 'diff', '--name-only', '--diff-filter=U']);
|
|
380
|
+
const conflictedFiles = stdout
|
|
381
|
+
.split('\n')
|
|
382
|
+
.map((s) => s.trim())
|
|
383
|
+
.filter(Boolean);
|
|
384
|
+
if (conflictedFiles.length > 0) {
|
|
385
|
+
return { kind: 'conflicts', conflictedFiles };
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
catch {
|
|
389
|
+
// Fall through to 'failed' — diff itself errored.
|
|
390
|
+
}
|
|
391
|
+
const reason = err instanceof Error ? err.message : String(err);
|
|
392
|
+
return { kind: 'failed', reason };
|
|
393
|
+
}
|
|
394
|
+
};
|
package/dist/version.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
declare const _default: "0.0.
|
|
1
|
+
declare const _default: "0.0.35";
|
|
2
2
|
export default _default;
|
package/dist/version.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
// AUTO-GENERATED from package.json by scripts/generate-version.mjs — do not edit.
|
|
2
|
-
export default '0.0.
|
|
2
|
+
export default '0.0.35';
|
package/oclif.manifest.json
CHANGED
|
@@ -1415,6 +1415,12 @@
|
|
|
1415
1415
|
"multiple": false,
|
|
1416
1416
|
"type": "option"
|
|
1417
1417
|
},
|
|
1418
|
+
"rebase": {
|
|
1419
|
+
"description": "Replay local commits on top of origin/main when the two have diverged. Conflicts are surfaced via standard git markers; resolve with `git rebase --continue`.",
|
|
1420
|
+
"name": "rebase",
|
|
1421
|
+
"allowNo": false,
|
|
1422
|
+
"type": "boolean"
|
|
1423
|
+
},
|
|
1418
1424
|
"workspace": {
|
|
1419
1425
|
"description": "Workspace ID (defaults to active profile)",
|
|
1420
1426
|
"name": "workspace",
|
|
@@ -2910,5 +2916,5 @@
|
|
|
2910
2916
|
]
|
|
2911
2917
|
}
|
|
2912
2918
|
},
|
|
2913
|
-
"version": "0.0.
|
|
2919
|
+
"version": "0.0.35"
|
|
2914
2920
|
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"packageManager": "yarn@4.11.0+sha512.4e54aeace9141df2f0177c266b05ec50dc044638157dae128c471ba65994ac802122d7ab35bcd9e81641228b7dcf24867d28e750e0bcae8a05277d600008ad54",
|
|
3
3
|
"name": "@quonfig/cli",
|
|
4
|
-
"version": "0.0.
|
|
4
|
+
"version": "0.0.35",
|
|
5
5
|
"bugs": {
|
|
6
6
|
"url": "https://github.com/quonfig/cli/issues"
|
|
7
7
|
},
|