@gitkraken/core-gitlens 0.16.5 → 0.17.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/CHANGELOG.md +32 -1
- package/dist/git/cache.d.ts +8 -2
- package/dist/git/cache.js +15 -6
- package/dist/git/cache.js.map +1 -1
- package/dist/git/models/repository.d.ts +4 -2
- package/dist/git/models/repository.js +1 -0
- package/dist/git/models/repository.js.map +1 -1
- package/dist/git/models/worktree.d.ts +5 -1
- package/dist/git/models/worktree.js +5 -3
- package/dist/git/models/worktree.js.map +1 -1
- package/dist/git/providers/provider.d.ts +17 -0
- package/dist/git/providers/worktrees.d.ts +17 -2
- package/dist/git/run.types.d.ts +7 -0
- package/dist/git/service.d.ts +5 -2
- package/dist/git/service.js +11 -5
- package/dist/git/service.js.map +1 -1
- package/dist/git/watching/classifyChange.d.ts +4 -3
- package/dist/git/watching/classifyChange.js +7 -4
- package/dist/git/watching/classifyChange.js.map +1 -1
- package/dist/git/watching/provider.d.ts +6 -0
- package/dist/git/watching/watchGroup.d.ts +142 -3
- package/dist/git/watching/watchGroup.js +424 -19
- package/dist/git/watching/watchGroup.js.map +1 -1
- package/dist/git/watching/watchService.d.ts +25 -0
- package/dist/git/watching/watchService.js +27 -7
- package/dist/git/watching/watchService.js.map +1 -1
- package/dist/git/watching/watchSession.d.ts +13 -8
- package/dist/git/watching/watchSession.js +50 -10
- package/dist/git/watching/watchSession.js.map +1 -1
- package/dist/git/watching/watcherPatterns.d.ts +14 -0
- package/dist/git/watching/watcherPatterns.js +38 -1
- package/dist/git/watching/watcherPatterns.js.map +1 -1
- package/dist/git/watching/worktreeSummary.d.ts +64 -2
- package/dist/git/watching/worktreeSummary.js +326 -13
- package/dist/git/watching/worktreeSummary.js.map +1 -1
- package/dist/git-cli/cliGitProvider.d.ts +26 -0
- package/dist/git-cli/cliGitProvider.js +66 -5
- package/dist/git-cli/cliGitProvider.js.map +1 -1
- package/dist/git-cli/exec/commandClassifier.d.ts +9 -3
- package/dist/git-cli/exec/commandClassifier.js +98 -17
- package/dist/git-cli/exec/commandClassifier.js.map +1 -1
- package/dist/git-cli/exec/git.d.ts +20 -0
- package/dist/git-cli/exec/git.js +69 -7
- package/dist/git-cli/exec/git.js.map +1 -1
- package/dist/git-cli/exec/headState.d.ts +5 -0
- package/dist/git-cli/exec/headState.js +14 -1
- package/dist/git-cli/exec/headState.js.map +1 -1
- package/dist/git-cli/parsers/worktreeParser.js +2 -2
- package/dist/git-cli/parsers/worktreeParser.js.map +1 -1
- package/dist/git-cli/providers/branches.js +8 -4
- package/dist/git-cli/providers/branches.js.map +1 -1
- package/dist/git-cli/providers/graph.js +1 -1
- package/dist/git-cli/providers/graph.js.map +1 -1
- package/dist/git-cli/providers/operations.d.ts +3 -0
- package/dist/git-cli/providers/operations.js +14 -5
- package/dist/git-cli/providers/operations.js.map +1 -1
- package/dist/git-cli/providers/worktrees.d.ts +25 -3
- package/dist/git-cli/providers/worktrees.js +125 -32
- package/dist/git-cli/providers/worktrees.js.map +1 -1
- package/dist/git-cli/service.d.ts +2 -0
- package/dist/git-cli/service.js +4 -2
- package/dist/git-cli/service.js.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"headState.js","names":["resolvePath"],"sources":["../../../../git-cli/src/exec/headState.ts"],"sourcesContent":["import { resolve as resolvePath } from 'node:path';\nimport type { Cache } from '@gitlens/git/cache.js';\nimport type { FileSystemProvider } from '@gitlens/git/context.js';\nimport { FileType } from '@gitlens/git/context.js';\nimport type { Uri } from '@gitlens/utils/uri.js';\nimport { fileUri, joinUriPath } from '@gitlens/utils/uri.js';\n\n/**\n * What a worktree's HEAD is on: the full name of its branch (`refs/heads/main`), `'detached'`, or `undefined` when\n * unknown — unreadable, not a branch name git allows, or a HEAD kept as a symlink to its branch\n * (`core.preferSymlinkRefs`). Reading such a HEAD follows the link to the branch's object id, as a detached HEAD\n * reads, so it is unknown when the git dir's listing flags it as a link, and `'detached'` on a host whose listing\n * doesn't.\n */\nexport type HeadState = { readonly branch: string } | 'detached' | undefined;\n\nconst headBranchRegex = /^ref:\\s*(refs\\/heads\\/\\S+)\\s*$/;\nconst headShaRegex = /^(?:[0-9a-f]{40}|[0-9a-f]{64})\\s*$/;\nconst gitFileRegex = /^gitdir:\\s*(.+?)\\s*$/m;\n\n/**\n * Reads `repoPath`'s HEAD from the worktree's own `HEAD` file, without running git: read around a write, it says which\n * branch that write moved, whatever a switch outside core left in the caches. The git dir is the cached one, else the\n * one `<repoPath>/.git` is or points to, so a worktree core never registered is read without spawning git either.\n * A reftable repository's `HEAD` file holds the placeholder `refs/heads/.invalid` (its real HEAD is in the tables),\n * which is no branch name git allows, so it reads as unknown, as does a branch that is a symbolic ref to another (a\n * `master` kept pointing at `main`), since git follows it and a write moves the target. An object id is detached only\n * when the git dir's listing doesn't flag `HEAD` as a symlink (a host's `stat` may follow the link): read as detached,\n * a symlinked HEAD would say a write on its branch moved no branch. Never rejects.\n */\nexport async function readHeadState(repoPath: string, fs: FileSystemProvider, cache: Cache): Promise<HeadState> {\n\ttry {\n\t\tconst cached = cache.gitDir.get(repoPath);\n\t\tconst gitDir =\n\t\t\tcached != null ? { uri: cached.uri, commonUri: cached.commonUri } : await findGitDir(repoPath, fs);\n\t\tif (gitDir == null) return undefined;\n\n\t\tconst decoder = new TextDecoder();\n\t\tconst head = decoder.decode(await fs.readFile(joinUriPath(gitDir.uri, 'HEAD')));\n\t\tif (headShaRegex.test(head)) {\n\t\t\tconst entries = await fs.readDirectory(gitDir.uri);\n\t\t\tconst linked = entries.some(([name, type]) => name === 'HEAD' && (type & FileType.SymbolicLink) !== 0);\n\t\t\treturn linked ? undefined : 'detached';\n\t\t}\n\n\t\tconst ref = headBranchRegex.exec(head)?.[1];\n\t\tif (ref == null || ref.split('/').some(part => part.startsWith('.'))) return undefined;\n\n\t\t// Packed refs can't hold a symbolic ref, so a missing loose file is a plain branch\n\t\tlet target: string | undefined;\n\t\ttry {\n\t\t\ttarget = decoder.decode(await fs.readFile(joinUriPath(gitDir.commonUri ?? gitDir.uri, ref)));\n\t\t} catch {}\n\t\treturn target?.startsWith('ref:') ? undefined : { branch: ref };\n\t} catch {\n\t\treturn undefined;\n\t}\n}\n\n/**\n * The git dir `<repoPath>/.git` is: the folder itself, or the one a linked worktree's `gitdir:` file names, whose\n * `commondir` file names the repository's shared one\n */\nasync function findGitDir(\n\trepoPath: string,\n\tfs: FileSystemProvider,\n): Promise<{ readonly uri: Uri; readonly commonUri: Uri | undefined } | undefined> {\n\tconst dotGit = joinUriPath(fileUri(repoPath), '.git');\n\tconst stat = await fs.stat(dotGit);\n\tif (stat == null) return undefined;\n\tif (stat.type & FileType.Directory) return { uri: dotGit, commonUri: undefined };\n\n\tconst dir = gitFileRegex.exec(new TextDecoder().decode(await fs.readFile(dotGit)))?.[1];\n\tif (dir == null) return undefined;\n\n\tconst gitDir = resolvePath(repoPath, dir);\n\tlet commonDir: string | undefined;\n\ttry {\n\t\tcommonDir = new TextDecoder().decode(await fs.readFile(joinUriPath(fileUri(gitDir), 'commondir'))).trim();\n\t} catch {}\n\treturn { uri: fileUri(gitDir), commonUri: commonDir ? fileUri(resolvePath(gitDir, commonDir)) : undefined };\n}\n\n/**\n * Which branch a write that moves only HEAD's branch moved, from HEAD read before and after it: that branch when HEAD\n * was on the same one both times, `'detached'` (no branch) when it was detached both times, otherwise `undefined` — a\n * hook or an outside switch moved HEAD meanwhile, or a read failed, so the moved branch is unknown.\n */\nexport function getMovedHead(before: HeadState, after: HeadState): HeadState {\n\tif (before == null || after == null) return undefined;\n\tif (before === 'detached') return after === 'detached' ? 'detached' : undefined;\n\tif (after === 'detached') return undefined;\n\n\treturn before.branch === after.branch ? before : undefined;\n}\n"],"mappings":";;;;AAgBA,MAAM,kBAAkB;AACxB,MAAM,eAAe;AACrB,MAAM,eAAe;;;;;;;;;;;AAYrB,eAAsB,cAAc,UAAkB,IAAwB,OAAkC;CAC/G,IAAI;EACH,MAAM,SAAS,MAAM,OAAO,IAAI,QAAQ;EACxC,MAAM,SACL,UAAU,OAAO;GAAE,KAAK,OAAO;GAAK,WAAW,OAAO;EAAU,IAAI,MAAM,WAAW,UAAU,EAAE;EAClG,IAAI,UAAU,MAAM,OAAO,KAAA;EAE3B,MAAM,UAAU,IAAI,YAAY;EAChC,MAAM,OAAO,QAAQ,OAAO,MAAM,GAAG,SAAS,YAAY,OAAO,KAAK,MAAM,CAAC,CAAC;EAC9E,IAAI,aAAa,KAAK,IAAI,GAGzB,QADe,MADO,GAAG,cAAc,OAAO,GAAG,EAAA,CAC1B,MAAM,CAAC,MAAM,UAAU,SAAS,WAAW,OAAO,SAAS,kBAAkB,CACxF,IAAI,KAAA,IAAY;EAG7B,MAAM,MAAM,gBAAgB,KAAK,IAAI,CAAC,GAAG;EACzC,IAAI,OAAO,QAAQ,IAAI,MAAM,GAAG,CAAC,CAAC,MAAK,SAAQ,KAAK,WAAW,GAAG,CAAC,GAAG,OAAO,KAAA;EAG7E,IAAI;EACJ,IAAI;GACH,SAAS,QAAQ,OAAO,MAAM,GAAG,SAAS,YAAY,OAAO,aAAa,OAAO,KAAK,GAAG,CAAC,CAAC;EAC5F,QAAQ,CAAC;EACT,OAAO,QAAQ,WAAW,MAAM,IAAI,KAAA,IAAY,EAAE,QAAQ,IAAI;CAC/D,QAAQ;EACP;CACD;AACD;;;;;AAMA,eAAe,WACd,UACA,IACkF;CAClF,MAAM,SAAS,YAAY,QAAQ,QAAQ,GAAG,MAAM;CACpD,MAAM,OAAO,MAAM,GAAG,KAAK,MAAM;CACjC,IAAI,QAAQ,MAAM,OAAO,KAAA;CACzB,IAAI,KAAK,OAAO,SAAS,WAAW,OAAO;EAAE,KAAK;EAAQ,WAAW,KAAA;CAAU;CAE/E,MAAM,MAAM,aAAa,KAAK,IAAI,YAAY,CAAC,CAAC,OAAO,MAAM,GAAG,SAAS,MAAM,CAAC,CAAC,CAAC,GAAG;CACrF,IAAI,OAAO,MAAM,OAAO,KAAA;CAExB,MAAM,SAASA,QAAY,UAAU,GAAG;CACxC,IAAI;CACJ,IAAI;EACH,YAAY,IAAI,YAAY,CAAC,CAAC,OAAO,MAAM,GAAG,SAAS,YAAY,QAAQ,MAAM,GAAG,WAAW,CAAC,CAAC,CAAC,CAAC,KAAK;CACzG,QAAQ,CAAC;CACT,OAAO;EAAE,KAAK,QAAQ,MAAM;EAAG,WAAW,YAAY,QAAQA,QAAY,QAAQ,SAAS,CAAC,IAAI,KAAA;CAAU;AAC3G;;;;;;AAOA,SAAgB,aAAa,QAAmB,OAA6B;CAC5E,IAAI,UAAU,QAAQ,SAAS,MAAM,OAAO,KAAA;CAC5C,IAAI,WAAW,YAAY,OAAO,UAAU,aAAa,aAAa,KAAA;CACtE,IAAI,UAAU,YAAY,OAAO,KAAA;CAEjC,OAAO,OAAO,WAAW,MAAM,SAAS,SAAS,KAAA;AAClD"}
|
|
1
|
+
{"version":3,"file":"headState.js","names":["resolvePath"],"sources":["../../../../git-cli/src/exec/headState.ts"],"sourcesContent":["import { resolve as resolvePath } from 'node:path';\nimport type { Cache } from '@gitlens/git/cache.js';\nimport type { FileSystemProvider } from '@gitlens/git/context.js';\nimport { FileType } from '@gitlens/git/context.js';\nimport type { Uri } from '@gitlens/utils/uri.js';\nimport { fileUri, joinUriPath } from '@gitlens/utils/uri.js';\n\n/**\n * What a worktree's HEAD is on: the full name of its branch (`refs/heads/main`), `'detached'`, or `undefined` when\n * unknown — unreadable, not a branch name git allows, or a HEAD kept as a symlink to its branch\n * (`core.preferSymlinkRefs`). Reading such a HEAD follows the link to the branch's object id, as a detached HEAD\n * reads, so it is unknown when the git dir's listing flags it as a link, and `'detached'` on a host whose listing\n * doesn't.\n */\nexport type HeadState = { readonly branch: string } | 'detached' | undefined;\n\nconst headBranchRegex = /^ref:\\s*(refs\\/heads\\/\\S+)\\s*$/;\nconst headShaRegex = /^(?:[0-9a-f]{40}|[0-9a-f]{64})\\s*$/;\nconst gitFileRegex = /^gitdir:\\s*(.+?)\\s*$/m;\n\n/**\n * Reads `repoPath`'s HEAD from the worktree's own `HEAD` file, without running git: read around a write, it says which\n * branch that write moved, whatever a switch outside core left in the caches. The git dir is the cached one, else the\n * one `<repoPath>/.git` is or points to, so a worktree core never registered is read without spawning git either.\n * A reftable repository's `HEAD` file holds the placeholder `refs/heads/.invalid` (its real HEAD is in the tables),\n * which is no branch name git allows, so it reads as unknown, as does a branch that is a symbolic ref to another (a\n * `master` kept pointing at `main`), since git follows it and a write moves the target. An object id is detached only\n * when the git dir's listing doesn't flag `HEAD` as a symlink (a host's `stat` may follow the link): read as detached,\n * a symlinked HEAD would say a write on its branch moved no branch. Never rejects.\n */\nexport async function readHeadState(repoPath: string, fs: FileSystemProvider, cache: Cache): Promise<HeadState> {\n\ttry {\n\t\tconst cached = cache.gitDir.get(repoPath);\n\t\tconst gitDir =\n\t\t\tcached != null ? { uri: cached.uri, commonUri: cached.commonUri } : await findGitDir(repoPath, fs);\n\t\tif (gitDir == null) return undefined;\n\n\t\tconst decoder = new TextDecoder();\n\t\tconst head = decoder.decode(await fs.readFile(joinUriPath(gitDir.uri, 'HEAD')));\n\t\tif (headShaRegex.test(head)) {\n\t\t\tconst entries = await fs.readDirectory(gitDir.uri);\n\t\t\tconst linked = entries.some(([name, type]) => name === 'HEAD' && (type & FileType.SymbolicLink) !== 0);\n\t\t\treturn linked ? undefined : 'detached';\n\t\t}\n\n\t\tconst ref = headBranchRegex.exec(head)?.[1];\n\t\tif (ref == null || ref.split('/').some(part => part.startsWith('.'))) return undefined;\n\n\t\t// Packed refs can't hold a symbolic ref, so a missing loose file is a plain branch\n\t\tlet target: string | undefined;\n\t\ttry {\n\t\t\ttarget = decoder.decode(await fs.readFile(joinUriPath(gitDir.commonUri ?? gitDir.uri, ref)));\n\t\t} catch {}\n\t\treturn target?.startsWith('ref:') ? undefined : { branch: ref };\n\t} catch {\n\t\treturn undefined;\n\t}\n}\n\n/**\n * The path of `repoPath`'s common git dir, without running git: the cached one, else the folder `<repoPath>/.git` is,\n * or the shared one a linked worktree's `gitdir:` file leads to. `undefined` when it can't be read. Never rejects.\n */\nexport async function readCommonGitDir(\n\trepoPath: string,\n\tfs: FileSystemProvider,\n\tcache: Cache,\n): Promise<string | undefined> {\n\ttry {\n\t\tconst gitDir = cache.gitDir.get(repoPath) ?? (await findGitDir(repoPath, fs));\n\t\tif (gitDir == null) return undefined;\n\n\t\treturn (gitDir.commonUri ?? gitDir.uri).fsPath;\n\t} catch {\n\t\treturn undefined;\n\t}\n}\n\n/**\n * The git dir `<repoPath>/.git` is: the folder itself, or the one a linked worktree's `gitdir:` file names, whose\n * `commondir` file names the repository's shared one\n */\nasync function findGitDir(\n\trepoPath: string,\n\tfs: FileSystemProvider,\n): Promise<{ readonly uri: Uri; readonly commonUri: Uri | undefined } | undefined> {\n\tconst dotGit = joinUriPath(fileUri(repoPath), '.git');\n\tconst stat = await fs.stat(dotGit);\n\tif (stat == null) return undefined;\n\tif (stat.type & FileType.Directory) return { uri: dotGit, commonUri: undefined };\n\n\tconst dir = gitFileRegex.exec(new TextDecoder().decode(await fs.readFile(dotGit)))?.[1];\n\tif (dir == null) return undefined;\n\n\tconst gitDir = resolvePath(repoPath, dir);\n\tlet commonDir: string | undefined;\n\ttry {\n\t\tcommonDir = new TextDecoder().decode(await fs.readFile(joinUriPath(fileUri(gitDir), 'commondir'))).trim();\n\t} catch {}\n\treturn { uri: fileUri(gitDir), commonUri: commonDir ? fileUri(resolvePath(gitDir, commonDir)) : undefined };\n}\n\n/**\n * Which branch a write that moves only HEAD's branch moved, from HEAD read before and after it: that branch when HEAD\n * was on the same one both times, `'detached'` (no branch) when it was detached both times, otherwise `undefined` — a\n * hook or an outside switch moved HEAD meanwhile, or a read failed, so the moved branch is unknown.\n */\nexport function getMovedHead(before: HeadState, after: HeadState): HeadState {\n\tif (before == null || after == null) return undefined;\n\tif (before === 'detached') return after === 'detached' ? 'detached' : undefined;\n\tif (after === 'detached') return undefined;\n\n\treturn before.branch === after.branch ? before : undefined;\n}\n"],"mappings":";;;;AAgBA,MAAM,kBAAkB;AACxB,MAAM,eAAe;AACrB,MAAM,eAAe;;;;;;;;;;;AAYrB,eAAsB,cAAc,UAAkB,IAAwB,OAAkC;CAC/G,IAAI;EACH,MAAM,SAAS,MAAM,OAAO,IAAI,QAAQ;EACxC,MAAM,SACL,UAAU,OAAO;GAAE,KAAK,OAAO;GAAK,WAAW,OAAO;EAAU,IAAI,MAAM,WAAW,UAAU,EAAE;EAClG,IAAI,UAAU,MAAM,OAAO,KAAA;EAE3B,MAAM,UAAU,IAAI,YAAY;EAChC,MAAM,OAAO,QAAQ,OAAO,MAAM,GAAG,SAAS,YAAY,OAAO,KAAK,MAAM,CAAC,CAAC;EAC9E,IAAI,aAAa,KAAK,IAAI,GAGzB,QADe,MADO,GAAG,cAAc,OAAO,GAAG,EAAA,CAC1B,MAAM,CAAC,MAAM,UAAU,SAAS,WAAW,OAAO,SAAS,kBAAkB,CACxF,IAAI,KAAA,IAAY;EAG7B,MAAM,MAAM,gBAAgB,KAAK,IAAI,CAAC,GAAG;EACzC,IAAI,OAAO,QAAQ,IAAI,MAAM,GAAG,CAAC,CAAC,MAAK,SAAQ,KAAK,WAAW,GAAG,CAAC,GAAG,OAAO,KAAA;EAG7E,IAAI;EACJ,IAAI;GACH,SAAS,QAAQ,OAAO,MAAM,GAAG,SAAS,YAAY,OAAO,aAAa,OAAO,KAAK,GAAG,CAAC,CAAC;EAC5F,QAAQ,CAAC;EACT,OAAO,QAAQ,WAAW,MAAM,IAAI,KAAA,IAAY,EAAE,QAAQ,IAAI;CAC/D,QAAQ;EACP;CACD;AACD;;;;;AAMA,eAAsB,iBACrB,UACA,IACA,OAC8B;CAC9B,IAAI;EACH,MAAM,SAAS,MAAM,OAAO,IAAI,QAAQ,KAAM,MAAM,WAAW,UAAU,EAAE;EAC3E,IAAI,UAAU,MAAM,OAAO,KAAA;EAE3B,QAAQ,OAAO,aAAa,OAAO,IAAA,CAAK;CACzC,QAAQ;EACP;CACD;AACD;;;;;AAMA,eAAe,WACd,UACA,IACkF;CAClF,MAAM,SAAS,YAAY,QAAQ,QAAQ,GAAG,MAAM;CACpD,MAAM,OAAO,MAAM,GAAG,KAAK,MAAM;CACjC,IAAI,QAAQ,MAAM,OAAO,KAAA;CACzB,IAAI,KAAK,OAAO,SAAS,WAAW,OAAO;EAAE,KAAK;EAAQ,WAAW,KAAA;CAAU;CAE/E,MAAM,MAAM,aAAa,KAAK,IAAI,YAAY,CAAC,CAAC,OAAO,MAAM,GAAG,SAAS,MAAM,CAAC,CAAC,CAAC,GAAG;CACrF,IAAI,OAAO,MAAM,OAAO,KAAA;CAExB,MAAM,SAASA,QAAY,UAAU,GAAG;CACxC,IAAI;CACJ,IAAI;EACH,YAAY,IAAI,YAAY,CAAC,CAAC,OAAO,MAAM,GAAG,SAAS,YAAY,QAAQ,MAAM,GAAG,WAAW,CAAC,CAAC,CAAC,CAAC,KAAK;CACzG,QAAQ,CAAC;CACT,OAAO;EAAE,KAAK,QAAQ,MAAM;EAAG,WAAW,YAAY,QAAQA,QAAY,QAAQ,SAAS,CAAC,IAAI,KAAA;CAAU;AAC3G;;;;;;AAOA,SAAgB,aAAa,QAAmB,OAA6B;CAC5E,IAAI,UAAU,QAAQ,SAAS,MAAM,OAAO,KAAA;CAC5C,IAAI,WAAW,YAAY,OAAO,UAAU,aAAa,aAAa,KAAA;CACtE,IAAI,UAAU,YAAY,OAAO,KAAA;CAEjC,OAAO,OAAO,WAAW,MAAM,SAAS,SAAS,KAAA;AAClD"}
|
|
@@ -36,7 +36,7 @@ function parseGitWorktrees(data, repoPath, branches, getWorkspaceFolder) {
|
|
|
36
36
|
if (!key && entry != null) {
|
|
37
37
|
const branch = entry.branch ? branches?.find((b) => b.name === entry.branch) : void 0;
|
|
38
38
|
const uri = fileUri(entry.path);
|
|
39
|
-
worktrees.push(new GitWorktree(main, entry.bare ? "bare" : entry.detached ? "detached" : "branch", repoPath, uri, entry.locked ?? false, entry.prunable ?? false, entry.sha, branch, getWorkspaceFolder?.(uri)));
|
|
39
|
+
worktrees.push(new GitWorktree(main, entry.bare ? "bare" : entry.detached ? "detached" : "branch", repoPath, uri, entry.locked ?? false, entry.prunable ?? false, entry.sha, branch, getWorkspaceFolder?.(uri), entry.branch));
|
|
40
40
|
entry = void 0;
|
|
41
41
|
main = false;
|
|
42
42
|
continue;
|
|
@@ -53,7 +53,7 @@ function parseGitWorktrees(data, repoPath, branches, getWorkspaceFolder) {
|
|
|
53
53
|
entry.sha = value;
|
|
54
54
|
break;
|
|
55
55
|
case "branch":
|
|
56
|
-
entry.branch = value.substring(11);
|
|
56
|
+
if (value.startsWith("refs/heads/")) entry.branch = value.substring(11);
|
|
57
57
|
break;
|
|
58
58
|
case "detached":
|
|
59
59
|
entry.detached = true;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"worktreeParser.js","names":[],"sources":["../../../../git-cli/src/parsers/worktreeParser.ts"],"sourcesContent":["import type { GitBranch } from '@gitlens/git/models/branch.js';\nimport type { WorkspaceFolderResolver } from '@gitlens/git/models/worktree.js';\nimport { GitWorktree } from '@gitlens/git/models/worktree.js';\nimport { normalizePath } from '@gitlens/utils/path.js';\nimport { maybeStopWatch } from '@gitlens/utils/stopwatch.js';\nimport { iterateByDelimiter } from '@gitlens/utils/string.js';\nimport { fileUri } from '@gitlens/utils/uri.js';\n\ninterface WorktreeEntry {\n\tpath: string;\n\tsha?: string;\n\tbranch?: string;\n\tbare: boolean;\n\tdetached: boolean;\n\tlocked?: boolean | string;\n\tprunable?: boolean | string;\n}\n\nexport function parseGitWorktrees(\n\tdata: string | undefined,\n\trepoPath: string,\n\tbranches: GitBranch[],\n\tgetWorkspaceFolder?: WorkspaceFolderResolver,\n): GitWorktree[] {\n\tusing sw = maybeStopWatch(`Git.parseWorktrees(${repoPath})`, { log: { onlyExit: true, level: 'debug' } });\n\n\tconst worktrees: GitWorktree[] = [];\n\tif (!data) {\n\t\tsw?.stop({ suffix: ` no data` });\n\t\treturn worktrees;\n\t}\n\n\tif (repoPath != null) {\n\t\trepoPath = normalizePath(repoPath);\n\t}\n\n\tlet entry: Partial<WorktreeEntry> | undefined = undefined;\n\tlet line: string;\n\tlet index: number;\n\tlet key: string;\n\tlet value: string;\n\tlet main = true; // the first worktree is the main worktree\n\n\tfor (line of iterateByDelimiter(data, '\\n')) {\n\t\tindex = line.indexOf(' ');\n\t\tif (index === -1) {\n\t\t\tkey = line;\n\t\t\tvalue = '';\n\t\t} else {\n\t\t\tkey = line.substring(0, index);\n\t\t\tvalue = line.substring(index + 1);\n\t\t}\n\n\t\tif (!key && entry != null) {\n\t\t\t// oxlint-disable-next-line no-loop-func\n\t\t\tconst branch = entry.branch ? branches?.find(b => b.name === entry!.branch) : undefined;\n\t\t\tconst uri = fileUri(entry.path!);\n\n\t\t\tworktrees.push(\n\t\t\t\tnew GitWorktree(\n\t\t\t\t\tmain,\n\t\t\t\t\tentry.bare ? 'bare' : entry.detached ? 'detached' : 'branch',\n\t\t\t\t\trepoPath,\n\t\t\t\t\turi,\n\t\t\t\t\tentry.locked ?? false,\n\t\t\t\t\tentry.prunable ?? false,\n\t\t\t\t\tentry.sha,\n\t\t\t\t\tbranch,\n\t\t\t\t\tgetWorkspaceFolder?.(uri),\n\t\t\t\t),\n\t\t\t);\n\n\t\t\tentry = undefined;\n\t\t\tmain = false;\n\t\t\tcontinue;\n\t\t}\n\n\t\tentry ??= {};\n\n\t\tswitch (key) {\n\t\t\tcase 'worktree':\n\t\t\t\tentry.path = value;\n\t\t\t\tbreak;\n\t\t\tcase 'bare':\n\t\t\t\tentry.bare = true;\n\t\t\t\tbreak;\n\t\t\tcase 'HEAD':\n\t\t\t\tentry.sha = value;\n\t\t\t\tbreak;\n\t\t\tcase 'branch':\n\t\t\t\t//
|
|
1
|
+
{"version":3,"file":"worktreeParser.js","names":[],"sources":["../../../../git-cli/src/parsers/worktreeParser.ts"],"sourcesContent":["import type { GitBranch } from '@gitlens/git/models/branch.js';\nimport type { WorkspaceFolderResolver } from '@gitlens/git/models/worktree.js';\nimport { GitWorktree } from '@gitlens/git/models/worktree.js';\nimport { normalizePath } from '@gitlens/utils/path.js';\nimport { maybeStopWatch } from '@gitlens/utils/stopwatch.js';\nimport { iterateByDelimiter } from '@gitlens/utils/string.js';\nimport { fileUri } from '@gitlens/utils/uri.js';\n\ninterface WorktreeEntry {\n\tpath: string;\n\tsha?: string;\n\tbranch?: string;\n\tbare: boolean;\n\tdetached: boolean;\n\tlocked?: boolean | string;\n\tprunable?: boolean | string;\n}\n\nexport function parseGitWorktrees(\n\tdata: string | undefined,\n\trepoPath: string,\n\tbranches: GitBranch[],\n\tgetWorkspaceFolder?: WorkspaceFolderResolver,\n): GitWorktree[] {\n\tusing sw = maybeStopWatch(`Git.parseWorktrees(${repoPath})`, { log: { onlyExit: true, level: 'debug' } });\n\n\tconst worktrees: GitWorktree[] = [];\n\tif (!data) {\n\t\tsw?.stop({ suffix: ` no data` });\n\t\treturn worktrees;\n\t}\n\n\tif (repoPath != null) {\n\t\trepoPath = normalizePath(repoPath);\n\t}\n\n\tlet entry: Partial<WorktreeEntry> | undefined = undefined;\n\tlet line: string;\n\tlet index: number;\n\tlet key: string;\n\tlet value: string;\n\tlet main = true; // the first worktree is the main worktree\n\n\tfor (line of iterateByDelimiter(data, '\\n')) {\n\t\tindex = line.indexOf(' ');\n\t\tif (index === -1) {\n\t\t\tkey = line;\n\t\t\tvalue = '';\n\t\t} else {\n\t\t\tkey = line.substring(0, index);\n\t\t\tvalue = line.substring(index + 1);\n\t\t}\n\n\t\tif (!key && entry != null) {\n\t\t\t// oxlint-disable-next-line no-loop-func\n\t\t\tconst branch = entry.branch ? branches?.find(b => b.name === entry!.branch) : undefined;\n\t\t\tconst uri = fileUri(entry.path!);\n\n\t\t\tworktrees.push(\n\t\t\t\tnew GitWorktree(\n\t\t\t\t\tmain,\n\t\t\t\t\tentry.bare ? 'bare' : entry.detached ? 'detached' : 'branch',\n\t\t\t\t\trepoPath,\n\t\t\t\t\turi,\n\t\t\t\t\tentry.locked ?? false,\n\t\t\t\t\tentry.prunable ?? false,\n\t\t\t\t\tentry.sha,\n\t\t\t\t\tbranch,\n\t\t\t\t\tgetWorkspaceFolder?.(uri),\n\t\t\t\t\tentry.branch,\n\t\t\t\t),\n\t\t\t);\n\n\t\t\tentry = undefined;\n\t\t\tmain = false;\n\t\t\tcontinue;\n\t\t}\n\n\t\tentry ??= {};\n\n\t\tswitch (key) {\n\t\t\tcase 'worktree':\n\t\t\t\tentry.path = value;\n\t\t\t\tbreak;\n\t\t\tcase 'bare':\n\t\t\t\tentry.bare = true;\n\t\t\t\tbreak;\n\t\t\tcase 'HEAD':\n\t\t\t\tentry.sha = value;\n\t\t\t\tbreak;\n\t\t\tcase 'branch':\n\t\t\t\t// A HEAD pointing outside `refs/heads/` names no branch\n\t\t\t\tif (value.startsWith('refs/heads/')) {\n\t\t\t\t\tentry.branch = value.substring(11);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase 'detached':\n\t\t\t\tentry.detached = true;\n\t\t\t\tbreak;\n\t\t\t// `value` is the whole reason, which is only present when the locker/Git provides one (Git < 2.31\n\t\t\t// prints a bare `locked` regardless). Without `-z`, a reason with unusual characters (e.g. newlines)\n\t\t\t// comes through C-quoted, with UTF-8 bytes as octal escapes unless `core.quotePath` is off (as core runs it)\n\t\t\tcase 'locked':\n\t\t\t\tentry.locked = unquoteCString(value.trim()) || true;\n\t\t\t\tbreak;\n\t\t\tcase 'prunable':\n\t\t\t\tentry.prunable = unquoteCString(value.trim()) || true;\n\t\t\t\tbreak;\n\t\t}\n\t}\n\n\tsw?.stop({ suffix: ` parsed ${worktrees.length} worktrees` });\n\n\treturn worktrees;\n}\n\nconst cEscapes: Record<string, number> = { a: 7, b: 8, f: 12, n: 10, r: 13, t: 9, v: 11, '\\\\': 92, '\"': 34 };\n\n/** Reverses Git's C-style quoting (`\"a\\nb\"`, `\\303\\251` octal UTF-8 bytes); returns unquoted values as-is */\nfunction unquoteCString(value: string): string {\n\tif (!value.startsWith('\"')) return value;\n\n\tconst end = value.length > 1 && value.endsWith('\"') ? value.length - 1 : value.length;\n\tconst encoder = new TextEncoder();\n\tconst bytes: number[] = [];\n\n\tlet i = 1;\n\twhile (i < end) {\n\t\tconst ch = value[i];\n\t\tif (ch !== '\\\\' || i + 1 >= end) {\n\t\t\t// A whole code point, so surrogate pairs encode correctly\n\t\t\tconst cp = String.fromCodePoint(value.codePointAt(i)!);\n\t\t\tbytes.push(...encoder.encode(cp));\n\t\t\ti += cp.length;\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst next = value[i + 1];\n\t\tif (next >= '0' && next <= '7') {\n\t\t\tlet j = i + 1;\n\t\t\twhile (j < i + 4 && j < end && value[j] >= '0' && value[j] <= '7') {\n\t\t\t\tj++;\n\t\t\t}\n\t\t\tbytes.push(Number.parseInt(value.substring(i + 1, j), 8) & 0xff);\n\t\t\ti = j;\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst code = cEscapes[next];\n\t\tif (code != null) {\n\t\t\tbytes.push(code);\n\t\t} else {\n\t\t\tbytes.push(...encoder.encode(next));\n\t\t}\n\t\ti += 2;\n\t}\n\n\treturn new TextDecoder().decode(new Uint8Array(bytes));\n}\n"],"mappings":"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"}
|
|
@@ -13,6 +13,7 @@ import { formatDetachedHeadName, getLocalBranchByUpstream, isDetachedHead, isRem
|
|
|
13
13
|
import { createReference } from "../../git/utils/reference.utils.js";
|
|
14
14
|
import __decorate from "../../_virtual/@oxc-project+runtime/helpers/esm/decorate.js";
|
|
15
15
|
import { BranchError, GitWarnings } from "../../git/errors.js";
|
|
16
|
+
import { LruMap } from "../../utils/lruMap.js";
|
|
16
17
|
import { mayWriteTracking } from "../exec/commandClassifier.js";
|
|
17
18
|
import { readHeadState } from "../exec/headState.js";
|
|
18
19
|
import { KeyedSequencer } from "../exec/indexLock.js";
|
|
@@ -22,7 +23,6 @@ import _usingCtx from "../../_virtual/@oxc-project+runtime/helpers/esm/usingCtx.
|
|
|
22
23
|
import { GitBranch } from "../../git/models/branch.js";
|
|
23
24
|
import { createConflictDetectionError } from "../../git/utils/mergeConflicts.utils.js";
|
|
24
25
|
import { sortBranches, sortContributors } from "../../git/utils/sorting.js";
|
|
25
|
-
import { LruMap } from "../../utils/lruMap.js";
|
|
26
26
|
import { PageableResult, emptyPagedResult } from "../../utils/paging.js";
|
|
27
27
|
import { parseMergeTreeConflict } from "../parsers/mergeTreeParser.js";
|
|
28
28
|
import { resolveBranchRemote } from "./branchRemote.js";
|
|
@@ -1476,9 +1476,12 @@ var BranchesGitSubProvider = class {
|
|
|
1476
1476
|
if (entries.length) {
|
|
1477
1477
|
if (entries[0].sha !== newTip) return false;
|
|
1478
1478
|
const oldest = entries.findLastIndex((e) => e.sha === oldTip);
|
|
1479
|
-
|
|
1480
|
-
since = new Set(entries.slice(1, oldest + 1).map((e) => e.sha));
|
|
1479
|
+
since = new Set(entries.slice(1, oldest < 0 ? void 0 : oldest + 1).map((e) => e.sha));
|
|
1481
1480
|
logged = new Set(entries.map((e) => e.sha));
|
|
1481
|
+
if (oldest < 0) {
|
|
1482
|
+
since.add(oldTip);
|
|
1483
|
+
logged.add(oldTip);
|
|
1484
|
+
}
|
|
1482
1485
|
const before = await this.git.run({
|
|
1483
1486
|
cwd: commonPath,
|
|
1484
1487
|
errors: "ignore"
|
|
@@ -1487,9 +1490,10 @@ var BranchesGitSubProvider = class {
|
|
|
1487
1490
|
if (before.exitCode === 0) {
|
|
1488
1491
|
const sha = before.stdout.trim();
|
|
1489
1492
|
if (!sha) return void 0;
|
|
1493
|
+
if (oldest < 0 && sha !== oldTip) return false;
|
|
1490
1494
|
logged.add(sha);
|
|
1491
1495
|
} else if (!before.stderr?.includes(" only has ")) return;
|
|
1492
|
-
else if (!await this.git.supports("git:rev-parse:reflog-oldest-old-value")) return false;
|
|
1496
|
+
else if (oldest < 0 || !await this.git.supports("git:rev-parse:reflog-oldest-old-value")) return false;
|
|
1493
1497
|
logged.delete(newTip);
|
|
1494
1498
|
}
|
|
1495
1499
|
} catch {
|