2727import javax .annotation .Nullable ;
2828import java .io .File ;
2929import java .nio .charset .Charset ;
30+ import java .nio .file .Path ;
3031import java .text .SimpleDateFormat ;
3132import java .util .*;
3233import java .util .function .Supplier ;
@@ -284,20 +285,14 @@ default Map<String, String> getSystemEnv() {
284285 boolean shouldFailOnNoGitDirectory ();
285286
286287 /**
287- * When set to {@code true}, the plugin will consider only commits affecting
288- * the folder containing this module.
289- *
290- * When set to {@code false}, the plugin will consider all commits in the
291- * repository.
288+ * When set to {@code true}, the plugin will only consider commits affecting
289+ * paths within the current project's base directory.
292290 *
293- * @return Controls whether the plugin only considers commits in the current module's directory.
291+ * <p>This is useful for multi-module projects stored in a single git repository where you want
292+ + properties like {@code git.commit.id.*} and {@code git.total.commit.count} to be based on the
293+ + latest commit that touched this module, not the whole repository.
294294 */
295- boolean getPerModuleVersions ();
296-
297- /**
298- * @return Base directory (folder) of the current module.
299- */
300- File getModuleBaseDir ();
295+ boolean isPerModuleVersions ();
301296 }
302297
303298 protected static final Pattern allowedCharactersForEvaluateOnCommit = Pattern .compile ("[a-zA-Z0-9\\ _\\ -\\ ^\\ /\\ .]+" );
@@ -384,19 +379,9 @@ private static void loadGitDataWithNativeGit(
384379 @ Nonnull File dotGitDirectory ,
385380 @ Nonnull Properties properties ) throws GitCommitIdExecutionException {
386381 GitDataProvider nativeGitProvider = NativeGitProvider
387- .on (dotGitDirectory , cb .getNativeGitTimeoutInMs (), cb .getLogInterface ())
388- .setPrefixDot (cb .getPrefixDot ())
389- .setAbbrevLength (cb .getAbbrevLength ())
390- .setDateFormat (cb .getDateFormat ())
391- .setDateFormatTimeZone (cb .getDateFormatTimeZone ())
392- .setGitDescribe (cb .getGitDescribe ())
393- .setCommitIdGenerationMode (cb .getCommitIdGenerationMode ())
394- .setUseBranchNameFromBuildEnvironment (cb .getUseBranchNameFromBuildEnvironment ())
395- .setExcludeProperties (cb .getExcludeProperties ())
396- .setIncludeOnlyProperties (cb .getIncludeOnlyProperties ())
397- .setPerModuleVersions (cb .getPerModuleVersions ())
398- .setModuleBaseDir (cb .getModuleBaseDir ())
399- .setOffline (cb .isOffline ());
382+ .on (dotGitDirectory , cb .getNativeGitTimeoutInMs (), cb .getLogInterface ());
383+
384+ configureCommonProvider (nativeGitProvider , cb , dotGitDirectory );
400385
401386 nativeGitProvider .loadGitData (cb .getEvaluateOnCommit (), cb .getSystemEnv (), properties );
402387 }
@@ -406,7 +391,18 @@ private static void loadGitDataWithJGit(
406391 @ Nonnull File dotGitDirectory ,
407392 @ Nonnull Properties properties ) throws GitCommitIdExecutionException {
408393 GitDataProvider jGitProvider = JGitProvider
409- .on (dotGitDirectory , cb .getLogInterface ())
394+ .on (dotGitDirectory , cb .getLogInterface ());
395+
396+ configureCommonProvider (jGitProvider , cb , dotGitDirectory );
397+
398+ jGitProvider .loadGitData (cb .getEvaluateOnCommit (), cb .getSystemEnv (), properties );
399+ }
400+
401+ private static void configureCommonProvider (
402+ @ Nonnull GitDataProvider provider ,
403+ @ Nonnull Callback cb ,
404+ @ Nonnull File dotGitDirectory ) {
405+ provider
410406 .setPrefixDot (cb .getPrefixDot ())
411407 .setAbbrevLength (cb .getAbbrevLength ())
412408 .setDateFormat (cb .getDateFormat ())
@@ -416,10 +412,57 @@ private static void loadGitDataWithJGit(
416412 .setUseBranchNameFromBuildEnvironment (cb .getUseBranchNameFromBuildEnvironment ())
417413 .setExcludeProperties (cb .getExcludeProperties ())
418414 .setIncludeOnlyProperties (cb .getIncludeOnlyProperties ())
419- .setPerModuleVersions (cb .getPerModuleVersions ())
420- .setModuleBaseDir (cb .getModuleBaseDir ())
421- .setOffline (cb .isOffline ());
415+ .setOffline (cb .isOffline ())
416+ .setPathFilter (
417+ cb .isPerModuleVersions ()
418+ ? resolveRelativeModulePath (cb , dotGitDirectory )
419+ : null );
420+ }
422421
423- jGitProvider .loadGitData (cb .getEvaluateOnCommit (), cb .getSystemEnv (), properties );
422+ /**
423+ * Resolves the relative module path from repository root to project base directory.
424+ * This is used for per-module filtering to limit git operations to the current project.
425+ * Returns null if the project directory is not within the repository or if resolution fails.
426+ */
427+ @ Nullable
428+ private static String resolveRelativeModulePath (@ Nonnull Callback cb , @ Nonnull File dotGitDirectory ) {
429+ try {
430+ // Determine repository work tree
431+ // If dotGitDirectory is named ".git", the work tree is its parent
432+ // Otherwise, dotGitDirectory might be the work tree itself (for bare repos or special cases)
433+ File repoWorkTree ;
434+ if (dotGitDirectory .getName ().equals (".git" )) {
435+ repoWorkTree = dotGitDirectory .getParentFile ();
436+ } else {
437+ repoWorkTree = dotGitDirectory ;
438+ }
439+
440+ if (repoWorkTree == null || !repoWorkTree .exists ()) {
441+ cb .getLogInterface ().warn ("Could not determine repository work tree from dotGitDirectory: " + dotGitDirectory );
442+ return null ;
443+ }
444+
445+ Path repoRoot = repoWorkTree .toPath ().toAbsolutePath ().normalize ();
446+ Path moduleDir = cb .getProjectBaseDir ().toPath ().toAbsolutePath ().normalize ();
447+
448+ if (!moduleDir .startsWith (repoRoot )) {
449+ cb .getLogInterface ()
450+ .warn ("Project directory is not within repository work tree. " +
451+ "Project: " + moduleDir + ", Repo: " + repoRoot + ". " +
452+ "Falling back to normal behavior." );
453+ return null ;
454+ }
455+
456+ String relative = repoRoot .relativize (moduleDir ).toString ();
457+ if (relative .isEmpty ()) {
458+ relative = "." ;
459+ }
460+ return relative .replace (File .separatorChar , '/' );
461+ } catch (Exception e ) {
462+ cb .getLogInterface ()
463+ .warn ("Failed to resolve relative module path: " + e .getMessage () +
464+ ". Falling back to normal behavior." );
465+ return null ;
466+ }
424467 }
425468}
0 commit comments