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

Commit 5058564

Browse files
committed
Warn user when changes in local version of file
Warn if there have been chances to the target file between when the permalink was created and the working copy.
1 parent 1d468d9 commit 5058564

File tree

4 files changed

+61
-1
lines changed

4 files changed

+61
-1
lines changed

src/GitHub.App/Services/GitHubContextService.cs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
using Microsoft.VisualStudio.Shell;
1515
using Microsoft.VisualStudio.Shell.Interop;
1616
using Microsoft.VisualStudio.TextManager.Interop;
17+
using LibGit2Sharp;
1718

1819
namespace GitHub.App.Services
1920
{
@@ -340,6 +341,17 @@ public string ResolvePath(GitHubContext context)
340341
}
341342
}
342343

344+
public bool HasChangesInWorkingDirectory(string repositoryDir, string commitish, string path)
345+
{
346+
using (var repo = gitService.GetRepository(repositoryDir))
347+
{
348+
var commit = repo.Lookup<Commit>(commitish);
349+
var paths = new[] { path };
350+
351+
return repo.Diff.Compare<Patch>(commit.Tree, DiffTargets.WorkingDirectory, paths).Count() > 0;
352+
}
353+
}
354+
343355
static IEnumerable<(string commitish, string path)> ToObjectish(string treeishPath)
344356
{
345357
var index = 0;

src/GitHub.Exports/Services/IGitHubContextService.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,5 +15,6 @@ public interface IGitHubContextService
1515
Uri ToRepositoryUrl(GitHubContext context);
1616
bool TryOpenFile(string repositoryDir, GitHubContext context);
1717
(string commitish, string path) ResolveGitObject(string repositoryDir, GitHubContext context);
18+
bool HasChangesInWorkingDirectory(string repositoryDir, string commitish, string path);
1819
}
1920
}

src/GitHub.VisualStudio/Commands/OpenFromClipboardCommand.cs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ public class OpenFromClipboardCommand : VsCommand<string>, IOpenFromClipboardCom
1313
public const string NoGitHubUrlMessage = "Couldn't a find a GitHub URL in clipboard";
1414
public const string NoResolveMessage = "Couldn't resolve Git object";
1515
public const string NoActiveRepositoryMessage = "There is no active repository to navigate";
16+
public const string ChangesInWorkingDirectoryMessage = "This file has changed since the permalink was created";
1617

1718
readonly Lazy<IGitHubContextService> gitHubContextService;
1819
readonly Lazy<ITeamExplorerContext> teamExplorerContext;
@@ -66,6 +67,12 @@ public override Task Execute(string url)
6667
return Task.CompletedTask;
6768
}
6869

70+
var hasChanges = gitHubContextService.Value.HasChangesInWorkingDirectory(repositoryDir, commitish, path);
71+
if (hasChanges)
72+
{
73+
vsServices.Value.ShowMessageBoxInfo(ChangesInWorkingDirectoryMessage);
74+
}
75+
6976
if (!gitHubContextService.Value.TryOpenFile(repositoryDir, context))
7077
{
7178
// Couldn't open file

test/GitHub.VisualStudio.UnitTests/Commands/OpenFromClipboardCommandTests.cs

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,13 +65,48 @@ public async Task CouldResolve()
6565
vsServices.DidNotReceiveWithAnyArgs().ShowMessageBoxInfo(null);
6666
}
6767

68+
[Test]
69+
public async Task NoChangesInWorkingDirectory()
70+
{
71+
var gitHubContextService = Substitute.For<IGitHubContextService>();
72+
var context = new GitHubContext();
73+
var repositoryDir = "repositoryDir";
74+
var gitObject = ("master", "foo.cs");
75+
var vsServices = Substitute.For<IVSServices>();
76+
var target = CreateOpenFromClipboardCommand(gitHubContextService: gitHubContextService, vsServices: vsServices,
77+
contextFromClipboard: context, repositoryDir: repositoryDir, gitObject: gitObject, hasChanges: false);
78+
79+
await target.Execute(null);
80+
81+
vsServices.DidNotReceiveWithAnyArgs().ShowMessageBoxInfo(null);
82+
gitHubContextService.Received(1).TryOpenFile(repositoryDir, context);
83+
}
84+
85+
[Test]
86+
public async Task HasChangesInWorkingDirectory()
87+
{
88+
var gitHubContextService = Substitute.For<IGitHubContextService>();
89+
var context = new GitHubContext();
90+
var repositoryDir = "repositoryDir";
91+
var gitObject = ("master", "foo.cs");
92+
var vsServices = Substitute.For<IVSServices>();
93+
var target = CreateOpenFromClipboardCommand(gitHubContextService: gitHubContextService, vsServices: vsServices,
94+
contextFromClipboard: context, repositoryDir: repositoryDir, gitObject: gitObject, hasChanges: true);
95+
96+
await target.Execute(null);
97+
98+
vsServices.Received(1).ShowMessageBoxInfo(OpenFromClipboardCommand.ChangesInWorkingDirectoryMessage);
99+
gitHubContextService.Received(1).TryOpenFile(repositoryDir, context);
100+
}
101+
68102
static OpenFromClipboardCommand CreateOpenFromClipboardCommand(
69103
IGitHubContextService gitHubContextService = null,
70104
ITeamExplorerContext teamExplorerContext = null,
71105
IVSServices vsServices = null,
72106
GitHubContext contextFromClipboard = null,
73107
string repositoryDir = null,
74-
(string, string)? gitObject = null)
108+
(string, string)? gitObject = null,
109+
bool? hasChanges = null)
75110
{
76111
var sp = Substitute.For<IServiceProvider>();
77112
gitHubContextService = gitHubContextService ?? Substitute.For<IGitHubContextService>();
@@ -85,6 +120,11 @@ static OpenFromClipboardCommand CreateOpenFromClipboardCommand(
85120
gitHubContextService.ResolveGitObject(repositoryDir, contextFromClipboard).Returns(gitObject.Value);
86121
}
87122

123+
if (hasChanges != null)
124+
{
125+
gitHubContextService.HasChangesInWorkingDirectory(repositoryDir, gitObject.Value.Item1, gitObject.Value.Item2).Returns(hasChanges.Value);
126+
}
127+
88128
return new OpenFromClipboardCommand(
89129
new Lazy<IGitHubContextService>(() => gitHubContextService),
90130
new Lazy<ITeamExplorerContext>(() => teamExplorerContext),

0 commit comments

Comments
 (0)