feat: validate only commits not yet on any remote#13
Conversation
Enables validation of commit messages before the git object exists, allowing gitlance to work as a commit-msg hook. Comment lines are ignored, matching how a commit message is interpreted. The new mode/argument is mutually exclusive with the ref-based options (--base, --head, --repo, --skip-merge-commits), which are only meaningful when validating existing commits. Signed-off-by: Andrei Gherzan <andrei.gherzan@canonical.com>
When pushing a new branch, the pre-push hook derived its base from a single remote's HEAD. If that remote was behind (e.g. a fork whose main is a stale copy of upstream), it re-validated commits already reviewed and merged elsewhere, and could reject a push over commits the author never touched. Base validation on every remote-tracking ref instead: a commit already present on any remote has been published and does not need rechecking. Excluding a set of refs rather than a single base also lets the root commit be validated, which a single exclusive base can never reach. Closes: canonical#10 Signed-off-by: Andrei Gherzan <andrei.gherzan@canonical.com>
There was a problem hiding this comment.
Pull request overview
This PR updates gitlance’s local-hook workflow to avoid re-validating already-published commits by validating only commits not yet reachable from any remote-tracking ref, and adds a commit-msg hook path via --message-file validation (addressing Issue #10’s root-commit validation gap).
Changes:
- Add
--not-on-remotesmode to validate commits reachable from--headbut not from any remote-tracking ref, with a clean success when there’s nothing new to check. - Add
--message-filemode to validate a single commit message file (forcommit-msghook usage), including git-like comment/scissors stripping. - Update hooks/tasks/tests/docs to support the new CLI behavior.
Reviewed changes
Copilot reviewed 8 out of 8 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| tests/integration_tests.rs | Refactors test runner to capture process output; adds integration coverage for --not-on-remotes and --message-file. |
| Taskfile.yml | Installs the new commit-msg hook alongside pre-push. |
| src/main.rs | Adds new CLI flags and routes execution into message-file, not-on-remotes, or base/head range modes. |
| src/lib.rs | Re-exports new git helpers used by the CLI. |
| src/git.rs | Adds remote-tracking ref enumeration, commit selection via exclude sets, and commit-message parsing utilities + unit tests. |
| README.md | Documents direct CLI usage, including --message-file and --not-on-remotes. |
| githooks/pre-push | Switches new-branch behavior to --not-on-remotes while keeping existing-branch merge-base behavior. |
| githooks/commit-msg | New hook that validates the commit message file via --message-file. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
jw-can
left a comment
There was a problem hiding this comment.
LGTM, nice and clean!
My only comment for potential future work: There's diverging code paths depending on arguments of the same command. Could the strategy design pattern help with organizing this?
When pushing a new branch, the pre-push hook derived its base from a
single remote's HEAD. If that remote was behind (e.g. a fork whose main
is a stale copy of upstream), it re-validated commits already reviewed
and merged elsewhere, and could reject a push over commits the author
never touched.
Base validation on every remote-tracking ref instead: a commit already
present on any remote has been published and does not need rechecking.
Excluding a set of refs rather than a single base also lets the root
commit be validated, which a single exclusive base can never reach.
Closes: #10