Git integration for reading commit messages from various sources including history ranges, edit files, and environment variables.
Main function for reading commit messages from Git repository or files.
/**
* Read commit messages from various sources
* @param options - Configuration for specifying source and range
* @returns Promise resolving to array of commit message strings
*/
function read(options: GetCommitMessageOptions): Promise<string[]>;Configuration options for specifying how and which commit messages to read.
interface GetCommitMessageOptions {
/** Working directory containing .git folder (default: process.cwd()) */
cwd?: string;
/** Start commit hash/reference for range reading */
from?: string;
/** Use last git tag as the start of the range */
fromLastTag?: boolean;
/** End commit hash/reference for range reading (default: HEAD) */
to?: string;
/** Read only the last commit */
last?: boolean;
/** Read from edit file (true for .git/COMMIT_EDITMSG, string for custom path) */
edit?: boolean | string;
/** Additional arguments to pass to git log command */
gitLogArgs?: string;
}Read individual commits using various methods.
// Last commit only
const messages = await read({ last: true });
// From edit file (Git hooks)
const messages = await read({ edit: true });
// From specific file path
const messages = await read({ edit: "/path/to/commit-msg" });Read multiple commits within a specified range.
// Commit range by hash/reference
const messages = await read({
from: "HEAD~5",
to: "HEAD"
});
// From last tag to HEAD
const messages = await read({
fromLastTag: true
});
// Custom range with additional git log arguments
const messages = await read({
from: "origin/main",
to: "HEAD",
gitLogArgs: "--first-parent --no-merges"
});Specify different Git repositories or working directories.
// Read from specific repository
const messages = await read({
cwd: "/path/to/git/repository",
last: true
});
// Read with relative paths
const messages = await read({
cwd: "../other-project",
from: "HEAD~3"
});import read from "@commitlint/read";
// Read last commit message
const messages = await read({ last: true });
console.log(messages[0]); // "feat: add user authentication"
// Read from commit edit file (useful in Git hooks)
const editMessages = await read({ edit: true });
console.log(editMessages[0]); // Content of .git/COMMIT_EDITMSGimport read from "@commitlint/read";
// Read commits in a range
const rangeMessages = await read({
from: "HEAD~10",
to: "HEAD"
});
console.log(`Found ${rangeMessages.length} commits`);
rangeMessages.forEach((msg, index) => {
console.log(`Commit ${index + 1}: ${msg.split('\n')[0]}`);
});import read from "@commitlint/read";
// Read all commits since last tag
const tagMessages = await read({
fromLastTag: true
});
console.log(`Commits since last tag: ${tagMessages.length}`);import read from "@commitlint/read";
// Use custom git log arguments
const messages = await read({
from: "origin/main",
gitLogArgs: "--first-parent --cherry-pick --no-merges"
});
// Read from feature branch
const featureMessages = await read({
from: "main",
to: "feature/new-api"
});import read from "@commitlint/read";
// Read from specific commit message file
const fileMessages = await read({
edit: "/tmp/commit-message.txt"
});
// Read from environment-specified file
const envFile = process.env.COMMIT_MSG_FILE;
if (envFile) {
const envMessages = await read({
edit: envFile
});
}import read from "@commitlint/read";
import lint from "@commitlint/lint";
import { load } from "@commitlint/load";
// Complete workflow: read, configure, and lint
async function lintCommits() {
// Load configuration
const config = await load();
// Read commit messages
const messages = await read({
from: "HEAD~5",
to: "HEAD"
});
// Lint each message
const results = await Promise.all(
messages.map(message =>
lint(message, config.rules, {
parserOpts: config.parserPreset?.parserOpts,
plugins: config.plugins
})
)
);
// Process results
results.forEach((result, index) => {
if (!result.valid) {
console.log(`Commit ${index + 1} failed validation:`);
console.log(`Message: ${result.input}`);
result.errors.forEach(error => {
console.log(` ❌ ${error.name}: ${error.message}`);
});
}
});
}
await lintCommits();import read from "@commitlint/read";
// Pre-commit hook example
async function preCommitHook() {
try {
// Read the commit message being created
const messages = await read({ edit: true });
if (messages.length === 0) {
console.log("No commit message found");
process.exit(1);
}
// Further processing...
return messages[0];
} catch (error) {
console.error("Failed to read commit message:", error);
process.exit(1);
}
}import read from "@commitlint/read";
// Validate commits in CI pipeline
async function validatePullRequest() {
const baseBranch = process.env.GITHUB_BASE_REF || "main";
const headBranch = process.env.GITHUB_HEAD_REF || "HEAD";
const messages = await read({
from: `origin/${baseBranch}`,
to: headBranch,
gitLogArgs: "--no-merges" // Skip merge commits
});
if (messages.length === 0) {
console.log("No commits to validate");
return;
}
console.log(`Validating ${messages.length} commits...`);
// Continue with validation logic...
}import read from "@commitlint/read";
async function safeRead(options) {
try {
const messages = await read(options);
return messages;
} catch (error) {
if (error.message.includes("not a git repository")) {
console.error("Current directory is not a Git repository");
} else if (error.message.includes("bad revision")) {
console.error("Invalid commit reference provided");
} else {
console.error("Failed to read commits:", error.message);
}
return [];
}
}
// Usage with error handling
const messages = await safeRead({
from: "invalid-ref",
to: "HEAD"
});