release:prepare should check for remote/local being in sync first
New feature, improvement proposal
Currently release:prepare only breaks in case of sync issues between remote/local once it tries to push at the very end. This check should be performed first to fail faster in that case (before any modifications to local working directory have been applied). Although there is a slight chance that between checking and pushing there are additional commits being added this should capture non-pulled changes for most of the cases.
@kwin I got your point.
Solution
A new phase ScmCheckRemoteSyncPhase has been added to the beginning of the prepare phase sequence (right after check-poms). This phase:
- Checks if push is enabled - Only runs when
pushChangesistrue(default) - Detects unpulled commits - Fails fast if the remote branch has commits that haven't been pulled locally
- Warns about unpushed commits - Provides information about local commits that will be pushed
- Provider-specific implementation - Currently fully implemented for Git, with graceful degradation for other SCM providers
How It Works
For Git Repositories
The phase executes the following Git commands:
git rev-parse --abbrev-ref HEAD- Gets the current branch namegit remote update- Fetches remote repository information without merginggit rev-parse --abbrev-ref <branch>@{upstream}- Gets the remote tracking branchgit rev-list --count HEAD..<remote>- Counts unpulled commits (remote ahead of local)git rev-list --count <remote>..HEAD- Counts unpushed commits (local ahead of remote)
Failure Conditions
The release will fail immediately if:
- The local branch is behind the remote branch (unpulled commits exist)
Warning Conditions
The release will continue with a warning if:
- The local branch has unpushed commits (these will be pushed at the end)
Configuration
No additional configuration is required. The feature respects the existing pushChanges parameter:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-release-plugin</artifactId>
<configuration>
<!-- Enable/disable the remote sync check -->
<pushChanges>true</pushChanges> <!-- default: true -->
</configuration>
</plugin>
Or via command line:
mvn release:prepare -DpushChanges=false # Skips remote sync check
Limitations
- Git-specific: Full implementation only available for Git repositories
- Requires Git installed: The phase executes Git commands via ProcessBuilder
- Network dependency: Requires network access to fetch remote information
- Race condition: There's a small time window between the check and the actual push where new commits could be added remotely
Let me know if I can proceed with a PR. Thanks!
The implementation should leverage https://maven.apache.org/scm/index.html for all SCM related operations. Also not sure if this justifies a dedicated phase. But in general please provide a PR. We can refine there.