diff --git a/packages/melos/lib/src/common/git.dart b/packages/melos/lib/src/common/git.dart index e06e062e..6f3dc89b 100644 --- a/packages/melos/lib/src/common/git.dart +++ b/packages/melos/lib/src/common/git.dart @@ -276,23 +276,8 @@ Future> gitCommitsForPackage( String? diff, required MelosLogger logger, }) async { - var revisionRange = diff?.trim(); - if (revisionRange != null) { - if (revisionRange.isEmpty) { - revisionRange = null; - } else if (!_gitVersionRangeShortHandRegExp.hasMatch(revisionRange)) { - // If the revision range is not a valid revision range short hand then we - // assume it's a commit or tag and default to the range from that - // commit/tag to HEAD. - revisionRange = '$revisionRange...HEAD'; - } - } - - if (revisionRange == null) { - final latestTag = await gitLatestTagForPackage(package, logger: logger); - // If no latest tag is found then we default to the entire git history. - revisionRange = latestTag != null ? '$latestTag...HEAD' : 'HEAD'; - } + final revisionRange = + await _resolveRevisionRange(package, diff: diff, logger: logger); logger.trace( '[GIT] Getting commits for package ${package.name} for revision range ' @@ -328,6 +313,34 @@ Future> gitCommitsForPackage( }).toList(); } +Future gitHasDiffInPackage( + Package package, { + required String? diff, + required MelosLogger logger, +}) async { + final revisionRange = + await _resolveRevisionRange(package, diff: diff, logger: logger); + + logger.trace( + '[GIT] Getting $diff diff for package ${package.name}.', + ); + + final processResult = await gitExecuteCommand( + arguments: [ + '--no-pager', + 'diff', + '--name-status', + revisionRange, + '--', + '.', + ], + workingDirectory: package.path, + logger: logger, + ); + + return (processResult.stdout as String).isNotEmpty; +} + /// Returns the current branch name of the local git repository. Future gitGetCurrentBranchName({ required String workingDirectory, @@ -396,3 +409,29 @@ Future gitIsBehindUpstream({ return isBehind; } + +Future _resolveRevisionRange( + Package package, { + required String? diff, + required MelosLogger logger, +}) async { + var revisionRange = diff?.trim(); + if (revisionRange != null) { + if (revisionRange.isEmpty) { + revisionRange = null; + } else if (!_gitVersionRangeShortHandRegExp.hasMatch(revisionRange)) { + // If the revision range is not a valid revision range short hand then we + // assume it's a commit or tag and default to the range from that + // commit/tag to HEAD. + return '$revisionRange...HEAD'; + } + } + + if (revisionRange == null) { + final latestTag = await gitLatestTagForPackage(package, logger: logger); + // If no latest tag is found then we default to the entire git history. + return latestTag != null ? '$latestTag...HEAD' : 'HEAD'; + } + + return 'HEAD'; +} diff --git a/packages/melos/lib/src/package.dart b/packages/melos/lib/src/package.dart index c3d0ac5a..e52ec555 100644 --- a/packages/melos/lib/src/package.dart +++ b/packages/melos/lib/src/package.dart @@ -689,9 +689,9 @@ extension on Iterable { return Pool(10) .forEach(this, (package) async { - final commits = - await gitCommitsForPackage(package, diff: diff, logger: logger); - return MapEntry(package, commits.isNotEmpty); + final hasDiff = + await gitHasDiffInPackage(package, diff: diff, logger: logger); + return MapEntry(package, hasDiff); }) .where((event) => event.value) .map((event) => event.key)