or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

built-in-rules.mdcli-interface.mdcommit-reading.mdconfiguration-presets.mdconfiguration-system.mdindex.mdlinting-engine.mdoutput-formatting.md
tile.json

commit-reading.mddocs/

Commit Reading

Git integration for reading commit messages from various sources including history ranges, edit files, and environment variables.

Capabilities

Read Function

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[]>;

Commit Message Options

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;
}

Reading Modes

Single Commit Reading

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" });

Range-based Reading

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"
});

Working Directory Context

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"
});

Usage Examples

Basic Usage

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_EDITMSG

Range Operations

import 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]}`);
});

Tag-based Reading

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}`);

Advanced Git Integration

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"
});

File-based Reading

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
  });
}

Integration with Linting

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();

Git Hook Integration

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);
  }
}

CI/CD Integration

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...
}

Error Handling

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"
});