Skip to content
This repository was archived by the owner on Jun 21, 2023. It is now read-only.

Commit 1ae6a85

Browse files
committed
Detect local commits in PR branch.
And invite user to check out PR to a new branch. The actual checkout is not yet implemented.
1 parent ebdf9e9 commit 1ae6a85

File tree

4 files changed

+59
-3
lines changed

4 files changed

+59
-3
lines changed

src/GitHub.App/ViewModels/PullRequestDetailViewModel.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -335,9 +335,9 @@ public async Task Load(PullRequest pullRequest, IList<PullRequestFile> files)
335335
{
336336
var divergence = await pullRequestsService.CalculateHistoryDivergence(repository, Number);
337337

338-
if (divergence.BehindBy == null)
338+
if (divergence.BehindBy == null || divergence.AheadBy > 0)
339339
{
340-
CheckoutMode = CheckoutMode.Fetch;
340+
CheckoutMode = CheckoutMode.InvalidState;
341341
}
342342
else if (divergence.BehindBy == 0)
343343
{
@@ -413,6 +413,7 @@ static string GetCheckoutModeDescription(CheckoutMode checkoutMode)
413413
case CheckoutMode.Switch:
414414
return "switch branches";
415415
case CheckoutMode.Fetch:
416+
case CheckoutMode.InvalidState:
416417
return "checkout pull request";
417418
default:
418419
Debug.Fail("Invalid CheckoutMode in GetCheckoutModeDescription");

src/GitHub.Exports.Reactive/ViewModels/IPullRequestDetailViewModel.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,12 @@ public enum CheckoutMode
6161
/// No local branch exists for the pull request.
6262
/// </summary>
6363
Fetch,
64+
65+
/// <summary>
66+
/// The checked out branch is marked as the branch for the pull request, but there are
67+
/// local commits or the branch shares no history.
68+
/// </summary>
69+
InvalidState,
6470
}
6571

6672
/// <summary>

src/GitHub.VisualStudio/UI/Views/PullRequestDetailView.xaml

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -187,7 +187,7 @@
187187
</TextBlock.Style>
188188
</TextBlock>
189189

190-
<!-- Branch checked out and neds pull -->
190+
<!-- Branch checked out and needs pull -->
191191
<TextBlock TextWrapping="Wrap">
192192
<ui:OcticonImage Icon="sync" Foreground="Orange" Margin="0 0 0 -4"/>
193193
<Run>Your local branch is behind by</Run>
@@ -221,6 +221,23 @@
221221
</TextBlock.Style>
222222
</TextBlock>
223223

224+
<!-- Local branch is checked out but is in an invalid state -->
225+
<TextBlock TextWrapping="Wrap">
226+
<ui:OcticonImage Icon="alert" Foreground="Orange" Margin="0 0 0 -4"/>
227+
<Run BaselineAlignment="Top">The pull request branch has local changes.</Run>
228+
<Hyperlink Command="{Binding Checkout}">Checkout to a new branch</Hyperlink>
229+
<TextBlock.Style>
230+
<Style TargetType="TextBlock" BasedOn="{StaticResource CheckoutMessage}">
231+
<Setter Property="Visibility" Value="Collapsed"/>
232+
<Style.Triggers>
233+
<DataTrigger Binding="{Binding CheckoutMode}" Value="InvalidState">
234+
<Setter Property="Visibility" Value="Visible"/>
235+
</DataTrigger>
236+
</Style.Triggers>
237+
</Style>
238+
</TextBlock.Style>
239+
</TextBlock>
240+
224241
<!-- Checkout disabled message -->
225242
<TextBlock Margin="0 4" TextWrapping="Wrap">
226243
<ui:OcticonImage Icon="alert" Foreground="Orange" Margin="0 0 0 -4"/>

src/UnitTests/GitHub.App/ViewModels/PullRequestDetailViewModelTests.cs

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,10 +153,41 @@ public async Task CheckoutDisabledMessageShouldBeSetWhenNeedsFetchAndWorkingDire
153153
Assert.False(target.Checkout.CanExecute(null));
154154
}
155155

156+
[Fact]
157+
public async Task CheckoutModeShouldBeInvalidStateWhenHasLocalCommits()
158+
{
159+
var target = CreateTarget(
160+
currentBranch: "pr/123",
161+
existingPrBranch: "pr/123",
162+
aheadBy: 1,
163+
behindBy: 2);
164+
await target.Load(CreatePullRequest(), new PullRequestFile[0]);
165+
166+
Assert.Equal(CheckoutMode.InvalidState, target.CheckoutMode);
167+
Assert.True(target.Checkout.CanExecute(null));
168+
}
169+
170+
[Fact]
171+
public async Task CheckoutDisabledMessageShouldBeSetWhenInvalidStateAndWorkingDirectoryDirty()
172+
{
173+
var target = CreateTarget(
174+
currentBranch: "pr/123",
175+
existingPrBranch: "pr/123",
176+
aheadBy: 1,
177+
behindBy: 2,
178+
dirty: true);
179+
await target.Load(CreatePullRequest(), new PullRequestFile[0]);
180+
181+
Assert.Equal(CheckoutMode.InvalidState, target.CheckoutMode);
182+
Assert.Equal("Cannot checkout pull request as your working directory has uncommitted changes.", target.CheckoutDisabledMessage);
183+
Assert.False(target.Checkout.CanExecute(null));
184+
}
185+
156186
PullRequestDetailViewModel CreateTarget(
157187
string currentBranch = "master",
158188
string existingPrBranch = null,
159189
bool dirty = false,
190+
int aheadBy = 0,
160191
int behindBy = 0)
161192
{
162193
var repository = Substitute.For<ILocalRepositoryModel>();
@@ -181,6 +212,7 @@ PullRequestDetailViewModel CreateTarget(
181212
pullRequestService.CleanForCheckout(repository).Returns(Observable.Return(!dirty));
182213

183214
var divergence = Substitute.For<HistoryDivergence>();
215+
divergence.AheadBy.Returns(aheadBy);
184216
divergence.BehindBy.Returns(behindBy);
185217
pullRequestService.CalculateHistoryDivergence(repository, Arg.Any<int>())
186218
.Returns(Observable.Return(divergence));

0 commit comments

Comments
 (0)