Skip to content

Commit 7233b9b

Browse files
authored
Merge pull request #9071 from gitbutlerapp/fix-amend-hunk-assignments
fix-amend-hunk-assignments
2 parents 03e0aec + ceb5e7d commit 7233b9b

File tree

5 files changed

+52
-6
lines changed

5 files changed

+52
-6
lines changed

apps/desktop/src/lib/commits/dropHandler.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,8 @@ export class AmendCommitWithChangeDzHandler implements DropzoneHandler {
110110
console.warn('Moving a branch into a commit is an invalid operation');
111111
break;
112112
case 'worktree': {
113-
const diffSpec = changesToDiffSpec(await data.treeChanges());
113+
const assignments = data.assignments();
114+
const diffSpec = changesToDiffSpec(await data.treeChanges(), assignments);
114115
return this.onresult(
115116
await this.trigger({
116117
projectId: this.projectId,

apps/desktop/src/lib/commits/utils.ts

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
1+
import { isDefined } from '@gitbutler/ui/utils/typeguards';
12
import type { DetailedCommit } from '$lib/commits/commit';
23
import type { TreeChange } from '$lib/hunks/change';
3-
import type { DiffSpec } from '$lib/hunks/hunk';
4+
import type { DiffSpec, HunkAssignment } from '$lib/hunks/hunk';
45

56
type DivergenceResult =
67
| { type: 'localDiverged'; commit: DetailedCommit }
@@ -35,14 +36,20 @@ export function findLastDivergentCommit(
3536
return { type: 'notDiverged' };
3637
}
3738
/** Helper function that turns tree changes into a diff spec */
38-
export function changesToDiffSpec(changes: TreeChange[]): DiffSpec[] {
39+
export function changesToDiffSpec(
40+
changes: TreeChange[],
41+
assignments?: Record<string, HunkAssignment[]>
42+
): DiffSpec[] {
3943
return changes.map((change) => {
4044
const previousPathBytes =
4145
change.status.type === 'Rename' ? change.status.subject.previousPathBytes : null;
46+
const assignment = assignments?.[change.path];
47+
const hunkHeaders = assignment?.map((a) => a.hunkHeader).filter(isDefined) ?? [];
48+
4249
return {
4350
previousPathBytes,
4451
pathBytes: change.pathBytes,
45-
hunkHeaders: []
52+
hunkHeaders
4653
};
4754
});
4855
}

apps/desktop/src/lib/dragging/draggables.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import type { AnyCommit } from '$lib/commits/commit';
44
import type { CommitDropData } from '$lib/commits/dropHandler';
55
import type { AnyFile } from '$lib/files/file';
66
import type { TreeChange } from '$lib/hunks/change';
7-
import type { Hunk, HunkHeader, HunkLock } from '$lib/hunks/hunk';
7+
import type { Hunk, HunkAssignment, HunkHeader, HunkLock } from '$lib/hunks/hunk';
88
import type { IdSelection } from '$lib/selection/idSelection.svelte';
99

1010
export const NON_DRAGGABLE = {
@@ -72,6 +72,13 @@ export class ChangeDropData {
7272
return [this.change];
7373
}
7474

75+
assignments(): Record<string, HunkAssignment[]> | undefined {
76+
if (this.selection.has(this.change.path, this.selectionId)) {
77+
return this.selection.hunkAssignments(this.selectionId) ?? undefined;
78+
}
79+
return undefined;
80+
}
81+
7582
get isCommitted(): boolean {
7683
return this.selectionId.type === 'commit' || this.selectionId.type === 'branch';
7784
}

apps/desktop/src/lib/selection/idSelection.svelte.ts

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import {
99
import { SvelteSet } from 'svelte/reactivity';
1010
import { get, writable, type Writable } from 'svelte/store';
1111
import type { TreeChange } from '$lib/hunks/change';
12+
import type { HunkAssignment } from '$lib/hunks/hunk';
1213
import type { UncommittedService } from '$lib/selection/uncommittedService.svelte';
1314
import type { StackService } from '$lib/stacks/stackService.svelte';
1415

@@ -144,6 +145,27 @@ export class IdSelection {
144145
}
145146
}
146147

148+
/**
149+
* Retrieve the hunk assignments for the current selection.
150+
*
151+
* Hunk assignments are only relevant when selecting worktree files.
152+
* For branches, commits, and snapshots, this will return null.
153+
*/
154+
hunkAssignments(params: SelectionId): Record<string, HunkAssignment[]> | null {
155+
switch (params.type) {
156+
case 'worktree': {
157+
const paths = this.values(params).map((fileSelection) => {
158+
return fileSelection.path;
159+
});
160+
return this.uncommittedService.getAssignmentsByPaths(params.stackId || null, paths);
161+
}
162+
case 'branch':
163+
case 'commit':
164+
case 'snapshot':
165+
return null;
166+
}
167+
}
168+
147169
get length() {
148170
return this.selections.size;
149171
}

apps/desktop/src/lib/selection/uncommittedService.svelte.ts

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -275,7 +275,8 @@ export class UncommittedService {
275275
}
276276

277277
getChangesByStackId(stackId: string | null): TreeChange[] {
278-
return uncommittedSelectors.treeChanges.selectByStackId(this.state, stackId);
278+
const stackIdChanges = uncommittedSelectors.treeChanges.selectByStackId(this.state, stackId);
279+
return stackIdChanges;
279280
}
280281

281282
changesByStackId(stackId: string | null): Reactive<TreeChange[]> {
@@ -290,6 +291,14 @@ export class UncommittedService {
290291
);
291292
}
292293

294+
getAssignmentsByPaths(stackId: string | null, paths: string[]): Record<string, HunkAssignment[]> {
295+
const assignments: Record<string, HunkAssignment[]> = {};
296+
for (const path of paths) {
297+
assignments[path] = this.getAssignmentsByPath(stackId, path);
298+
}
299+
return assignments;
300+
}
301+
293302
getAssignmentsByStackId(stackId: string): HunkAssignment[] {
294303
return uncommittedSelectors.hunkAssignments.selectByPrefix(
295304
this.state.hunkAssignments,

0 commit comments

Comments
 (0)