Skip to content

Check that repository isn't a shallow clone and show an error if it is #3479

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Apr 14, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions docs/input/docs/reference/build-servers/azure-devops.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,14 @@ either using the Command Line build step or install an extension / custom build
step. The custom build step requires a one-time setup to import the GitVersion
task into your TFS or Azure DevOps Pipeline instance.

:::{.alert .alert-danger}
**Important**

You must disable shallow fetch, either in the pipeline settings UI or by setting `fetchDepth: 0` in your `checkout` step;
without it, Azure DevOps Pipelines will perform a shallow clone, which will cause GitVersion to display an error message.
See [the Azure DevOps documentation](https://learn.microsoft.com/en-us/azure/devops/pipelines/yaml-schema/steps-checkout?view=azure-pipelines#shallow-fetch) for more information.
:::

## Executing GitVersion

### Using GitVersion with the MSBuild Task NuGet Package
Expand Down
21 changes: 21 additions & 0 deletions src/GitVersion.Core.Tests/Core/GitVersionExecutorTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -544,6 +544,27 @@ public void CalculateVersionVariables_TwoBranchHasSameCommitHeadDetachedAndTagge
version.Sha.ShouldBe(commits.First().Sha);
}

[Test]
public void CalculateVersionVariables_ShallowFetch_ThrowException()
{
// Setup
using var fixture = new RemoteRepositoryFixture();
fixture.LocalRepositoryFixture.MakeShallow();

using var worktreeFixture = new LocalRepositoryFixture(new Repository(fixture.LocalRepositoryFixture.RepositoryPath));
var gitVersionOptions = new GitVersionOptions { WorkingDirectory = worktreeFixture.RepositoryPath };

var environment = new TestEnvironment();
environment.SetEnvironmentVariable(AzurePipelines.EnvironmentVariableName, "true");

this.sp = GetServiceProvider(gitVersionOptions, environment: environment);
var sut = sp.GetRequiredService<IGitVersionCalculateTool>();

// Execute & Verify
var exception = Assert.Throws<WarningException>(() => sut.CalculateVersionVariables());
exception?.Message.ShouldBe("Repository is a shallow clone. Git repositories must contain the full history. See https://gitversion.net/docs/reference/requirements#unshallow for more info.");
}

private IGitVersionCalculateTool GetGitVersionCalculator(GitVersionOptions gitVersionOptions, ILog? logger = null, IGitRepository? repository = null, IFileSystem? fs = null)
{
this.sp = GetServiceProvider(gitVersionOptions, logger, repository, fs);
Expand Down
5 changes: 5 additions & 0 deletions src/GitVersion.Core/Core/GitPreparer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,11 @@ private void NormalizeGitDirectory(bool noFetch, string? currentBranchName, bool

EnsureHeadIsAttachedToBranch(currentBranchName, authentication);
EnsureRepositoryHeadDuringNormalisation(nameof(EnsureHeadIsAttachedToBranch), expectedSha);

if (this.repository.IsShallow)
{
throw new WarningException("Repository is a shallow clone. Git repositories must contain the full history. See https://gitversion.net/docs/reference/requirements#unshallow for more info.");
}
}

private void EnsureRepositoryHeadDuringNormalisation(string occasion, string? expectedSha)
Expand Down
1 change: 1 addition & 0 deletions src/GitVersion.Core/Git/IGitRepository.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ public interface IGitRepository : IDisposable
string Path { get; }
string WorkingDirectory { get; }
bool IsHeadDetached { get; }
bool IsShallow { get; }
IBranch Head { get; }
ITagCollection Tags { get; }
IReferenceCollection Refs { get; }
Expand Down
1 change: 1 addition & 0 deletions src/GitVersion.Core/PublicAPI.Unshipped.txt
Original file line number Diff line number Diff line change
Expand Up @@ -335,6 +335,7 @@ GitVersion.IGitRepository.FindMergeBase(GitVersion.ICommit! commit, GitVersion.I
GitVersion.IGitRepository.GetNumberOfUncommittedChanges() -> int
GitVersion.IGitRepository.Head.get -> GitVersion.IBranch!
GitVersion.IGitRepository.IsHeadDetached.get -> bool
GitVersion.IGitRepository.IsShallow.get -> bool
GitVersion.IGitRepository.Path.get -> string!
GitVersion.IGitRepository.Refs.get -> GitVersion.IReferenceCollection!
GitVersion.IGitRepository.Remotes.get -> GitVersion.IRemoteCollection!
Expand Down
1 change: 1 addition & 0 deletions src/GitVersion.LibGit2Sharp/Git/GitRepository.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ private IRepository RepositoryInstance
public string Path => RepositoryInstance.Info.Path;
public string WorkingDirectory => RepositoryInstance.Info.WorkingDirectory;
public bool IsHeadDetached => RepositoryInstance.Info.IsHeadDetached;
public bool IsShallow => RepositoryInstance.Info.IsShallow;
public IBranch Head => new Branch(RepositoryInstance.Head);
public ITagCollection Tags => new TagCollection(RepositoryInstance.Tags);
public IReferenceCollection Refs => new ReferenceCollection(RepositoryInstance.Refs);
Expand Down
9 changes: 9 additions & 0 deletions src/GitVersion.Testing/Fixtures/RepositoryFixtureBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,15 @@ public LocalRepositoryFixture CloneRepository()
return new LocalRepositoryFixture(new Repository(localPath));
}

/// <summary>
/// Pulls with a depth of 1 and prunes all older commits, making the repository shallow.
/// </summary>
public void MakeShallow()
{
GitTestExtensions.ExecuteGitCmd($"-C {RepositoryPath} pull --depth 1");
GitTestExtensions.ExecuteGitCmd($"-C {RepositoryPath} gc --prune=all");
}

public void Fetch(string remote, FetchOptions? options = null)
=> Commands.Fetch(Repository, remote, Array.Empty<string>(), options, null);
}