Adds AI powered explain feature of a branch#4522
Conversation
Updates branch context detection to add a '+recomposable' flag for branches that have commits eligible for recomposition, determined by checking recent merge bases against stored targets. Adjusts menu conditions so the AI rebase command is shown only when a branch can be recomposed, preventing unnecessary options for branches without suitable commits. (#4443, #4522)
3fe767e to
7de9ae3
Compare
Introduces AI-powered branch actions ("Recompose" and "Explain") directly into the branches view, enabling context menu options when branches are recomposable or have unpushed commits. Refactors and centralizes branch recomposability detection to ensure consistent logic across graph and views, improving maintainability and user experience. Enhances discoverability and workflow integration for AI-assisted Git operations.
(#4443, #4522)
Updates branch context detection to add a '+recomposable' flag for branches that have commits eligible for recomposition, determined by checking recent merge bases against stored targets. Adjusts menu conditions so the AI rebase command is shown only when a branch can be recomposed, preventing unnecessary options for branches without suitable commits. (#4443, #4522)
7de9ae3 to
5153fa9
Compare
Introduces AI-powered branch actions ("Recompose" and "Explain") directly into the branches view, enabling context menu options when branches are recomposable or have unpushed commits. Refactors and centralizes branch recomposability detection to ensure consistent logic across graph and views, improving maintainability and user experience. Enhances discoverability and workflow integration for AI-assisted Git operations.
(#4443, #4522)
5153fa9 to
2094d32
Compare
Updates branch context detection to add a '+recomposable' flag for branches that have commits eligible for recomposition, determined by checking recent merge bases against stored targets. Adjusts menu conditions so the AI rebase command is shown only when a branch can be recomposed, preventing unnecessary options for branches without suitable commits. (#4443, #4522)
0c7d889 to
61a93c6
Compare
Introduces AI-powered branch actions ("Recompose" and "Explain") directly into the branches view, enabling context menu options when branches are recomposable or have unpushed commits. Refactors and centralizes branch recomposability detection to ensure consistent logic across graph and views, improving maintainability and user experience. Enhances discoverability and workflow integration for AI-assisted Git operations.
(#4443, #4522)
Updates branch context detection to add a '+recomposable' flag for branches that have commits eligible for recomposition, determined by checking recent merge bases against stored targets. Adjusts menu conditions so the AI rebase command is shown only when a branch can be recomposed, preventing unnecessary options for branches without suitable commits. (#4443, #4522)
61a93c6 to
aceac5f
Compare
Introduces AI-powered branch actions ("Recompose" and "Explain") directly into the branches view, enabling context menu options when branches are recomposable or have unpushed commits. Refactors and centralizes branch recomposability detection to ensure consistent logic across graph and views, improving maintainability and user experience. Enhances discoverability and workflow integration for AI-assisted Git operations.
(#4443, #4522)
src/constants.commands.ts
Outdated
| | 'gitlens.ai.aiRebaseBranch:graph' | ||
| | 'gitlens.ai.aiRebaseUnpushed:graph' |
There was a problem hiding this comment.
Why are these listed under InternalGraphWebviewCommands? In contributions it looks like they are fully exposed graph commands?
| /** | ||
| * Selects the most recent merge base from multiple target branches. | ||
| * This is the same logic used in graph.ts selectMostRecentMergeBase method. | ||
| */ | ||
| async function selectMostRecentMergeBase( | ||
| branchName: string, | ||
| targets: string[], | ||
| svc: ReturnType<typeof Container.prototype.git.getRepositoryService>, | ||
| ): Promise<{ commit: string; branch: string } | undefined> { | ||
| const mergeBaseResults = await Promise.allSettled( | ||
| targets.map(async target => { | ||
| const commit = await svc.refs.getMergeBase(branchName, target); | ||
| return { | ||
| commit: commit, | ||
| branch: target, | ||
| }; | ||
| }), | ||
| ); | ||
| const mergeBases = mergeBaseResults | ||
| .map(result => getSettledValue(result)) | ||
| .filter((r): r is { commit: string; branch: string } => r?.commit != null); | ||
|
|
||
| if (mergeBases.length === 0) return undefined; | ||
|
|
||
| let mostRecentMergeBase = mergeBases[0]; | ||
| for (let i = 1; i < mergeBases.length; i++) { | ||
| const isCurrentMoreRecent = await svc.commits.isAncestorOf(mostRecentMergeBase?.commit, mergeBases[i].commit); | ||
| if (isCurrentMoreRecent) { | ||
| mostRecentMergeBase = mergeBases[i]; | ||
| } | ||
| } | ||
|
|
||
| return mostRecentMergeBase; | ||
| } |
There was a problem hiding this comment.
Can I get a more detailed rundown of what this function is doing? Also, if it already exists in graph.ts, can we just have that import from here so we aren't duplicating logic?
There was a problem hiding this comment.
@axosoft-ramint
I've added to the explanation and removed the obsolete sentence about the duplication:
/**
* Selects the most recent merge base from multiple target branches.
*
* It gets the merge base for each target, then uses isAncestorOf() to find which one is newest.
*/
The story was that I've implemented originally in graph, then created the dupe here and marked it in the comment. But eventually I refactored to re-use this function everywhere so it's stopped being duplicated, but the explanation phrase has left.
There was a problem hiding this comment.
@axosoft-ramint
I've updated the code according to your notes above. Also I've refreshed the branch and fixed the conflicts.
The question now is the following: should I actually call "Rebase" action, or is it better to try to launch the Commit Composer?
|
@axosoft-ramint , @ericf-axosoft I've moved "recompose" related part of requirements and the code to another PR draft: #4644 All other review notes has been attended. |
ramin-t
left a comment
There was a problem hiding this comment.
The context calculations are tanking graph performance. We need to find a lighter way to get that context included.
| const mergeBaseResult = | ||
| branch && (await getBranchMergeBaseAndCommonCommit(this.container, branch)); | ||
| const isRecomposable = Boolean(mergeBaseResult && mergeBaseResult.commit !== branch?.sha); | ||
| const mergeBase = isRecomposable ? mergeBaseResult : undefined; |
There was a problem hiding this comment.
It seems these calculations are expensive in some cases, especially when placed in the main graph loop.
Without these operations (commented out and left out of context), I can load the graph for my test repo (not a very large one) in about 5 seconds:
Same repo, same graph, with these operations, takes nearly 2 minutes to load:
There was a problem hiding this comment.
Let me know if you need any details about my repo/branches/commits that would help with reproducing this.
There was a problem hiding this comment.
@axosoft-ramint I've moved more changes out to rebase related branch. So, the problem can be handled in a future PR. Now this PR only contains Explain related changes that are not bring new calculations to rendering.
Introduces AI-powered branch actions ("Recompose" and "Explain") directly into the branches view, enabling context menu options when branches are recomposable or have unpushed commits. Refactors and centralizes branch recomposability detection to ensure consistent logic across graph and views, improving maintainability and user experience. Enhances discoverability and workflow integration for AI-assisted Git operations.
(#4443, #4522)


Description
Resolves #4443
Graph:

Panel:

Checklist
Fixes $XXX -orCloses #XXX -prefix to auto-close the issue that your PR addresses