@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
|
@@ -75,7 +75,6 @@ import { getSettledValue } from '../../utils/promise.js';
|
|
|
75
75
|
import { maybeStopWatch } from '../../utils/stopwatch.js';
|
|
76
76
|
import { getGitCommandError, gitConfigsBranch, gitConfigsLog, GitError, GitErrors, GitWarnings } from '../exec/git.js';
|
|
77
77
|
import { parseMergeTreeConflict } from '../parsers/mergeTreeParser.js';
|
|
78
|
-
import { getBranchParser } from '../parsers/refParser.js';
|
|
79
78
|
/** Minimum time between writes to the config for last accessed/modified dates */
|
|
80
79
|
const dateMetadataStaleThresholdMs = 5 * 60 * 1000; // 5 minutes
|
|
81
80
|
export class BranchesGitSubProvider {
|
|
@@ -110,10 +109,10 @@ export class BranchesGitSubProvider {
|
|
|
110
109
|
return undefined;
|
|
111
110
|
const [pausedOpStatusResult, committerDateResult, defaultWorktreePathResult, metadataMapResult] = await Promise.allSettled([
|
|
112
111
|
isDetachedHead(ref.name)
|
|
113
|
-
? this.provider.pausedOps?.getPausedOperationStatus(repoPath, cancellation)
|
|
112
|
+
? this.provider.pausedOps?.getPausedOperationStatus(repoPath, undefined, cancellation)
|
|
114
113
|
: undefined,
|
|
115
114
|
this.git
|
|
116
|
-
.
|
|
115
|
+
.run({
|
|
117
116
|
cwd: repoPath,
|
|
118
117
|
cancellation: cancellation,
|
|
119
118
|
configs: gitConfigsLog,
|
|
@@ -147,32 +146,37 @@ export class BranchesGitSubProvider {
|
|
|
147
146
|
try {
|
|
148
147
|
const env_1 = { stack: [], error: void 0, hasError: false };
|
|
149
148
|
try {
|
|
150
|
-
const
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
this.git.exec({ cwd: commonPath, cancellation: signal }, 'for-each-ref', ...parser.arguments, 'refs/heads/', 'refs/remotes/'),
|
|
149
|
+
const [recordsResult, supportedResult, defaultWorktreePathResult, metadataMapResult] = await Promise.allSettled([
|
|
150
|
+
this.provider.refs.getRefs(commonPath, signal),
|
|
151
|
+
this.git.supported('git:for-each-ref'),
|
|
154
152
|
this.provider.config.getDefaultWorktreePath?.(commonPath),
|
|
155
153
|
this.getBranchMetadataMap(commonPath),
|
|
156
154
|
]);
|
|
157
|
-
const
|
|
155
|
+
const records = getSettledValue(recordsResult) ?? [];
|
|
156
|
+
const supported = getSettledValue(supportedResult) ?? [];
|
|
158
157
|
const metadataMap = getSettledValue(metadataMapResult) ?? new Map();
|
|
159
158
|
const defaultWorktreePath = getSettledValue(defaultWorktreePathResult);
|
|
159
|
+
const worktreePathSupported = supported.includes('git:for-each-ref:worktreePath');
|
|
160
160
|
// If we don't get any data, assume the repo doesn't have any commits yet so check if we have a current branch
|
|
161
|
-
if (!
|
|
161
|
+
if (!records.length) {
|
|
162
162
|
const current = await this.getCurrentBranch(commonPath, metadataMap, options?.ordering ?? this.context.config?.commits.ordering ?? undefined, signal);
|
|
163
163
|
return current != null ? { values: [current] } : emptyPagedResult;
|
|
164
164
|
}
|
|
165
165
|
const sw = __addDisposableResource(env_1, maybeStopWatch(scope, { log: { onlyExit: true, level: 'debug' } }), false);
|
|
166
166
|
const branches = [];
|
|
167
|
-
for (const
|
|
167
|
+
for (const record of records) {
|
|
168
|
+
const fullName = record.name;
|
|
169
|
+
// Filter to branches and remote-tracking branches; skip tags from the unified records.
|
|
170
|
+
if (!fullName.startsWith('refs/heads/') && !fullName.startsWith('refs/remotes/'))
|
|
171
|
+
continue;
|
|
168
172
|
// Skip HEAD refs in remote branches
|
|
169
|
-
if (isRemoteHEAD(
|
|
173
|
+
if (isRemoteHEAD(fullName))
|
|
170
174
|
continue;
|
|
171
|
-
const upstream = parseUpstream(
|
|
172
|
-
const metadata = metadataMap.get(parseRefName(
|
|
173
|
-
const worktreePath =
|
|
174
|
-
branches.push(new GitBranch(commonPath,
|
|
175
|
-
|
|
175
|
+
const upstream = parseUpstream(record.upstream, record.upstreamTracking);
|
|
176
|
+
const metadata = metadataMap.get(parseRefName(fullName).name);
|
|
177
|
+
const worktreePath = record.worktreePath ? normalizePath(record.worktreePath) : undefined;
|
|
178
|
+
branches.push(new GitBranch(commonPath, fullName, false, // Don't trust %(HEAD) for current as it's per-worktree -- we will set it later
|
|
179
|
+
record.committerDate ? new Date(record.committerDate) : undefined, metadata, record.objectname, upstream, worktreePathSupported
|
|
176
180
|
? worktreePath
|
|
177
181
|
? { path: worktreePath, isDefault: worktreePath === defaultWorktreePath }
|
|
178
182
|
: false
|
|
@@ -286,35 +290,25 @@ export class BranchesGitSubProvider {
|
|
|
286
290
|
}
|
|
287
291
|
async getBranchContributionsOverview(repoPath, ref, options, cancellation) {
|
|
288
292
|
const scope = getScopedLogger();
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
const storedTarget = await this.getStoredMergeTargetBranchName(repoPath, ref);
|
|
296
|
-
if (storedTarget) {
|
|
297
|
-
const validated = await this.provider.refs.getSymbolicReferenceName(repoPath, storedTarget);
|
|
298
|
-
mergeTarget = validated || storedTarget;
|
|
299
|
-
}
|
|
300
|
-
// Tier 2: PR-based lookup (caller provides the PR promise)
|
|
301
|
-
if (mergeTarget == null && options?.associatedPullRequest != null) {
|
|
302
|
-
const pr = await options.associatedPullRequest;
|
|
303
|
-
if (pr?.refs?.base != null) {
|
|
304
|
-
mergeTarget = `${branch.remoteName}/${pr.refs.base.branch}`;
|
|
305
|
-
// Store for future reuse
|
|
306
|
-
void this.storeMergeTargetBranchName(repoPath, ref, mergeTarget);
|
|
307
|
-
}
|
|
308
|
-
}
|
|
309
|
-
// Tier 3: Base branch, then default branch
|
|
310
|
-
mergeTarget ??= await this.getBaseBranchName(repoPath, ref, cancellation);
|
|
311
|
-
mergeTarget ??= await this.getDefaultBranchName(repoPath, undefined, cancellation);
|
|
312
|
-
if (mergeTarget == null)
|
|
313
|
-
return undefined;
|
|
314
|
-
const mergeBase = await this.provider.refs.getMergeBase(repoPath, ref, mergeTarget, undefined, cancellation);
|
|
293
|
+
const priority = options?.priority;
|
|
294
|
+
const priorityOpts = priority != null ? { priority: priority } : undefined;
|
|
295
|
+
// Expensive body — runs only on cache miss. Closes over `mergeTarget` so the cache key
|
|
296
|
+
// (`${ref}|${mergeTarget}`) fully captures every input that affects the result.
|
|
297
|
+
const fetchBody = async (mergeTarget, signal) => {
|
|
298
|
+
const mergeBase = await this.provider.refs.getMergeBase(repoPath, ref, mergeTarget, priorityOpts, signal);
|
|
315
299
|
if (mergeBase == null)
|
|
316
300
|
return undefined;
|
|
317
|
-
|
|
301
|
+
// Fetch the merge-base commit's dates in parallel with contributors so consumers
|
|
302
|
+
// (e.g. the graph minimap scope window) don't pay a separate round-trip for them.
|
|
303
|
+
// `allSettled` so a transient failure in one side doesn't drop the overview entirely.
|
|
304
|
+
const [contributorsSettled, mergeBaseDatesSettled] = await Promise.allSettled([
|
|
305
|
+
this.provider.contributors.getContributors(repoPath, createRevisionRange(mergeBase, ref, '..'), { stats: true }, signal),
|
|
306
|
+
this.provider.commits.getCommitDates(repoPath, mergeBase, signal),
|
|
307
|
+
]);
|
|
308
|
+
if (signal?.aborted)
|
|
309
|
+
throw new CancellationError();
|
|
310
|
+
const result = getSettledValue(contributorsSettled) ?? { contributors: [] };
|
|
311
|
+
const mergeBaseDates = getSettledValue(mergeBaseDatesSettled);
|
|
318
312
|
sortContributors(result.contributors, { orderBy: 'score:desc' });
|
|
319
313
|
let totalCommits = 0;
|
|
320
314
|
let totalFiles = 0;
|
|
@@ -345,6 +339,7 @@ export class BranchesGitSubProvider {
|
|
|
345
339
|
branch: ref,
|
|
346
340
|
mergeTarget: mergeTarget,
|
|
347
341
|
mergeBase: mergeBase,
|
|
342
|
+
mergeBaseDate: mergeBaseDates?.committerDate,
|
|
348
343
|
commits: totalCommits,
|
|
349
344
|
files: totalFiles,
|
|
350
345
|
additions: totalAdditions,
|
|
@@ -353,6 +348,49 @@ export class BranchesGitSubProvider {
|
|
|
353
348
|
firstCommitDate: firstCommitTimestamp != null ? new Date(firstCommitTimestamp) : undefined,
|
|
354
349
|
contributors: result.contributors,
|
|
355
350
|
};
|
|
351
|
+
};
|
|
352
|
+
try {
|
|
353
|
+
// Resolve `mergeTarget` through Tier 1 → Tier 2 → Tier 3. The pieces of each tier are
|
|
354
|
+
// already individually cached (`getStoredMergeTargetBranchName`, `getBaseBranchName`,
|
|
355
|
+
// `getDefaultBranchName`), so this resolution path is cheap on warm caches. Only the
|
|
356
|
+
// expensive body below (`getMergeBase` + `getContributors` w/ stats + `getCommitDates`)
|
|
357
|
+
// is wrapped by `cache.getBranchOverview`, keyed on the resolved `mergeTarget` so any
|
|
358
|
+
// caller that resolves to the same target shares; differing targets get independent
|
|
359
|
+
// slots, which is the correctness constraint that previously forced the Tier 2/3 paths
|
|
360
|
+
// to bypass the cache entirely.
|
|
361
|
+
let mergeTarget;
|
|
362
|
+
// Tier 1: Stored merge target (user-set or previously detected from PR).
|
|
363
|
+
const storedTarget = await this.getStoredMergeTargetBranchName(repoPath, ref);
|
|
364
|
+
if (storedTarget) {
|
|
365
|
+
const validated = await this.provider.refs.getSymbolicReferenceName(repoPath, storedTarget, priorityOpts, cancellation);
|
|
366
|
+
mergeTarget = validated || storedTarget;
|
|
367
|
+
}
|
|
368
|
+
// Tier 2: PR-based lookup. The branch object is only needed here (for `remoteName`),
|
|
369
|
+
// so lazy-load it on the cold path instead of paying for it on every call.
|
|
370
|
+
if (mergeTarget == null && options?.associatedPullRequest != null) {
|
|
371
|
+
const pr = await options.associatedPullRequest;
|
|
372
|
+
if (pr?.refs?.base != null) {
|
|
373
|
+
const branch = await this.getBranch(repoPath, ref, cancellation);
|
|
374
|
+
if (branch == null)
|
|
375
|
+
return undefined;
|
|
376
|
+
mergeTarget = `${branch.remoteName}/${pr.refs.base.branch}`;
|
|
377
|
+
// Store for future reuse — turns the next call into a Tier 1 path. Skip the
|
|
378
|
+
// `branchOverviews` invalidation that the write would otherwise trigger: we're
|
|
379
|
+
// about to populate `${ref}|${mergeTarget}` with this exact target, so evicting
|
|
380
|
+
// it would just force the next caller to redo the body. (gk-merge-target writes
|
|
381
|
+
// do not affect `baseBranchName`, so no need to skip that target.)
|
|
382
|
+
void this.storeMergeTargetBranchName(repoPath, ref, mergeTarget, {
|
|
383
|
+
skipInvalidation: ['branchOverviews'],
|
|
384
|
+
});
|
|
385
|
+
}
|
|
386
|
+
}
|
|
387
|
+
// Tier 3: Base branch, then default branch.
|
|
388
|
+
mergeTarget ??= await this.getBaseBranchName(repoPath, ref, priorityOpts, cancellation);
|
|
389
|
+
mergeTarget ??= await this.getDefaultBranchName(repoPath, undefined, priorityOpts, cancellation);
|
|
390
|
+
if (mergeTarget == null)
|
|
391
|
+
return undefined;
|
|
392
|
+
const resolvedTarget = mergeTarget;
|
|
393
|
+
return await this.cache.getBranchOverview(repoPath, `${ref}|${resolvedTarget}`, (_commonPath, _cacheable, signal) => fetchBody(resolvedTarget, signal ?? cancellation), { cancellation: cancellation });
|
|
356
394
|
}
|
|
357
395
|
catch (ex) {
|
|
358
396
|
scope?.error(ex);
|
|
@@ -387,7 +425,7 @@ export class BranchesGitSubProvider {
|
|
|
387
425
|
if (options?.name != null) {
|
|
388
426
|
params.push(options.name);
|
|
389
427
|
}
|
|
390
|
-
return this.git.
|
|
428
|
+
return this.git.run({
|
|
391
429
|
cwd: repoPath,
|
|
392
430
|
cancellation: cancellation,
|
|
393
431
|
configs: gitConfigsBranch,
|
|
@@ -414,7 +452,7 @@ export class BranchesGitSubProvider {
|
|
|
414
452
|
let data;
|
|
415
453
|
let result;
|
|
416
454
|
try {
|
|
417
|
-
result = await this.git.
|
|
455
|
+
result = await this.git.run({ cwd: repoPath, cancellation: signal, errors: 'throw' }, 'rev-parse', '--abbrev-ref', '--symbolic-full-name', '@', '@{u}', '--');
|
|
418
456
|
data = [result.stdout, undefined];
|
|
419
457
|
}
|
|
420
458
|
catch (ex) {
|
|
@@ -427,7 +465,7 @@ export class BranchesGitSubProvider {
|
|
|
427
465
|
}
|
|
428
466
|
else {
|
|
429
467
|
try {
|
|
430
|
-
result = await this.git.
|
|
468
|
+
result = await this.git.run({ cwd: repoPath, cancellation: signal }, 'symbolic-ref', '--short', 'HEAD');
|
|
431
469
|
if (result.stdout) {
|
|
432
470
|
data = [result.stdout.trim(), undefined];
|
|
433
471
|
}
|
|
@@ -437,7 +475,7 @@ export class BranchesGitSubProvider {
|
|
|
437
475
|
throw ex;
|
|
438
476
|
}
|
|
439
477
|
if (data == null) {
|
|
440
|
-
const symbolicRef = await this.getDefaultBranchName(repoPath, 'origin', signal);
|
|
478
|
+
const symbolicRef = await this.getDefaultBranchName(repoPath, 'origin', undefined, signal);
|
|
441
479
|
if (symbolicRef != null) {
|
|
442
480
|
data = [
|
|
443
481
|
symbolicRef.startsWith('origin/')
|
|
@@ -463,7 +501,7 @@ export class BranchesGitSubProvider {
|
|
|
463
501
|
}
|
|
464
502
|
}
|
|
465
503
|
else if (GitWarnings.headNotABranch.test(msg)) {
|
|
466
|
-
result = await this.git.
|
|
504
|
+
result = await this.git.run({
|
|
467
505
|
cwd: repoPath,
|
|
468
506
|
cancellation: signal,
|
|
469
507
|
configs: gitConfigsLog,
|
|
@@ -494,15 +532,17 @@ export class BranchesGitSubProvider {
|
|
|
494
532
|
});
|
|
495
533
|
}, { cancellation: cancellation });
|
|
496
534
|
}
|
|
497
|
-
async getDefaultBranchName(repoPath, remote, cancellation) {
|
|
535
|
+
async getDefaultBranchName(repoPath, remote, options, cancellation) {
|
|
498
536
|
if (repoPath == null)
|
|
499
537
|
return undefined;
|
|
500
538
|
remote ??= 'origin';
|
|
539
|
+
const priority = options?.priority;
|
|
540
|
+
const priorityOpts = priority != null ? { priority: priority } : undefined;
|
|
501
541
|
return this.cache.getDefaultBranchName(repoPath, remote, async (commonPath) => {
|
|
502
542
|
let retried = false;
|
|
503
543
|
while (true) {
|
|
504
544
|
try {
|
|
505
|
-
const result = await this.git.
|
|
545
|
+
const result = await this.git.run({ cwd: commonPath, cancellation: cancellation, ...priorityOpts }, 'symbolic-ref', '--short', `refs/remotes/${remote}/HEAD`);
|
|
506
546
|
return result.stdout.trim() || undefined;
|
|
507
547
|
}
|
|
508
548
|
catch (ex) {
|
|
@@ -510,10 +550,10 @@ export class BranchesGitSubProvider {
|
|
|
510
550
|
try {
|
|
511
551
|
if (!retried) {
|
|
512
552
|
retried = true;
|
|
513
|
-
await this.git.
|
|
553
|
+
await this.git.run({ cwd: commonPath, cancellation: cancellation, ...priorityOpts }, 'remote', 'set-head', '-a', remote);
|
|
514
554
|
continue;
|
|
515
555
|
}
|
|
516
|
-
const result = await this.git.
|
|
556
|
+
const result = await this.git.run({ cwd: commonPath, cancellation: cancellation, ...priorityOpts }, 'ls-remote', '--symref', remote, 'HEAD');
|
|
517
557
|
if (result.stdout) {
|
|
518
558
|
const match = /ref:\s(\S+)\s+HEAD/m.exec(result.stdout);
|
|
519
559
|
if (match != null) {
|
|
@@ -538,7 +578,7 @@ export class BranchesGitSubProvider {
|
|
|
538
578
|
args.push('--no-track');
|
|
539
579
|
}
|
|
540
580
|
try {
|
|
541
|
-
await this.git.
|
|
581
|
+
await this.git.run({ cwd: repoPath }, ...args);
|
|
542
582
|
this.context.hooks?.cache?.onReset?.(repoPath, 'branches');
|
|
543
583
|
this.context.hooks?.repository?.onChanged?.(repoPath, ['heads']);
|
|
544
584
|
}
|
|
@@ -555,7 +595,7 @@ export class BranchesGitSubProvider {
|
|
|
555
595
|
const branches = ensureArray(names);
|
|
556
596
|
const args = ['branch', options?.force ? '-D' : '-d', ...branches];
|
|
557
597
|
try {
|
|
558
|
-
await this.git.
|
|
598
|
+
await this.git.run({ cwd: repoPath }, ...args);
|
|
559
599
|
this.context.hooks?.cache?.onReset?.(repoPath, 'branches');
|
|
560
600
|
this.context.hooks?.repository?.onChanged?.(repoPath, ['heads']);
|
|
561
601
|
}
|
|
@@ -578,7 +618,7 @@ export class BranchesGitSubProvider {
|
|
|
578
618
|
const branches = ensureArray(names);
|
|
579
619
|
const args = ['push', '-d', remote, ...branches];
|
|
580
620
|
try {
|
|
581
|
-
await this.git.
|
|
621
|
+
await this.git.run({ cwd: repoPath }, ...args);
|
|
582
622
|
this.context.hooks?.cache?.onReset?.(repoPath, 'branches');
|
|
583
623
|
this.context.hooks?.repository?.onChanged?.(repoPath, ['remotes']);
|
|
584
624
|
}
|
|
@@ -593,42 +633,55 @@ export class BranchesGitSubProvider {
|
|
|
593
633
|
throw new BranchError({ action: 'delete', branch: branches.join(', '), gitCommand: { repoPath: repoPath, args: args } }, ex);
|
|
594
634
|
}
|
|
595
635
|
}
|
|
596
|
-
|
|
636
|
+
getBranchMergedStatus(repoPath, branch, into, cancellation) {
|
|
597
637
|
if (branch.name === into.name || branch.upstream?.name === into.name) {
|
|
598
|
-
return { merged: false };
|
|
638
|
+
return Promise.resolve({ merged: false });
|
|
599
639
|
}
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
const
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
640
|
+
// Cache key omits repoPath so worktrees of the same common repo share the cached answer.
|
|
641
|
+
// Branch refs (`refs/heads/*` / `refs/remotes/*`) are unique within a common repo, so
|
|
642
|
+
// `name` + `remote` flag is the minimal stable identity.
|
|
643
|
+
const cacheKey = `${branch.remote ? 'r' : 'l'}:${branch.name}|${into.remote ? 'r' : 'l'}:${into.name}`;
|
|
644
|
+
return this.cache.getBranchMergedStatus(repoPath, cacheKey, async (commonPath, _cacheable, signal) => {
|
|
645
|
+
const result = await this.getBranchMergedStatusCore(commonPath, branch, into, signal);
|
|
646
|
+
if (result.merged)
|
|
647
|
+
return result;
|
|
648
|
+
// If the branch we are checking is a remote branch, check if it has been merged into its local branch (if there is one)
|
|
649
|
+
if (into.remote) {
|
|
650
|
+
const localIntoBranch = await this.getLocalBranchByUpstream(commonPath, into.name, signal);
|
|
651
|
+
// If there is a local branch and it is not the branch we are checking, check if it has been merged into it
|
|
652
|
+
if (localIntoBranch != null && localIntoBranch.name !== branch.name) {
|
|
653
|
+
// Skip the second full merge-check cycle when the local branch points at the same commit as the remote —
|
|
654
|
+
// the merge-base/cherry/diff/apply pipeline would produce the same answer we already got for `into` above
|
|
655
|
+
if (localIntoBranch.sha != null && localIntoBranch.sha === into.sha) {
|
|
656
|
+
return { merged: false };
|
|
657
|
+
}
|
|
658
|
+
const result = await this.getBranchMergedStatusCore(commonPath, branch, localIntoBranch, signal);
|
|
659
|
+
if (result.merged) {
|
|
660
|
+
// `localBranchOnly` is built against `commonPath` here; the cache mapper rewrites
|
|
661
|
+
// `repoPath`/`id` to the requesting worktree on retrieval.
|
|
662
|
+
return {
|
|
663
|
+
...result,
|
|
664
|
+
localBranchOnly: createReference(localIntoBranch.ref, localIntoBranch.repoPath, {
|
|
665
|
+
id: localIntoBranch.id,
|
|
666
|
+
refType: 'branch',
|
|
667
|
+
name: localIntoBranch.name,
|
|
668
|
+
remote: localIntoBranch.remote,
|
|
669
|
+
upstream: localIntoBranch.upstream,
|
|
670
|
+
sha: localIntoBranch.sha,
|
|
671
|
+
}),
|
|
672
|
+
};
|
|
673
|
+
}
|
|
621
674
|
}
|
|
622
675
|
}
|
|
623
|
-
|
|
624
|
-
|
|
676
|
+
return { merged: false };
|
|
677
|
+
}, cancellation);
|
|
625
678
|
}
|
|
626
679
|
async getBranchMergedStatusCore(repoPath, branch, into, cancellation) {
|
|
627
680
|
const scope = getScopedLogger();
|
|
628
681
|
try {
|
|
629
682
|
// Check if branch is direct ancestor (handles FF merges)
|
|
630
683
|
try {
|
|
631
|
-
await this.git.
|
|
684
|
+
await this.git.run({ cwd: repoPath, cancellation: cancellation, errors: 'throw' }, 'merge-base', '--is-ancestor', branch.name, into.name);
|
|
632
685
|
return { merged: true, confidence: 'highest' };
|
|
633
686
|
}
|
|
634
687
|
catch (ex) {
|
|
@@ -636,7 +689,7 @@ export class BranchesGitSubProvider {
|
|
|
636
689
|
throw ex;
|
|
637
690
|
}
|
|
638
691
|
// Cherry-pick detection (handles cherry-picks, rebases, etc)
|
|
639
|
-
let result = await this.git.
|
|
692
|
+
let result = await this.git.run({ cwd: repoPath, cancellation: cancellation }, 'cherry', '--abbrev', '-v', into.name, branch.name);
|
|
640
693
|
// Check if there are no lines or all lines startwith a `-` (i.e. likely merged)
|
|
641
694
|
if (!result.stdout ||
|
|
642
695
|
result.stdout
|
|
@@ -647,14 +700,14 @@ export class BranchesGitSubProvider {
|
|
|
647
700
|
}
|
|
648
701
|
// Attempt to detect squash merges by checking if the diff of the branch can be cleanly removed from the target
|
|
649
702
|
const mergeBase = await this.provider.refs.getMergeBase(repoPath, into.name, branch.name, undefined, cancellation);
|
|
650
|
-
result = await this.git.
|
|
703
|
+
result = await this.git.run({ cwd: repoPath, cancellation: cancellation }, 'diff', mergeBase, branch.name);
|
|
651
704
|
if (result.stdout) {
|
|
652
705
|
const env_2 = { stack: [], error: void 0, hasError: false };
|
|
653
706
|
try {
|
|
654
707
|
// Create a temporary index file
|
|
655
708
|
const disposableIndex = __addDisposableResource(env_2, await this.provider.staging.createTemporaryIndex(repoPath, 'ref', into.name), true);
|
|
656
709
|
const { env } = disposableIndex;
|
|
657
|
-
result = await this.git.
|
|
710
|
+
result = await this.git.run({
|
|
658
711
|
cwd: repoPath,
|
|
659
712
|
cancellation: cancellation,
|
|
660
713
|
env: env,
|
|
@@ -700,7 +753,7 @@ export class BranchesGitSubProvider {
|
|
|
700
753
|
const parentRefs = shas.map(c => `${c}^`);
|
|
701
754
|
let parentShas;
|
|
702
755
|
try {
|
|
703
|
-
const result = await this.git.
|
|
756
|
+
const result = await this.git.run({ cwd: repoPath, cancellation: signal, errors: 'throw' }, 'rev-parse', ...parentRefs);
|
|
704
757
|
parentShas = result.stdout.trim().split('\n');
|
|
705
758
|
}
|
|
706
759
|
catch (ex) {
|
|
@@ -727,7 +780,7 @@ export class BranchesGitSubProvider {
|
|
|
727
780
|
}
|
|
728
781
|
let data;
|
|
729
782
|
try {
|
|
730
|
-
const result = await this.git.
|
|
783
|
+
const result = await this.git.run({ cwd: repoPath, cancellation: signal, errors: 'throw' }, 'merge-tree', '-z', '--name-only', '--no-messages', branch, targetBranch);
|
|
731
784
|
data = result.stdout;
|
|
732
785
|
}
|
|
733
786
|
catch (ex) {
|
|
@@ -780,7 +833,7 @@ export class BranchesGitSubProvider {
|
|
|
780
833
|
let currentTreeOid;
|
|
781
834
|
try {
|
|
782
835
|
// Get the initial target branch tree OID
|
|
783
|
-
const treeResult = await this.git.
|
|
836
|
+
const treeResult = await this.git.run({ cwd: repoPath, cancellation: cancellation, errors: 'throw' }, 'rev-parse', `${targetBranch}^{tree}`);
|
|
784
837
|
currentTreeOid = treeResult.stdout.trim();
|
|
785
838
|
}
|
|
786
839
|
catch (ex) {
|
|
@@ -802,7 +855,7 @@ export class BranchesGitSubProvider {
|
|
|
802
855
|
// - base = commit.parent (where the commit started)
|
|
803
856
|
// - ours = currentTreeOid (current state of the target)
|
|
804
857
|
// - theirs = commit.sha (what we're cherry-picking)
|
|
805
|
-
const result = await this.git.
|
|
858
|
+
const result = await this.git.run({ cwd: repoPath, cancellation: cancellation, errors: 'throw' }, 'merge-tree', '--write-tree', '-z', '--name-only', '--no-messages', `--merge-base=${commit.parent}`, currentTreeOid, commit.sha);
|
|
806
859
|
data = result.stdout;
|
|
807
860
|
}
|
|
808
861
|
catch (ex) {
|
|
@@ -872,37 +925,51 @@ export class BranchesGitSubProvider {
|
|
|
872
925
|
}
|
|
873
926
|
return { status: 'clean' };
|
|
874
927
|
}
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
928
|
+
getBaseBranchName(repoPath, ref, options, cancellation) {
|
|
929
|
+
const priority = options?.priority;
|
|
930
|
+
const priorityOpts = priority != null ? { priority: priority } : undefined;
|
|
931
|
+
return this.cache.getBaseBranchName(repoPath, ref, async (commonPath, signal) => {
|
|
932
|
+
try {
|
|
933
|
+
// getGkConfig has built-in fallback to regular config for backward compatibility
|
|
934
|
+
let mergeBase = await this.provider.config.getGkConfig(commonPath, `branch.${ref}.gk-merge-base`);
|
|
935
|
+
let update = false;
|
|
936
|
+
// Also check vscode-merge-base in regular config (VS Code compatibility)
|
|
937
|
+
if (mergeBase == null) {
|
|
938
|
+
mergeBase = await this.provider.config.getConfig(commonPath, `branch.${ref}.vscode-merge-base`);
|
|
939
|
+
update = mergeBase != null;
|
|
940
|
+
}
|
|
941
|
+
if (mergeBase != null) {
|
|
942
|
+
const branch = await this.provider.refs.getSymbolicReferenceName(commonPath, mergeBase, priorityOpts);
|
|
943
|
+
if (branch != null) {
|
|
944
|
+
if (update) {
|
|
945
|
+
// Self-write: the value we're storing is exactly what this factory is
|
|
946
|
+
// returning, so any in-flight `branchOverviews` or `baseBranchName` entry
|
|
947
|
+
// being populated against this resolution should NOT be evicted.
|
|
948
|
+
void this.storeBaseBranchName(commonPath, ref, branch, {
|
|
949
|
+
skipInvalidation: ['branchOverviews', 'baseBranchName'],
|
|
950
|
+
});
|
|
951
|
+
}
|
|
952
|
+
return branch;
|
|
890
953
|
}
|
|
891
|
-
return branch;
|
|
892
954
|
}
|
|
893
955
|
}
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
956
|
+
catch { }
|
|
957
|
+
const branch = await this.getBaseBranchFromReflog(commonPath, ref, { upstream: true, priority: priority }, signal);
|
|
958
|
+
if (branch != null) {
|
|
959
|
+
// Self-write: see comment on the migration path above.
|
|
960
|
+
void this.storeBaseBranchName(commonPath, ref, branch, {
|
|
961
|
+
skipInvalidation: ['branchOverviews', 'baseBranchName'],
|
|
962
|
+
});
|
|
963
|
+
return branch;
|
|
964
|
+
}
|
|
965
|
+
return undefined;
|
|
966
|
+
}, cancellation);
|
|
902
967
|
}
|
|
903
968
|
async getBaseBranchFromReflog(repoPath, ref, options, cancellation) {
|
|
969
|
+
const priority = options?.priority;
|
|
970
|
+
const priorityOpts = priority != null ? { priority: priority } : undefined;
|
|
904
971
|
try {
|
|
905
|
-
let result = await this.git.
|
|
972
|
+
let result = await this.git.run({ cwd: repoPath, cancellation: cancellation, ...priorityOpts }, 'reflog', ref, '--grep-reflog=branch: Created from *.');
|
|
906
973
|
let entries = result.stdout.split('\n').filter(entry => Boolean(entry));
|
|
907
974
|
if (entries.length !== 1)
|
|
908
975
|
return undefined;
|
|
@@ -912,17 +979,17 @@ export class BranchesGitSubProvider {
|
|
|
912
979
|
let name = match[1];
|
|
913
980
|
if (name !== 'HEAD') {
|
|
914
981
|
if (options?.upstream) {
|
|
915
|
-
const upstream = await this.provider.refs.getSymbolicReferenceName(repoPath, `${name}@{u}
|
|
982
|
+
const upstream = await this.provider.refs.getSymbolicReferenceName(repoPath, `${name}@{u}`, priorityOpts);
|
|
916
983
|
if (upstream)
|
|
917
984
|
return upstream;
|
|
918
985
|
}
|
|
919
|
-
name = await this.provider.refs.getSymbolicReferenceName(repoPath, name);
|
|
986
|
+
name = await this.provider.refs.getSymbolicReferenceName(repoPath, name, priorityOpts);
|
|
920
987
|
if (name)
|
|
921
988
|
return name;
|
|
922
989
|
}
|
|
923
990
|
}
|
|
924
991
|
// Check if branch was created from HEAD
|
|
925
|
-
result = await this.git.
|
|
992
|
+
result = await this.git.run({ cwd: repoPath, cancellation: cancellation, ...priorityOpts }, 'reflog', 'HEAD', `--grep-reflog=checkout: moving from .* to ${ref.replace('refs/heads/', '')}`);
|
|
926
993
|
entries = result.stdout.split('\n').filter(entry => Boolean(entry));
|
|
927
994
|
if (!entries.length)
|
|
928
995
|
return undefined;
|
|
@@ -930,11 +997,11 @@ export class BranchesGitSubProvider {
|
|
|
930
997
|
if (match?.length === 2) {
|
|
931
998
|
let name = match[1];
|
|
932
999
|
if (options?.upstream) {
|
|
933
|
-
const upstream = await this.provider.refs.getSymbolicReferenceName(repoPath, `${name}@{u}
|
|
1000
|
+
const upstream = await this.provider.refs.getSymbolicReferenceName(repoPath, `${name}@{u}`, priorityOpts);
|
|
934
1001
|
if (upstream)
|
|
935
1002
|
return upstream;
|
|
936
1003
|
}
|
|
937
|
-
name = await this.provider.refs.getSymbolicReferenceName(repoPath, name);
|
|
1004
|
+
name = await this.provider.refs.getSymbolicReferenceName(repoPath, name, priorityOpts);
|
|
938
1005
|
if (name)
|
|
939
1006
|
return name;
|
|
940
1007
|
}
|
|
@@ -975,10 +1042,17 @@ export class BranchesGitSubProvider {
|
|
|
975
1042
|
await this.storeBranchMetadata(repoPath, 'gk-last-accessed', branch.name, now);
|
|
976
1043
|
await this.storeBranchMetadata(repoPath, 'gk-last-modified', branch.name, now);
|
|
977
1044
|
}
|
|
1045
|
+
/** Updates the agent last activity timestamp for the current branch */
|
|
1046
|
+
async onCurrentBranchAgentActivity(repoPath) {
|
|
1047
|
+
const branch = await this.getBranch(repoPath);
|
|
1048
|
+
if (branch == null || branch.remote || branch.detached)
|
|
1049
|
+
return;
|
|
1050
|
+
await this.storeBranchMetadata(repoPath, 'gk-agent-last-activity', branch.name, new Date());
|
|
1051
|
+
}
|
|
978
1052
|
async renameBranch(repoPath, oldName, newName) {
|
|
979
1053
|
const args = ['branch', '-m', oldName, newName];
|
|
980
1054
|
try {
|
|
981
|
-
await this.git.
|
|
1055
|
+
await this.git.run({ cwd: repoPath }, ...args);
|
|
982
1056
|
this.context.hooks?.cache?.onReset?.(repoPath, 'branches');
|
|
983
1057
|
this.context.hooks?.repository?.onChanged?.(repoPath, ['heads']);
|
|
984
1058
|
}
|
|
@@ -994,7 +1068,7 @@ export class BranchesGitSubProvider {
|
|
|
994
1068
|
async setUpstreamBranch(repoPath, name, upstream) {
|
|
995
1069
|
const args = upstream == null ? ['branch', '--unset-upstream', name] : ['branch', '--set-upstream-to', upstream, name];
|
|
996
1070
|
try {
|
|
997
|
-
await this.git.
|
|
1071
|
+
await this.git.run({ cwd: repoPath }, ...args);
|
|
998
1072
|
this.context.hooks?.cache?.onReset?.(repoPath, 'branches');
|
|
999
1073
|
this.context.hooks?.repository?.onChanged?.(repoPath, ['heads']);
|
|
1000
1074
|
}
|
|
@@ -1007,11 +1081,11 @@ export class BranchesGitSubProvider {
|
|
|
1007
1081
|
}, ex));
|
|
1008
1082
|
}
|
|
1009
1083
|
}
|
|
1010
|
-
async storeBaseBranchName(repoPath, ref, base) {
|
|
1011
|
-
await this.provider.config.setGkConfig(repoPath, `branch.${ref}.gk-merge-base`, base);
|
|
1084
|
+
async storeBaseBranchName(repoPath, ref, base, options) {
|
|
1085
|
+
await this.provider.config.setGkConfig(repoPath, `branch.${ref}.gk-merge-base`, base, options);
|
|
1012
1086
|
}
|
|
1013
|
-
async storeMergeTargetBranchName(repoPath, ref, target) {
|
|
1014
|
-
await this.provider.config.setGkConfig(repoPath, `branch.${ref}.gk-merge-target`, target);
|
|
1087
|
+
async storeMergeTargetBranchName(repoPath, ref, target, options) {
|
|
1088
|
+
await this.provider.config.setGkConfig(repoPath, `branch.${ref}.gk-merge-target`, target, options);
|
|
1015
1089
|
}
|
|
1016
1090
|
async storeUserMergeTargetBranchName(repoPath, ref, target) {
|
|
1017
1091
|
await this.provider.config.setGkConfig(repoPath, `branch.${ref}.gk-merge-target-user`, target);
|
|
@@ -1020,47 +1094,52 @@ export class BranchesGitSubProvider {
|
|
|
1020
1094
|
* Gets all branch metadata (dates and disposition) from git config in a single batch operation.
|
|
1021
1095
|
* @returns A map of branch name to metadata.
|
|
1022
1096
|
*/
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
metadata
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
if (
|
|
1054
|
-
metadata.
|
|
1097
|
+
getBranchMetadataMap(repoPath) {
|
|
1098
|
+
return this.cache.getBranchMetadataMap(repoPath, async (commonPath) => {
|
|
1099
|
+
const scope = getScopedLogger();
|
|
1100
|
+
const metadataMap = new Map();
|
|
1101
|
+
try {
|
|
1102
|
+
// Use git config --get-regexp to load all gk-* branch metadata in one call
|
|
1103
|
+
const configMap = await this.provider.config.getGkConfigRegex(commonPath, '^branch\\..*\\.gk-(last-(accessed|modified)|disposition|agent-last-activity)$');
|
|
1104
|
+
if (!configMap.size)
|
|
1105
|
+
return metadataMap;
|
|
1106
|
+
for (const [key, value] of configMap) {
|
|
1107
|
+
// Extract branch name and metadata key from "branch.{name}.gk-{key}"
|
|
1108
|
+
if (!key.startsWith('branch.'))
|
|
1109
|
+
continue;
|
|
1110
|
+
const keyParts = key.split('.');
|
|
1111
|
+
if (keyParts.length < 3)
|
|
1112
|
+
continue;
|
|
1113
|
+
// Branch name is everything between "branch." and the last ".gk-*"
|
|
1114
|
+
const metaKey = keyParts.at(-1);
|
|
1115
|
+
const branchName = keyParts.slice(1, -1).join('.');
|
|
1116
|
+
let metadata = metadataMap.get(branchName);
|
|
1117
|
+
if (metadata == null) {
|
|
1118
|
+
metadata = {};
|
|
1119
|
+
metadataMap.set(branchName, metadata);
|
|
1120
|
+
}
|
|
1121
|
+
if (metaKey === 'gk-last-accessed') {
|
|
1122
|
+
metadata.lastAccessedAt = value;
|
|
1123
|
+
}
|
|
1124
|
+
else if (metaKey === 'gk-last-modified') {
|
|
1125
|
+
metadata.lastModifiedAt = value;
|
|
1126
|
+
}
|
|
1127
|
+
else if (metaKey === 'gk-agent-last-activity') {
|
|
1128
|
+
metadata.agentLastActivityAt = value;
|
|
1129
|
+
}
|
|
1130
|
+
else if (metaKey === 'gk-disposition') {
|
|
1131
|
+
if (value === 'starred' || value === 'archived') {
|
|
1132
|
+
metadata.disposition = value;
|
|
1133
|
+
}
|
|
1055
1134
|
}
|
|
1056
1135
|
}
|
|
1057
1136
|
}
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1137
|
+
catch (ex) {
|
|
1138
|
+
debugger;
|
|
1139
|
+
scope?.error(ex);
|
|
1140
|
+
}
|
|
1141
|
+
return metadataMap;
|
|
1142
|
+
});
|
|
1064
1143
|
}
|
|
1065
1144
|
async storeBranchMetadata(repoPath, key, ref, date) {
|
|
1066
1145
|
const value = await this.provider.config.getGkConfig(repoPath, `branch.${ref}.${key}`);
|
|
@@ -1135,6 +1214,10 @@ __decorate([
|
|
|
1135
1214
|
debounce(2.5 * 60 * 1000),
|
|
1136
1215
|
debug()
|
|
1137
1216
|
], BranchesGitSubProvider.prototype, "onCurrentBranchModified", null);
|
|
1217
|
+
__decorate([
|
|
1218
|
+
debounce(2.5 * 60 * 1000),
|
|
1219
|
+
debug()
|
|
1220
|
+
], BranchesGitSubProvider.prototype, "onCurrentBranchAgentActivity", null);
|
|
1138
1221
|
__decorate([
|
|
1139
1222
|
debug()
|
|
1140
1223
|
], BranchesGitSubProvider.prototype, "renameBranch", null);
|