@gitkraken/core-gitlens 0.16.5 → 0.18.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.
Files changed (71) hide show
  1. package/CHANGELOG.md +35 -1
  2. package/dist/git/cache.d.ts +15 -2
  3. package/dist/git/cache.js +36 -9
  4. package/dist/git/cache.js.map +1 -1
  5. package/dist/git/models/repository.d.ts +4 -2
  6. package/dist/git/models/repository.js +1 -0
  7. package/dist/git/models/repository.js.map +1 -1
  8. package/dist/git/models/worktree.d.ts +5 -1
  9. package/dist/git/models/worktree.js +5 -3
  10. package/dist/git/models/worktree.js.map +1 -1
  11. package/dist/git/providers/provider.d.ts +17 -0
  12. package/dist/git/providers/worktrees.d.ts +17 -2
  13. package/dist/git/run.types.d.ts +7 -0
  14. package/dist/git/service.d.ts +5 -2
  15. package/dist/git/service.js +11 -5
  16. package/dist/git/service.js.map +1 -1
  17. package/dist/git/watching/classifyChange.d.ts +4 -3
  18. package/dist/git/watching/classifyChange.js +7 -4
  19. package/dist/git/watching/classifyChange.js.map +1 -1
  20. package/dist/git/watching/gitIgnoreFilter.d.ts +21 -3
  21. package/dist/git/watching/gitIgnoreFilter.js +74 -14
  22. package/dist/git/watching/gitIgnoreFilter.js.map +1 -1
  23. package/dist/git/watching/provider.d.ts +14 -0
  24. package/dist/git/watching/watchGroup.d.ts +142 -3
  25. package/dist/git/watching/watchGroup.js +424 -19
  26. package/dist/git/watching/watchGroup.js.map +1 -1
  27. package/dist/git/watching/watchService.d.ts +39 -1
  28. package/dist/git/watching/watchService.js +81 -20
  29. package/dist/git/watching/watchService.js.map +1 -1
  30. package/dist/git/watching/watchSession.d.ts +13 -8
  31. package/dist/git/watching/watchSession.js +50 -10
  32. package/dist/git/watching/watchSession.js.map +1 -1
  33. package/dist/git/watching/watcherPatterns.d.ts +14 -0
  34. package/dist/git/watching/watcherPatterns.js +38 -1
  35. package/dist/git/watching/watcherPatterns.js.map +1 -1
  36. package/dist/git/watching/worktreeSummary.d.ts +97 -7
  37. package/dist/git/watching/worktreeSummary.js +454 -27
  38. package/dist/git/watching/worktreeSummary.js.map +1 -1
  39. package/dist/git-cli/cliGitProvider.d.ts +26 -0
  40. package/dist/git-cli/cliGitProvider.js +70 -9
  41. package/dist/git-cli/cliGitProvider.js.map +1 -1
  42. package/dist/git-cli/exec/commandClassifier.d.ts +9 -3
  43. package/dist/git-cli/exec/commandClassifier.js +98 -17
  44. package/dist/git-cli/exec/commandClassifier.js.map +1 -1
  45. package/dist/git-cli/exec/git.d.ts +20 -0
  46. package/dist/git-cli/exec/git.js +69 -7
  47. package/dist/git-cli/exec/git.js.map +1 -1
  48. package/dist/git-cli/exec/headState.d.ts +5 -0
  49. package/dist/git-cli/exec/headState.js +14 -1
  50. package/dist/git-cli/exec/headState.js.map +1 -1
  51. package/dist/git-cli/parsers/worktreeParser.js +2 -2
  52. package/dist/git-cli/parsers/worktreeParser.js.map +1 -1
  53. package/dist/git-cli/providers/branches.js +9 -36
  54. package/dist/git-cli/providers/branches.js.map +1 -1
  55. package/dist/git-cli/providers/config.d.ts +21 -0
  56. package/dist/git-cli/providers/config.js +72 -1
  57. package/dist/git-cli/providers/config.js.map +1 -1
  58. package/dist/git-cli/providers/graph.js +1 -1
  59. package/dist/git-cli/providers/graph.js.map +1 -1
  60. package/dist/git-cli/providers/operations.d.ts +3 -0
  61. package/dist/git-cli/providers/operations.js +14 -5
  62. package/dist/git-cli/providers/operations.js.map +1 -1
  63. package/dist/git-cli/providers/worktrees.d.ts +25 -3
  64. package/dist/git-cli/providers/worktrees.js +125 -32
  65. package/dist/git-cli/providers/worktrees.js.map +1 -1
  66. package/dist/git-cli/service.d.ts +2 -0
  67. package/dist/git-cli/service.js +4 -2
  68. package/dist/git-cli/service.js.map +1 -1
  69. package/dist/plus/integrations/providers/issueSorts.d.ts +0 -1
  70. package/dist/plus/integrations/reads/drains.d.ts +0 -1
  71. 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// Strip off refs/heads/\n\t\t\t\tentry.branch = value.substring(11);\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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"}
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,11 +23,10 @@ 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";
29
- import { isGitBooleanFalse } from "./config.js";
29
+ import { mayConfigDifferByCheckout, parseConfigListing } from "./config.js";
30
30
  //#region ../git-cli/src/providers/branches.ts
31
31
  /** Minimum time between writes to the config for last accessed/modified dates */
32
32
  const dateMetadataStaleThresholdMs = 3e5;
@@ -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
- if (oldest < 0) return false;
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 {
@@ -2830,37 +2834,6 @@ function withDefaultBranch(answer, defaultBranch) {
2830
2834
  defaultBranch
2831
2835
  } : answer;
2832
2836
  }
2833
- /** Splits `git config --null --get-regexp` output into its entries, in order; a key set without a value has none */
2834
- function parseConfigListing(listing) {
2835
- const entries = [];
2836
- for (const entry of listing.split("\0")) {
2837
- if (!entry) continue;
2838
- const separator = entry.indexOf("\n");
2839
- entries.push(separator < 0 ? [entry, void 0] : [entry.substring(0, separator), entry.substring(separator + 1)]);
2840
- }
2841
- return entries;
2842
- }
2843
- /**
2844
- * Whether `listing` shows config that can differ by checkout over time: `extensions.worktreeConfig` (each checkout's
2845
- * `config.worktree`), or a conditional include that is neither `hasconfig:` nor `gitdir:`, since `onbranch:` follows
2846
- * each checkout's HEAD and an unknown condition might follow anything. A `gitdir:` include matching only some
2847
- * checkouts is accepted as shared: it is the common identity setup, and treating it as differing would end sharing for
2848
- * nearly everyone. The cost is a known gap: an edit to a file only those checkouts include goes unseen there, since
2849
- * nothing watches it, until a change the shared listing does see.
2850
- */
2851
- function mayConfigDifferByCheckout(listing) {
2852
- for (const [key, value] of parseConfigListing(listing)) {
2853
- if (key === "extensions.worktreeconfig") {
2854
- if (value == null || !isGitBooleanFalse(value)) return true;
2855
- continue;
2856
- }
2857
- if (!key.startsWith("includeif.")) continue;
2858
- const condition = key.substring(10, key.lastIndexOf("."));
2859
- if (condition.startsWith("hasconfig:") || condition.startsWith("gitdir:") || condition.startsWith("gitdir/i:")) continue;
2860
- return true;
2861
- }
2862
- return false;
2863
- }
2864
2837
  /**
2865
2838
  * Adds the full ref names a `.git/refs` watcher would report for `name`. A short name can't be told tag from local
2866
2839
  * from remote without a spawn, so it adds every form, including the tag git resolves it to first; a spurious one