To complement torek's answer, here is a way in PowerShell to perform a variant on option #3.
Do another (different) push inside the hook, after adding the new commit, taking care that your hook does not endlessly recurse because the "inner" push runs the hook which decides to do another "inner-again" push, etc.
The difference is that we exit zero and do the "inner" push after completing the "outer" push.
pre-push
#!/bin/sh
dir=$(dirname "$0")
pwsh -NoProfile -File "$dir/pre-push.ps1";
pre-push.ps1
Register-EngineEvent PowerShell.Exiting -SupportEvent -Action {
Write-Host "Registering post-formatting job.";
try {
$waitCommand = "while((git status -sb) -match 'ahead') { Start-Sleep -Seconds 1; };";
$gitCommand = "git commit --allow-empty -m 'format'; git push --no-verify;"
Import-Module Microsoft.PowerShell.Management;
Start-Process pwsh `
-WindowStyle Hidden `
-ArgumentList "-NoProfile -Command $waitCommand $gitCommand";
} catch {
Write-Host $_;
}
Write-Host "Registered post-formatting job.";
}
# --------------
# Perform the auto-formatting here.
# --------------
exit 0;
The scenario is auto-formatting, but it could be any task that changes the code before making a commit and push.