diff --git a/src/NerdBank.GitVersioning.Tests/VersionOracleTests.cs b/src/NerdBank.GitVersioning.Tests/VersionOracleTests.cs
index 2f433859..937b0575 100644
--- a/src/NerdBank.GitVersioning.Tests/VersionOracleTests.cs
+++ b/src/NerdBank.GitVersioning.Tests/VersionOracleTests.cs
@@ -444,7 +444,7 @@ public void Worktree_Support(bool detachedHead)
var context = this.CreateGitContext(workTreePath);
var oracleWorkTree = new VersionOracle(context);
Assert.Equal(oracleOriginal.Version, oracleWorkTree.Version);
-
+
Assert.True(context.TrySelectCommit("HEAD"));
Assert.True(context.TrySelectCommit(this.LibGit2Repository.Head.Tip.Sha));
}
@@ -731,6 +731,28 @@ public void GetVersionHeight_IncludeRootExcludeSome()
Assert.Equal(2, this.GetVersionHeight(relativeDirectory));
}
+ [Fact]
+ public void GetVersion_PathFilterInTwoDeepSubDirAndVersionBump()
+ {
+ this.InitializeSourceControl();
+
+ const string relativeDirectory = "src/lib";
+ var versionOptions = new VersionOptions
+ {
+ Version = new SemanticVersion("1.1"),
+ PathFilters = new FilterPath[]
+ {
+ new FilterPath(".", relativeDirectory),
+ },
+ };
+ this.WriteVersionFile(versionOptions, relativeDirectory);
+ Assert.Equal(1, this.GetVersionHeight(relativeDirectory));
+
+ versionOptions.Version = new SemanticVersion("1.2");
+ this.WriteVersionFile(versionOptions, relativeDirectory);
+ Assert.Equal(1, this.GetVersionHeight(relativeDirectory));
+ }
+
[Fact]
public void GetVersionHeight_ProjectDirectoryDifferentToVersionJsonDirectory()
{
diff --git a/src/NerdBank.GitVersioning/FilterPath.cs b/src/NerdBank.GitVersioning/FilterPath.cs
index 52edad43..72322045 100644
--- a/src/NerdBank.GitVersioning/FilterPath.cs
+++ b/src/NerdBank.GitVersioning/FilterPath.cs
@@ -199,6 +199,31 @@ public bool Includes(string repoRelativePath, bool ignoreCase)
stringComparison);
}
+ ///
+ /// Determines if children of may be included
+ /// by this .
+ ///
+ /// Forward-slash delimited path (repo relative).
+ ///
+ /// Whether paths should be compared case insensitively.
+ /// Should be the 'core.ignorecase' config value for the repository.
+ ///
+ ///
+ /// if this is an including filter that may match
+ /// children of , otherwise .
+ ///
+ public bool IncludesChildren(string repoRelativePath, bool ignoreCase)
+ {
+ if (repoRelativePath is null)
+ throw new ArgumentNullException(nameof(repoRelativePath));
+
+ if (!this.IsInclude) return false;
+ if (this.IsRoot) return true;
+
+ var stringComparison = ignoreCase ? StringComparison.OrdinalIgnoreCase : StringComparison.Ordinal;
+ return this.RepoRelativePath.StartsWith(repoRelativePath + "/", stringComparison);
+ }
+
private static (int dirsToAscend, StringBuilder result) GetRelativePath(string path, string relativeTo)
{
var pathParts = path.Split('/');
diff --git a/src/NerdBank.GitVersioning/Managed/ManagedGitExtensions.cs b/src/NerdBank.GitVersioning/Managed/ManagedGitExtensions.cs
index a2f1fefc..58b8206e 100644
--- a/src/NerdBank.GitVersioning/Managed/ManagedGitExtensions.cs
+++ b/src/NerdBank.GitVersioning/Managed/ManagedGitExtensions.cs
@@ -165,15 +165,6 @@ bool TryCalculateHeight(GitCommit commit)
var ignoreCase = repository.IgnoreCase;
- /*
- bool ContainsRelevantChanges(IEnumerable changes) =>
- excludePaths.Count == 0
- ? changes.Any()
- // If there is a single change that isn't excluded,
- // then this commit is relevant.
- : changes.Any(change => !excludePaths.Any(exclude => exclude.Excludes(change.Path, ignoreCase)));
- */
-
int height = 1;
if (pathFilters != null)
@@ -194,26 +185,6 @@ bool TryCalculateHeight(GitCommit commit)
}
}
- /*
- // If there are no include paths, or any of the include
- // paths refer to the root of the repository, then do not
- // filter the diff at all.
- var diffInclude =
- includePaths.Count == 0 || pathFilters.Any(filter => filter.IsRoot)
- ? null
- : includePaths;
-
- // If the diff between this commit and any of its parents
- // does not touch a path that we care about, don't bump the
- // height.
- var relevantCommit =
- commit.Parents.Any()
- ? commit.Parents.Any(parent => ContainsRelevantChanges(commit.GetRepository().Diff
- .Compare(parent.Tree, commit.Tree, diffInclude, DiffOptions)))
- : ContainsRelevantChanges(commit.GetRepository().Diff
- .Compare(null, commit.Tree, diffInclude, DiffOptions));
- */
-
if (!relevantCommit)
{
height = 0;
@@ -268,7 +239,8 @@ private static bool IsRelevantCommit(GitRepository repository, GitTree tree, Git
bool isRelevant =
// Either there are no include filters at all (i.e. everything is included), or there's an explicit include filter
- (!filters.Any(f => f.IsInclude) || filters.Any(f => f.Includes(fullPath, repository.IgnoreCase)))
+ (!filters.Any(f => f.IsInclude) || filters.Any(f => f.Includes(fullPath, repository.IgnoreCase))
+ || (!entry.IsFile && filters.Any(f => f.IncludesChildren(fullPath, repository.IgnoreCase))))
// The path is not excluded by any filters
&& !filters.Any(f => f.Excludes(fullPath, repository.IgnoreCase));