isomorphic-jj 1.2.0 → 1.4.0
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/index.cjs +141 -136
- package/dist/index.cjs.map +1 -1
- package/dist/index.mjs +161 -156
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
- package/src/api/repository.js +141 -136
- package/src/types.d.ts +166 -2
package/package.json
CHANGED
package/src/api/repository.js
CHANGED
|
@@ -756,69 +756,116 @@ export async function createJJ(options) {
|
|
|
756
756
|
* @param {string[]} [args.paths] - Paths to move between changes (for history operations)
|
|
757
757
|
* @returns {Promise<Object>} Returns change object for history operations, file info for file operations
|
|
758
758
|
*/
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
759
|
+
/**
|
|
760
|
+
* Move a file in the working copy
|
|
761
|
+
*
|
|
762
|
+
* @param {Object} args - Move file arguments
|
|
763
|
+
* @param {string} args.from - Source file path
|
|
764
|
+
* @param {string} args.to - Destination file path
|
|
765
|
+
* @returns {Promise<Object>} Operation result including from, to paths and file stats
|
|
766
|
+
*/
|
|
767
|
+
async moveFile(args) {
|
|
768
|
+
if (!args.from || typeof args.from !== 'string') {
|
|
769
|
+
throw new JJError('INVALID_ARGUMENT', 'Missing or invalid from path', {
|
|
770
|
+
suggestion: 'Provide a valid source file path',
|
|
771
|
+
provided: { from: args.from, type: typeof args.from },
|
|
763
772
|
});
|
|
764
773
|
}
|
|
765
774
|
|
|
766
|
-
|
|
767
|
-
|
|
775
|
+
if (!args.to || typeof args.to !== 'string') {
|
|
776
|
+
throw new JJError('INVALID_ARGUMENT', 'Missing or invalid to path', {
|
|
777
|
+
suggestion: 'Provide a valid destination file path',
|
|
778
|
+
provided: { to: args.to, type: typeof args.to },
|
|
779
|
+
});
|
|
780
|
+
}
|
|
768
781
|
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
782
|
+
// Prevent moving to the same location
|
|
783
|
+
if (args.from === args.to) {
|
|
784
|
+
throw new JJError('INVALID_OPERATION', 'Source and destination paths are the same', {
|
|
785
|
+
path: args.from,
|
|
786
|
+
suggestion: 'Specify a different destination path',
|
|
787
|
+
});
|
|
773
788
|
}
|
|
774
|
-
},
|
|
775
789
|
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
*/
|
|
783
|
-
_detectHistoryOperation(args) {
|
|
784
|
-
// Explicit history operation indicators
|
|
785
|
-
if (args.paths || args.changeId || args.newParent) {
|
|
786
|
-
return true;
|
|
790
|
+
// Prevent absolute paths
|
|
791
|
+
if (args.from.startsWith('/') || args.to.startsWith('/')) {
|
|
792
|
+
throw new JJError('INVALID_PATH', 'Absolute paths are not allowed', {
|
|
793
|
+
suggestion: 'Use paths relative to the repository root',
|
|
794
|
+
provided: { from: args.from, to: args.to },
|
|
795
|
+
});
|
|
787
796
|
}
|
|
788
797
|
|
|
789
|
-
//
|
|
790
|
-
if (args.from
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
798
|
+
// Prevent parent directory traversal
|
|
799
|
+
if (args.from.includes('..') || args.to.includes('..')) {
|
|
800
|
+
throw new JJError('INVALID_PATH', 'Parent directory traversal (..) is not allowed', {
|
|
801
|
+
suggestion: 'Use paths within the repository',
|
|
802
|
+
provided: { from: args.from, to: args.to },
|
|
803
|
+
});
|
|
804
|
+
}
|
|
795
805
|
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
// Users should use explicit { changeId, newParent } for clarity
|
|
799
|
-
if (fromLooksLikeChangeId && toLooksLikeChangeId) {
|
|
800
|
-
// This is ambiguous - throw a helpful error
|
|
801
|
-
throw new JJError('AMBIGUOUS_OPERATION',
|
|
802
|
-
'Ambiguous move operation: arguments look like change IDs', {
|
|
803
|
-
suggestion: 'Use { changeId, newParent } for history operations or ensure file paths don\'t match change ID pattern',
|
|
804
|
-
args,
|
|
805
|
-
});
|
|
806
|
-
}
|
|
806
|
+
const fromPath = `${dir}/${args.from}`;
|
|
807
|
+
const toPath = `${dir}/${args.to}`;
|
|
807
808
|
|
|
808
|
-
|
|
809
|
+
// Check if source file exists
|
|
810
|
+
try {
|
|
811
|
+
await fs.promises.stat(fromPath);
|
|
812
|
+
} catch (error) {
|
|
813
|
+
throw new JJError('FILE_NOT_FOUND', `Source file not found: ${args.from}`, {
|
|
814
|
+
path: args.from,
|
|
815
|
+
suggestion: 'Check that the source file exists',
|
|
816
|
+
});
|
|
809
817
|
}
|
|
810
818
|
|
|
811
|
-
|
|
819
|
+
// Ensure destination directory exists
|
|
820
|
+
const toDir = toPath.substring(0, toPath.lastIndexOf('/'));
|
|
821
|
+
try {
|
|
822
|
+
await fs.promises.mkdir(toDir, { recursive: true });
|
|
823
|
+
} catch (error) {
|
|
824
|
+
throw new JJError('FILE_SYSTEM_ERROR', `Failed to create destination directory: ${error.message}`, {
|
|
825
|
+
path: toDir,
|
|
826
|
+
error: error.message,
|
|
827
|
+
});
|
|
828
|
+
}
|
|
829
|
+
|
|
830
|
+
// Move the file
|
|
831
|
+
try {
|
|
832
|
+
await fs.promises.rename(fromPath, toPath);
|
|
833
|
+
} catch (error) {
|
|
834
|
+
throw new JJError('FILE_SYSTEM_ERROR', `Failed to move file: ${error.message}`, {
|
|
835
|
+
from: args.from,
|
|
836
|
+
to: args.to,
|
|
837
|
+
error: error.message,
|
|
838
|
+
});
|
|
839
|
+
}
|
|
840
|
+
|
|
841
|
+
// Update working copy tracking
|
|
842
|
+
await workingCopy.load();
|
|
843
|
+
await workingCopy.untrackFile(args.from);
|
|
844
|
+
const stats = await fs.promises.stat(toPath);
|
|
845
|
+
await workingCopy.trackFile(args.to, {
|
|
846
|
+
mtime: stats.mtime,
|
|
847
|
+
size: stats.size,
|
|
848
|
+
mode: stats.mode,
|
|
849
|
+
});
|
|
850
|
+
|
|
851
|
+
return {
|
|
852
|
+
from: args.from,
|
|
853
|
+
to: args.to,
|
|
854
|
+
size: stats.size,
|
|
855
|
+
mode: stats.mode,
|
|
856
|
+
mtime: stats.mtime,
|
|
857
|
+
};
|
|
812
858
|
},
|
|
813
859
|
|
|
814
860
|
/**
|
|
815
|
-
* Move
|
|
861
|
+
* Move (rebase) a change to a new parent
|
|
816
862
|
*
|
|
817
|
-
* @
|
|
818
|
-
* @param {
|
|
863
|
+
* @param {Object} args - Move change arguments
|
|
864
|
+
* @param {string} args.changeId - Change ID to move (also accepts 'from' or 'source')
|
|
865
|
+
* @param {string} args.newParent - New parent change ID (also accepts 'to' or 'destination')
|
|
819
866
|
* @returns {Promise<Object>} Updated change object
|
|
820
867
|
*/
|
|
821
|
-
async
|
|
868
|
+
async moveChange(args) {
|
|
822
869
|
await graph.load();
|
|
823
870
|
|
|
824
871
|
// Support multiple parameter names for flexibility
|
|
@@ -906,110 +953,62 @@ export async function createJJ(options) {
|
|
|
906
953
|
},
|
|
907
954
|
|
|
908
955
|
/**
|
|
909
|
-
*
|
|
910
|
-
*
|
|
911
|
-
* @private
|
|
912
|
-
* @param {Object} args - Move arguments
|
|
913
|
-
* @returns {Promise<Object>} Operation result including from, to paths and file stats
|
|
956
|
+
* @deprecated Use moveFile() for files or moveChange() for history operations
|
|
957
|
+
* Move operation - delegates to moveFile or moveChange based on arguments
|
|
914
958
|
*/
|
|
915
|
-
async
|
|
916
|
-
if (!args
|
|
917
|
-
throw new JJError('INVALID_ARGUMENT', 'Missing or invalid
|
|
918
|
-
suggestion: '
|
|
919
|
-
provided: { from: args.from, type: typeof args.from },
|
|
920
|
-
});
|
|
921
|
-
}
|
|
922
|
-
|
|
923
|
-
if (!args.to || typeof args.to !== 'string') {
|
|
924
|
-
throw new JJError('INVALID_ARGUMENT', 'Missing or invalid to path', {
|
|
925
|
-
suggestion: 'Provide a valid destination file path',
|
|
926
|
-
provided: { to: args.to, type: typeof args.to },
|
|
959
|
+
async move(args) {
|
|
960
|
+
if (!args || typeof args !== 'object') {
|
|
961
|
+
throw new JJError('INVALID_ARGUMENT', 'Missing or invalid arguments', {
|
|
962
|
+
suggestion: 'Use moveFile({ from, to }) for files or moveChange({ changeId, newParent }) for history',
|
|
927
963
|
});
|
|
928
964
|
}
|
|
929
965
|
|
|
930
|
-
//
|
|
931
|
-
|
|
932
|
-
throw new JJError('INVALID_OPERATION', 'Source and destination paths are the same', {
|
|
933
|
-
path: args.from,
|
|
934
|
-
suggestion: 'Specify a different destination path',
|
|
935
|
-
});
|
|
936
|
-
}
|
|
966
|
+
// Detect operation type based on arguments
|
|
967
|
+
const isHistoryOp = this._detectHistoryOperation(args);
|
|
937
968
|
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
provided: { from: args.from, to: args.to },
|
|
943
|
-
});
|
|
969
|
+
if (isHistoryOp) {
|
|
970
|
+
return await this.moveChange(args);
|
|
971
|
+
} else {
|
|
972
|
+
return await this.moveFile(args);
|
|
944
973
|
}
|
|
974
|
+
},
|
|
945
975
|
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
976
|
+
/**
|
|
977
|
+
* Detect if move operation is for history (rebase) or files
|
|
978
|
+
*
|
|
979
|
+
* @private
|
|
980
|
+
* @param {Object} args - Move arguments
|
|
981
|
+
* @returns {boolean} True if history operation, false if file operation
|
|
982
|
+
*/
|
|
983
|
+
_detectHistoryOperation(args) {
|
|
984
|
+
// Explicit history operation indicators
|
|
985
|
+
if (args.paths || args.changeId || args.newParent) {
|
|
986
|
+
return true;
|
|
952
987
|
}
|
|
953
988
|
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
} catch (error) {
|
|
961
|
-
throw new JJError('FILE_NOT_FOUND', `Source file not found: ${args.from}`, {
|
|
962
|
-
path: args.from,
|
|
963
|
-
fullPath: fromPath,
|
|
964
|
-
suggestion: 'Check that the file exists',
|
|
965
|
-
});
|
|
966
|
-
}
|
|
989
|
+
// If only from/to are present, check if they look like change IDs
|
|
990
|
+
if (args.from && args.to && !args.changeId && !args.newParent && !args.paths) {
|
|
991
|
+
// Change IDs are 32-character hex strings
|
|
992
|
+
const changeIdPattern = /^[0-9a-f]{32}$/;
|
|
993
|
+
const fromLooksLikeChangeId = changeIdPattern.test(args.from);
|
|
994
|
+
const toLooksLikeChangeId = changeIdPattern.test(args.to);
|
|
967
995
|
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
`Failed to create destination directory: ${dirPath}`, {
|
|
978
|
-
directory: dirPath,
|
|
979
|
-
originalError: error.message,
|
|
996
|
+
// If both look like change IDs, it's likely a history operation
|
|
997
|
+
// However, we err on the side of file operations to be safe
|
|
998
|
+
// Users should use explicit { changeId, newParent } for clarity
|
|
999
|
+
if (fromLooksLikeChangeId && toLooksLikeChangeId) {
|
|
1000
|
+
// This is ambiguous - throw a helpful error
|
|
1001
|
+
throw new JJError('AMBIGUOUS_OPERATION',
|
|
1002
|
+
'Ambiguous move operation: arguments look like change IDs', {
|
|
1003
|
+
suggestion: 'Use { changeId, newParent } for history operations or ensure file paths don\'t match change ID pattern',
|
|
1004
|
+
args,
|
|
980
1005
|
});
|
|
981
1006
|
}
|
|
982
|
-
}
|
|
983
1007
|
|
|
984
|
-
|
|
985
|
-
try {
|
|
986
|
-
await fs.promises.rename(fromPath, toPath);
|
|
987
|
-
} catch (error) {
|
|
988
|
-
throw new JJError('FILE_MOVE_FAILED', `Failed to move file: ${error.message}`, {
|
|
989
|
-
from: args.from,
|
|
990
|
-
to: args.to,
|
|
991
|
-
originalError: error.message,
|
|
992
|
-
});
|
|
1008
|
+
return false; // Treat as file operation
|
|
993
1009
|
}
|
|
994
1010
|
|
|
995
|
-
|
|
996
|
-
await workingCopy.load();
|
|
997
|
-
await workingCopy.untrackFile(args.from);
|
|
998
|
-
const stats = await fs.promises.stat(toPath);
|
|
999
|
-
await workingCopy.trackFile(args.to, {
|
|
1000
|
-
mtime: stats.mtime,
|
|
1001
|
-
size: stats.size,
|
|
1002
|
-
mode: stats.mode,
|
|
1003
|
-
});
|
|
1004
|
-
|
|
1005
|
-
// Return useful information about the move operation
|
|
1006
|
-
return {
|
|
1007
|
-
from: args.from,
|
|
1008
|
-
to: args.to,
|
|
1009
|
-
size: stats.size,
|
|
1010
|
-
mode: stats.mode,
|
|
1011
|
-
mtime: stats.mtime,
|
|
1012
|
-
};
|
|
1011
|
+
return false;
|
|
1013
1012
|
},
|
|
1014
1013
|
|
|
1015
1014
|
/**
|
|
@@ -1085,6 +1084,11 @@ export async function createJJ(options) {
|
|
|
1085
1084
|
change.timestamp = new Date().toISOString();
|
|
1086
1085
|
}
|
|
1087
1086
|
|
|
1087
|
+
// Update metadata
|
|
1088
|
+
if (args.metadata !== undefined) {
|
|
1089
|
+
change.metadata = args.metadata;
|
|
1090
|
+
}
|
|
1091
|
+
|
|
1088
1092
|
// Only snapshot files if describing working copy
|
|
1089
1093
|
if (isWorkingCopy) {
|
|
1090
1094
|
// Snapshot current file contents for conflict detection
|
|
@@ -1689,10 +1693,11 @@ export async function createJJ(options) {
|
|
|
1689
1693
|
* @param {Object} [args={}] - Arguments
|
|
1690
1694
|
* @param {string} [args.message] - Description for current change
|
|
1691
1695
|
* @param {Object} [args.author] - Author for current change
|
|
1696
|
+
* @param {Object} [args.metadata] - Metadata to attach to the change
|
|
1692
1697
|
* @returns {Promise<Object>} The newly created change
|
|
1693
1698
|
*/
|
|
1694
1699
|
async commit(args = {}) {
|
|
1695
|
-
await this.describe({ message: args.message, author: args.author });
|
|
1700
|
+
await this.describe({ message: args.message, author: args.author, metadata: args.metadata });
|
|
1696
1701
|
return await this.new({ message: args.nextMessage });
|
|
1697
1702
|
},
|
|
1698
1703
|
|
|
@@ -2516,7 +2521,7 @@ export async function createJJ(options) {
|
|
|
2516
2521
|
* });
|
|
2517
2522
|
*/
|
|
2518
2523
|
async rebase(args) {
|
|
2519
|
-
return await this.
|
|
2524
|
+
return await this.moveChange(args);
|
|
2520
2525
|
},
|
|
2521
2526
|
|
|
2522
2527
|
/**
|
package/src/types.d.ts
CHANGED
|
@@ -76,6 +76,7 @@ export interface Change {
|
|
|
76
76
|
description: string;
|
|
77
77
|
timestamp: Date;
|
|
78
78
|
fileSnapshot?: Record<string, FileSnapshot>;
|
|
79
|
+
metadata?: Record<string, any>;
|
|
79
80
|
}
|
|
80
81
|
|
|
81
82
|
/**
|
|
@@ -330,6 +331,24 @@ export interface MoveFileArgs {
|
|
|
330
331
|
to: string;
|
|
331
332
|
}
|
|
332
333
|
|
|
334
|
+
/**
|
|
335
|
+
* Move change (rebase) arguments
|
|
336
|
+
*/
|
|
337
|
+
export interface MoveChangeArgs {
|
|
338
|
+
/** Change ID to move (also accepts 'from' or 'source') */
|
|
339
|
+
changeId?: ChangeID;
|
|
340
|
+
/** Source change ID (alias for changeId) */
|
|
341
|
+
from?: ChangeID;
|
|
342
|
+
/** Source change ID (alias for changeId) */
|
|
343
|
+
source?: ChangeID;
|
|
344
|
+
/** New parent change ID (also accepts 'to' or 'destination') */
|
|
345
|
+
newParent?: ChangeID;
|
|
346
|
+
/** Destination change ID (alias for newParent) */
|
|
347
|
+
to?: ChangeID;
|
|
348
|
+
/** Destination change ID (alias for newParent) */
|
|
349
|
+
destination?: ChangeID;
|
|
350
|
+
}
|
|
351
|
+
|
|
333
352
|
/**
|
|
334
353
|
* Remove file arguments
|
|
335
354
|
*/
|
|
@@ -460,6 +479,8 @@ export interface UnabandonArgs {
|
|
|
460
479
|
export interface LogOptions {
|
|
461
480
|
revset?: Revset;
|
|
462
481
|
limit?: number;
|
|
482
|
+
/** If true, return count of commits instead of commit objects */
|
|
483
|
+
count?: boolean;
|
|
463
484
|
}
|
|
464
485
|
|
|
465
486
|
/**
|
|
@@ -856,6 +877,122 @@ export interface MergeResult {
|
|
|
856
877
|
conflicts: Conflict[];
|
|
857
878
|
}
|
|
858
879
|
|
|
880
|
+
/**
|
|
881
|
+
* Absorb operation arguments
|
|
882
|
+
*/
|
|
883
|
+
export interface AbsorbArgs {
|
|
884
|
+
/** Change to absorb into (optional, defaults to working copy parent) */
|
|
885
|
+
changeId?: ChangeID;
|
|
886
|
+
/** Destination change to absorb into (alias for changeId) */
|
|
887
|
+
destination?: ChangeID;
|
|
888
|
+
/** Dry run mode - don't apply changes */
|
|
889
|
+
dryRun?: boolean;
|
|
890
|
+
/** Specific paths to absorb */
|
|
891
|
+
paths?: string[];
|
|
892
|
+
}
|
|
893
|
+
|
|
894
|
+
/**
|
|
895
|
+
* Absorb operation result
|
|
896
|
+
*/
|
|
897
|
+
export interface AbsorbResult {
|
|
898
|
+
/** Changes that were absorbed */
|
|
899
|
+
absorbed: Array<{
|
|
900
|
+
path: string;
|
|
901
|
+
hunks: number;
|
|
902
|
+
destination: ChangeID;
|
|
903
|
+
}>;
|
|
904
|
+
/** Changes affected by the absorb */
|
|
905
|
+
affectedChanges: ChangeID[];
|
|
906
|
+
/** Changes that would be absorbed (dry run mode) */
|
|
907
|
+
wouldAbsorb?: Array<{
|
|
908
|
+
path: string;
|
|
909
|
+
hunks: number;
|
|
910
|
+
destination: ChangeID;
|
|
911
|
+
}>;
|
|
912
|
+
}
|
|
913
|
+
|
|
914
|
+
/**
|
|
915
|
+
* Bisect start arguments
|
|
916
|
+
*/
|
|
917
|
+
export interface BisectStartArgs {
|
|
918
|
+
/** Good change ID */
|
|
919
|
+
good: ChangeID;
|
|
920
|
+
/** Bad change ID */
|
|
921
|
+
bad: ChangeID;
|
|
922
|
+
}
|
|
923
|
+
|
|
924
|
+
/**
|
|
925
|
+
* Bisect state
|
|
926
|
+
*/
|
|
927
|
+
export interface BisectState {
|
|
928
|
+
/** Whether bisect is active */
|
|
929
|
+
active: boolean;
|
|
930
|
+
/** Good change */
|
|
931
|
+
good?: ChangeID;
|
|
932
|
+
/** Bad change */
|
|
933
|
+
bad?: ChangeID;
|
|
934
|
+
/** Current change being tested */
|
|
935
|
+
current?: ChangeID;
|
|
936
|
+
/** Remaining changes to test */
|
|
937
|
+
remaining?: number;
|
|
938
|
+
}
|
|
939
|
+
|
|
940
|
+
/**
|
|
941
|
+
* Sparse checkout set arguments
|
|
942
|
+
*/
|
|
943
|
+
export interface SparseSetArgs {
|
|
944
|
+
/** Patterns to set (replaces existing patterns) */
|
|
945
|
+
patterns: string[];
|
|
946
|
+
}
|
|
947
|
+
|
|
948
|
+
/**
|
|
949
|
+
* Sparse checkout add arguments
|
|
950
|
+
*/
|
|
951
|
+
export interface SparseAddArgs {
|
|
952
|
+
/** Patterns to add to existing sparse checkout */
|
|
953
|
+
patterns: string[];
|
|
954
|
+
}
|
|
955
|
+
|
|
956
|
+
/**
|
|
957
|
+
* Sparse checkout remove arguments
|
|
958
|
+
*/
|
|
959
|
+
export interface SparseRemoveArgs {
|
|
960
|
+
/** Patterns to remove from sparse checkout */
|
|
961
|
+
patterns: string[];
|
|
962
|
+
}
|
|
963
|
+
|
|
964
|
+
/**
|
|
965
|
+
* Merge driver for custom file merging
|
|
966
|
+
*/
|
|
967
|
+
export interface MergeDriver {
|
|
968
|
+
/** Driver name */
|
|
969
|
+
name: string;
|
|
970
|
+
/** Detect if this driver should handle a file */
|
|
971
|
+
detect(path: string, content: string): boolean;
|
|
972
|
+
/** Merge three versions of a file */
|
|
973
|
+
merge(args: {
|
|
974
|
+
path: string;
|
|
975
|
+
base: string;
|
|
976
|
+
ours: string;
|
|
977
|
+
theirs: string;
|
|
978
|
+
}): {
|
|
979
|
+
merged: string;
|
|
980
|
+
conflicts?: Array<{ line: number; message: string }>;
|
|
981
|
+
};
|
|
982
|
+
}
|
|
983
|
+
|
|
984
|
+
/**
|
|
985
|
+
* Merge driver registry
|
|
986
|
+
*/
|
|
987
|
+
export interface MergeDriverRegistry {
|
|
988
|
+
/** Register a custom merge driver */
|
|
989
|
+
register(driver: MergeDriver): void;
|
|
990
|
+
/** Get driver for a file path */
|
|
991
|
+
getDriver(path: string, content: string): MergeDriver | null;
|
|
992
|
+
/** List all registered drivers */
|
|
993
|
+
list(): MergeDriver[];
|
|
994
|
+
}
|
|
995
|
+
|
|
859
996
|
// ============================================================================
|
|
860
997
|
// Main JJ Repository Interface
|
|
861
998
|
// ============================================================================
|
|
@@ -875,6 +1012,7 @@ export interface JJ {
|
|
|
875
1012
|
revset: any;
|
|
876
1013
|
gitBackend?: any;
|
|
877
1014
|
backgroundOps?: any;
|
|
1015
|
+
mergeDrivers: MergeDriverRegistry;
|
|
878
1016
|
|
|
879
1017
|
// Repository lifecycle
|
|
880
1018
|
init(opts?: InitOptions): Promise<void>;
|
|
@@ -883,7 +1021,12 @@ export interface JJ {
|
|
|
883
1021
|
write(args: WriteArgs): Promise<WriteResult>;
|
|
884
1022
|
read(args: ReadArgs): Promise<string | Uint8Array>;
|
|
885
1023
|
cat(args: ReadArgs): Promise<string | Uint8Array>;
|
|
886
|
-
|
|
1024
|
+
moveFile(args: MoveFileArgs): Promise<MoveResult>;
|
|
1025
|
+
moveChange(args: MoveChangeArgs): Promise<Change>;
|
|
1026
|
+
/**
|
|
1027
|
+
* @deprecated Use moveFile() for files or moveChange() for history operations
|
|
1028
|
+
*/
|
|
1029
|
+
move(args: MoveFileArgs | MoveChangeArgs): Promise<MoveResult | Change>;
|
|
887
1030
|
remove(args: RemoveArgs): Promise<RemoveResult>;
|
|
888
1031
|
listFiles(args?: ListFilesArgs): Promise<string[]>;
|
|
889
1032
|
readStream(args: ReadStreamArgs): Promise<any>;
|
|
@@ -904,9 +1047,11 @@ export interface JJ {
|
|
|
904
1047
|
rebase(args: RebaseArgs): Promise<Change>;
|
|
905
1048
|
abandon(args: AbandonArgs): Promise<void>;
|
|
906
1049
|
unabandon(args: UnabandonArgs): Promise<void>;
|
|
1050
|
+
absorb(args?: AbsorbArgs): Promise<AbsorbResult>;
|
|
907
1051
|
|
|
908
1052
|
// Queries
|
|
909
|
-
log(opts?: LogOptions): Promise<LogEntry[]>;
|
|
1053
|
+
log(opts?: LogOptions & { count?: false }): Promise<LogEntry[]>;
|
|
1054
|
+
log(opts: LogOptions & { count: true }): Promise<number>;
|
|
910
1055
|
show(args: ShowArgs): Promise<Change>;
|
|
911
1056
|
obslog(opts?: ObslogOptions): Promise<Operation[]>;
|
|
912
1057
|
|
|
@@ -1104,6 +1249,25 @@ export interface JJ {
|
|
|
1104
1249
|
}>;
|
|
1105
1250
|
parent: ChangeID;
|
|
1106
1251
|
}>;
|
|
1252
|
+
|
|
1253
|
+
// Bisect operations
|
|
1254
|
+
bisect: {
|
|
1255
|
+
start(args: BisectStartArgs): Promise<void>;
|
|
1256
|
+
good(): Promise<void>;
|
|
1257
|
+
bad(): Promise<void>;
|
|
1258
|
+
status(): Promise<BisectState>;
|
|
1259
|
+
reset(): Promise<void>;
|
|
1260
|
+
};
|
|
1261
|
+
|
|
1262
|
+
// Sparse checkout
|
|
1263
|
+
sparse: {
|
|
1264
|
+
list(): Promise<string[]>;
|
|
1265
|
+
set(args: SparseSetArgs): Promise<void>;
|
|
1266
|
+
add(args: SparseAddArgs): Promise<void>;
|
|
1267
|
+
remove(args: SparseRemoveArgs): Promise<void>;
|
|
1268
|
+
reset(): Promise<void>;
|
|
1269
|
+
clear(): Promise<void>;
|
|
1270
|
+
};
|
|
1107
1271
|
}
|
|
1108
1272
|
|
|
1109
1273
|
// ============================================================================
|