@openvcs/git-plugin 0.3.0-edge.20260511.73 → 0.3.0-edge.20260517.83

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.
Files changed (3) hide show
  1. package/bin/git.js +52 -7
  2. package/package.json +2 -2
  3. package/src/git.ts +67 -7
package/bin/git.js CHANGED
@@ -234,9 +234,9 @@ export class GitCommand {
234
234
  if (options.path) {
235
235
  args.push('--', options.path);
236
236
  }
237
- const result = this.run(args);
237
+ const result = this.runChecked(args, 'git-log-failed');
238
238
  const commits = parseCommits(result.stdout);
239
- return { commits, exitCode: result.status };
239
+ return { commits, exitCode: 0 };
240
240
  }
241
241
  /** Reads `.gitmodules` entries indexed by submodule name and path. */
242
242
  readSubmoduleConfig() {
@@ -356,15 +356,18 @@ export class GitCommand {
356
356
  }
357
357
  }
358
358
  diffFile(path) {
359
- const worktreeDiff = this.runChecked(['diff', '--no-ext-diff', '--', path], 'git-diff-failed')
359
+ const cachedDiff = this.runChecked(['diff', '--cached', '--no-ext-diff', '--', path], 'git-diff-failed')
360
360
  .stdout;
361
- if (worktreeDiff.trim().length > 0)
362
- return worktreeDiff;
363
- return this.runChecked(['diff', '--cached', '--no-ext-diff', '--', path], 'git-diff-failed')
361
+ const worktreeDiff = this.runChecked(['diff', '--no-ext-diff', '--', path], 'git-diff-failed')
364
362
  .stdout;
363
+ return cachedDiff + worktreeDiff;
365
364
  }
366
365
  diffCommit(commit) {
367
- return this.runChecked(['diff', `${commit}^`, commit], 'git-diff-failed').stdout;
366
+ const parentCheck = this.run(['rev-parse', '--verify', `${commit}^`]);
367
+ if (parentCheck.status === 0) {
368
+ return this.runChecked(['diff', `${commit}^`, commit], 'git-diff-failed').stdout;
369
+ }
370
+ return this.runChecked(['diff-tree', '--root', '--no-commit-id', '--no-ext-diff', '-p', commit], 'git-diff-failed').stdout;
368
371
  }
369
372
  getConflictDetails(path) {
370
373
  const ours = this.run(['show', `:2:${path}`]);
@@ -399,6 +402,48 @@ export class GitCommand {
399
402
  }
400
403
  /** Stages a textual patch into the index without requiring worktree/index parity. */
401
404
  stagePatch(patch) {
405
+ const lines = patch.split('\n');
406
+ const retained = [];
407
+ let current = [];
408
+ let currentPath = null;
409
+ let unparseable = false;
410
+ const flush = () => {
411
+ if (current.length === 0) {
412
+ return;
413
+ }
414
+ if (!currentPath) {
415
+ unparseable = true;
416
+ return;
417
+ }
418
+ retained.push({ path: currentPath, text: current });
419
+ };
420
+ for (const line of lines) {
421
+ if (line.startsWith('diff --git ')) {
422
+ flush();
423
+ current = [line];
424
+ const marker = line.indexOf(' b/');
425
+ currentPath = marker >= 0 ? line.slice(marker + 3) : null;
426
+ continue;
427
+ }
428
+ if (current.length > 0) {
429
+ current.push(line);
430
+ }
431
+ }
432
+ flush();
433
+ if (retained.length > 1 && !unparseable) {
434
+ const seen = new Set();
435
+ const filtered = [];
436
+ for (let index = retained.length - 1; index >= 0; index -= 1) {
437
+ const section = retained[index];
438
+ if (seen.has(section.path)) {
439
+ continue;
440
+ }
441
+ seen.add(section.path);
442
+ filtered.push(section.text);
443
+ }
444
+ filtered.reverse();
445
+ patch = filtered.map((section) => section.join('\n')).join('\n');
446
+ }
402
447
  this.runChecked(['apply', '--cached', '--unidiff-zero'], 'git-stage-patch-failed', {
403
448
  stdin: patch,
404
449
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openvcs/git-plugin",
3
- "version": "0.3.0-edge.20260511.73",
3
+ "version": "0.3.0-edge.20260517.83",
4
4
  "description": "OpenVCS Git plugin - Node.js runtime",
5
5
  "license": "GPL-3.0-or-later",
6
6
  "homepage": "https://github.com/Open-VCS/OpenVCS-Plugin-Git",
@@ -18,7 +18,7 @@
18
18
  "openvcs": {
19
19
  "id": "openvcs.git",
20
20
  "name": "Git",
21
- "version": "0.3.0-edge.20260511.73",
21
+ "version": "0.3.0-edge.20260517.83",
22
22
  "author": "OpenVCS Contributors",
23
23
  "description": "Git VCS backend plugin for OpenVCS",
24
24
  "default_enabled": true,
package/src/git.ts CHANGED
@@ -364,9 +364,9 @@ export class GitCommand {
364
364
  args.push('--', options.path);
365
365
  }
366
366
 
367
- const result = this.run(args);
367
+ const result = this.runChecked(args, 'git-log-failed');
368
368
  const commits = parseCommits(result.stdout);
369
- return { commits, exitCode: result.status };
369
+ return { commits, exitCode: 0 };
370
370
  }
371
371
 
372
372
  /** Reads `.gitmodules` entries indexed by submodule name and path. */
@@ -502,16 +502,23 @@ export class GitCommand {
502
502
  }
503
503
 
504
504
  diffFile(path: string): string {
505
- const worktreeDiff = this.runChecked(['diff', '--no-ext-diff', '--', path], 'git-diff-failed')
505
+ const cachedDiff = this.runChecked(['diff', '--cached', '--no-ext-diff', '--', path], 'git-diff-failed')
506
506
  .stdout;
507
- if (worktreeDiff.trim().length > 0) return worktreeDiff;
508
-
509
- return this.runChecked(['diff', '--cached', '--no-ext-diff', '--', path], 'git-diff-failed')
507
+ const worktreeDiff = this.runChecked(['diff', '--no-ext-diff', '--', path], 'git-diff-failed')
510
508
  .stdout;
509
+ return cachedDiff + worktreeDiff;
511
510
  }
512
511
 
513
512
  diffCommit(commit: string): string {
514
- return this.runChecked(['diff', `${commit}^`, commit], 'git-diff-failed').stdout;
513
+ const parentCheck = this.run(['rev-parse', '--verify', `${commit}^`]);
514
+ if (parentCheck.status === 0) {
515
+ return this.runChecked(['diff', `${commit}^`, commit], 'git-diff-failed').stdout;
516
+ }
517
+
518
+ return this.runChecked(
519
+ ['diff-tree', '--root', '--no-commit-id', '--no-ext-diff', '-p', commit],
520
+ 'git-diff-failed',
521
+ ).stdout;
515
522
  }
516
523
 
517
524
  getConflictDetails(path: string): ConflictDetails {
@@ -556,6 +563,59 @@ export class GitCommand {
556
563
 
557
564
  /** Stages a textual patch into the index without requiring worktree/index parity. */
558
565
  stagePatch(patch: string): void {
566
+ const lines = patch.split('\n');
567
+ const retained: Array<{ path: string; text: string[] }> = [];
568
+ let current: string[] = [];
569
+ let currentPath: string | null = null;
570
+ let unparseable = false;
571
+
572
+ const flush = (): void => {
573
+ if (current.length === 0) {
574
+ return;
575
+ }
576
+
577
+ if (!currentPath) {
578
+ unparseable = true;
579
+ return;
580
+ }
581
+
582
+ retained.push({ path: currentPath, text: current });
583
+ };
584
+
585
+ for (const line of lines) {
586
+ if (line.startsWith('diff --git ')) {
587
+ flush();
588
+ current = [line];
589
+ const marker = line.indexOf(' b/');
590
+ currentPath = marker >= 0 ? line.slice(marker + 3) : null;
591
+ continue;
592
+ }
593
+
594
+ if (current.length > 0) {
595
+ current.push(line);
596
+ }
597
+ }
598
+
599
+ flush();
600
+
601
+ if (retained.length > 1 && !unparseable) {
602
+ const seen = new Set<string>();
603
+ const filtered: string[][] = [];
604
+
605
+ for (let index = retained.length - 1; index >= 0; index -= 1) {
606
+ const section = retained[index];
607
+ if (seen.has(section.path)) {
608
+ continue;
609
+ }
610
+
611
+ seen.add(section.path);
612
+ filtered.push(section.text);
613
+ }
614
+
615
+ filtered.reverse();
616
+ patch = filtered.map((section) => section.join('\n')).join('\n');
617
+ }
618
+
559
619
  this.runChecked(['apply', '--cached', '--unidiff-zero'], 'git-stage-patch-failed', {
560
620
  stdin: patch,
561
621
  });