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

Commit 8a5e0bb

Browse files
committed
Merge branch 'bump-version' into update-rx
2 parents 99d30e2 + 4fec01a commit 8a5e0bb

File tree

16 files changed

+363
-44
lines changed

16 files changed

+363
-44
lines changed

Directory.Build.Props

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<Project>
22
<PropertyGroup>
33
<Product>GitHub Extension for Visual Studio</Product>
4-
<Version>2.5.7.0</Version>
4+
<Version>2.5.8.0</Version>
55
<Copyright>Copyright © GitHub, Inc. 2014-2018</Copyright>
66
<LangVersion>7.3</LangVersion>
77
</PropertyGroup>

appveyor.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
os: Visual Studio 2017
2-
version: '2.5.7.{build}'
2+
version: '2.5.8.{build}'
33
skip_tags: true
44
install:
55
- ps: |

codecov.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,8 @@ parsers:
2121
macro: no
2222

2323
comment:
24-
layout: "header, reach, diff, files"
25-
behavior: new
24+
layout: "header, diff, files"
25+
behavior: once
2626
require_changes: no
2727

2828
fixes:
@@ -31,4 +31,4 @@ fixes:
3131
ignore:
3232
- "*.xaml"
3333
- "*.xaml.cs"
34-
- "**/SampleData/*"
34+
- "**/SampleData/*"

src/GitHub.App/SampleData/GitServiceDesigner.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ namespace GitHub.SampleData
77
{
88
class GitServiceDesigner : IGitService
99
{
10-
public Task<string> GetLatestPushedSha(string path) => Task.FromResult<string>(null);
10+
public Task<string> GetLatestPushedSha(string path, string remote = "origin") => Task.FromResult<string>(null);
1111
public UriString GetRemoteUri(IRepository repo, string remote = "origin") => null;
1212
public IRepository GetRepository(string path) => null;
1313
public UriString GetUri(string path, string remote = "origin") => null;

src/GitHub.Exports/Services/GitService.cs

Lines changed: 48 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,14 @@ namespace GitHub.Services
1313
[PartCreationPolicy(CreationPolicy.NonShared)]
1414
public class GitService : IGitService
1515
{
16+
readonly IRepositoryFacade repositoryFacade;
17+
18+
[ImportingConstructor]
19+
public GitService(IRepositoryFacade repositoryFacade)
20+
{
21+
this.repositoryFacade = repositoryFacade;
22+
}
23+
1624
/// <summary>
1725
/// Returns the URL of the remote for the specified <see cref="repository"/>. If the repository
1826
/// is null or no remote named origin exists, this method returns null
@@ -56,8 +64,8 @@ public UriString GetUri(string path, string remote = "origin")
5664
/// <returns>An instance of <see cref="IRepositoryModel"/> or null</returns>
5765
public IRepository GetRepository(string path)
5866
{
59-
var repoPath = Repository.Discover(path);
60-
return repoPath == null ? null : new Repository(repoPath);
67+
var repoPath = repositoryFacade.Discover(path);
68+
return repoPath == null ? null : repositoryFacade.NewRepository(repoPath);
6169
}
6270

6371
/// <summary>
@@ -80,42 +88,70 @@ public UriString GetRemoteUri(IRepository repo, string remote = "origin")
8088
/// <remarks>
8189
/// This is equivalent to creating it via MEF with <see cref="CreationPolicy.NonShared"/>
8290
/// </remarks>
83-
public static IGitService GitServiceHelper => new GitService();
91+
public static IGitService GitServiceHelper => new GitService(new RepositoryFacade());
8492

8593
/// <summary>
8694
/// Finds the latest pushed commit of a file and returns the sha of that commit. Returns null when no commits have
8795
/// been found in any remote branches or the current local branch.
8896
/// </summary>
8997
/// <param name="path">The local path of a repository or a file inside a repository. This cannot be null.</param>
98+
/// <param name="remote">The remote name to look for</param>
9099
/// <returns></returns>
91-
public Task<string> GetLatestPushedSha(string path)
100+
public Task<string> GetLatestPushedSha(string path, string remote = "origin")
92101
{
93102
Guard.ArgumentNotNull(path, nameof(path));
94103

95-
return Task.Factory.StartNew(() =>
104+
return Task.Run(() =>
96105
{
97106
using (var repo = GetRepository(path))
98107
{
99108
if (repo != null)
100109
{
101-
if (repo.Head.IsTracking && repo.Head.Tip.Sha == repo.Head.TrackedBranch.Tip.Sha)
110+
// This is the common case where HEAD is tracking a remote branch
111+
var commonAncestor = repo.Head.TrackingDetails.CommonAncestor;
112+
if (commonAncestor != null)
102113
{
103-
return repo.Head.Tip.Sha;
114+
return commonAncestor.Sha;
104115
}
105116

106-
var remoteHeads = repo.Refs.Where(r => r.IsRemoteTrackingBranch).ToList();
107-
foreach (var c in repo.Commits)
117+
// This is the common case where a branch was forked from a local branch.
118+
// Use CommonAncestor because we don't want to search for a commit that only exists
119+
// locally or that has been added to the remote tracking branch since the fork.
120+
var commonAncestorShas = repo.Branches
121+
.Where(b => b.IsTracking)
122+
.Select(b => b.TrackingDetails.CommonAncestor?.Sha)
123+
.Where(s => s != null)
124+
.ToArray();
125+
126+
var sortByTopological = new CommitFilter { SortBy = CommitSortStrategies.Topological };
127+
foreach (var commit in repo.Commits.QueryBy(sortByTopological))
108128
{
109-
if (repo.Refs.ReachableFrom(remoteHeads, new[] { c }).Any())
129+
if (commonAncestorShas.Contains(commit.Sha))
110130
{
111-
return c.Sha;
131+
return commit.Sha;
112132
}
113133
}
134+
135+
// This is a less common case where a branch was forked from a branch
136+
// which has since had new commits added to it.
137+
var nearestCommonAncestor = repo.Branches
138+
.Where(b => b.IsRemote)
139+
.Select(b => b.Tip)
140+
.Distinct()
141+
.Select(c => repo.ObjectDatabase.CalculateHistoryDivergence(c, repo.Head.Tip))
142+
.Where(hd => hd.AheadBy != null)
143+
.OrderBy(hd => hd.BehindBy)
144+
.Select(hd => hd.CommonAncestor)
145+
.FirstOrDefault();
146+
if (nearestCommonAncestor != null)
147+
{
148+
return nearestCommonAncestor.Sha;
149+
}
114150
}
115151

116152
return null;
117153
}
118154
});
119155
}
120156
}
121-
}
157+
}

src/GitHub.Exports/Services/IGitService.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ public interface IGitService
2828
/// <param name="remote">The remote name to look for</param>
2929
/// <returns>A <see cref="UriString"/> representing the origin or null if none found.</returns>
3030
UriString GetUri(string path, string remote = "origin");
31-
31+
3232
/// <summary>
3333
/// Probes for a git repository and if one is found, returns a <see cref="IRepositoryModel"/> instance for the
3434
/// repository.
@@ -54,7 +54,8 @@ public interface IGitService
5454
/// been found in any remote branches or the current local branch.
5555
/// </summary>
5656
/// <param name="path">The local path of a repository or a file inside a repository. This cannot be null.</param>
57+
/// <param name="remote">The remote name to look for</param>
5758
/// <returns></returns>
58-
Task<string> GetLatestPushedSha(string path);
59+
Task<string> GetLatestPushedSha(string path, string remote = "origin");
5960
}
6061
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
using LibGit2Sharp;
2+
3+
namespace GitHub.Services
4+
{
5+
/// <summary>
6+
/// Facade for <see cref="LibGit2Sharp.Repository"/> static methods.
7+
/// </summary>
8+
public interface IRepositoryFacade
9+
{
10+
IRepository NewRepository(string path);
11+
string Discover(string startingPath);
12+
}
13+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
using System.ComponentModel.Composition;
2+
using LibGit2Sharp;
3+
4+
namespace GitHub.Services
5+
{
6+
/// <summary>
7+
/// Facade for <see cref="LibGit2Sharp.Repository"/> static methods.
8+
/// </summary>
9+
[Export(typeof(IRepositoryFacade))]
10+
public class RepositoryFacade : IRepositoryFacade
11+
{
12+
public IRepository NewRepository(string path)
13+
{
14+
return new Repository(path);
15+
}
16+
17+
public string Discover(string startingPath)
18+
{
19+
return Repository.Discover(startingPath);
20+
}
21+
}
22+
}

src/GitHub.InlineReviews/GitHub.InlineReviews.csproj

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -357,9 +357,8 @@
357357
<HintPath>..\..\packages\Microsoft.VisualStudio.Validation.14.1.111\lib\net45\Microsoft.VisualStudio.Validation.dll</HintPath>
358358
<Private>True</Private>
359359
</Reference>
360-
<Reference Include="Newtonsoft.Json, Version=10.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
361-
<HintPath>..\..\packages\Newtonsoft.Json.10.0.3\lib\net45\Newtonsoft.Json.dll</HintPath>
362-
<Private>True</Private>
360+
<Reference Include="Newtonsoft.Json, Version=9.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
361+
<HintPath>..\..\packages\Newtonsoft.Json.9.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
363362
</Reference>
364363
<Reference Include="Octokit.GraphQL, Version=0.1.1.0, Culture=neutral, PublicKeyToken=0be8860aee462442, processorArchitecture=MSIL">
365364
<HintPath>..\..\packages\Octokit.GraphQL.0.1.1-beta\lib\netstandard1.1\Octokit.GraphQL.dll</HintPath>

src/GitHub.Resources/Resources.zh-CN.resx

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -118,13 +118,13 @@
118118
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
119119
</resheader>
120120
<data name="BrowseForDirectory" xml:space="preserve">
121-
<value>为新版本库选择文件夹。</value>
121+
<value>为新存储库选择包含文件夹。</value>
122122
</data>
123123
<data name="CloneTitle" xml:space="preserve">
124-
<value>克隆一个 版本库</value>
124+
<value>克隆存储库</value>
125125
</data>
126126
<data name="OpenFromGitHubTitle" xml:space="preserve">
127-
<value>Open from GitHub</value>
127+
<value>GitHub 打开</value>
128128
</data>
129129
<data name="CouldNotConnectToGitHub" xml:space="preserve">
130130
<value>无法连接到github.com</value>
@@ -330,7 +330,7 @@
330330
<value>取消评审</value>
331331
</data>
332332
<data name="DestinationAlreadyExists" xml:space="preserve">
333-
<value>A file exists at the destination path.</value>
333+
<value>有一个文件在目标路径已存在。</value>
334334
</data>
335335
<data name="LogoutRequired" xml:space="preserve">
336336
<value>需要注销</value>
@@ -824,15 +824,15 @@
824824
<value>无法在当前存储库中找到目标URL。在进行提取后再试一次。</value>
825825
</data>
826826
<data name="CantFindARepositoryAtLocalPath" xml:space="preserve">
827-
<value>There is already a directory at this location, but it doesn't contain a repository.</value>
827+
<value>此位置已经有一个目录, 但它不包含存储库。</value>
828828
</data>
829829
<data name="LocalRepositoryDoesntHaveARemoteOrigin" xml:space="preserve">
830-
<value>A repository already exists at this location, but it doesn't have a remote named "origin".</value>
830+
<value>此位置已存在存储库, 但它没有名为 "origin"的远端。</value>
831831
</data>
832832
<data name="LocalRepositoryHasARemoteOf" xml:space="preserve">
833-
<value>A repository already exists at this location, but it has a remote of {0}.</value>
833+
<value>此位置已存在存储库, 但它具有 {0} 的远端。</value>
834834
</data>
835835
<data name="YouHaveAlreadyClonedToThisLocation" xml:space="preserve">
836-
<value>You have already cloned to this location. Click 'Open' to open the local repository.</value>
836+
<value>您已经克隆到此位置。单击 "打开" 打开本地存储库。</value>
837837
</data>
838838
</root>

0 commit comments

Comments
 (0)