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

Commit 8881c18

Browse files
Accurately representing the chain-like nature of the fork repository options
1 parent 7b9df87 commit 8881c18

File tree

5 files changed

+74
-34
lines changed

5 files changed

+74
-34
lines changed

src/GitHub.App/SampleData/ForkRepositoryExecuteViewModelDesigner.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,10 @@ public ForkRepositoryExecuteViewModelDesigner()
4646

4747
public bool UpdateOrigin { get; set; } = true;
4848

49+
public bool CanAddUpstream => UpdateOrigin;
50+
51+
public bool CanResetMasterTracking => UpdateOrigin && AddUpstream;
52+
4953
public Task InitializeAsync(ILocalRepositoryModel sourceRepository, IAccount destinationAccount, IConnection connection)
5054
{
5155
return Task.CompletedTask;

src/GitHub.App/Services/RepositoryForkService.cs

Lines changed: 34 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
using GitHub.Extensions;
77
using GitHub.Logging;
88
using GitHub.Models;
9+
using GitHub.ViewModels.Dialog;
910
using LibGit2Sharp;
1011
using Octokit;
1112
using ReactiveUI;
@@ -18,6 +19,8 @@ namespace GitHub.Services
1819
[PartCreationPolicy(CreationPolicy.Shared)]
1920
public class RepositoryForkService : IRepositoryForkService
2021
{
22+
static readonly ILogger log = LogManager.ForContext<RepositoryForkService>();
23+
2124
readonly IGitClient gitClient;
2225
readonly IVSGitServices vsGitServices;
2326
readonly IUsageTracker usageTracker;
@@ -32,22 +35,28 @@ public RepositoryForkService(IGitClient gitClient, IVSGitServices vsGitServices,
3235

3336
public IObservable<Repository> ForkRepository(IApiClient apiClient, IRepositoryModel sourceRepository, NewRepositoryFork repositoryFork, bool updateOrigin, bool addUpstream, bool trackMasterUpstream)
3437
{
38+
log.Verbose("ForkRepository Source:{SourceOwner}/{SourceName} To:{DestinationOwner}", sourceRepository.Owner, sourceRepository.Name, repositoryFork.Organization ?? "[Current User]");
39+
log.Verbose("ForkRepository updateOrigin:{UpdateOrigin} addUpstream:{AddUpstream} trackMasterUpstream:{TrackMasterUpstream}", updateOrigin, addUpstream, trackMasterUpstream);
40+
41+
RecordForkRepositoryUsage(updateOrigin, addUpstream, trackMasterUpstream).Forget();
42+
3543
return Observable.Defer(() => apiClient.ForkRepository(sourceRepository.Owner, sourceRepository.Name, repositoryFork)
3644
.ObserveOn(RxApp.MainThreadScheduler)
37-
.Select(remoteRepo => new { RemoteRepo = remoteRepo, ActiveRepo = vsGitServices.GetActiveRepo() }))
45+
.Select(remoteRepo => new { RemoteRepo = remoteRepo, ActiveRepo = updateOrigin ? vsGitServices.GetActiveRepo() : null }))
3846
.SelectMany(async repo =>
3947
{
40-
using (repo.ActiveRepo)
48+
if (repo.ActiveRepo != null)
4149
{
42-
var originUri = repo.RemoteRepo != null ? new Uri(repo.RemoteRepo.CloneUrl) : null;
43-
var upstreamUri = addUpstream ? sourceRepository.CloneUrl.ToUri() : null;
44-
45-
await SwitchRemotes(repo.ActiveRepo, originUri, upstreamUri, trackMasterUpstream);
46-
47-
RecordForkRepositoryUsage(updateOrigin, addUpstream, trackMasterUpstream).Forget();
50+
using (repo.ActiveRepo)
51+
{
52+
var originUri = repo.RemoteRepo != null ? new Uri(repo.RemoteRepo.CloneUrl) : null;
53+
var upstreamUri = addUpstream ? sourceRepository.CloneUrl.ToUri() : null;
4854

49-
return repo.RemoteRepo;
55+
await SwitchRemotes(repo.ActiveRepo, originUri, upstreamUri, trackMasterUpstream);
56+
}
5057
}
58+
59+
return repo.RemoteRepo;
5160
});
5261
}
5362

@@ -96,25 +105,27 @@ await SwitchRemotes(activeRepo, updateOrigin ? destinationRepository.CloneUrl.To
96105
});
97106
}
98107

99-
private async Task SwitchRemotes(IRepository repository, Uri originUri = null, Uri upstreamUri = null, bool trackMasterUpstream = false)
108+
private async Task SwitchRemotes(IRepository repository, Uri originUri, Uri upstreamUri = null, bool trackMasterUpstream = false)
100109
{
101-
if (originUri != null || upstreamUri != null)
110+
Guard.ArgumentNotNull(originUri, nameof(originUri));
111+
112+
log.Verbose("Set remote origin to {OriginUri}", originUri);
113+
114+
await gitClient.SetRemote(repository, "origin", originUri);
115+
116+
if (upstreamUri != null)
102117
{
103-
if (originUri != null)
104-
{
105-
await gitClient.SetRemote(repository, "origin", originUri);
106-
}
118+
log.Verbose("Set remote upstream to {UpstreamUri}", upstreamUri);
107119

108-
if (upstreamUri != null)
109-
{
110-
await gitClient.SetRemote(repository, "upstream", upstreamUri);
120+
await gitClient.SetRemote(repository, "upstream", upstreamUri);
111121

112-
await gitClient.Fetch(repository, "upstream");
122+
await gitClient.Fetch(repository, "upstream");
113123

114-
if (trackMasterUpstream)
115-
{
116-
await gitClient.SetTrackingBranch(repository, "master", "upstream");
117-
}
124+
if (trackMasterUpstream)
125+
{
126+
log.Verbose("set master tracking to upstream");
127+
128+
await gitClient.SetTrackingBranch(repository, "master", "upstream");
118129
}
119130
}
120131
}

src/GitHub.App/ViewModels/Dialog/ForkRepositoryExecuteViewModel.cs

Lines changed: 30 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,12 @@ IRepositoryForkService repositoryForkService
4141
this.notificationService = notificationService;
4242
this.repositoryForkService = repositoryForkService;
4343

44+
this.WhenAnyValue(model => model.UpdateOrigin)
45+
.Subscribe(value => CanAddUpstream = value);
46+
47+
this.WhenAnyValue(model => model.UpdateOrigin, model => model.AddUpstream)
48+
.Subscribe(tuple => CanResetMasterTracking = tuple.Item1 && tuple.Item2);
49+
4450
CreateFork = ReactiveCommand.CreateAsyncObservable(OnCreateFork);
4551
}
4652

@@ -88,7 +94,8 @@ IObservable<Repository> OnCreateFork(object o)
8894
Organization = !DestinationAccount.IsUser ? DestinationAccount.Login : null
8995
};
9096

91-
return repositoryForkService.ForkRepository(apiClient, SourceRepository, newRepositoryFork, UpdateOrigin, AddUpstream, ResetMasterTracking)
97+
return repositoryForkService
98+
.ForkRepository(apiClient, SourceRepository, newRepositoryFork, UpdateOrigin, CanAddUpstream && AddUpstream, CanResetMasterTracking && ResetMasterTracking)
9299
.Catch<Repository, Exception>(ex =>
93100
{
94101
if (!ex.IsCriticalException())
@@ -102,11 +109,18 @@ IObservable<Repository> OnCreateFork(object o)
102109
});
103110
}
104111

105-
bool resetMasterTracking = true;
106-
public bool ResetMasterTracking
112+
bool updateOrigin = true;
113+
public bool UpdateOrigin
107114
{
108-
get { return resetMasterTracking; }
109-
set { this.RaiseAndSetIfChanged(ref resetMasterTracking, value); }
115+
get { return updateOrigin; }
116+
set { this.RaiseAndSetIfChanged(ref updateOrigin, value); }
117+
}
118+
119+
bool canAddUpstream = true;
120+
public bool CanAddUpstream
121+
{
122+
get { return canAddUpstream; }
123+
private set { this.RaiseAndSetIfChanged(ref canAddUpstream, value); }
110124
}
111125

112126
bool addUpstream = true;
@@ -116,11 +130,18 @@ public bool AddUpstream
116130
set { this.RaiseAndSetIfChanged(ref addUpstream, value); }
117131
}
118132

119-
bool updateOrigin = true;
120-
public bool UpdateOrigin
133+
bool canResetMasterTracking = true;
134+
public bool CanResetMasterTracking
121135
{
122-
get { return updateOrigin; }
123-
set { this.RaiseAndSetIfChanged(ref updateOrigin, value); }
136+
get { return canResetMasterTracking; }
137+
private set { this.RaiseAndSetIfChanged(ref canResetMasterTracking, value); }
138+
}
139+
140+
bool resetMasterTracking = true;
141+
public bool ResetMasterTracking
142+
{
143+
get { return resetMasterTracking; }
144+
set { this.RaiseAndSetIfChanged(ref resetMasterTracking, value); }
124145
}
125146
}
126147
}

src/GitHub.Exports.Reactive/ViewModels/Dialog/IForkRepositoryExecuteViewModel.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,10 @@ public interface IForkRepositoryExecuteViewModel : IDialogContentViewModel
2929

3030
bool UpdateOrigin { get; set; }
3131

32+
bool CanAddUpstream { get; }
33+
34+
bool CanResetMasterTracking { get; }
35+
3236
/// <summary>
3337
/// Initializes the view model.
3438
/// </summary>

src/GitHub.VisualStudio/Views/Dialog/ForkRepositoryExecuteView.xaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@
5555
</Border>
5656
<Border Style="{StaticResource ItemBorder}">
5757
<DockPanel>
58-
<CheckBox IsChecked="{Binding AddUpstream}"/>
58+
<CheckBox IsChecked="{Binding AddUpstream}" IsEnabled="{Binding CanAddUpstream}" />
5959
<TextBlock TextWrapping="Wrap">
6060
Add an <Run Style="{DynamicResource {x:Static markdig:Styles.CodeStyleKey}}">upstream</Run> remote pointing to
6161
<Hyperlink><Run Text="{Binding SourceRepository.CloneUrl, Mode=OneWay}"/></Hyperlink>
@@ -64,7 +64,7 @@
6464
</Border>
6565
<Border Style="{StaticResource ItemBorder}">
6666
<DockPanel>
67-
<CheckBox IsChecked="{Binding ResetMasterTracking}"/>
67+
<CheckBox IsChecked="{Binding ResetMasterTracking}" IsEnabled="{Binding CanResetMasterTracking}" />
6868
<TextBlock TextWrapping="Wrap">
6969
Set the <Run Style="{DynamicResource {x:Static markdig:Styles.CodeStyleKey}}">master</Run> branch to track
7070
<Run Style="{DynamicResource {x:Static markdig:Styles.CodeStyleKey}}">upstream/master</Run>

0 commit comments

Comments
 (0)