sync-worktrees 1.7.3 → 1.7.5

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 (31) hide show
  1. package/dist/constants.d.ts +54 -0
  2. package/dist/constants.d.ts.map +1 -0
  3. package/dist/constants.js +66 -0
  4. package/dist/constants.js.map +1 -0
  5. package/dist/errors/index.d.ts +51 -0
  6. package/dist/errors/index.d.ts.map +1 -0
  7. package/dist/errors/index.js +119 -0
  8. package/dist/errors/index.js.map +1 -0
  9. package/dist/services/git.service.d.ts.map +1 -1
  10. package/dist/services/git.service.js +86 -40
  11. package/dist/services/git.service.js.map +1 -1
  12. package/dist/services/path-resolution.service.d.ts +7 -0
  13. package/dist/services/path-resolution.service.d.ts.map +1 -0
  14. package/dist/services/path-resolution.service.js +58 -0
  15. package/dist/services/path-resolution.service.js.map +1 -0
  16. package/dist/services/worktree-metadata.service.d.ts +12 -0
  17. package/dist/services/worktree-metadata.service.d.ts.map +1 -1
  18. package/dist/services/worktree-metadata.service.js +162 -3
  19. package/dist/services/worktree-metadata.service.js.map +1 -1
  20. package/dist/services/worktree-status.service.d.ts +28 -0
  21. package/dist/services/worktree-status.service.d.ts.map +1 -0
  22. package/dist/services/worktree-status.service.js +229 -0
  23. package/dist/services/worktree-status.service.js.map +1 -0
  24. package/dist/services/worktree-sync.service.d.ts.map +1 -1
  25. package/dist/services/worktree-sync.service.js +7 -10
  26. package/dist/services/worktree-sync.service.js.map +1 -1
  27. package/dist/utils/lfs-error.d.ts +6 -0
  28. package/dist/utils/lfs-error.d.ts.map +1 -1
  29. package/dist/utils/lfs-error.js +16 -14
  30. package/dist/utils/lfs-error.js.map +1 -1
  31. package/package.json +1 -1
@@ -0,0 +1,54 @@
1
+ export declare const GIT_CONSTANTS: {
2
+ readonly REMOTE_PREFIX: "origin/";
3
+ readonly REMOTE_NAME: "origin";
4
+ readonly HEAD_REF: "/HEAD";
5
+ readonly DEFAULT_BRANCH: "main";
6
+ readonly BARE_DIR_NAME: ".bare";
7
+ readonly DIVERGED_DIR_NAME: ".diverged";
8
+ readonly REFS: {
9
+ readonly HEADS: "refs/heads/";
10
+ readonly REMOTES: "refs/remotes/origin";
11
+ readonly REMOTES_ORIGIN: "refs/remotes/origin/*";
12
+ };
13
+ readonly FETCH_CONFIG: "+refs/heads/*:refs/remotes/origin/*";
14
+ };
15
+ export declare const GIT_OPERATIONS: {
16
+ readonly MERGE_HEAD: "MERGE_HEAD";
17
+ readonly CHERRY_PICK_HEAD: "CHERRY_PICK_HEAD";
18
+ readonly REVERT_HEAD: "REVERT_HEAD";
19
+ readonly BISECT_LOG: "BISECT_LOG";
20
+ readonly REBASE_MERGE: "rebase-merge";
21
+ readonly REBASE_APPLY: "rebase-apply";
22
+ };
23
+ export declare const DEFAULT_CONFIG: {
24
+ readonly CRON_SCHEDULE: "0 * * * *";
25
+ readonly RETRY: {
26
+ readonly MAX_ATTEMPTS: 3;
27
+ readonly MAX_LFS_RETRIES: 2;
28
+ readonly INITIAL_DELAY_MS: 1000;
29
+ readonly MAX_DELAY_MS: 30000;
30
+ readonly BACKOFF_MULTIPLIER: 2;
31
+ };
32
+ readonly UPDATE_EXISTING_WORKTREES: true;
33
+ };
34
+ export declare const ERROR_MESSAGES: {
35
+ readonly GIT_NOT_INITIALIZED: "Git service not initialized. Call initialize() first.";
36
+ readonly ALREADY_EXISTS: "already exists";
37
+ readonly ALREADY_REGISTERED: "already registered worktree";
38
+ readonly FAST_FORWARD_FAILED: readonly ["Not possible to fast-forward", "fatal: Not possible to fast-forward, aborting", "cannot fast-forward"];
39
+ readonly NO_UPSTREAM: readonly ["fatal: no upstream configured", "no upstream configured for branch", "fatal: ambiguous argument", "unknown revision or path"];
40
+ readonly LFS_ERROR: readonly ["smudge filter lfs failed", "git-lfs", "LFS"];
41
+ readonly EXDEV: "EXDEV";
42
+ };
43
+ export declare const TEST_TIMEOUT: {
44
+ readonly DEFAULT: 10000;
45
+ readonly E2E: 60000;
46
+ };
47
+ export declare const PATH_CONSTANTS: {
48
+ readonly GIT_DIR: ".git";
49
+ readonly README: "README";
50
+ };
51
+ export declare const METADATA_CONSTANTS: {
52
+ readonly MAX_HISTORY_ENTRIES: 10;
53
+ };
54
+ //# sourceMappingURL=constants.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,aAAa;;;;;;;;;;;;;CAahB,CAAC;AAEX,eAAO,MAAM,cAAc;;;;;;;CAOjB,CAAC;AAEX,eAAO,MAAM,cAAc;;;;;;;;;;CAUjB,CAAC;AAEX,eAAO,MAAM,cAAc;;;;;;;;CAiBjB,CAAC;AAEX,eAAO,MAAM,YAAY;;;CAGf,CAAC;AAEX,eAAO,MAAM,cAAc;;;CAGjB,CAAC;AAEX,eAAO,MAAM,kBAAkB;;CAErB,CAAC"}
@@ -0,0 +1,66 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.METADATA_CONSTANTS = exports.PATH_CONSTANTS = exports.TEST_TIMEOUT = exports.ERROR_MESSAGES = exports.DEFAULT_CONFIG = exports.GIT_OPERATIONS = exports.GIT_CONSTANTS = void 0;
4
+ exports.GIT_CONSTANTS = {
5
+ REMOTE_PREFIX: "origin/",
6
+ REMOTE_NAME: "origin",
7
+ HEAD_REF: "/HEAD",
8
+ DEFAULT_BRANCH: "main",
9
+ BARE_DIR_NAME: ".bare",
10
+ DIVERGED_DIR_NAME: ".diverged",
11
+ REFS: {
12
+ HEADS: "refs/heads/",
13
+ REMOTES: "refs/remotes/origin",
14
+ REMOTES_ORIGIN: "refs/remotes/origin/*",
15
+ },
16
+ FETCH_CONFIG: "+refs/heads/*:refs/remotes/origin/*",
17
+ };
18
+ exports.GIT_OPERATIONS = {
19
+ MERGE_HEAD: "MERGE_HEAD",
20
+ CHERRY_PICK_HEAD: "CHERRY_PICK_HEAD",
21
+ REVERT_HEAD: "REVERT_HEAD",
22
+ BISECT_LOG: "BISECT_LOG",
23
+ REBASE_MERGE: "rebase-merge",
24
+ REBASE_APPLY: "rebase-apply",
25
+ };
26
+ exports.DEFAULT_CONFIG = {
27
+ CRON_SCHEDULE: "0 * * * *",
28
+ RETRY: {
29
+ MAX_ATTEMPTS: 3,
30
+ MAX_LFS_RETRIES: 2,
31
+ INITIAL_DELAY_MS: 1000,
32
+ MAX_DELAY_MS: 30000,
33
+ BACKOFF_MULTIPLIER: 2,
34
+ },
35
+ UPDATE_EXISTING_WORKTREES: true,
36
+ };
37
+ exports.ERROR_MESSAGES = {
38
+ GIT_NOT_INITIALIZED: "Git service not initialized. Call initialize() first.",
39
+ ALREADY_EXISTS: "already exists",
40
+ ALREADY_REGISTERED: "already registered worktree",
41
+ FAST_FORWARD_FAILED: [
42
+ "Not possible to fast-forward",
43
+ "fatal: Not possible to fast-forward, aborting",
44
+ "cannot fast-forward",
45
+ ],
46
+ NO_UPSTREAM: [
47
+ "fatal: no upstream configured",
48
+ "no upstream configured for branch",
49
+ "fatal: ambiguous argument",
50
+ "unknown revision or path",
51
+ ],
52
+ LFS_ERROR: ["smudge filter lfs failed", "git-lfs", "LFS"],
53
+ EXDEV: "EXDEV",
54
+ };
55
+ exports.TEST_TIMEOUT = {
56
+ DEFAULT: 10000,
57
+ E2E: 60000,
58
+ };
59
+ exports.PATH_CONSTANTS = {
60
+ GIT_DIR: ".git",
61
+ README: "README",
62
+ };
63
+ exports.METADATA_CONSTANTS = {
64
+ MAX_HISTORY_ENTRIES: 10,
65
+ };
66
+ //# sourceMappingURL=constants.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"constants.js","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":";;;AAAa,QAAA,aAAa,GAAG;IAC3B,aAAa,EAAE,SAAS;IACxB,WAAW,EAAE,QAAQ;IACrB,QAAQ,EAAE,OAAO;IACjB,cAAc,EAAE,MAAM;IACtB,aAAa,EAAE,OAAO;IACtB,iBAAiB,EAAE,WAAW;IAC9B,IAAI,EAAE;QACJ,KAAK,EAAE,aAAa;QACpB,OAAO,EAAE,qBAAqB;QAC9B,cAAc,EAAE,uBAAuB;KACxC;IACD,YAAY,EAAE,qCAAqC;CAC3C,CAAC;AAEE,QAAA,cAAc,GAAG;IAC5B,UAAU,EAAE,YAAY;IACxB,gBAAgB,EAAE,kBAAkB;IACpC,WAAW,EAAE,aAAa;IAC1B,UAAU,EAAE,YAAY;IACxB,YAAY,EAAE,cAAc;IAC5B,YAAY,EAAE,cAAc;CACpB,CAAC;AAEE,QAAA,cAAc,GAAG;IAC5B,aAAa,EAAE,WAAW;IAC1B,KAAK,EAAE;QACL,YAAY,EAAE,CAAC;QACf,eAAe,EAAE,CAAC;QAClB,gBAAgB,EAAE,IAAI;QACtB,YAAY,EAAE,KAAK;QACnB,kBAAkB,EAAE,CAAC;KACtB;IACD,yBAAyB,EAAE,IAAI;CACvB,CAAC;AAEE,QAAA,cAAc,GAAG;IAC5B,mBAAmB,EAAE,uDAAuD;IAC5E,cAAc,EAAE,gBAAgB;IAChC,kBAAkB,EAAE,6BAA6B;IACjD,mBAAmB,EAAE;QACnB,8BAA8B;QAC9B,+CAA+C;QAC/C,qBAAqB;KACtB;IACD,WAAW,EAAE;QACX,+BAA+B;QAC/B,mCAAmC;QACnC,2BAA2B;QAC3B,0BAA0B;KAC3B;IACD,SAAS,EAAE,CAAC,0BAA0B,EAAE,SAAS,EAAE,KAAK,CAAC;IACzD,KAAK,EAAE,OAAO;CACN,CAAC;AAEE,QAAA,YAAY,GAAG;IAC1B,OAAO,EAAE,KAAK;IACd,GAAG,EAAE,KAAK;CACF,CAAC;AAEE,QAAA,cAAc,GAAG;IAC5B,OAAO,EAAE,MAAM;IACf,MAAM,EAAE,QAAQ;CACR,CAAC;AAEE,QAAA,kBAAkB,GAAG;IAChC,mBAAmB,EAAE,EAAE;CACf,CAAC"}
@@ -0,0 +1,51 @@
1
+ export declare class SyncWorktreesError extends Error {
2
+ readonly code: string;
3
+ readonly cause?: Error | undefined;
4
+ constructor(message: string, code: string, cause?: Error | undefined);
5
+ }
6
+ export declare class GitError extends SyncWorktreesError {
7
+ constructor(message: string, code: string, cause?: Error);
8
+ }
9
+ export declare class GitNotInitializedError extends GitError {
10
+ constructor();
11
+ }
12
+ export declare class GitOperationError extends GitError {
13
+ constructor(operation: string, details: string, cause?: Error);
14
+ }
15
+ export declare class FastForwardError extends GitError {
16
+ readonly branchName: string;
17
+ constructor(branchName: string, cause?: Error);
18
+ }
19
+ export declare class WorktreeError extends SyncWorktreesError {
20
+ constructor(message: string, code: string, cause?: Error);
21
+ }
22
+ export declare class WorktreeAlreadyExistsError extends WorktreeError {
23
+ readonly path: string;
24
+ readonly branchName: string;
25
+ constructor(path: string, branchName: string);
26
+ }
27
+ export declare class WorktreeNotCleanError extends WorktreeError {
28
+ readonly path: string;
29
+ readonly reasons: string[];
30
+ constructor(path: string, reasons: string[]);
31
+ }
32
+ export declare class ConfigError extends SyncWorktreesError {
33
+ constructor(message: string, code: string, cause?: Error);
34
+ }
35
+ export declare class ConfigValidationError extends ConfigError {
36
+ readonly field: string;
37
+ readonly reason: string;
38
+ constructor(field: string, reason: string);
39
+ }
40
+ export declare class PathResolutionError extends SyncWorktreesError {
41
+ readonly path: string;
42
+ readonly reason: string;
43
+ constructor(path: string, reason: string);
44
+ }
45
+ export declare class LfsError extends GitError {
46
+ constructor(message: string, cause?: Error);
47
+ }
48
+ export declare function isLfsError(error: Error | string): boolean;
49
+ export declare function isFastForwardError(error: Error | string): boolean;
50
+ export declare function isNoUpstreamError(error: Error | string): boolean;
51
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/errors/index.ts"],"names":[],"mappings":"AAEA,qBAAa,kBAAmB,SAAQ,KAAK;aAGzB,IAAI,EAAE,MAAM;aACZ,KAAK,CAAC,EAAE,KAAK;gBAF7B,OAAO,EAAE,MAAM,EACC,IAAI,EAAE,MAAM,EACZ,KAAK,CAAC,EAAE,KAAK,YAAA;CAShC;AAED,qBAAa,QAAS,SAAQ,kBAAkB;gBAClC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,KAAK;CAGzD;AAED,qBAAa,sBAAuB,SAAQ,QAAQ;;CAInD;AAED,qBAAa,iBAAkB,SAAQ,QAAQ;gBACjC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,KAAK;CAG9D;AAED,qBAAa,gBAAiB,SAAQ,QAAQ;aAE1B,UAAU,EAAE,MAAM;gBAAlB,UAAU,EAAE,MAAM,EAClC,KAAK,CAAC,EAAE,KAAK;CAIhB;AAED,qBAAa,aAAc,SAAQ,kBAAkB;gBACvC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,KAAK;CAGzD;AAED,qBAAa,0BAA2B,SAAQ,aAAa;aAEzC,IAAI,EAAE,MAAM;aACZ,UAAU,EAAE,MAAM;gBADlB,IAAI,EAAE,MAAM,EACZ,UAAU,EAAE,MAAM;CAIrC;AAED,qBAAa,qBAAsB,SAAQ,aAAa;aAEpC,IAAI,EAAE,MAAM;aACZ,OAAO,EAAE,MAAM,EAAE;gBADjB,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,EAAE;CAIpC;AAED,qBAAa,WAAY,SAAQ,kBAAkB;gBACrC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,KAAK;CAGzD;AAED,qBAAa,qBAAsB,SAAQ,WAAW;aAElC,KAAK,EAAE,MAAM;aACb,MAAM,EAAE,MAAM;gBADd,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM;CAIjC;AAED,qBAAa,mBAAoB,SAAQ,kBAAkB;aAEvC,IAAI,EAAE,MAAM;aACZ,MAAM,EAAE,MAAM;gBADd,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,MAAM;CAIjC;AAED,qBAAa,QAAS,SAAQ,QAAQ;gBACxB,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,KAAK;CAG3C;AAED,wBAAgB,UAAU,CAAC,KAAK,EAAE,KAAK,GAAG,MAAM,GAAG,OAAO,CAGzD;AAED,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,KAAK,GAAG,MAAM,GAAG,OAAO,CAGjE;AAED,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,KAAK,GAAG,MAAM,GAAG,OAAO,CAGhE"}
@@ -0,0 +1,119 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.LfsError = exports.PathResolutionError = exports.ConfigValidationError = exports.ConfigError = exports.WorktreeNotCleanError = exports.WorktreeAlreadyExistsError = exports.WorktreeError = exports.FastForwardError = exports.GitOperationError = exports.GitNotInitializedError = exports.GitError = exports.SyncWorktreesError = void 0;
4
+ exports.isLfsError = isLfsError;
5
+ exports.isFastForwardError = isFastForwardError;
6
+ exports.isNoUpstreamError = isNoUpstreamError;
7
+ const constants_1 = require("../constants");
8
+ class SyncWorktreesError extends Error {
9
+ code;
10
+ cause;
11
+ constructor(message, code, cause) {
12
+ super(message);
13
+ this.code = code;
14
+ this.cause = cause;
15
+ this.name = this.constructor.name;
16
+ Object.setPrototypeOf(this, new.target.prototype);
17
+ if (cause && cause.stack) {
18
+ this.stack = `${this.stack}\nCaused by: ${cause.stack}`;
19
+ }
20
+ }
21
+ }
22
+ exports.SyncWorktreesError = SyncWorktreesError;
23
+ class GitError extends SyncWorktreesError {
24
+ constructor(message, code, cause) {
25
+ super(message, `GIT_${code}`, cause);
26
+ }
27
+ }
28
+ exports.GitError = GitError;
29
+ class GitNotInitializedError extends GitError {
30
+ constructor() {
31
+ super(constants_1.ERROR_MESSAGES.GIT_NOT_INITIALIZED, "NOT_INITIALIZED");
32
+ }
33
+ }
34
+ exports.GitNotInitializedError = GitNotInitializedError;
35
+ class GitOperationError extends GitError {
36
+ constructor(operation, details, cause) {
37
+ super(`Git operation '${operation}' failed: ${details}`, "OPERATION_FAILED", cause);
38
+ }
39
+ }
40
+ exports.GitOperationError = GitOperationError;
41
+ class FastForwardError extends GitError {
42
+ branchName;
43
+ constructor(branchName, cause) {
44
+ super(`Cannot fast-forward branch '${branchName}'`, "FAST_FORWARD_FAILED", cause);
45
+ this.branchName = branchName;
46
+ }
47
+ }
48
+ exports.FastForwardError = FastForwardError;
49
+ class WorktreeError extends SyncWorktreesError {
50
+ constructor(message, code, cause) {
51
+ super(message, `WORKTREE_${code}`, cause);
52
+ }
53
+ }
54
+ exports.WorktreeError = WorktreeError;
55
+ class WorktreeAlreadyExistsError extends WorktreeError {
56
+ path;
57
+ branchName;
58
+ constructor(path, branchName) {
59
+ super(`Worktree already exists at '${path}' for branch '${branchName}'`, "ALREADY_EXISTS");
60
+ this.path = path;
61
+ this.branchName = branchName;
62
+ }
63
+ }
64
+ exports.WorktreeAlreadyExistsError = WorktreeAlreadyExistsError;
65
+ class WorktreeNotCleanError extends WorktreeError {
66
+ path;
67
+ reasons;
68
+ constructor(path, reasons) {
69
+ super(`Worktree at '${path}' is not clean: ${reasons.join(", ")}`, "NOT_CLEAN");
70
+ this.path = path;
71
+ this.reasons = reasons;
72
+ }
73
+ }
74
+ exports.WorktreeNotCleanError = WorktreeNotCleanError;
75
+ class ConfigError extends SyncWorktreesError {
76
+ constructor(message, code, cause) {
77
+ super(message, `CONFIG_${code}`, cause);
78
+ }
79
+ }
80
+ exports.ConfigError = ConfigError;
81
+ class ConfigValidationError extends ConfigError {
82
+ field;
83
+ reason;
84
+ constructor(field, reason) {
85
+ super(`Invalid configuration for '${field}': ${reason}`, "VALIDATION_FAILED");
86
+ this.field = field;
87
+ this.reason = reason;
88
+ }
89
+ }
90
+ exports.ConfigValidationError = ConfigValidationError;
91
+ class PathResolutionError extends SyncWorktreesError {
92
+ path;
93
+ reason;
94
+ constructor(path, reason) {
95
+ super(`Path resolution failed for '${path}': ${reason}`, "PATH_RESOLUTION_FAILED");
96
+ this.path = path;
97
+ this.reason = reason;
98
+ }
99
+ }
100
+ exports.PathResolutionError = PathResolutionError;
101
+ class LfsError extends GitError {
102
+ constructor(message, cause) {
103
+ super(`LFS operation failed: ${message}`, "LFS_ERROR", cause);
104
+ }
105
+ }
106
+ exports.LfsError = LfsError;
107
+ function isLfsError(error) {
108
+ const message = typeof error === "string" ? error : error.message;
109
+ return constants_1.ERROR_MESSAGES.LFS_ERROR.some((pattern) => message.includes(pattern));
110
+ }
111
+ function isFastForwardError(error) {
112
+ const message = typeof error === "string" ? error : error.message;
113
+ return constants_1.ERROR_MESSAGES.FAST_FORWARD_FAILED.some((pattern) => message.includes(pattern));
114
+ }
115
+ function isNoUpstreamError(error) {
116
+ const message = typeof error === "string" ? error : error.message;
117
+ return constants_1.ERROR_MESSAGES.NO_UPSTREAM.some((pattern) => message.includes(pattern));
118
+ }
119
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/errors/index.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"git.service.d.ts","sourceRoot":"","sources":["../../src/services/git.service.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AACvC,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAE5C,qBAAa,UAAU;IAOT,OAAO,CAAC,MAAM;IAN1B,OAAO,CAAC,GAAG,CAA0B;IACrC,OAAO,CAAC,YAAY,CAAS;IAC7B,OAAO,CAAC,gBAAgB,CAAS;IACjC,OAAO,CAAC,aAAa,CAAkB;IACvC,OAAO,CAAC,eAAe,CAA0B;gBAE7B,MAAM,EAAE,MAAM;IAM5B,UAAU,IAAI,OAAO,CAAC,SAAS,CAAC;IA6HtC,MAAM,IAAI,SAAS;IAOnB,gBAAgB,IAAI,MAAM;IAIpB,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IAWzB,WAAW,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAW9C,iBAAiB,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;IAQtC,6BAA6B,IAAI,OAAO,CAAC;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,YAAY,EAAE,IAAI,CAAA;KAAE,EAAE,CAAC;YA8B1E,sBAAsB;IAqB9B,WAAW,CAAC,UAAU,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAyFpE,cAAc,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IA2BnD,cAAc,IAAI,OAAO,CAAC,IAAI,CAAC;IAM/B,mBAAmB,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;YAMnD,cAAc;IAStB,kBAAkB,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAyC1D,eAAe,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IA6CvD,iBAAiB,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAYzD,qBAAqB,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAW7D,sBAAsB,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IA+B9D,gBAAgB,IAAI,OAAO,CAAC,MAAM,CAAC;YAM3B,mBAAmB;IAsCjC,OAAO,CAAC,gBAAgB;IAIlB,YAAY,IAAI,OAAO,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IAK3D,gBAAgB,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAsBxD,cAAc,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IA0BnD,kBAAkB,CAAC,YAAY,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAmBlF,cAAc,CAAC,YAAY,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAmBtE,kBAAkB,CAAC,YAAY,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAe1E,eAAe,CAAC,YAAY,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAgBpE,gBAAgB,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAMvD,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;YAOrC,oBAAoB;CAiCnC"}
1
+ {"version":3,"file":"git.service.d.ts","sourceRoot":"","sources":["../../src/services/git.service.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AACvC,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAE5C,qBAAa,UAAU;IAOT,OAAO,CAAC,MAAM;IAN1B,OAAO,CAAC,GAAG,CAA0B;IACrC,OAAO,CAAC,YAAY,CAAS;IAC7B,OAAO,CAAC,gBAAgB,CAAS;IACjC,OAAO,CAAC,aAAa,CAAkB;IACvC,OAAO,CAAC,eAAe,CAA0B;gBAE7B,MAAM,EAAE,MAAM;IAM5B,UAAU,IAAI,OAAO,CAAC,SAAS,CAAC;IA6HtC,MAAM,IAAI,SAAS;IAOnB,gBAAgB,IAAI,MAAM;IAIpB,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IAWzB,WAAW,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAW9C,iBAAiB,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;IAStC,6BAA6B,IAAI,OAAO,CAAC;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,YAAY,EAAE,IAAI,CAAA;KAAE,EAAE,CAAC;YAkC1E,sBAAsB;IAsB9B,WAAW,CAAC,UAAU,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IA8HpE,cAAc,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAcnD,cAAc,IAAI,OAAO,CAAC,IAAI,CAAC;IAM/B,mBAAmB,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;YAMnD,cAAc;IAStB,kBAAkB,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAyC1D,eAAe,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAkEvD,iBAAiB,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAYzD,qBAAqB,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAW7D,sBAAsB,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IA+B9D,gBAAgB,IAAI,OAAO,CAAC,MAAM,CAAC;YAM3B,mBAAmB;IAsCjC,OAAO,CAAC,gBAAgB;IAIlB,YAAY,IAAI,OAAO,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IAK3D,gBAAgB,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAsBxD,cAAc,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAgCnD,kBAAkB,CAAC,YAAY,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAmBlF,cAAc,CAAC,YAAY,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAmBtE,kBAAkB,CAAC,YAAY,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAe1E,eAAe,CAAC,YAAY,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAsBpE,gBAAgB,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAMvD,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;YAOrC,oBAAoB;CAiCnC"}
@@ -41,6 +41,7 @@ const fs = __importStar(require("fs/promises"));
41
41
  const path = __importStar(require("path"));
42
42
  const simple_git_1 = __importDefault(require("simple-git"));
43
43
  const git_url_1 = require("../utils/git-url");
44
+ const lfs_error_1 = require("../utils/lfs-error");
44
45
  const worktree_metadata_service_1 = require("./worktree-metadata.service");
45
46
  class GitService {
46
47
  config;
@@ -132,7 +133,7 @@ class GitService {
132
133
  }
133
134
  }
134
135
  catch (error) {
135
- const errorMessage = error instanceof Error ? error.message : String(error);
136
+ const errorMessage = (0, lfs_error_1.getErrorMessage)(error);
136
137
  // Check if error is because directory already exists
137
138
  if (errorMessage.includes("already exists")) {
138
139
  console.log(`${this.defaultBranch} worktree directory already exists at '${absoluteWorktreePath}', skipping creation.`);
@@ -144,7 +145,7 @@ class GitService {
144
145
  await bareGit.raw(["worktree", "add", absoluteWorktreePath, this.defaultBranch]);
145
146
  }
146
147
  catch (fallbackError) {
147
- const fallbackErrorMessage = fallbackError instanceof Error ? fallbackError.message : String(fallbackError);
148
+ const fallbackErrorMessage = (0, lfs_error_1.getErrorMessage)(fallbackError);
148
149
  if (fallbackErrorMessage.includes("already exists")) {
149
150
  console.log(`${this.defaultBranch} worktree directory already exists at '${absoluteWorktreePath}', skipping creation.`);
150
151
  }
@@ -202,7 +203,8 @@ class GitService {
202
203
  const branches = await git.branch(["-r"]);
203
204
  return branches.all
204
205
  .filter((b) => b.startsWith("origin/") && !b.endsWith("/HEAD"))
205
- .map((b) => b.replace("origin/", ""));
206
+ .map((b) => b.replace("origin/", ""))
207
+ .filter((b) => b !== "origin" && b.length > 0);
206
208
  }
207
209
  async getRemoteBranchesWithActivity() {
208
210
  const git = this.getGit();
@@ -221,6 +223,10 @@ class GitService {
221
223
  const [ref, dateStr] = line.split("|", 2);
222
224
  if (ref && dateStr && !ref.endsWith("/HEAD")) {
223
225
  const branch = ref.replace("origin/", "");
226
+ // Skip invalid branch names
227
+ if (branch === "origin" || branch.length === 0) {
228
+ continue;
229
+ }
224
230
  const lastActivity = new Date(dateStr);
225
231
  // Skip if the date is invalid
226
232
  if (!isNaN(lastActivity.getTime())) {
@@ -237,10 +243,11 @@ class GitService {
237
243
  : (0, simple_git_1.default)(worktreePath);
238
244
  const currentCommit = await worktreeGit.revparse(["HEAD"]);
239
245
  const parentCommit = await bareGit.revparse([this.defaultBranch]);
240
- await this.metadataService.createInitialMetadata(this.bareRepoPath, branchName, currentCommit.trim(), `origin/${branchName}`, this.defaultBranch, parentCommit.trim());
246
+ await this.metadataService.createInitialMetadataFromPath(this.bareRepoPath, worktreePath, currentCommit.trim(), `origin/${branchName}`, this.defaultBranch, parentCommit.trim());
241
247
  }
242
248
  catch (metadataError) {
243
- console.warn(` - Failed to create metadata for worktree: ${metadataError}`);
249
+ console.error(` - Failed to create metadata for '${branchName}': ${metadataError}`);
250
+ throw new Error(`Metadata creation failed for ${branchName}. This worktree cannot be auto-managed.`);
244
251
  }
245
252
  }
246
253
  async addWorktree(branchName, worktreePath) {
@@ -298,6 +305,42 @@ class GitService {
298
305
  await this.createWorktreeMetadata(bareGit, absoluteWorktreePath, branchName);
299
306
  }
300
307
  catch (error) {
308
+ const errorMessage = (0, lfs_error_1.getErrorMessage)(error);
309
+ // Re-throw metadata creation errors - these are fatal and should not fall back
310
+ if (errorMessage.includes("Metadata creation failed")) {
311
+ throw error;
312
+ }
313
+ // Check if this is an "already registered" error
314
+ if (errorMessage.includes("already registered worktree")) {
315
+ console.warn(` - Worktree already registered but missing. Pruning and retrying...`);
316
+ await bareGit.raw(["worktree", "prune"]);
317
+ // Clean up directory if it exists
318
+ try {
319
+ await fs.rm(absoluteWorktreePath, { recursive: true, force: true });
320
+ }
321
+ catch {
322
+ // Directory might not exist, ignore
323
+ }
324
+ // Retry once after pruning
325
+ try {
326
+ await bareGit.raw([
327
+ "worktree",
328
+ "add",
329
+ "--track",
330
+ "-b",
331
+ branchName,
332
+ absoluteWorktreePath,
333
+ `origin/${branchName}`,
334
+ ]);
335
+ console.log(` - Created worktree for '${branchName}' after pruning`);
336
+ await this.createWorktreeMetadata(bareGit, absoluteWorktreePath, branchName);
337
+ return;
338
+ }
339
+ catch (retryError) {
340
+ console.error(` - Failed to create worktree after pruning: ${retryError}`);
341
+ throw retryError;
342
+ }
343
+ }
301
344
  // If the worktree add fails with tracking, fall back to non-tracking version
302
345
  // This handles edge cases where the remote branch might not exist yet
303
346
  console.warn(` - Failed to create worktree with tracking, falling back to simple add: ${error}`);
@@ -328,27 +371,14 @@ class GitService {
328
371
  }
329
372
  async removeWorktree(worktreePath) {
330
373
  const bareGit = (0, simple_git_1.default)(this.bareRepoPath);
331
- // Try to get branch name before removing worktree
332
- let branchName = null;
333
- try {
334
- const worktrees = await this.getWorktreesFromBare(bareGit);
335
- const worktree = worktrees.find((w) => path.resolve(w.path) === path.resolve(worktreePath));
336
- branchName = worktree?.branch || null;
337
- }
338
- catch {
339
- // If we can't get the branch name, extract from path as fallback
340
- branchName = path.basename(worktreePath);
341
- }
342
374
  await bareGit.raw(["worktree", "remove", worktreePath, "--force"]);
343
375
  console.log(` - ✅ Safely removed stale worktree at '${worktreePath}'.`);
344
- // Clean up metadata
345
- if (branchName) {
346
- try {
347
- await this.metadataService.deleteMetadata(this.bareRepoPath, branchName);
348
- }
349
- catch (metadataError) {
350
- console.warn(`Failed to delete metadata for worktree: ${metadataError}`);
351
- }
376
+ // Clean up metadata using the worktree path
377
+ try {
378
+ await this.metadataService.deleteMetadataFromPath(this.bareRepoPath, worktreePath);
379
+ }
380
+ catch (metadataError) {
381
+ console.warn(`Failed to delete metadata for worktree: ${metadataError}`);
352
382
  }
353
383
  }
354
384
  async pruneWorktrees() {
@@ -383,8 +413,8 @@ class GitService {
383
413
  // Check if upstream is gone
384
414
  const upstreamGone = await this.hasUpstreamGone(worktreePath);
385
415
  if (upstreamGone) {
386
- // Load metadata to check for commits after last sync
387
- const metadata = await this.metadataService.loadMetadata(this.bareRepoPath, currentBranch);
416
+ // Load metadata to check for commits after last sync (use path-based method)
417
+ const metadata = await this.metadataService.loadMetadataFromPath(this.bareRepoPath, worktreePath);
388
418
  if (metadata?.lastSyncCommit) {
389
419
  try {
390
420
  // Check for commits after last sync
@@ -424,22 +454,38 @@ class GitService {
424
454
  return !remoteBranches.all.includes(upstream.trim());
425
455
  }
426
456
  catch (error) {
427
- // Check if the error is because of no upstream configured
428
- const errorMessage = error instanceof Error ? error.message : String(error);
429
- // Match specific Git error messages for missing upstream
457
+ const errorMessage = (0, lfs_error_1.getErrorMessage)(error);
430
458
  if (errorMessage.includes("fatal: no upstream configured") ||
431
- errorMessage.includes("no upstream configured for branch") ||
432
- errorMessage.includes("fatal: ambiguous argument") ||
433
- errorMessage.includes("unknown revision or path")) {
434
- // This is expected when there's no upstream - not an error condition
459
+ errorMessage.includes("no upstream configured for branch")) {
460
+ return false;
461
+ }
462
+ if (errorMessage.includes("fatal: ambiguous argument") || errorMessage.includes("unknown revision or path")) {
463
+ try {
464
+ const branchSummary = await worktreeGit.branch();
465
+ const currentBranch = branchSummary.current;
466
+ const remoteResult = await worktreeGit
467
+ .raw(["config", "--get", `branch.${currentBranch}.remote`])
468
+ .catch(() => "");
469
+ const mergeResult = await worktreeGit
470
+ .raw(["config", "--get", `branch.${currentBranch}.merge`])
471
+ .catch(() => "");
472
+ const remote = remoteResult.trim();
473
+ const merge = mergeResult.trim();
474
+ if (remote && merge) {
475
+ const remoteBranchName = merge.replace("refs/heads/", "");
476
+ const expectedUpstream = `${remote}/${remoteBranchName}`;
477
+ const remoteBranches = await worktreeGit.branch(["-r"]);
478
+ return !remoteBranches.all.includes(expectedUpstream);
479
+ }
480
+ }
481
+ catch {
482
+ // Can't determine config, be conservative
483
+ }
435
484
  return false;
436
485
  }
437
- // Log unexpected errors that don't match known patterns
438
486
  console.error(`Unexpected error checking upstream status for ${worktreePath}. ` +
439
487
  `This might indicate a real issue rather than a missing upstream. ` +
440
488
  `Error: ${errorMessage}`);
441
- // Return false to be safe - we don't want to accidentally delete worktrees
442
- // due to transient errors
443
489
  return false;
444
490
  }
445
491
  }
@@ -582,10 +628,10 @@ class GitService {
582
628
  if (isMainWorktree) {
583
629
  return;
584
630
  }
585
- // Update metadata after successful update
631
+ // Update metadata after successful update (use path-based method)
586
632
  try {
587
633
  const currentCommit = await worktreeGit.revparse(["HEAD"]);
588
- await this.metadataService.updateLastSync(this.bareRepoPath, currentBranch, currentCommit.trim(), "updated");
634
+ await this.metadataService.updateLastSyncFromPath(this.bareRepoPath, worktreePath, currentCommit.trim(), "updated", this.defaultBranch);
589
635
  }
590
636
  catch (metadataError) {
591
637
  console.warn(`Failed to update metadata for worktree: ${metadataError}`);
@@ -644,10 +690,10 @@ class GitService {
644
690
  ? (0, simple_git_1.default)(worktreePath).env({ GIT_LFS_SKIP_SMUDGE: "1" })
645
691
  : (0, simple_git_1.default)(worktreePath);
646
692
  await worktreeGit.reset(["--hard", `origin/${branch}`]);
647
- // Update metadata after reset
693
+ // Update metadata after reset (use path-based method)
648
694
  try {
649
695
  const currentCommit = await worktreeGit.revparse(["HEAD"]);
650
- await this.metadataService.updateLastSync(this.bareRepoPath, branch, currentCommit.trim(), "updated");
696
+ await this.metadataService.updateLastSyncFromPath(this.bareRepoPath, worktreePath, currentCommit.trim(), "updated", this.defaultBranch);
651
697
  }
652
698
  catch (metadataError) {
653
699
  console.warn(`Failed to update metadata after reset: ${metadataError}`);