Skip to content

Commit a78492f

Browse files
committed
moved GitRepository extensions to GitExtensions
1 parent 542d1ce commit a78492f

File tree

6 files changed

+109
-110
lines changed

6 files changed

+109
-110
lines changed

src/GitVersionCore.Tests/Extensions/GitToolsTestingExtensions.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ public static Branch FindBranch(this IGitRepository repository, string branchNam
2727

2828
public static void DumpGraph(this IGitRepository repository, Action<string> writer = null, int? maxCommits = null)
2929
{
30-
GitExtensions.DumpGraph(repository.Info.Path, writer, maxCommits);
30+
GitExtensions.DumpGraph(repository.Path, writer, maxCommits);
3131
}
3232

3333
public static VersionVariables GetVersion(this RepositoryFixtureBase fixture, Config configuration = null, IRepository repository = null, string commitId = null, bool onlyTrackedBranches = true, string branch = null)

src/GitVersionCore.Tests/Mocks/MockRepository.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,9 @@ public CommitCollection Commits
3030

3131
public BranchCollection Branches { get; set; }
3232
public TagCollection Tags { get; set; }
33-
public RepositoryInformation Info { get; set; }
34-
3533
public Network Network { get; set; }
34+
public string Path { get; }
35+
public bool IsHeadDetached { get; }
3636
public int GetNumberOfUncommittedChanges() => 0;
3737
public Commit FindMergeBase(Commit commit, Commit otherCommit) => throw new NotImplementedException();
3838
public string ShortenObjectId(Commit commit) => throw new NotImplementedException();

src/GitVersionCore/Core/Abstractions/IGitRepository.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,14 @@ namespace GitVersion
55
{
66
public interface IGitRepository : IDisposable
77
{
8+
string Path { get; }
9+
bool IsHeadDetached { get; }
810
IGitRepositoryCommands Commands { get; }
911
Branch Head { get; }
1012
CommitCollection Commits { get; }
1113
BranchCollection Branches { get; }
1214
TagCollection Tags { get; }
1315
ReferenceCollection Refs { get; }
14-
RepositoryInformation Info { get; }
1516
Network Network { get; }
1617
int GetNumberOfUncommittedChanges();
1718
Commit FindMergeBase(Commit commit, Commit otherCommit);

src/GitVersionCore/Core/GitPreparer.cs

Lines changed: 3 additions & 104 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
using System;
2-
using System.Collections.Generic;
32
using System.IO;
43
using System.Linq;
54
using GitVersion.Extensions;
@@ -209,9 +208,7 @@ private void NormalizeGitDirectory(string gitDirectory, bool noFetch, string cur
209208

210209
try
211210
{
212-
var remote = EnsureOnlyOneRemoteIsDefined(repository, log);
213-
214-
AddMissingRefSpecs(repository, log, remote);
211+
var remote = repository.EnsureOnlyOneRemoteIsDefined(log);
215212

216213
//If noFetch is enabled, then GitVersion will assume that the git repository is normalized before execution, so that fetching from remotes is not required.
217214
if (noFetch)
@@ -242,7 +239,7 @@ private void NormalizeGitDirectory(string gitDirectory, bool noFetch, string cur
242239

243240
var headSha = repository.Refs.Head.TargetIdentifier;
244241

245-
if (!repository.Info.IsHeadDetached)
242+
if (!repository.IsHeadDetached)
246243
{
247244
log.Info($"HEAD points at branch '{headSha}'.");
248245
return;
@@ -295,7 +292,7 @@ private void NormalizeGitDirectory(string gitDirectory, bool noFetch, string cur
295292
else if (localBranchesWhereCommitShaIsHead.Count == 0)
296293
{
297294
log.Info($"No local branch pointing at the commit '{headSha}'. Fake branch needs to be created.");
298-
CreateFakeBranchPointingAtThePullRequestTip(repository, log, authentication);
295+
repository.CreateFakeBranchPointingAtThePullRequestTip(log, authentication);
299296
}
300297
else
301298
{
@@ -410,103 +407,5 @@ private static void EnsureLocalBranchExistsForCurrentBranch(IGitRepository repo,
410407

411408
repo.Commands.Checkout(localCanonicalName);
412409
}
413-
414-
private static Remote EnsureOnlyOneRemoteIsDefined(IGitRepository repo, ILog log)
415-
{
416-
var remotes = repo.Network.Remotes;
417-
var howMany = remotes.Count();
418-
419-
if (howMany == 1)
420-
{
421-
var remote = remotes.Single();
422-
log.Info($"One remote found ({remote.Name} -> '{remote.Url}').");
423-
return remote;
424-
}
425-
426-
var message = $"{howMany} remote(s) have been detected. When being run on a build server, the Git repository is expected to bear one (and no more than one) remote.";
427-
throw new WarningException(message);
428-
}
429-
430-
private static void AddMissingRefSpecs(IGitRepository repo, ILog log, Remote remote)
431-
{
432-
if (remote.FetchRefSpecs.Any(r => r.Source == "refs/heads/*"))
433-
return;
434-
435-
var allBranchesFetchRefSpec = $"+refs/heads/*:refs/remotes/{remote.Name}/*";
436-
437-
log.Info($"Adding refspec: {allBranchesFetchRefSpec}");
438-
439-
repo.Network.Remotes.Update(remote.Name,
440-
r => r.FetchRefSpecs.Add(allBranchesFetchRefSpec));
441-
}
442-
443-
private static void CreateFakeBranchPointingAtThePullRequestTip(IGitRepository repo, ILog log, AuthenticationInfo authentication)
444-
{
445-
var remote = repo.Network.Remotes.Single();
446-
447-
log.Info("Fetching remote refs to see if there is a pull request ref");
448-
var remoteTips = (string.IsNullOrEmpty(authentication.Username) ?
449-
GetRemoteTipsForAnonymousUser(repo, remote) :
450-
GetRemoteTipsUsingUsernamePasswordCredentials(repo, remote, authentication.Username, authentication.Password))
451-
.ToList();
452-
453-
log.Info($"Remote Refs:{System.Environment.NewLine}" + string.Join(System.Environment.NewLine, remoteTips.Select(r => r.CanonicalName)));
454-
455-
var headTipSha = repo.Head.Tip.Sha;
456-
457-
var refs = remoteTips.Where(r => r.TargetIdentifier == headTipSha).ToList();
458-
459-
if (refs.Count == 0)
460-
{
461-
var message = $"Couldn't find any remote tips from remote '{remote.Url}' pointing at the commit '{headTipSha}'.";
462-
throw new WarningException(message);
463-
}
464-
465-
if (refs.Count > 1)
466-
{
467-
var names = string.Join(", ", refs.Select(r => r.CanonicalName));
468-
var message = $"Found more than one remote tip from remote '{remote.Url}' pointing at the commit '{headTipSha}'. Unable to determine which one to use ({names}).";
469-
throw new WarningException(message);
470-
}
471-
472-
var reference = refs[0];
473-
var canonicalName = reference.CanonicalName;
474-
log.Info($"Found remote tip '{canonicalName}' pointing at the commit '{headTipSha}'.");
475-
476-
if (canonicalName.StartsWith("refs/tags"))
477-
{
478-
log.Info($"Checking out tag '{canonicalName}'");
479-
repo.Commands.Checkout(reference.Target.Sha);
480-
return;
481-
}
482-
483-
if (!canonicalName.StartsWith("refs/pull/") && !canonicalName.StartsWith("refs/pull-requests/"))
484-
{
485-
var message = $"Remote tip '{canonicalName}' from remote '{remote.Url}' doesn't look like a valid pull request.";
486-
throw new WarningException(message);
487-
}
488-
489-
var fakeBranchName = canonicalName.Replace("refs/pull/", "refs/heads/pull/").Replace("refs/pull-requests/", "refs/heads/pull-requests/");
490-
491-
log.Info($"Creating fake local branch '{fakeBranchName}'.");
492-
repo.Refs.Add(fakeBranchName, new ObjectId(headTipSha));
493-
494-
log.Info($"Checking local branch '{fakeBranchName}' out.");
495-
repo.Commands.Checkout(fakeBranchName);
496-
}
497-
498-
private static IEnumerable<DirectReference> GetRemoteTipsUsingUsernamePasswordCredentials(IGitRepository repository, Remote remote, string username, string password)
499-
{
500-
return repository.Network.ListReferences(remote, (url, fromUrl, types) => new UsernamePasswordCredentials
501-
{
502-
Username = username,
503-
Password = password ?? string.Empty
504-
}).Select(r => r.ResolveToDirectReference());
505-
}
506-
507-
private static IEnumerable<DirectReference> GetRemoteTipsForAnonymousUser(IGitRepository repository, Remote remote)
508-
{
509-
return repository.Network.ListReferences(remote).Select(r => r.ResolveToDirectReference());
510-
}
511410
}
512411
}

src/GitVersionCore/Core/GitRepository.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@ public void Dispose()
3333
if (repositoryLazy.IsValueCreated) repositoryInstance.Dispose();
3434
}
3535

36+
public string Path => repositoryInstance.Info.Path;
37+
public bool IsHeadDetached => repositoryInstance.Info.IsHeadDetached;
3638
public int GetNumberOfUncommittedChanges()
3739
{
3840
// check if we have a branch tip at all to behave properly with empty repos
@@ -82,8 +84,6 @@ public string ShortenObjectId(Commit commit)
8284

8385
public TagCollection Tags => (TagCollection)repositoryInstance.Tags;
8486

85-
public RepositoryInformation Info => repositoryInstance.Info;
86-
8787
public Network Network => repositoryInstance.Network;
8888
}
8989
}

src/GitVersionCore/Extensions/GitExtensions.cs

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
using System.Linq;
55
using System.Text;
66
using GitVersion.Helpers;
7+
using GitVersion.Logging;
78
using LibGit2Sharp;
89

910
namespace GitVersion.Extensions
@@ -243,5 +244,103 @@ public static CommitCollection GetCommitLog(this IGitRepository repository, Comm
243244

244245
return commitCollection;
245246
}
247+
248+
public static Remote EnsureOnlyOneRemoteIsDefined(this IGitRepository repo, ILog log)
249+
{
250+
var remotes = repo.Network.Remotes;
251+
var howMany = remotes.Count();
252+
253+
if (howMany == 1)
254+
{
255+
var remote = remotes.Single();
256+
log.Info($"One remote found ({remote.Name} -> '{remote.Url}').");
257+
repo.AddMissingRefSpecs(log, remote);
258+
return remote;
259+
}
260+
261+
var message = $"{howMany} remote(s) have been detected. When being run on a build server, the Git repository is expected to bear one (and no more than one) remote.";
262+
throw new WarningException(message);
263+
}
264+
265+
public static void CreateFakeBranchPointingAtThePullRequestTip(this IGitRepository repo, ILog log, AuthenticationInfo authentication)
266+
{
267+
var remote = repo.Network.Remotes.Single();
268+
269+
log.Info("Fetching remote refs to see if there is a pull request ref");
270+
var remoteTips = (string.IsNullOrWhiteSpace(authentication.Username) ?
271+
repo.GetRemoteTipsForAnonymousUser(remote) :
272+
repo.GetRemoteTipsUsingUsernamePasswordCredentials(remote, authentication.Username, authentication.Password))
273+
.Select(r => r.ResolveToDirectReference()).ToList();
274+
275+
log.Info($"Remote Refs:{System.Environment.NewLine}" + string.Join(System.Environment.NewLine, remoteTips.Select(r => r.CanonicalName)));
276+
277+
var headTipSha = repo.Head.Tip.Sha;
278+
279+
var refs = remoteTips.Where(r => r.TargetIdentifier == headTipSha).ToList();
280+
281+
if (refs.Count == 0)
282+
{
283+
var message = $"Couldn't find any remote tips from remote '{remote.Url}' pointing at the commit '{headTipSha}'.";
284+
throw new WarningException(message);
285+
}
286+
287+
if (refs.Count > 1)
288+
{
289+
var names = string.Join(", ", refs.Select(r => r.CanonicalName));
290+
var message = $"Found more than one remote tip from remote '{remote.Url}' pointing at the commit '{headTipSha}'. Unable to determine which one to use ({names}).";
291+
throw new WarningException(message);
292+
}
293+
294+
var reference = refs[0];
295+
var canonicalName = reference.CanonicalName;
296+
log.Info($"Found remote tip '{canonicalName}' pointing at the commit '{headTipSha}'.");
297+
298+
if (canonicalName.StartsWith("refs/tags"))
299+
{
300+
log.Info($"Checking out tag '{canonicalName}'");
301+
repo.Commands.Checkout(reference.Target.Sha);
302+
return;
303+
}
304+
305+
if (!canonicalName.StartsWith("refs/pull/") && !canonicalName.StartsWith("refs/pull-requests/"))
306+
{
307+
var message = $"Remote tip '{canonicalName}' from remote '{remote.Url}' doesn't look like a valid pull request.";
308+
throw new WarningException(message);
309+
}
310+
311+
var fakeBranchName = canonicalName.Replace("refs/pull/", "refs/heads/pull/").Replace("refs/pull-requests/", "refs/heads/pull-requests/");
312+
313+
log.Info($"Creating fake local branch '{fakeBranchName}'.");
314+
repo.Refs.Add(fakeBranchName, new ObjectId(headTipSha));
315+
316+
log.Info($"Checking local branch '{fakeBranchName}' out.");
317+
repo.Commands.Checkout(fakeBranchName);
318+
}
319+
320+
private static IEnumerable<Reference> GetRemoteTipsUsingUsernamePasswordCredentials(this IGitRepository repository, Remote remote, string username, string password)
321+
{
322+
return repository.Network.ListReferences(remote, (url, fromUrl, types) => new UsernamePasswordCredentials
323+
{
324+
Username = username,
325+
Password = password ?? string.Empty
326+
});
327+
}
328+
329+
private static IEnumerable<Reference> GetRemoteTipsForAnonymousUser(this IGitRepository repository, Remote remote)
330+
{
331+
return repository.Network.ListReferences(remote);
332+
}
333+
334+
private static void AddMissingRefSpecs(this IGitRepository repo, ILog log, Remote remote)
335+
{
336+
if (remote.FetchRefSpecs.Any(r => r.Source == "refs/heads/*"))
337+
return;
338+
339+
var allBranchesFetchRefSpec = $"+refs/heads/*:refs/remotes/{remote.Name}/*";
340+
341+
log.Info($"Adding refspec: {allBranchesFetchRefSpec}");
342+
343+
repo.Network.Remotes.Update(remote.Name, r => r.FetchRefSpecs.Add(allBranchesFetchRefSpec));
344+
}
246345
}
247346
}

0 commit comments

Comments
 (0)