Skip to content

Commit dbd0053

Browse files
eamodioaxosoft-ramint
authored andcommitted
Adds merge detect actions & squash merge detect (wip)
1 parent c9e21db commit dbd0053

File tree

4 files changed

+71
-1
lines changed

4 files changed

+71
-1
lines changed

src/constants.commands.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,8 @@ type InternalGraphWebviewCommands =
148148
| 'gitlens.graph.skipPausedOperation';
149149

150150
type InternalHomeWebviewCommands =
151+
| 'gitlens.home.deleteBranchOrWorktree'
152+
| 'gitlens.home.pushBranch'
151153
| 'gitlens.home.openMergeTargetComparison'
152154
| 'gitlens.home.openPullRequestChanges'
153155
| 'gitlens.home.openPullRequestComparison'

src/env/node/git/sub-providers/branches.ts

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -394,12 +394,33 @@ export class BranchesGitSubProvider implements GitBranchesSubProvider {
394394
} catch {}
395395

396396
// Cherry-pick detection (handles cherry-picks, rebases, etc)
397-
const data = await this.git.exec({ cwd: repoPath }, 'cherry', '--abbrev', '-v', into.name, branch.name);
397+
let data = await this.git.exec({ cwd: repoPath }, 'cherry', '--abbrev', '-v', into.name, branch.name);
398398
// Check if there are no lines or all lines startwith a `-` (i.e. likely merged)
399399
if (!data || data.split('\n').every(l => l.startsWith('-'))) {
400400
return { merged: true, confidence: 'high' };
401401
}
402402

403+
// Attempt to detect squash merges by checking if the diff of the branch can be cleanly removed from the target
404+
const mergeBase = await this.getMergeBase(repoPath, into.name, branch.name);
405+
data = await this.git.exec<string>({ cwd: repoPath }, 'diff', mergeBase, branch.name);
406+
if (data?.length) {
407+
// Create a temporary index file
408+
await using disposableIndex = await this.provider.staging!.createTemporaryIndex(repoPath, into.name);
409+
const { env } = disposableIndex;
410+
411+
data = await this.git.exec<string>(
412+
{ cwd: repoPath, env: env, stdin: data },
413+
'apply',
414+
'--cached',
415+
'--reverse',
416+
'--check',
417+
'-',
418+
);
419+
if (!data?.trim().length) {
420+
return { merged: true, confidence: 'medium' };
421+
}
422+
}
423+
403424
return { merged: false };
404425
} catch (ex) {
405426
Logger.error(ex, scope);

src/webviews/apps/plus/home/components/merge-target-status.ts

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -301,6 +301,24 @@ export class GlMergeTargetStatus extends LitElement {
301301
${this.mergedStatus.confidence !== 'highest' ? 'likely ' : ''}been merged into its merge
302302
target's local branch ${renderBranchName(this.mergedStatus.localBranchOnly.name)}.
303303
</p>
304+
<div class="button-container">
305+
<gl-button
306+
full
307+
href="${createCommandLink('gitlens.home.pushBranch', {
308+
repoPath: this.branch.repoPath,
309+
branchId: this.mergedStatus.localBranchOnly.id!,
310+
branchName: this.mergedStatus.localBranchOnly.name,
311+
} satisfies BranchRef)}"
312+
>Push ${renderBranchName(this.mergedStatus.localBranchOnly.name)}</gl-button
313+
>
314+
<gl-button
315+
full
316+
appearance="secondary"
317+
href="${createCommandLink('gitlens.home.deleteBranchOrWorktree', this.branchRef)}"
318+
>Delete ${this.branch.worktree ? 'Worktree' : 'Branch'}
319+
${renderBranchName(this.branch.name, this.branch.worktree != null)}</gl-button
320+
>
321+
</div>
304322
</div>`;
305323
}
306324

@@ -318,6 +336,14 @@ export class GlMergeTargetStatus extends LitElement {
318336
${this.mergedStatus.confidence !== 'highest' ? 'likely ' : ''}been merged into its merge target
319337
${target}.
320338
</p>
339+
<div class="button-container">
340+
<gl-button
341+
full
342+
href="${createCommandLink('gitlens.home.deleteBranchOrWorktree', this.branchRef)}"
343+
>Delete ${this.branch.worktree ? 'Worktree' : 'Branch'}
344+
${renderBranchName(this.branch.name, this.branch.worktree != null)}</gl-button
345+
>
346+
</div>
321347
</div>`;
322348
}
323349

src/webviews/home/homeWebview.ts

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -321,6 +321,8 @@ export class HomeWebviewProvider implements WebviewProvider<State, State, HomeWe
321321
(src?: Source) => this.container.subscription.validate({ force: true }, src),
322322
this,
323323
),
324+
registerCommand('gitlens.home.deleteBranchOrWorktree', this.deleteBranchOrWorktree, this),
325+
registerCommand('gitlens.home.pushBranch', this.pushBranch, this),
324326
registerCommand('gitlens.home.openMergeTargetComparison', this.mergeTargetCompare, this),
325327
registerCommand('gitlens.home.openPullRequestChanges', this.pullRequestChanges, this),
326328
registerCommand('gitlens.home.openPullRequestComparison', this.pullRequestCompare, this),
@@ -1185,6 +1187,25 @@ export class HomeWebviewProvider implements WebviewProvider<State, State, HomeWe
11851187
});
11861188
}
11871189

1190+
private deleteBranchOrWorktree(ref: BranchRef) {
1191+
const repo = this._repositoryBranches.get(ref.repoPath);
1192+
const branch = repo?.branches.find(b => b.id === ref.branchId);
1193+
if (branch == null) return;
1194+
1195+
void executeGitCommand({
1196+
command: 'branch',
1197+
state: {
1198+
subcommand: 'delete',
1199+
repo: ref.repoPath,
1200+
references: branch,
1201+
},
1202+
});
1203+
}
1204+
1205+
private pushBranch(_ref: BranchRef) {
1206+
// TODO
1207+
}
1208+
11881209
private mergeTargetCompare(ref: BranchAndTargetRefs) {
11891210
return this.container.views.searchAndCompare.compare(ref.repoPath, ref.branchName, ref.mergeTargetName);
11901211
}

0 commit comments

Comments
 (0)