Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 32 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,38 @@ steps:
run: exit 1
```

## CLI Usage

gitlance can also be run directly as a command-line tool, independent of GitHub
Actions.

### Validating a Single Commit Message

Instead of a commit range, gitlance can validate a single commit message read
from a file, using `--message-file`. This makes it convenient to use in a local
`commit-msg` git hook, where git passes the path to the prepared message:

```bash
gitlance --message-file .git/COMMIT_EDITMSG
```

A specific check can also be selected:

```bash
gitlance conventional-commits --message-file .git/COMMIT_EDITMSG
```

### Validating Unpublished Commits

With `--not-on-remotes`, gitlance validates only the commits reachable from
`--head` that are not yet present on any remote. This makes it convenient to use
in a local `pre-push` git hook. It exits successfully when there is nothing new
to check:

```bash
gitlance --head <head_ref> --not-on-remotes
```

## Installation

### GitHub Action
Expand Down
2 changes: 2 additions & 0 deletions Taskfile.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ tasks:
cmds:
- cp githooks/pre-push "{{.HOOKS_DIR}}/"
- chmod +x "{{.HOOKS_DIR}}/pre-push"
- cp githooks/commit-msg "{{.HOOKS_DIR}}/"
- chmod +x "{{.HOOKS_DIR}}/commit-msg"
- echo "✓ Git hooks installed to {{.HOOKS_DIR}}"

setup:
Expand Down
25 changes: 25 additions & 0 deletions githooks/commit-msg
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#!/bin/bash

# SPDX-FileCopyrightText: Canonical Ltd.
#
# SPDX-License-Identifier: Apache-2.0

set -e

# Check that gitlance is available
if ! command -v gitlance >/dev/null 2>&1; then
echo "Error: gitlance is not installed or not in PATH"
echo "To bypass: git commit --no-verify"
exit 1
fi

message_file="$1"

if ! gitlance --message-file "$message_file"; then
echo
echo "Commit rejected: Message validation failed"
echo "To bypass: git commit --no-verify"
exit 1
fi

exit 0
41 changes: 20 additions & 21 deletions githooks/pre-push
Original file line number Diff line number Diff line change
Expand Up @@ -34,35 +34,34 @@ do
continue
fi

# Determine base commit
# Run gitlance
echo "Checking git commit logs with gitlance:"
echo
if [ "$remote_oid" = "0000000000000000000000000000000000000000" ]; then
# New branch - try to find common ancestor with remote HEAD
base=""
if remote_head=$(git ls-remote "$remote" HEAD 2>/dev/null | awk '{print $1}') && [ -n "$remote_head" ]; then
base=$(git merge-base "$remote_head" "$local_oid" 2>/dev/null) || true
fi
# Fall back to root commit if no common ancestor found
if [ -z "$base" ]; then
base=$(git rev-list --max-parents=0 "$local_oid" | head -1)
# New branch: validate commits not yet present on any remote. gitlance
# derives the set from remote-tracking refs, which is more reliable than
# a single remote's HEAD (a stale remote would re-check known commits).
if ! gitlance --head "$local_oid" --not-on-remotes; then
echo ""
echo "Push rejected: Commit validation failed"
echo "To fix: git commit --amend, or git rebase -i"
echo "To bypass: git push --no-verify"
exit 1
fi
else
# Existing branch - find common ancestor to only check divergent commits
# Existing branch: check only commits that diverge from the remote.
if ! base=$(git merge-base "$remote_oid" "$local_oid"); then
echo "Error: Failed to find merge-base between remote and local commits"
echo "To bypass: git push --no-verify"
exit 1
fi
fi

# Run gitlance
echo "Checking git commit logs with gitlance:"
echo
if ! gitlance --base "$base" --head "$local_oid"; then
echo ""
echo "Push rejected: Commit validation failed"
echo "To fix: git commit --amend, or git rebase -i $base"
echo "To bypass: git push --no-verify"
exit 1
if ! gitlance --base "$base" --head "$local_oid"; then
echo ""
echo "Push rejected: Commit validation failed"
echo "To fix: git commit --amend, or git rebase -i $base"
echo "To bypass: git push --no-verify"
exit 1
fi
fi
done

Expand Down
Loading
Loading