Skip to content

Commit ac1b030

Browse files
authored
Merge pull request desktop#19817 from sfadschm/fix-rebase-commit-checks
fix: inconsistent rebase behaviour
2 parents ee8fe19 + d79786b commit ac1b030

File tree

5 files changed

+59
-25
lines changed

5 files changed

+59
-25
lines changed

app/src/models/rebase.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,10 @@ export type RebaseProgressOptions = {
3232

3333
export type CleanRebase = {
3434
readonly kind: ComputedAction.Clean
35-
readonly commits: ReadonlyArray<CommitOneLine>
35+
/** The commits present in the base branch but not in the target branch */
36+
readonly commitsAhead: ReadonlyArray<CommitOneLine>
37+
/** The commits present in the target branch but not in the base branch */
38+
readonly commitsBehind: ReadonlyArray<CommitOneLine>
3639
}
3740

3841
export type RebaseWithConflicts = {

app/src/ui/history/merge-call-to-action-with-conflicts.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ export class MergeCallToActionWithConflicts extends React.Component<
5858
if (selectedOperation === MultiCommitOperationKind.Rebase) {
5959
return rebasePreview !== null &&
6060
rebasePreview.kind === ComputedAction.Clean
61-
? rebasePreview.commits.length
61+
? rebasePreview.commitsAhead.length
6262
: 0
6363
}
6464

@@ -148,7 +148,7 @@ export class MergeCallToActionWithConflicts extends React.Component<
148148
const commits =
149149
this.state.rebasePreview !== null &&
150150
this.state.rebasePreview.kind === ComputedAction.Clean
151-
? this.state.rebasePreview.commits
151+
? this.state.rebasePreview.commitsAhead
152152
: []
153153
return dispatcher.startRebase(
154154
repository,

app/src/ui/lib/update-branch.ts

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,17 @@ export async function updateRebasePreview(
4242
kind: ComputedAction.Loading,
4343
})
4444

45-
const commits = await promiseWithMinimumTimeout(
45+
const commitsBehind = await promiseWithMinimumTimeout(
46+
() =>
47+
getCommitsBetweenCommits(
48+
repository,
49+
targetBranch.tip.sha,
50+
baseBranch.tip.sha
51+
),
52+
500
53+
)
54+
55+
const commitsAhead = await promiseWithMinimumTimeout(
4656
() =>
4757
getCommitsBetweenCommits(
4858
repository,
@@ -62,7 +72,7 @@ export async function updateRebasePreview(
6272

6373
// if we are unable to find any commits to rebase, indicate that we're
6474
// unable to proceed with the rebase
65-
if (commits === null) {
75+
if (commitsBehind === null) {
6676
onUpdate({
6777
kind: ComputedAction.Invalid,
6878
})
@@ -71,6 +81,7 @@ export async function updateRebasePreview(
7181

7282
onUpdate({
7383
kind: ComputedAction.Clean,
74-
commits,
84+
commitsAhead: commitsAhead ?? [],
85+
commitsBehind: commitsBehind,
7586
})
7687
}

app/src/ui/multi-commit-operation/choose-branch/merge-choose-branch-dialog.tsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -182,8 +182,9 @@ export class MergeChooseBranchDialog extends React.Component<
182182
if (commitCount === 0) {
183183
return (
184184
<React.Fragment>
185-
{`This branch is up to date with `}
186-
<strong>{branch.name}</strong>
185+
<strong>{currentBranch.name}</strong>
186+
{` `}
187+
is already up to date with <strong>{branch.name}</strong>
187188
</React.Fragment>
188189
)
189190
}

app/src/ui/multi-commit-operation/choose-branch/rebase-choose-branch-dialog.tsx

Lines changed: 36 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ export class RebaseChooseBranchDialog extends React.Component<
5050
repository,
5151
selectedBranch,
5252
currentBranch,
53-
rebasePreview.commits
53+
rebasePreview.commitsAhead
5454
)
5555
}
5656

@@ -59,7 +59,7 @@ export class RebaseChooseBranchDialog extends React.Component<
5959
const { selectedBranch, rebasePreview } = this.state
6060
const commitCount =
6161
rebasePreview?.kind === ComputedAction.Clean
62-
? rebasePreview.commits.length
62+
? rebasePreview.commitsBehind.length
6363
: undefined
6464
return canStartOperation(
6565
selectedBranch,
@@ -89,15 +89,15 @@ export class RebaseChooseBranchDialog extends React.Component<
8989
currentBranch !== null &&
9090
selectedBranch.name === currentBranch.name
9191

92-
const areCommitsToRebase =
92+
const currentBranchIsBehindSelectedBranch =
9393
rebasePreview?.kind === ComputedAction.Clean
94-
? rebasePreview.commits.length > 0
94+
? rebasePreview.commitsBehind.length > 0
9595
: false
9696

9797
return selectedBranchIsCurrentBranch
9898
? 'You are not able to rebase this branch onto itself.'
99-
: !areCommitsToRebase
100-
? 'There are no commits on the current branch to rebase.'
99+
: !currentBranchIsBehindSelectedBranch
100+
? 'The current branch is already up to date with the selected branch.'
101101
: undefined
102102
}
103103

@@ -135,7 +135,8 @@ export class RebaseChooseBranchDialog extends React.Component<
135135
return this.renderCleanRebaseMessage(
136136
currentBranch,
137137
baseBranch,
138-
rebasePreview.commits.length
138+
rebasePreview.commitsAhead.length,
139+
rebasePreview.commitsBehind.length
139140
)
140141
}
141142

@@ -157,25 +158,43 @@ export class RebaseChooseBranchDialog extends React.Component<
157158
private renderCleanRebaseMessage(
158159
currentBranch: Branch,
159160
baseBranch: Branch,
160-
commitsToRebase: number
161+
commitsAheadCount: number,
162+
commitsBehindCount: number
161163
) {
162-
if (commitsToRebase <= 0) {
164+
// The current branch is behind the base branch
165+
if (commitsBehindCount > 0 && commitsAheadCount <= 0) {
166+
const pluralized = commitsBehindCount === 1 ? 'commit' : 'commits'
163167
return (
164168
<>
165-
This branch is up to date with{` `}
166-
<strong>{currentBranch.name}</strong>
169+
This will fast-forward <strong>{currentBranch.name}</strong> by
170+
<strong>{` ${commitsBehindCount} ${pluralized}`}</strong>
171+
{` to match `}
172+
<strong>{baseBranch.name}</strong>
167173
</>
168174
)
169175
}
170176

171-
const pluralized = commitsToRebase === 1 ? 'commit' : 'commits'
177+
// The current branch is behind and ahead of the base branch
178+
if (commitsBehindCount > 0 && commitsAheadCount > 0) {
179+
const pluralized = commitsAheadCount === 1 ? 'commit' : 'commits'
180+
return (
181+
<>
182+
This will update <strong>{currentBranch.name}</strong>
183+
{` by applying its `}
184+
<strong>{` ${commitsAheadCount} ${pluralized}`}</strong>
185+
{` on top of `}
186+
<strong>{baseBranch.name}</strong>
187+
</>
188+
)
189+
}
190+
191+
// The current branch is a direct child of the base branch
192+
// Condition: commitsBehindCount <= 0 && commitsAheadCount >= 0
172193
return (
173194
<>
174-
This will update <strong>{currentBranch.name}</strong>
175-
{` by applying its `}
176-
<strong>{` ${commitsToRebase} ${pluralized}`}</strong>
177-
{` on top of `}
178-
<strong>{baseBranch.name}</strong>
195+
<strong>{currentBranch.name}</strong>
196+
{` `}
197+
is already up to date with <strong>{baseBranch.name}</strong>
179198
</>
180199
)
181200
}

0 commit comments

Comments
 (0)