@gitkraken/core-gitlens 0.1.0 → 0.3.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 +25 -1
- package/dist/git/cache.d.ts +49 -9
- package/dist/git/cache.d.ts.map +1 -1
- package/dist/git/cache.js +174 -14
- package/dist/git/cache.js.map +1 -1
- package/dist/git/context.d.ts +11 -2
- package/dist/git/context.d.ts.map +1 -1
- package/dist/git/context.js.map +1 -1
- package/dist/git/models/branch.d.ts +1 -0
- package/dist/git/models/branch.d.ts.map +1 -1
- package/dist/git/models/branch.js.map +1 -1
- package/dist/git/models/commit.d.ts +1 -9
- package/dist/git/models/commit.d.ts.map +1 -1
- package/dist/git/models/commit.js +4 -9
- package/dist/git/models/commit.js.map +1 -1
- package/dist/git/models/graph.d.ts +2 -4
- package/dist/git/models/graph.d.ts.map +1 -1
- package/dist/git/models/reference.d.ts +31 -0
- package/dist/git/models/reference.d.ts.map +1 -1
- package/dist/git/models/remote.d.ts.map +1 -1
- package/dist/git/models/remote.js.map +1 -1
- package/dist/git/models/repository.d.ts +20 -3
- package/dist/git/models/repository.d.ts.map +1 -1
- package/dist/git/models/repository.js +42 -5
- package/dist/git/models/repository.js.map +1 -1
- package/dist/git/models/search.d.ts +2 -2
- package/dist/git/models/search.d.ts.map +1 -1
- package/dist/git/models/worktree.d.ts +4 -1
- package/dist/git/models/worktree.d.ts.map +1 -1
- package/dist/git/models/worktree.js +2 -2
- package/dist/git/models/worktree.js.map +1 -1
- package/dist/git/parsers/diffParser.d.ts +0 -1
- package/dist/git/parsers/diffParser.d.ts.map +1 -1
- package/dist/git/parsers/diffParser.js +22 -61
- package/dist/git/parsers/diffParser.js.map +1 -1
- package/dist/git/providers/branches.d.ts +18 -4
- package/dist/git/providers/branches.d.ts.map +1 -1
- package/dist/git/providers/commits.d.ts +6 -0
- package/dist/git/providers/commits.d.ts.map +1 -1
- package/dist/git/providers/config.d.ts +6 -1
- package/dist/git/providers/config.d.ts.map +1 -1
- package/dist/git/providers/diff.d.ts +2 -0
- package/dist/git/providers/diff.d.ts.map +1 -1
- package/dist/git/providers/operations.d.ts +39 -10
- package/dist/git/providers/operations.d.ts.map +1 -1
- package/dist/git/providers/pausedOperations.d.ts +3 -1
- package/dist/git/providers/pausedOperations.d.ts.map +1 -1
- package/dist/git/providers/refs.d.ts +23 -2
- package/dist/git/providers/refs.d.ts.map +1 -1
- package/dist/git/providers/revision.d.ts +1 -1
- package/dist/git/providers/revision.d.ts.map +1 -1
- package/dist/git/providers/staging.d.ts +18 -0
- package/dist/git/providers/staging.d.ts.map +1 -1
- package/dist/git/providers/status.d.ts +4 -1
- package/dist/git/providers/status.d.ts.map +1 -1
- package/dist/git/remotes/azure-devops.d.ts.map +1 -1
- package/dist/git/remotes/azure-devops.js.map +1 -1
- package/dist/git/{exec.types.d.ts → run.types.d.ts} +22 -3
- package/dist/git/run.types.d.ts.map +1 -0
- package/dist/git/run.types.js +2 -0
- package/dist/git/run.types.js.map +1 -0
- package/dist/git/service.d.ts.map +1 -1
- package/dist/git/service.js.map +1 -1
- package/dist/git/utils/autolink.utils.d.ts.map +1 -1
- package/dist/git/utils/autolink.utils.js.map +1 -1
- package/dist/git/utils/blame.utils.d.ts.map +1 -1
- package/dist/git/utils/blame.utils.js.map +1 -1
- package/dist/git/utils/conflictResolution.utils.d.ts +6 -0
- package/dist/git/utils/conflictResolution.utils.d.ts.map +1 -0
- package/dist/git/utils/conflictResolution.utils.js +25 -0
- package/dist/git/utils/conflictResolution.utils.js.map +1 -0
- package/dist/git/utils/fileStatus.utils.d.ts +2 -1
- package/dist/git/utils/fileStatus.utils.d.ts.map +1 -1
- package/dist/git/utils/fileStatus.utils.js +4 -0
- package/dist/git/utils/fileStatus.utils.js.map +1 -1
- package/dist/git/utils/search.utils.d.ts.map +1 -1
- package/dist/git/utils/search.utils.js +3 -0
- package/dist/git/utils/search.utils.js.map +1 -1
- package/dist/git/utils/sorting.d.ts +14 -0
- package/dist/git/utils/sorting.d.ts.map +1 -1
- package/dist/git/utils/sorting.js +34 -0
- package/dist/git/utils/sorting.js.map +1 -1
- package/dist/git/utils/status.utils.d.ts.map +1 -1
- package/dist/git/utils/status.utils.js.map +1 -1
- package/dist/git/watching/classifyChange.d.ts.map +1 -1
- package/dist/git/watching/classifyChange.js +8 -0
- package/dist/git/watching/classifyChange.js.map +1 -1
- package/dist/git/watching/gitIgnoreFilter.js +1 -1
- package/dist/git/watching/gitIgnoreFilter.js.map +1 -1
- package/dist/git/watching/initWatcher.d.ts.map +1 -1
- package/dist/git/watching/initWatcher.js.map +1 -1
- package/dist/git/watching/watchGroup.d.ts.map +1 -1
- package/dist/git/watching/watchGroup.js.map +1 -1
- package/dist/git/watching/watchService.d.ts.map +1 -1
- package/dist/git/watching/watchService.js +24 -4
- package/dist/git/watching/watchService.js.map +1 -1
- package/dist/git/watching/watchSession.d.ts.map +1 -1
- package/dist/git/watching/watchSession.js.map +1 -1
- package/dist/git-cli/cliGitProvider.js +1 -1
- package/dist/git-cli/cliGitProvider.js.map +1 -1
- package/dist/git-cli/exec/exec.types.d.ts +1 -1
- package/dist/git-cli/exec/exec.types.d.ts.map +1 -1
- package/dist/git-cli/exec/git.d.ts +31 -6
- package/dist/git-cli/exec/git.d.ts.map +1 -1
- package/dist/git-cli/exec/git.js +70 -9
- package/dist/git-cli/exec/git.js.map +1 -1
- package/dist/git-cli/exec/gitQueue.d.ts +22 -6
- package/dist/git-cli/exec/gitQueue.d.ts.map +1 -1
- package/dist/git-cli/exec/gitQueue.js +88 -24
- package/dist/git-cli/exec/gitQueue.js.map +1 -1
- package/dist/git-cli/parsers/blameParser.d.ts.map +1 -1
- package/dist/git-cli/parsers/blameParser.js.map +1 -1
- package/dist/git-cli/parsers/logParser.d.ts +1 -0
- package/dist/git-cli/parsers/logParser.d.ts.map +1 -1
- package/dist/git-cli/parsers/logParser.js +4 -0
- package/dist/git-cli/parsers/logParser.js.map +1 -1
- package/dist/git-cli/parsers/refParser.d.ts +3 -30
- package/dist/git-cli/parsers/refParser.d.ts.map +1 -1
- package/dist/git-cli/parsers/refParser.js +30 -30
- package/dist/git-cli/parsers/refParser.js.map +1 -1
- package/dist/git-cli/providers/blame.d.ts.map +1 -1
- package/dist/git-cli/providers/blame.js +1 -1
- package/dist/git-cli/providers/blame.js.map +1 -1
- package/dist/git-cli/providers/branches.d.ts +17 -5
- package/dist/git-cli/providers/branches.d.ts.map +1 -1
- package/dist/git-cli/providers/branches.js +245 -162
- package/dist/git-cli/providers/branches.js.map +1 -1
- package/dist/git-cli/providers/commits.d.ts +4 -0
- package/dist/git-cli/providers/commits.d.ts.map +1 -1
- package/dist/git-cli/providers/commits.js +120 -35
- package/dist/git-cli/providers/commits.js.map +1 -1
- package/dist/git-cli/providers/config.d.ts +11 -2
- package/dist/git-cli/providers/config.d.ts.map +1 -1
- package/dist/git-cli/providers/config.js +36 -11
- package/dist/git-cli/providers/config.js.map +1 -1
- package/dist/git-cli/providers/contributors.d.ts.map +1 -1
- package/dist/git-cli/providers/contributors.js +7 -4
- package/dist/git-cli/providers/contributors.js.map +1 -1
- package/dist/git-cli/providers/diff.d.ts +2 -0
- package/dist/git-cli/providers/diff.d.ts.map +1 -1
- package/dist/git-cli/providers/diff.js +92 -20
- package/dist/git-cli/providers/diff.js.map +1 -1
- package/dist/git-cli/providers/graph.d.ts.map +1 -1
- package/dist/git-cli/providers/graph.js +49 -28
- package/dist/git-cli/providers/graph.js.map +1 -1
- package/dist/git-cli/providers/operations.d.ts +30 -11
- package/dist/git-cli/providers/operations.d.ts.map +1 -1
- package/dist/git-cli/providers/operations.js +146 -43
- package/dist/git-cli/providers/operations.js.map +1 -1
- package/dist/git-cli/providers/patch.d.ts.map +1 -1
- package/dist/git-cli/providers/patch.js +15 -30
- package/dist/git-cli/providers/patch.js.map +1 -1
- package/dist/git-cli/providers/pausedOperations.d.ts +3 -1
- package/dist/git-cli/providers/pausedOperations.d.ts.map +1 -1
- package/dist/git-cli/providers/pausedOperations.js +13 -7
- package/dist/git-cli/providers/pausedOperations.js.map +1 -1
- package/dist/git-cli/providers/refs.d.ts +19 -2
- package/dist/git-cli/providers/refs.d.ts.map +1 -1
- package/dist/git-cli/providers/refs.js +312 -9
- package/dist/git-cli/providers/refs.js.map +1 -1
- package/dist/git-cli/providers/remotes.js +4 -4
- package/dist/git-cli/providers/remotes.js.map +1 -1
- package/dist/git-cli/providers/revision.d.ts +1 -1
- package/dist/git-cli/providers/revision.d.ts.map +1 -1
- package/dist/git-cli/providers/revision.js +15 -11
- package/dist/git-cli/providers/revision.js.map +1 -1
- package/dist/git-cli/providers/staging.d.ts +8 -0
- package/dist/git-cli/providers/staging.d.ts.map +1 -1
- package/dist/git-cli/providers/staging.js +52 -8
- package/dist/git-cli/providers/staging.js.map +1 -1
- package/dist/git-cli/providers/stash.d.ts +0 -8
- package/dist/git-cli/providers/stash.d.ts.map +1 -1
- package/dist/git-cli/providers/stash.js +63 -119
- package/dist/git-cli/providers/stash.js.map +1 -1
- package/dist/git-cli/providers/status.d.ts +4 -1
- package/dist/git-cli/providers/status.d.ts.map +1 -1
- package/dist/git-cli/providers/status.js +10 -9
- package/dist/git-cli/providers/status.js.map +1 -1
- package/dist/git-cli/providers/tags.d.ts.map +1 -1
- package/dist/git-cli/providers/tags.js +13 -9
- package/dist/git-cli/providers/tags.js.map +1 -1
- package/dist/git-cli/providers/worktrees.js +3 -3
- package/dist/git-cli/providers/worktrees.js.map +1 -1
- package/dist/ipc/discovery.d.ts +27 -0
- package/dist/ipc/discovery.d.ts.map +1 -0
- package/dist/ipc/discovery.js +38 -0
- package/dist/ipc/discovery.js.map +1 -0
- package/dist/ipc/ipcServer.d.ts +20 -0
- package/dist/ipc/ipcServer.d.ts.map +1 -0
- package/dist/ipc/ipcServer.js +162 -0
- package/dist/ipc/ipcServer.js.map +1 -0
- package/dist/plus/agents/providers/claudeCodeProvider.d.ts +114 -0
- package/dist/plus/agents/providers/claudeCodeProvider.d.ts.map +1 -0
- package/dist/plus/agents/providers/claudeCodeProvider.js +1480 -0
- package/dist/plus/agents/providers/claudeCodeProvider.js.map +1 -0
- package/dist/plus/agents/providers/claudeCodeTranscript.d.ts +36 -0
- package/dist/plus/agents/providers/claudeCodeTranscript.d.ts.map +1 -0
- package/dist/plus/agents/providers/claudeCodeTranscript.js +171 -0
- package/dist/plus/agents/providers/claudeCodeTranscript.js.map +1 -0
- package/dist/plus/agents/sanitizePrompt.d.ts +15 -0
- package/dist/plus/agents/sanitizePrompt.d.ts.map +1 -0
- package/dist/plus/agents/sanitizePrompt.js +103 -0
- package/dist/plus/agents/sanitizePrompt.js.map +1 -0
- package/dist/plus/agents/stateMachine.d.ts +32 -0
- package/dist/plus/agents/stateMachine.d.ts.map +1 -0
- package/dist/plus/agents/stateMachine.js +180 -0
- package/dist/plus/agents/stateMachine.js.map +1 -0
- package/dist/plus/agents/types.d.ts +203 -0
- package/dist/plus/agents/types.d.ts.map +1 -0
- package/dist/plus/agents/types.js +49 -0
- package/dist/plus/agents/types.js.map +1 -0
- package/dist/plus/ai/constants.d.ts +2 -1
- package/dist/plus/ai/constants.d.ts.map +1 -1
- package/dist/plus/ai/constants.js +7 -0
- package/dist/plus/ai/constants.js.map +1 -1
- package/dist/plus/ai/errors.d.ts +4 -1
- package/dist/plus/ai/errors.d.ts.map +1 -1
- package/dist/plus/ai/errors.js +38 -0
- package/dist/plus/ai/errors.js.map +1 -1
- package/dist/plus/ai/models/model.d.ts +1 -1
- package/dist/plus/ai/models/model.d.ts.map +1 -1
- package/dist/plus/ai/models/model.js.map +1 -1
- package/dist/plus/ai/models/promptTemplates.d.ts +28 -2
- package/dist/plus/ai/models/promptTemplates.d.ts.map +1 -1
- package/dist/plus/ai/models/results.d.ts +28 -0
- package/dist/plus/ai/models/results.d.ts.map +1 -1
- package/dist/plus/ai/prompts.d.ts +4 -0
- package/dist/plus/ai/prompts.d.ts.map +1 -1
- package/dist/plus/ai/prompts.js +167 -1
- package/dist/plus/ai/prompts.js.map +1 -1
- package/dist/plus/ai/utils/ai.utils.d.ts.map +1 -1
- package/dist/plus/ai/utils/ai.utils.js +2 -0
- package/dist/plus/ai/utils/ai.utils.js.map +1 -1
- package/dist/plus/ai/utils/results.utils.d.ts +3 -0
- package/dist/plus/ai/utils/results.utils.d.ts.map +1 -1
- package/dist/plus/ai/utils/results.utils.js +75 -0
- package/dist/plus/ai/utils/results.utils.js.map +1 -1
- package/dist/plus/ai/utils/truncation.utils.d.ts +1 -1
- package/dist/plus/ai/utils/truncation.utils.d.ts.map +1 -1
- package/dist/plus/ai/utils/truncation.utils.js.map +1 -1
- package/dist/plus/git-github/api/github.d.ts +10 -1
- package/dist/plus/git-github/api/github.d.ts.map +1 -1
- package/dist/plus/git-github/api/github.js +156 -49
- package/dist/plus/git-github/api/github.js.map +1 -1
- package/dist/plus/git-github/api/types.d.ts +8 -0
- package/dist/plus/git-github/api/types.d.ts.map +1 -1
- package/dist/plus/git-github/models.d.ts +1 -1
- package/dist/plus/git-github/models.d.ts.map +1 -1
- package/dist/plus/git-github/models.js.map +1 -1
- package/dist/plus/git-github/providers/github/blame.d.ts.map +1 -1
- package/dist/plus/git-github/providers/github/blame.js.map +1 -1
- package/dist/plus/git-github/providers/github/branches.d.ts +5 -1
- package/dist/plus/git-github/providers/github/branches.d.ts.map +1 -1
- package/dist/plus/git-github/providers/github/branches.js +60 -22
- package/dist/plus/git-github/providers/github/branches.js.map +1 -1
- package/dist/plus/git-github/providers/github/commits.d.ts.map +1 -1
- package/dist/plus/git-github/providers/github/commits.js +144 -92
- package/dist/plus/git-github/providers/github/commits.js.map +1 -1
- package/dist/plus/git-github/providers/github/diff.d.ts +3 -1
- package/dist/plus/git-github/providers/github/diff.d.ts.map +1 -1
- package/dist/plus/git-github/providers/github/diff.js +23 -9
- package/dist/plus/git-github/providers/github/diff.js.map +1 -1
- package/dist/plus/git-github/providers/github/refs.d.ts +9 -1
- package/dist/plus/git-github/providers/github/refs.d.ts.map +1 -1
- package/dist/plus/git-github/providers/github/refs.js +38 -13
- package/dist/plus/git-github/providers/github/refs.js.map +1 -1
- package/dist/plus/git-github/providers/github/revision.d.ts.map +1 -1
- package/dist/plus/git-github/providers/github/revision.js +1 -2
- package/dist/plus/git-github/providers/github/revision.js.map +1 -1
- package/dist/plus/git-github/providers/github/status.d.ts +4 -1
- package/dist/plus/git-github/providers/github/status.d.ts.map +1 -1
- package/dist/plus/git-github/providers/github/status.js +1 -1
- package/dist/plus/git-github/providers/github/status.js.map +1 -1
- package/dist/plus/git-github/providers/github/tags.d.ts.map +1 -1
- package/dist/plus/git-github/providers/github/tags.js +35 -36
- package/dist/plus/git-github/providers/github/tags.js.map +1 -1
- package/dist/plus/git-github/providers/githubGitProvider.d.ts.map +1 -1
- package/dist/plus/git-github/providers/githubGitProvider.js.map +1 -1
- package/dist/utils/color.d.ts.map +1 -1
- package/dist/utils/color.js.map +1 -1
- package/dist/utils/decorators/log.js +1 -1
- package/dist/utils/decorators/log.js.map +1 -1
- package/dist/utils/decorators/sequentialize.d.ts.map +1 -1
- package/dist/utils/decorators/sequentialize.js +4 -2
- package/dist/utils/decorators/sequentialize.js.map +1 -1
- package/dist/utils/decorators/serializable.d.ts.map +1 -1
- package/dist/utils/decorators/serializable.js.map +1 -1
- package/dist/utils/dedupedAsyncCache.d.ts +37 -0
- package/dist/utils/dedupedAsyncCache.d.ts.map +1 -0
- package/dist/utils/dedupedAsyncCache.js +68 -0
- package/dist/utils/dedupedAsyncCache.js.map +1 -0
- package/dist/utils/diff.d.ts +2 -0
- package/dist/utils/diff.d.ts.map +1 -0
- package/dist/utils/diff.js +53 -0
- package/dist/utils/diff.js.map +1 -0
- package/dist/utils/disposable.d.ts.map +1 -1
- package/dist/utils/disposable.js.map +1 -1
- package/dist/utils/env/node/base64.js.map +1 -1
- package/dist/utils/env/node/exec.d.ts.map +1 -1
- package/dist/utils/env/node/exec.js.map +1 -1
- package/dist/utils/error.d.ts.map +1 -1
- package/dist/utils/error.js.map +1 -1
- package/dist/utils/formatter.d.ts.map +1 -1
- package/dist/utils/formatter.js +4 -10
- package/dist/utils/formatter.js.map +1 -1
- package/dist/utils/iterable.d.ts.map +1 -1
- package/dist/utils/iterable.js.map +1 -1
- package/dist/utils/logger.d.ts.map +1 -1
- package/dist/utils/logger.js.map +1 -1
- package/dist/utils/lruMap.d.ts +49 -0
- package/dist/utils/lruMap.d.ts.map +1 -0
- package/dist/utils/lruMap.js +103 -0
- package/dist/utils/lruMap.js.map +1 -0
- package/dist/utils/markdown.d.ts.map +1 -1
- package/dist/utils/markdown.js.map +1 -1
- package/dist/utils/mru.d.ts.map +1 -1
- package/dist/utils/mru.js.map +1 -1
- package/dist/utils/path.d.ts.map +1 -1
- package/dist/utils/path.js.map +1 -1
- package/dist/utils/promise.d.ts +1 -0
- package/dist/utils/promise.d.ts.map +1 -1
- package/dist/utils/promise.js +17 -0
- package/dist/utils/promise.js.map +1 -1
- package/dist/utils/promiseCache.d.ts +10 -0
- package/dist/utils/promiseCache.d.ts.map +1 -1
- package/dist/utils/promiseCache.js +22 -0
- package/dist/utils/promiseCache.js.map +1 -1
- package/dist/utils/string.d.ts.map +1 -1
- package/dist/utils/string.js.map +1 -1
- package/dist/utils/uri.d.ts.map +1 -1
- package/dist/utils/uri.js.map +1 -1
- package/dist/utils/version.d.ts +14 -0
- package/dist/utils/version.d.ts.map +1 -1
- package/dist/utils/version.js +48 -0
- package/dist/utils/version.js.map +1 -1
- package/package.json +13 -1
- package/src/git/cache.ts +309 -29
- package/src/git/context.ts +11 -2
- package/src/git/models/branch.ts +1 -0
- package/src/git/models/commit.ts +2 -17
- package/src/git/models/graph.ts +2 -4
- package/src/git/models/reference.ts +33 -0
- package/src/git/models/remote.ts +1 -0
- package/src/git/models/repository.ts +44 -6
- package/src/git/models/search.ts +2 -2
- package/src/git/models/worktree.ts +10 -2
- package/src/git/parsers/diffParser.ts +9 -44
- package/src/git/providers/branches.ts +25 -4
- package/src/git/providers/commits.ts +7 -0
- package/src/git/providers/config.ts +4 -0
- package/src/git/providers/diff.ts +8 -2
- package/src/git/providers/operations.ts +54 -3
- package/src/git/providers/pausedOperations.ts +1 -0
- package/src/git/providers/refs.ts +32 -3
- package/src/git/providers/revision.ts +5 -1
- package/src/git/providers/staging.ts +14 -0
- package/src/git/providers/status.ts +6 -1
- package/src/git/remotes/azure-devops.ts +2 -0
- package/src/git/{exec.types.ts → run.types.ts} +22 -2
- package/src/git/service.ts +1 -0
- package/src/git/utils/autolink.utils.ts +1 -0
- package/src/git/utils/blame.utils.ts +2 -0
- package/src/git/utils/conflictResolution.utils.ts +31 -0
- package/src/git/utils/fileStatus.utils.ts +7 -1
- package/src/git/utils/search.utils.ts +2 -0
- package/src/git/utils/sorting.ts +38 -0
- package/src/git/utils/status.utils.ts +1 -0
- package/src/git/watching/classifyChange.ts +9 -0
- package/src/git/watching/gitIgnoreFilter.ts +2 -2
- package/src/git/watching/initWatcher.ts +2 -0
- package/src/git/watching/watchGroup.ts +3 -0
- package/src/git/watching/watchService.ts +38 -5
- package/src/git/watching/watchSession.ts +10 -0
- package/src/git-cli/cliGitProvider.ts +1 -1
- package/src/git-cli/exec/exec.types.ts +2 -2
- package/src/git-cli/exec/git.ts +76 -23
- package/src/git-cli/exec/gitQueue.ts +98 -25
- package/src/git-cli/parsers/blameParser.ts +1 -0
- package/src/git-cli/parsers/logParser.ts +6 -1
- package/src/git-cli/parsers/refParser.ts +33 -34
- package/src/git-cli/providers/blame.ts +2 -1
- package/src/git-cli/providers/branches.ts +341 -196
- package/src/git-cli/providers/commits.ts +145 -46
- package/src/git-cli/providers/config.ts +50 -16
- package/src/git-cli/providers/contributors.ts +7 -12
- package/src/git-cli/providers/diff.ts +107 -20
- package/src/git-cli/providers/graph.ts +58 -29
- package/src/git-cli/providers/operations.ts +253 -57
- package/src/git-cli/providers/patch.ts +16 -37
- package/src/git-cli/providers/pausedOperations.ts +14 -6
- package/src/git-cli/providers/refs.ts +274 -11
- package/src/git-cli/providers/remotes.ts +4 -4
- package/src/git-cli/providers/revision.ts +22 -15
- package/src/git-cli/providers/staging.ts +51 -8
- package/src/git-cli/providers/stash.ts +67 -134
- package/src/git-cli/providers/status.ts +21 -10
- package/src/git-cli/providers/tags.ts +18 -19
- package/src/git-cli/providers/worktrees.ts +3 -3
- package/src/ipc/discovery.ts +56 -0
- package/src/ipc/ipcServer.ts +171 -0
- package/src/plus/agents/providers/claudeCodeProvider.ts +1782 -0
- package/src/plus/agents/providers/claudeCodeTranscript.ts +214 -0
- package/src/plus/agents/sanitizePrompt.ts +109 -0
- package/src/plus/agents/stateMachine.ts +197 -0
- package/src/plus/agents/types.ts +277 -0
- package/src/plus/ai/constants.ts +8 -0
- package/src/plus/ai/errors.ts +40 -0
- package/src/plus/ai/models/model.ts +1 -0
- package/src/plus/ai/models/promptTemplates.ts +42 -0
- package/src/plus/ai/models/results.ts +30 -0
- package/src/plus/ai/prompts.ts +171 -1
- package/src/plus/ai/utils/ai.utils.ts +2 -0
- package/src/plus/ai/utils/results.utils.ts +101 -0
- package/src/plus/ai/utils/truncation.utils.ts +3 -1
- package/src/plus/git-github/api/github.ts +199 -53
- package/src/plus/git-github/api/types.ts +15 -0
- package/src/plus/git-github/models.ts +1 -1
- package/src/plus/git-github/providers/github/blame.ts +2 -0
- package/src/plus/git-github/providers/github/branches.ts +75 -33
- package/src/plus/git-github/providers/github/commits.ts +231 -160
- package/src/plus/git-github/providers/github/diff.ts +35 -21
- package/src/plus/git-github/providers/github/refs.ts +57 -22
- package/src/plus/git-github/providers/github/revision.ts +1 -2
- package/src/plus/git-github/providers/github/status.ts +6 -1
- package/src/plus/git-github/providers/github/tags.ts +61 -62
- package/src/plus/git-github/providers/githubGitProvider.ts +1 -0
- package/src/utils/color.ts +2 -0
- package/src/utils/decorators/log.ts +1 -1
- package/src/utils/decorators/sequentialize.ts +8 -6
- package/src/utils/decorators/serializable.ts +1 -0
- package/src/utils/dedupedAsyncCache.ts +74 -0
- package/src/utils/diff.ts +61 -0
- package/src/utils/disposable.ts +2 -0
- package/src/utils/env/node/base64.ts +1 -1
- package/src/utils/env/node/exec.ts +4 -2
- package/src/utils/error.ts +1 -0
- package/src/utils/formatter.ts +4 -11
- package/src/utils/iterable.ts +4 -1
- package/src/utils/logger.ts +1 -0
- package/src/utils/lruMap.ts +112 -0
- package/src/utils/markdown.ts +1 -0
- package/src/utils/mru.ts +2 -0
- package/src/utils/path.ts +1 -0
- package/src/utils/promise.ts +22 -0
- package/src/utils/promiseCache.ts +24 -0
- package/src/utils/string.ts +2 -0
- package/src/utils/uri.ts +1 -0
- package/src/utils/version.ts +49 -0
- package/dist/git/exec.types.d.ts.map +0 -1
- package/dist/git/exec.types.js +0 -2
- package/dist/git/exec.types.js.map +0 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { Cache, ConflictDetectionCacheKey } from '../../git/cache.js';
|
|
1
|
+
import type { Cache, ConflictDetectionCacheKey, GkConfigInvalidationTarget } from '../../git/cache.js';
|
|
2
2
|
import type { GitServiceContext } from '../../git/context.js';
|
|
3
3
|
import { BranchError } from '../../git/errors.js';
|
|
4
4
|
import type { BranchDisposition, BranchMetadata } from '../../git/models/branch.js';
|
|
@@ -10,6 +10,7 @@ import type {
|
|
|
10
10
|
GitBranchesSubProvider,
|
|
11
11
|
GitBranchMergedStatus,
|
|
12
12
|
} from '../../git/providers/branches.js';
|
|
13
|
+
import type { GitCommandPriority } from '../../git/run.types.js';
|
|
13
14
|
import {
|
|
14
15
|
formatDetachedHeadName,
|
|
15
16
|
getBranchId,
|
|
@@ -41,7 +42,6 @@ import type { GitResult } from '../exec/exec.types.js';
|
|
|
41
42
|
import type { Git } from '../exec/git.js';
|
|
42
43
|
import { getGitCommandError, gitConfigsBranch, gitConfigsLog, GitError, GitErrors, GitWarnings } from '../exec/git.js';
|
|
43
44
|
import { parseMergeTreeConflict } from '../parsers/mergeTreeParser.js';
|
|
44
|
-
import { getBranchParser } from '../parsers/refParser.js';
|
|
45
45
|
|
|
46
46
|
/** Minimum time between writes to the config for last accessed/modified dates */
|
|
47
47
|
const dateMetadataStaleThresholdMs = 5 * 60 * 1000; // 5 minutes
|
|
@@ -96,10 +96,10 @@ export class BranchesGitSubProvider implements GitBranchesSubProvider {
|
|
|
96
96
|
const [pausedOpStatusResult, committerDateResult, defaultWorktreePathResult, metadataMapResult] =
|
|
97
97
|
await Promise.allSettled([
|
|
98
98
|
isDetachedHead(ref.name)
|
|
99
|
-
? this.provider.pausedOps?.getPausedOperationStatus(repoPath, cancellation)
|
|
99
|
+
? this.provider.pausedOps?.getPausedOperationStatus(repoPath, undefined, cancellation)
|
|
100
100
|
: undefined,
|
|
101
101
|
this.git
|
|
102
|
-
.
|
|
102
|
+
.run(
|
|
103
103
|
{
|
|
104
104
|
cwd: repoPath,
|
|
105
105
|
cancellation: cancellation,
|
|
@@ -168,27 +168,22 @@ export class BranchesGitSubProvider implements GitBranchesSubProvider {
|
|
|
168
168
|
// own cancellation when bypassing the cache (e.g. paging-cursor path).
|
|
169
169
|
signal ??= cancellation;
|
|
170
170
|
try {
|
|
171
|
-
const
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
),
|
|
182
|
-
this.provider.config.getDefaultWorktreePath?.(commonPath),
|
|
183
|
-
this.getBranchMetadataMap(commonPath),
|
|
184
|
-
]);
|
|
185
|
-
|
|
186
|
-
const result = getSettledValue(gitResult);
|
|
171
|
+
const [recordsResult, supportedResult, defaultWorktreePathResult, metadataMapResult] =
|
|
172
|
+
await Promise.allSettled([
|
|
173
|
+
this.provider.refs.getRefs(commonPath, signal),
|
|
174
|
+
this.git.supported('git:for-each-ref'),
|
|
175
|
+
this.provider.config.getDefaultWorktreePath?.(commonPath),
|
|
176
|
+
this.getBranchMetadataMap(commonPath),
|
|
177
|
+
]);
|
|
178
|
+
|
|
179
|
+
const records = getSettledValue(recordsResult) ?? [];
|
|
180
|
+
const supported = getSettledValue(supportedResult) ?? [];
|
|
187
181
|
const metadataMap = getSettledValue(metadataMapResult) ?? new Map<string, BranchMetadata>();
|
|
188
182
|
const defaultWorktreePath = getSettledValue(defaultWorktreePathResult);
|
|
183
|
+
const worktreePathSupported = supported.includes('git:for-each-ref:worktreePath');
|
|
189
184
|
|
|
190
185
|
// If we don't get any data, assume the repo doesn't have any commits yet so check if we have a current branch
|
|
191
|
-
if (!
|
|
186
|
+
if (!records.length) {
|
|
192
187
|
const current = await this.getCurrentBranch(
|
|
193
188
|
commonPath,
|
|
194
189
|
metadataMap,
|
|
@@ -202,25 +197,28 @@ export class BranchesGitSubProvider implements GitBranchesSubProvider {
|
|
|
202
197
|
|
|
203
198
|
const branches: GitBranch[] = [];
|
|
204
199
|
|
|
205
|
-
for (const
|
|
200
|
+
for (const record of records) {
|
|
201
|
+
const fullName = record.name;
|
|
202
|
+
// Filter to branches and remote-tracking branches; skip tags from the unified records.
|
|
203
|
+
if (!fullName.startsWith('refs/heads/') && !fullName.startsWith('refs/remotes/')) continue;
|
|
206
204
|
// Skip HEAD refs in remote branches
|
|
207
|
-
if (isRemoteHEAD(
|
|
205
|
+
if (isRemoteHEAD(fullName)) continue;
|
|
208
206
|
|
|
209
|
-
const upstream = parseUpstream(
|
|
207
|
+
const upstream = parseUpstream(record.upstream, record.upstreamTracking);
|
|
210
208
|
|
|
211
|
-
const metadata = metadataMap.get(parseRefName(
|
|
212
|
-
const worktreePath =
|
|
209
|
+
const metadata = metadataMap.get(parseRefName(fullName).name);
|
|
210
|
+
const worktreePath = record.worktreePath ? normalizePath(record.worktreePath) : undefined;
|
|
213
211
|
|
|
214
212
|
branches.push(
|
|
215
213
|
new GitBranch(
|
|
216
214
|
commonPath,
|
|
217
|
-
|
|
215
|
+
fullName,
|
|
218
216
|
false, // Don't trust %(HEAD) for current as it's per-worktree -- we will set it later
|
|
219
|
-
|
|
217
|
+
record.committerDate ? new Date(record.committerDate) : undefined,
|
|
220
218
|
metadata,
|
|
221
|
-
|
|
219
|
+
record.objectname,
|
|
222
220
|
upstream,
|
|
223
|
-
|
|
221
|
+
worktreePathSupported
|
|
224
222
|
? worktreePath
|
|
225
223
|
? { path: worktreePath, isDefault: worktreePath === defaultWorktreePath }
|
|
226
224
|
: false
|
|
@@ -360,55 +358,42 @@ export class BranchesGitSubProvider implements GitBranchesSubProvider {
|
|
|
360
358
|
async getBranchContributionsOverview(
|
|
361
359
|
repoPath: string,
|
|
362
360
|
ref: string,
|
|
363
|
-
options?: {
|
|
361
|
+
options?: {
|
|
362
|
+
associatedPullRequest?: Promise<{ refs?: { base?: { branch: string } } } | undefined>;
|
|
363
|
+
priority?: GitCommandPriority;
|
|
364
|
+
},
|
|
364
365
|
cancellation?: AbortSignal,
|
|
365
366
|
): Promise<BranchContributionsOverview | undefined> {
|
|
366
367
|
const scope = getScopedLogger();
|
|
368
|
+
const priority = options?.priority;
|
|
369
|
+
const priorityOpts = priority != null ? { priority: priority } : undefined;
|
|
370
|
+
|
|
371
|
+
// Expensive body — runs only on cache miss. Closes over `mergeTarget` so the cache key
|
|
372
|
+
// (`${ref}|${mergeTarget}`) fully captures every input that affects the result.
|
|
373
|
+
const fetchBody = async (
|
|
374
|
+
mergeTarget: string,
|
|
375
|
+
signal: AbortSignal | undefined,
|
|
376
|
+
): Promise<BranchContributionsOverview | undefined> => {
|
|
377
|
+
const mergeBase = await this.provider.refs.getMergeBase(repoPath, ref, mergeTarget, priorityOpts, signal);
|
|
378
|
+
if (mergeBase == null) return undefined;
|
|
367
379
|
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
// Tier 2: PR-based lookup (caller provides the PR promise)
|
|
382
|
-
if (mergeTarget == null && options?.associatedPullRequest != null) {
|
|
383
|
-
const pr = await options.associatedPullRequest;
|
|
384
|
-
if (pr?.refs?.base != null) {
|
|
385
|
-
mergeTarget = `${branch.remoteName}/${pr.refs.base.branch}`;
|
|
386
|
-
// Store for future reuse
|
|
387
|
-
void this.storeMergeTargetBranchName(repoPath, ref, mergeTarget);
|
|
388
|
-
}
|
|
389
|
-
}
|
|
390
|
-
|
|
391
|
-
// Tier 3: Base branch, then default branch
|
|
392
|
-
mergeTarget ??= await this.getBaseBranchName(repoPath, ref, cancellation);
|
|
393
|
-
mergeTarget ??= await this.getDefaultBranchName(repoPath, undefined, cancellation);
|
|
394
|
-
|
|
395
|
-
if (mergeTarget == null) return undefined;
|
|
380
|
+
// Fetch the merge-base commit's dates in parallel with contributors so consumers
|
|
381
|
+
// (e.g. the graph minimap scope window) don't pay a separate round-trip for them.
|
|
382
|
+
// `allSettled` so a transient failure in one side doesn't drop the overview entirely.
|
|
383
|
+
const [contributorsSettled, mergeBaseDatesSettled] = await Promise.allSettled([
|
|
384
|
+
this.provider.contributors.getContributors(
|
|
385
|
+
repoPath,
|
|
386
|
+
createRevisionRange(mergeBase, ref, '..'),
|
|
387
|
+
{ stats: true },
|
|
388
|
+
signal,
|
|
389
|
+
),
|
|
390
|
+
this.provider.commits.getCommitDates(repoPath, mergeBase, signal),
|
|
391
|
+
]);
|
|
396
392
|
|
|
397
|
-
|
|
398
|
-
repoPath,
|
|
399
|
-
ref,
|
|
400
|
-
mergeTarget,
|
|
401
|
-
undefined,
|
|
402
|
-
cancellation,
|
|
403
|
-
);
|
|
404
|
-
if (mergeBase == null) return undefined;
|
|
393
|
+
if (signal?.aborted) throw new CancellationError();
|
|
405
394
|
|
|
406
|
-
const result =
|
|
407
|
-
|
|
408
|
-
createRevisionRange(mergeBase, ref, '..'),
|
|
409
|
-
{ stats: true },
|
|
410
|
-
cancellation,
|
|
411
|
-
);
|
|
395
|
+
const result = getSettledValue(contributorsSettled) ?? { contributors: [] };
|
|
396
|
+
const mergeBaseDates = getSettledValue(mergeBaseDatesSettled);
|
|
412
397
|
|
|
413
398
|
sortContributors(result.contributors, { orderBy: 'score:desc' });
|
|
414
399
|
|
|
@@ -446,6 +431,7 @@ export class BranchesGitSubProvider implements GitBranchesSubProvider {
|
|
|
446
431
|
branch: ref,
|
|
447
432
|
mergeTarget: mergeTarget,
|
|
448
433
|
mergeBase: mergeBase,
|
|
434
|
+
mergeBaseDate: mergeBaseDates?.committerDate,
|
|
449
435
|
|
|
450
436
|
commits: totalCommits,
|
|
451
437
|
files: totalFiles,
|
|
@@ -457,6 +443,64 @@ export class BranchesGitSubProvider implements GitBranchesSubProvider {
|
|
|
457
443
|
|
|
458
444
|
contributors: result.contributors,
|
|
459
445
|
};
|
|
446
|
+
};
|
|
447
|
+
|
|
448
|
+
try {
|
|
449
|
+
// Resolve `mergeTarget` through Tier 1 → Tier 2 → Tier 3. The pieces of each tier are
|
|
450
|
+
// already individually cached (`getStoredMergeTargetBranchName`, `getBaseBranchName`,
|
|
451
|
+
// `getDefaultBranchName`), so this resolution path is cheap on warm caches. Only the
|
|
452
|
+
// expensive body below (`getMergeBase` + `getContributors` w/ stats + `getCommitDates`)
|
|
453
|
+
// is wrapped by `cache.getBranchOverview`, keyed on the resolved `mergeTarget` so any
|
|
454
|
+
// caller that resolves to the same target shares; differing targets get independent
|
|
455
|
+
// slots, which is the correctness constraint that previously forced the Tier 2/3 paths
|
|
456
|
+
// to bypass the cache entirely.
|
|
457
|
+
let mergeTarget: string | undefined;
|
|
458
|
+
|
|
459
|
+
// Tier 1: Stored merge target (user-set or previously detected from PR).
|
|
460
|
+
const storedTarget = await this.getStoredMergeTargetBranchName(repoPath, ref);
|
|
461
|
+
if (storedTarget) {
|
|
462
|
+
const validated = await this.provider.refs.getSymbolicReferenceName(
|
|
463
|
+
repoPath,
|
|
464
|
+
storedTarget,
|
|
465
|
+
priorityOpts,
|
|
466
|
+
cancellation,
|
|
467
|
+
);
|
|
468
|
+
mergeTarget = validated || storedTarget;
|
|
469
|
+
}
|
|
470
|
+
|
|
471
|
+
// Tier 2: PR-based lookup. The branch object is only needed here (for `remoteName`),
|
|
472
|
+
// so lazy-load it on the cold path instead of paying for it on every call.
|
|
473
|
+
if (mergeTarget == null && options?.associatedPullRequest != null) {
|
|
474
|
+
const pr = await options.associatedPullRequest;
|
|
475
|
+
if (pr?.refs?.base != null) {
|
|
476
|
+
const branch = await this.getBranch(repoPath, ref, cancellation);
|
|
477
|
+
if (branch == null) return undefined;
|
|
478
|
+
|
|
479
|
+
mergeTarget = `${branch.remoteName}/${pr.refs.base.branch}`;
|
|
480
|
+
// Store for future reuse — turns the next call into a Tier 1 path. Skip the
|
|
481
|
+
// `branchOverviews` invalidation that the write would otherwise trigger: we're
|
|
482
|
+
// about to populate `${ref}|${mergeTarget}` with this exact target, so evicting
|
|
483
|
+
// it would just force the next caller to redo the body. (gk-merge-target writes
|
|
484
|
+
// do not affect `baseBranchName`, so no need to skip that target.)
|
|
485
|
+
void this.storeMergeTargetBranchName(repoPath, ref, mergeTarget, {
|
|
486
|
+
skipInvalidation: ['branchOverviews'],
|
|
487
|
+
});
|
|
488
|
+
}
|
|
489
|
+
}
|
|
490
|
+
|
|
491
|
+
// Tier 3: Base branch, then default branch.
|
|
492
|
+
mergeTarget ??= await this.getBaseBranchName(repoPath, ref, priorityOpts, cancellation);
|
|
493
|
+
mergeTarget ??= await this.getDefaultBranchName(repoPath, undefined, priorityOpts, cancellation);
|
|
494
|
+
|
|
495
|
+
if (mergeTarget == null) return undefined;
|
|
496
|
+
|
|
497
|
+
const resolvedTarget = mergeTarget;
|
|
498
|
+
return await this.cache.getBranchOverview(
|
|
499
|
+
repoPath,
|
|
500
|
+
`${ref}|${resolvedTarget}`,
|
|
501
|
+
(_commonPath, _cacheable, signal) => fetchBody(resolvedTarget, signal ?? cancellation),
|
|
502
|
+
{ cancellation: cancellation },
|
|
503
|
+
);
|
|
460
504
|
} catch (ex) {
|
|
461
505
|
scope?.error(ex);
|
|
462
506
|
if (isCancellationError(ex)) throw ex;
|
|
@@ -520,7 +564,7 @@ export class BranchesGitSubProvider implements GitBranchesSubProvider {
|
|
|
520
564
|
params.push(options.name);
|
|
521
565
|
}
|
|
522
566
|
|
|
523
|
-
return this.git.
|
|
567
|
+
return this.git.run(
|
|
524
568
|
{
|
|
525
569
|
cwd: repoPath,
|
|
526
570
|
cancellation: cancellation,
|
|
@@ -563,7 +607,7 @@ export class BranchesGitSubProvider implements GitBranchesSubProvider {
|
|
|
563
607
|
let data: [string, string | undefined] | undefined;
|
|
564
608
|
let result;
|
|
565
609
|
try {
|
|
566
|
-
result = await this.git.
|
|
610
|
+
result = await this.git.run(
|
|
567
611
|
{ cwd: repoPath, cancellation: signal, errors: 'throw' },
|
|
568
612
|
'rev-parse',
|
|
569
613
|
'--abbrev-ref',
|
|
@@ -582,7 +626,7 @@ export class BranchesGitSubProvider implements GitBranchesSubProvider {
|
|
|
582
626
|
data = [ex.stdout, undefined];
|
|
583
627
|
} else {
|
|
584
628
|
try {
|
|
585
|
-
result = await this.git.
|
|
629
|
+
result = await this.git.run(
|
|
586
630
|
{ cwd: repoPath, cancellation: signal },
|
|
587
631
|
'symbolic-ref',
|
|
588
632
|
'--short',
|
|
@@ -596,7 +640,12 @@ export class BranchesGitSubProvider implements GitBranchesSubProvider {
|
|
|
596
640
|
}
|
|
597
641
|
|
|
598
642
|
if (data == null) {
|
|
599
|
-
const symbolicRef = await this.getDefaultBranchName(
|
|
643
|
+
const symbolicRef = await this.getDefaultBranchName(
|
|
644
|
+
repoPath,
|
|
645
|
+
'origin',
|
|
646
|
+
undefined,
|
|
647
|
+
signal,
|
|
648
|
+
);
|
|
600
649
|
if (symbolicRef != null) {
|
|
601
650
|
data = [
|
|
602
651
|
symbolicRef.startsWith('origin/')
|
|
@@ -629,7 +678,7 @@ export class BranchesGitSubProvider implements GitBranchesSubProvider {
|
|
|
629
678
|
}
|
|
630
679
|
}
|
|
631
680
|
} else if (GitWarnings.headNotABranch.test(msg)) {
|
|
632
|
-
result = await this.git.
|
|
681
|
+
result = await this.git.run(
|
|
633
682
|
{
|
|
634
683
|
cwd: repoPath,
|
|
635
684
|
cancellation: signal,
|
|
@@ -677,18 +726,21 @@ export class BranchesGitSubProvider implements GitBranchesSubProvider {
|
|
|
677
726
|
async getDefaultBranchName(
|
|
678
727
|
repoPath: string | undefined,
|
|
679
728
|
remote?: string,
|
|
729
|
+
options?: { priority?: GitCommandPriority },
|
|
680
730
|
cancellation?: AbortSignal,
|
|
681
731
|
): Promise<string | undefined> {
|
|
682
732
|
if (repoPath == null) return undefined;
|
|
683
733
|
|
|
684
734
|
remote ??= 'origin';
|
|
735
|
+
const priority = options?.priority;
|
|
736
|
+
const priorityOpts = priority != null ? { priority: priority } : undefined;
|
|
685
737
|
|
|
686
738
|
return this.cache.getDefaultBranchName(repoPath, remote, async commonPath => {
|
|
687
739
|
let retried = false;
|
|
688
740
|
while (true) {
|
|
689
741
|
try {
|
|
690
|
-
const result = await this.git.
|
|
691
|
-
{ cwd: commonPath, cancellation: cancellation },
|
|
742
|
+
const result = await this.git.run(
|
|
743
|
+
{ cwd: commonPath, cancellation: cancellation, ...priorityOpts },
|
|
692
744
|
'symbolic-ref',
|
|
693
745
|
'--short',
|
|
694
746
|
`refs/remotes/${remote}/HEAD`,
|
|
@@ -699,8 +751,8 @@ export class BranchesGitSubProvider implements GitBranchesSubProvider {
|
|
|
699
751
|
try {
|
|
700
752
|
if (!retried) {
|
|
701
753
|
retried = true;
|
|
702
|
-
await this.git.
|
|
703
|
-
{ cwd: commonPath, cancellation: cancellation },
|
|
754
|
+
await this.git.run(
|
|
755
|
+
{ cwd: commonPath, cancellation: cancellation, ...priorityOpts },
|
|
704
756
|
'remote',
|
|
705
757
|
'set-head',
|
|
706
758
|
'-a',
|
|
@@ -709,8 +761,8 @@ export class BranchesGitSubProvider implements GitBranchesSubProvider {
|
|
|
709
761
|
continue;
|
|
710
762
|
}
|
|
711
763
|
|
|
712
|
-
const result = await this.git.
|
|
713
|
-
{ cwd: commonPath, cancellation: cancellation },
|
|
764
|
+
const result = await this.git.run(
|
|
765
|
+
{ cwd: commonPath, cancellation: cancellation, ...priorityOpts },
|
|
714
766
|
'ls-remote',
|
|
715
767
|
'--symref',
|
|
716
768
|
remote,
|
|
@@ -741,7 +793,7 @@ export class BranchesGitSubProvider implements GitBranchesSubProvider {
|
|
|
741
793
|
args.push('--no-track');
|
|
742
794
|
}
|
|
743
795
|
try {
|
|
744
|
-
await this.git.
|
|
796
|
+
await this.git.run({ cwd: repoPath }, ...args);
|
|
745
797
|
this.context.hooks?.cache?.onReset?.(repoPath, 'branches');
|
|
746
798
|
this.context.hooks?.repository?.onChanged?.(repoPath, ['heads']);
|
|
747
799
|
} catch (ex) {
|
|
@@ -767,7 +819,7 @@ export class BranchesGitSubProvider implements GitBranchesSubProvider {
|
|
|
767
819
|
const branches = ensureArray(names);
|
|
768
820
|
const args = ['branch', options?.force ? '-D' : '-d', ...branches];
|
|
769
821
|
try {
|
|
770
|
-
await this.git.
|
|
822
|
+
await this.git.run({ cwd: repoPath }, ...args);
|
|
771
823
|
this.context.hooks?.cache?.onReset?.(repoPath, 'branches');
|
|
772
824
|
this.context.hooks?.repository?.onChanged?.(repoPath, ['heads']);
|
|
773
825
|
} catch (ex) {
|
|
@@ -795,7 +847,7 @@ export class BranchesGitSubProvider implements GitBranchesSubProvider {
|
|
|
795
847
|
const branches = ensureArray(names);
|
|
796
848
|
const args = ['push', '-d', remote, ...branches];
|
|
797
849
|
try {
|
|
798
|
-
await this.git.
|
|
850
|
+
await this.git.run({ cwd: repoPath }, ...args);
|
|
799
851
|
this.context.hooks?.cache?.onReset?.(repoPath, 'branches');
|
|
800
852
|
this.context.hooks?.repository?.onChanged?.(repoPath, ['remotes']);
|
|
801
853
|
} catch (ex) {
|
|
@@ -815,42 +867,67 @@ export class BranchesGitSubProvider implements GitBranchesSubProvider {
|
|
|
815
867
|
}
|
|
816
868
|
|
|
817
869
|
@debug()
|
|
818
|
-
|
|
870
|
+
getBranchMergedStatus(
|
|
819
871
|
repoPath: string,
|
|
820
872
|
branch: GitBranchReference,
|
|
821
873
|
into: GitBranchReference,
|
|
822
874
|
cancellation?: AbortSignal,
|
|
823
875
|
): Promise<GitBranchMergedStatus> {
|
|
824
876
|
if (branch.name === into.name || branch.upstream?.name === into.name) {
|
|
825
|
-
return { merged: false };
|
|
877
|
+
return Promise.resolve({ merged: false });
|
|
826
878
|
}
|
|
827
879
|
|
|
828
|
-
|
|
829
|
-
|
|
880
|
+
// Cache key omits repoPath so worktrees of the same common repo share the cached answer.
|
|
881
|
+
// Branch refs (`refs/heads/*` / `refs/remotes/*`) are unique within a common repo, so
|
|
882
|
+
// `name` + `remote` flag is the minimal stable identity.
|
|
883
|
+
const cacheKey = `${branch.remote ? 'r' : 'l'}:${branch.name}|${into.remote ? 'r' : 'l'}:${into.name}`;
|
|
830
884
|
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
}
|
|
848
|
-
|
|
885
|
+
return this.cache.getBranchMergedStatus(
|
|
886
|
+
repoPath,
|
|
887
|
+
cacheKey,
|
|
888
|
+
async (commonPath, _cacheable, signal) => {
|
|
889
|
+
const result = await this.getBranchMergedStatusCore(commonPath, branch, into, signal);
|
|
890
|
+
if (result.merged) return result;
|
|
891
|
+
|
|
892
|
+
// If the branch we are checking is a remote branch, check if it has been merged into its local branch (if there is one)
|
|
893
|
+
if (into.remote) {
|
|
894
|
+
const localIntoBranch = await this.getLocalBranchByUpstream(commonPath, into.name, signal);
|
|
895
|
+
// If there is a local branch and it is not the branch we are checking, check if it has been merged into it
|
|
896
|
+
if (localIntoBranch != null && localIntoBranch.name !== branch.name) {
|
|
897
|
+
// Skip the second full merge-check cycle when the local branch points at the same commit as the remote —
|
|
898
|
+
// the merge-base/cherry/diff/apply pipeline would produce the same answer we already got for `into` above
|
|
899
|
+
if (localIntoBranch.sha != null && localIntoBranch.sha === into.sha) {
|
|
900
|
+
return { merged: false };
|
|
901
|
+
}
|
|
902
|
+
|
|
903
|
+
const result = await this.getBranchMergedStatusCore(
|
|
904
|
+
commonPath,
|
|
905
|
+
branch,
|
|
906
|
+
localIntoBranch,
|
|
907
|
+
signal,
|
|
908
|
+
);
|
|
909
|
+
if (result.merged) {
|
|
910
|
+
// `localBranchOnly` is built against `commonPath` here; the cache mapper rewrites
|
|
911
|
+
// `repoPath`/`id` to the requesting worktree on retrieval.
|
|
912
|
+
return {
|
|
913
|
+
...result,
|
|
914
|
+
localBranchOnly: createReference(localIntoBranch.ref, localIntoBranch.repoPath, {
|
|
915
|
+
id: localIntoBranch.id,
|
|
916
|
+
refType: 'branch',
|
|
917
|
+
name: localIntoBranch.name,
|
|
918
|
+
remote: localIntoBranch.remote,
|
|
919
|
+
upstream: localIntoBranch.upstream,
|
|
920
|
+
sha: localIntoBranch.sha,
|
|
921
|
+
}),
|
|
922
|
+
};
|
|
923
|
+
}
|
|
924
|
+
}
|
|
849
925
|
}
|
|
850
|
-
}
|
|
851
|
-
}
|
|
852
926
|
|
|
853
|
-
|
|
927
|
+
return { merged: false };
|
|
928
|
+
},
|
|
929
|
+
cancellation,
|
|
930
|
+
);
|
|
854
931
|
}
|
|
855
932
|
|
|
856
933
|
private async getBranchMergedStatusCore(
|
|
@@ -864,7 +941,7 @@ export class BranchesGitSubProvider implements GitBranchesSubProvider {
|
|
|
864
941
|
try {
|
|
865
942
|
// Check if branch is direct ancestor (handles FF merges)
|
|
866
943
|
try {
|
|
867
|
-
await this.git.
|
|
944
|
+
await this.git.run(
|
|
868
945
|
{ cwd: repoPath, cancellation: cancellation, errors: 'throw' },
|
|
869
946
|
'merge-base',
|
|
870
947
|
'--is-ancestor',
|
|
@@ -877,7 +954,7 @@ export class BranchesGitSubProvider implements GitBranchesSubProvider {
|
|
|
877
954
|
}
|
|
878
955
|
|
|
879
956
|
// Cherry-pick detection (handles cherry-picks, rebases, etc)
|
|
880
|
-
let result = await this.git.
|
|
957
|
+
let result = await this.git.run(
|
|
881
958
|
{ cwd: repoPath, cancellation: cancellation },
|
|
882
959
|
'cherry',
|
|
883
960
|
'--abbrev',
|
|
@@ -904,7 +981,7 @@ export class BranchesGitSubProvider implements GitBranchesSubProvider {
|
|
|
904
981
|
undefined,
|
|
905
982
|
cancellation,
|
|
906
983
|
);
|
|
907
|
-
result = await this.git.
|
|
984
|
+
result = await this.git.run({ cwd: repoPath, cancellation: cancellation }, 'diff', mergeBase, branch.name);
|
|
908
985
|
if (result.stdout) {
|
|
909
986
|
// Create a temporary index file
|
|
910
987
|
await using disposableIndex = await this.provider.staging.createTemporaryIndex(
|
|
@@ -914,7 +991,7 @@ export class BranchesGitSubProvider implements GitBranchesSubProvider {
|
|
|
914
991
|
);
|
|
915
992
|
const { env } = disposableIndex;
|
|
916
993
|
|
|
917
|
-
result = await this.git.
|
|
994
|
+
result = await this.git.run(
|
|
918
995
|
{
|
|
919
996
|
cwd: repoPath,
|
|
920
997
|
cancellation: cancellation,
|
|
@@ -977,7 +1054,7 @@ export class BranchesGitSubProvider implements GitBranchesSubProvider {
|
|
|
977
1054
|
const parentRefs = shas.map(c => `${c}^`);
|
|
978
1055
|
let parentShas: string[];
|
|
979
1056
|
try {
|
|
980
|
-
const result = await this.git.
|
|
1057
|
+
const result = await this.git.run(
|
|
981
1058
|
{ cwd: repoPath, cancellation: signal, errors: 'throw' },
|
|
982
1059
|
'rev-parse',
|
|
983
1060
|
...parentRefs,
|
|
@@ -1022,7 +1099,7 @@ export class BranchesGitSubProvider implements GitBranchesSubProvider {
|
|
|
1022
1099
|
|
|
1023
1100
|
let data;
|
|
1024
1101
|
try {
|
|
1025
|
-
const result = await this.git.
|
|
1102
|
+
const result = await this.git.run(
|
|
1026
1103
|
{ cwd: repoPath, cancellation: signal, errors: 'throw' },
|
|
1027
1104
|
'merge-tree',
|
|
1028
1105
|
'-z',
|
|
@@ -1095,7 +1172,7 @@ export class BranchesGitSubProvider implements GitBranchesSubProvider {
|
|
|
1095
1172
|
let currentTreeOid: string;
|
|
1096
1173
|
try {
|
|
1097
1174
|
// Get the initial target branch tree OID
|
|
1098
|
-
const treeResult = await this.git.
|
|
1175
|
+
const treeResult = await this.git.run(
|
|
1099
1176
|
{ cwd: repoPath, cancellation: cancellation, errors: 'throw' },
|
|
1100
1177
|
'rev-parse',
|
|
1101
1178
|
`${targetBranch}^{tree}`,
|
|
@@ -1103,6 +1180,7 @@ export class BranchesGitSubProvider implements GitBranchesSubProvider {
|
|
|
1103
1180
|
currentTreeOid = treeResult.stdout.trim();
|
|
1104
1181
|
} catch (ex) {
|
|
1105
1182
|
if (isCancellationError(ex)) throw ex;
|
|
1183
|
+
|
|
1106
1184
|
scope?.error(ex, `Failed to resolve target branch '${targetBranch}'`);
|
|
1107
1185
|
return createConflictDetectionError('refNotFound');
|
|
1108
1186
|
}
|
|
@@ -1121,7 +1199,7 @@ export class BranchesGitSubProvider implements GitBranchesSubProvider {
|
|
|
1121
1199
|
// - base = commit.parent (where the commit started)
|
|
1122
1200
|
// - ours = currentTreeOid (current state of the target)
|
|
1123
1201
|
// - theirs = commit.sha (what we're cherry-picking)
|
|
1124
|
-
const result = await this.git.
|
|
1202
|
+
const result = await this.git.run(
|
|
1125
1203
|
{ cwd: repoPath, cancellation: cancellation, errors: 'throw' },
|
|
1126
1204
|
'merge-tree',
|
|
1127
1205
|
'--write-tree',
|
|
@@ -1210,47 +1288,82 @@ export class BranchesGitSubProvider implements GitBranchesSubProvider {
|
|
|
1210
1288
|
}
|
|
1211
1289
|
|
|
1212
1290
|
@debug({ exit: true })
|
|
1213
|
-
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
|
-
mergeBase = await this.provider.config.getConfig(repoPath, `branch.${ref}.vscode-merge-base`);
|
|
1222
|
-
update = mergeBase != null;
|
|
1223
|
-
}
|
|
1291
|
+
getBaseBranchName(
|
|
1292
|
+
repoPath: string,
|
|
1293
|
+
ref: string,
|
|
1294
|
+
options?: { priority?: GitCommandPriority },
|
|
1295
|
+
cancellation?: AbortSignal,
|
|
1296
|
+
): Promise<string | undefined> {
|
|
1297
|
+
const priority = options?.priority;
|
|
1298
|
+
const priorityOpts = priority != null ? { priority: priority } : undefined;
|
|
1224
1299
|
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
|
|
1300
|
+
return this.cache.getBaseBranchName(
|
|
1301
|
+
repoPath,
|
|
1302
|
+
ref,
|
|
1303
|
+
async (commonPath, signal) => {
|
|
1304
|
+
try {
|
|
1305
|
+
// getGkConfig has built-in fallback to regular config for backward compatibility
|
|
1306
|
+
let mergeBase = await this.provider.config.getGkConfig(commonPath, `branch.${ref}.gk-merge-base`);
|
|
1307
|
+
let update = false;
|
|
1308
|
+
|
|
1309
|
+
// Also check vscode-merge-base in regular config (VS Code compatibility)
|
|
1310
|
+
if (mergeBase == null) {
|
|
1311
|
+
mergeBase = await this.provider.config.getConfig(commonPath, `branch.${ref}.vscode-merge-base`);
|
|
1312
|
+
update = mergeBase != null;
|
|
1230
1313
|
}
|
|
1314
|
+
|
|
1315
|
+
if (mergeBase != null) {
|
|
1316
|
+
const branch = await this.provider.refs.getSymbolicReferenceName(
|
|
1317
|
+
commonPath,
|
|
1318
|
+
mergeBase,
|
|
1319
|
+
priorityOpts,
|
|
1320
|
+
);
|
|
1321
|
+
if (branch != null) {
|
|
1322
|
+
if (update) {
|
|
1323
|
+
// Self-write: the value we're storing is exactly what this factory is
|
|
1324
|
+
// returning, so any in-flight `branchOverviews` or `baseBranchName` entry
|
|
1325
|
+
// being populated against this resolution should NOT be evicted.
|
|
1326
|
+
void this.storeBaseBranchName(commonPath, ref, branch, {
|
|
1327
|
+
skipInvalidation: ['branchOverviews', 'baseBranchName'],
|
|
1328
|
+
});
|
|
1329
|
+
}
|
|
1330
|
+
return branch;
|
|
1331
|
+
}
|
|
1332
|
+
}
|
|
1333
|
+
} catch {}
|
|
1334
|
+
|
|
1335
|
+
const branch = await this.getBaseBranchFromReflog(
|
|
1336
|
+
commonPath,
|
|
1337
|
+
ref,
|
|
1338
|
+
{ upstream: true, priority: priority },
|
|
1339
|
+
signal,
|
|
1340
|
+
);
|
|
1341
|
+
if (branch != null) {
|
|
1342
|
+
// Self-write: see comment on the migration path above.
|
|
1343
|
+
void this.storeBaseBranchName(commonPath, ref, branch, {
|
|
1344
|
+
skipInvalidation: ['branchOverviews', 'baseBranchName'],
|
|
1345
|
+
});
|
|
1231
1346
|
return branch;
|
|
1232
1347
|
}
|
|
1233
|
-
}
|
|
1234
|
-
} catch {}
|
|
1235
|
-
|
|
1236
|
-
const branch = await this.getBaseBranchFromReflog(repoPath, ref, { upstream: true }, cancellation);
|
|
1237
|
-
if (branch != null) {
|
|
1238
|
-
void this.storeBaseBranchName(repoPath, ref, branch);
|
|
1239
|
-
return branch;
|
|
1240
|
-
}
|
|
1241
1348
|
|
|
1242
|
-
|
|
1349
|
+
return undefined;
|
|
1350
|
+
},
|
|
1351
|
+
cancellation,
|
|
1352
|
+
);
|
|
1243
1353
|
}
|
|
1244
1354
|
|
|
1245
1355
|
private async getBaseBranchFromReflog(
|
|
1246
1356
|
repoPath: string,
|
|
1247
1357
|
ref: string,
|
|
1248
|
-
options?: { upstream: true },
|
|
1358
|
+
options?: { upstream: true; priority?: GitCommandPriority },
|
|
1249
1359
|
cancellation?: AbortSignal,
|
|
1250
1360
|
): Promise<string | undefined> {
|
|
1361
|
+
const priority = options?.priority;
|
|
1362
|
+
const priorityOpts = priority != null ? { priority: priority } : undefined;
|
|
1363
|
+
|
|
1251
1364
|
try {
|
|
1252
|
-
let result = await this.git.
|
|
1253
|
-
{ cwd: repoPath, cancellation: cancellation },
|
|
1365
|
+
let result = await this.git.run(
|
|
1366
|
+
{ cwd: repoPath, cancellation: cancellation, ...priorityOpts },
|
|
1254
1367
|
'reflog',
|
|
1255
1368
|
ref,
|
|
1256
1369
|
'--grep-reflog=branch: Created from *.',
|
|
@@ -1265,18 +1378,22 @@ export class BranchesGitSubProvider implements GitBranchesSubProvider {
|
|
|
1265
1378
|
let name: string | undefined = match[1];
|
|
1266
1379
|
if (name !== 'HEAD') {
|
|
1267
1380
|
if (options?.upstream) {
|
|
1268
|
-
const upstream = await this.provider.refs.getSymbolicReferenceName(
|
|
1381
|
+
const upstream = await this.provider.refs.getSymbolicReferenceName(
|
|
1382
|
+
repoPath,
|
|
1383
|
+
`${name}@{u}`,
|
|
1384
|
+
priorityOpts,
|
|
1385
|
+
);
|
|
1269
1386
|
if (upstream) return upstream;
|
|
1270
1387
|
}
|
|
1271
1388
|
|
|
1272
|
-
name = await this.provider.refs.getSymbolicReferenceName(repoPath, name);
|
|
1389
|
+
name = await this.provider.refs.getSymbolicReferenceName(repoPath, name, priorityOpts);
|
|
1273
1390
|
if (name) return name;
|
|
1274
1391
|
}
|
|
1275
1392
|
}
|
|
1276
1393
|
|
|
1277
1394
|
// Check if branch was created from HEAD
|
|
1278
|
-
result = await this.git.
|
|
1279
|
-
{ cwd: repoPath, cancellation: cancellation },
|
|
1395
|
+
result = await this.git.run(
|
|
1396
|
+
{ cwd: repoPath, cancellation: cancellation, ...priorityOpts },
|
|
1280
1397
|
'reflog',
|
|
1281
1398
|
'HEAD',
|
|
1282
1399
|
`--grep-reflog=checkout: moving from .* to ${ref.replace('refs/heads/', '')}`,
|
|
@@ -1289,11 +1406,15 @@ export class BranchesGitSubProvider implements GitBranchesSubProvider {
|
|
|
1289
1406
|
if (match?.length === 2) {
|
|
1290
1407
|
let name: string | undefined = match[1];
|
|
1291
1408
|
if (options?.upstream) {
|
|
1292
|
-
const upstream = await this.provider.refs.getSymbolicReferenceName(
|
|
1409
|
+
const upstream = await this.provider.refs.getSymbolicReferenceName(
|
|
1410
|
+
repoPath,
|
|
1411
|
+
`${name}@{u}`,
|
|
1412
|
+
priorityOpts,
|
|
1413
|
+
);
|
|
1293
1414
|
if (upstream) return upstream;
|
|
1294
1415
|
}
|
|
1295
1416
|
|
|
1296
|
-
name = await this.provider.refs.getSymbolicReferenceName(repoPath, name);
|
|
1417
|
+
name = await this.provider.refs.getSymbolicReferenceName(repoPath, name, priorityOpts);
|
|
1297
1418
|
if (name) return name;
|
|
1298
1419
|
}
|
|
1299
1420
|
} catch (ex) {
|
|
@@ -1347,11 +1468,21 @@ export class BranchesGitSubProvider implements GitBranchesSubProvider {
|
|
|
1347
1468
|
await this.storeBranchMetadata(repoPath, 'gk-last-modified', branch.name, now);
|
|
1348
1469
|
}
|
|
1349
1470
|
|
|
1471
|
+
/** Updates the agent last activity timestamp for the current branch */
|
|
1472
|
+
@debounce(2.5 * 60 * 1000)
|
|
1473
|
+
@debug()
|
|
1474
|
+
async onCurrentBranchAgentActivity(repoPath: string): Promise<void> {
|
|
1475
|
+
const branch = await this.getBranch(repoPath);
|
|
1476
|
+
if (branch == null || branch.remote || branch.detached) return;
|
|
1477
|
+
|
|
1478
|
+
await this.storeBranchMetadata(repoPath, 'gk-agent-last-activity', branch.name, new Date());
|
|
1479
|
+
}
|
|
1480
|
+
|
|
1350
1481
|
@debug()
|
|
1351
1482
|
async renameBranch(repoPath: string, oldName: string, newName: string): Promise<void> {
|
|
1352
1483
|
const args = ['branch', '-m', oldName, newName];
|
|
1353
1484
|
try {
|
|
1354
|
-
await this.git.
|
|
1485
|
+
await this.git.run({ cwd: repoPath }, ...args);
|
|
1355
1486
|
this.context.hooks?.cache?.onReset?.(repoPath, 'branches');
|
|
1356
1487
|
this.context.hooks?.repository?.onChanged?.(repoPath, ['heads']);
|
|
1357
1488
|
} catch (ex) {
|
|
@@ -1377,7 +1508,7 @@ export class BranchesGitSubProvider implements GitBranchesSubProvider {
|
|
|
1377
1508
|
const args =
|
|
1378
1509
|
upstream == null ? ['branch', '--unset-upstream', name] : ['branch', '--set-upstream-to', upstream, name];
|
|
1379
1510
|
try {
|
|
1380
|
-
await this.git.
|
|
1511
|
+
await this.git.run({ cwd: repoPath }, ...args);
|
|
1381
1512
|
this.context.hooks?.cache?.onReset?.(repoPath, 'branches');
|
|
1382
1513
|
this.context.hooks?.repository?.onChanged?.(repoPath, ['heads']);
|
|
1383
1514
|
} catch (ex) {
|
|
@@ -1399,13 +1530,23 @@ export class BranchesGitSubProvider implements GitBranchesSubProvider {
|
|
|
1399
1530
|
}
|
|
1400
1531
|
|
|
1401
1532
|
@debug()
|
|
1402
|
-
async storeBaseBranchName(
|
|
1403
|
-
|
|
1533
|
+
async storeBaseBranchName(
|
|
1534
|
+
repoPath: string,
|
|
1535
|
+
ref: string,
|
|
1536
|
+
base: string,
|
|
1537
|
+
options?: { skipInvalidation?: readonly GkConfigInvalidationTarget[] },
|
|
1538
|
+
): Promise<void> {
|
|
1539
|
+
await this.provider.config.setGkConfig(repoPath, `branch.${ref}.gk-merge-base`, base, options);
|
|
1404
1540
|
}
|
|
1405
1541
|
|
|
1406
1542
|
@debug()
|
|
1407
|
-
async storeMergeTargetBranchName(
|
|
1408
|
-
|
|
1543
|
+
async storeMergeTargetBranchName(
|
|
1544
|
+
repoPath: string,
|
|
1545
|
+
ref: string,
|
|
1546
|
+
target: string,
|
|
1547
|
+
options?: { skipInvalidation?: readonly GkConfigInvalidationTarget[] },
|
|
1548
|
+
): Promise<void> {
|
|
1549
|
+
await this.provider.config.setGkConfig(repoPath, `branch.${ref}.gk-merge-target`, target, options);
|
|
1409
1550
|
}
|
|
1410
1551
|
|
|
1411
1552
|
@debug()
|
|
@@ -1417,56 +1558,60 @@ export class BranchesGitSubProvider implements GitBranchesSubProvider {
|
|
|
1417
1558
|
* Gets all branch metadata (dates and disposition) from git config in a single batch operation.
|
|
1418
1559
|
* @returns A map of branch name to metadata.
|
|
1419
1560
|
*/
|
|
1420
|
-
private
|
|
1421
|
-
|
|
1422
|
-
|
|
1561
|
+
private getBranchMetadataMap(repoPath: string): Promise<Map<string, BranchMetadata>> {
|
|
1562
|
+
return this.cache.getBranchMetadataMap(repoPath, async commonPath => {
|
|
1563
|
+
const scope = getScopedLogger();
|
|
1564
|
+
const metadataMap = new Map<string, BranchMetadata>();
|
|
1423
1565
|
|
|
1424
|
-
|
|
1425
|
-
|
|
1426
|
-
|
|
1427
|
-
|
|
1428
|
-
|
|
1429
|
-
|
|
1430
|
-
|
|
1566
|
+
try {
|
|
1567
|
+
// Use git config --get-regexp to load all gk-* branch metadata in one call
|
|
1568
|
+
const configMap = await this.provider.config.getGkConfigRegex(
|
|
1569
|
+
commonPath,
|
|
1570
|
+
'^branch\\..*\\.gk-(last-(accessed|modified)|disposition|agent-last-activity)$',
|
|
1571
|
+
);
|
|
1572
|
+
if (!configMap.size) return metadataMap;
|
|
1431
1573
|
|
|
1432
|
-
|
|
1433
|
-
|
|
1434
|
-
|
|
1574
|
+
for (const [key, value] of configMap) {
|
|
1575
|
+
// Extract branch name and metadata key from "branch.{name}.gk-{key}"
|
|
1576
|
+
if (!key.startsWith('branch.')) continue;
|
|
1435
1577
|
|
|
1436
|
-
|
|
1437
|
-
|
|
1578
|
+
const keyParts = key.split('.');
|
|
1579
|
+
if (keyParts.length < 3) continue;
|
|
1438
1580
|
|
|
1439
|
-
|
|
1440
|
-
|
|
1441
|
-
|
|
1581
|
+
// Branch name is everything between "branch." and the last ".gk-*"
|
|
1582
|
+
const metaKey = keyParts.at(-1);
|
|
1583
|
+
const branchName = keyParts.slice(1, -1).join('.');
|
|
1442
1584
|
|
|
1443
|
-
|
|
1444
|
-
|
|
1445
|
-
|
|
1446
|
-
|
|
1447
|
-
|
|
1585
|
+
let metadata = metadataMap.get(branchName);
|
|
1586
|
+
if (metadata == null) {
|
|
1587
|
+
metadata = {};
|
|
1588
|
+
metadataMap.set(branchName, metadata);
|
|
1589
|
+
}
|
|
1448
1590
|
|
|
1449
|
-
|
|
1450
|
-
|
|
1451
|
-
|
|
1452
|
-
|
|
1453
|
-
|
|
1454
|
-
|
|
1455
|
-
|
|
1591
|
+
if (metaKey === 'gk-last-accessed') {
|
|
1592
|
+
metadata.lastAccessedAt = value;
|
|
1593
|
+
} else if (metaKey === 'gk-last-modified') {
|
|
1594
|
+
metadata.lastModifiedAt = value;
|
|
1595
|
+
} else if (metaKey === 'gk-agent-last-activity') {
|
|
1596
|
+
metadata.agentLastActivityAt = value;
|
|
1597
|
+
} else if (metaKey === 'gk-disposition') {
|
|
1598
|
+
if (value === 'starred' || value === 'archived') {
|
|
1599
|
+
metadata.disposition = value;
|
|
1600
|
+
}
|
|
1456
1601
|
}
|
|
1457
1602
|
}
|
|
1603
|
+
} catch (ex) {
|
|
1604
|
+
debugger;
|
|
1605
|
+
scope?.error(ex);
|
|
1458
1606
|
}
|
|
1459
|
-
} catch (ex) {
|
|
1460
|
-
debugger;
|
|
1461
|
-
scope?.error(ex);
|
|
1462
|
-
}
|
|
1463
1607
|
|
|
1464
|
-
|
|
1608
|
+
return metadataMap;
|
|
1609
|
+
});
|
|
1465
1610
|
}
|
|
1466
1611
|
|
|
1467
1612
|
private async storeBranchMetadata(
|
|
1468
1613
|
repoPath: string,
|
|
1469
|
-
key: 'gk-last-accessed' | 'gk-last-modified',
|
|
1614
|
+
key: 'gk-last-accessed' | 'gk-last-modified' | 'gk-agent-last-activity',
|
|
1470
1615
|
ref: string,
|
|
1471
1616
|
date: Date,
|
|
1472
1617
|
): Promise<void> {
|