{"id":34933946,"url":"https://github.com/rommeld/mixed-pickles","last_synced_at":"2026-05-19T08:06:49.940Z","repository":{"id":330145337,"uuid":"1114017945","full_name":"rommeld/mixed-pickles","owner":"rommeld","description":"Simple git linter written in Rust.","archived":false,"fork":false,"pushed_at":"2026-01-03T20:18:17.000Z","size":368,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-01-06T22:25:12.587Z","etag":null,"topics":["beta-release","git","linter","pypi","python","rust"],"latest_commit_sha":null,"homepage":"https://pypi.org/project/mixed-pickles/","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/rommeld.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-12-10T19:29:29.000Z","updated_at":"2026-01-03T20:18:20.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/rommeld/mixed-pickles","commit_stats":null,"previous_names":["rommeld/mixed-pickles"],"tags_count":4,"template":false,"template_full_name":null,"purl":"pkg:github/rommeld/mixed-pickles","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rommeld%2Fmixed-pickles","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rommeld%2Fmixed-pickles/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rommeld%2Fmixed-pickles/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rommeld%2Fmixed-pickles/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/rommeld","download_url":"https://codeload.github.com/rommeld/mixed-pickles/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rommeld%2Fmixed-pickles/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33207608,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-19T07:54:09.561Z","status":"ssl_error","status_checked_at":"2026-05-19T07:54:08.508Z","response_time":58,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["beta-release","git","linter","pypi","python","rust"],"created_at":"2025-12-26T17:59:16.867Z","updated_at":"2026-05-19T08:06:49.935Z","avatar_url":"https://github.com/rommeld.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Mixed Pickles\n\nA fast git commit message linter written in Rust. Validates commit messages against best practices and provides actionable suggestions.\n\n## Installation\n\n### Python (Recommended)\n\n```bash\npip install mixed-pickles\n```\n\nOr with [uv](https://github.com/astral-sh/uv):\n\n```bash\nuv pip install mixed-pickles\n```\n\n### Rust\n\n```bash\ncargo install mixed-pickles\n```\n\nOr build from source:\n\n```bash\ngit clone https://github.com/rommeld/mixed-pickles.git\ncd mixed-pickles\ncargo build --release\n```\n\n## What It Checks\n\n| Validation         | Default Severity | Description                                  |\n| ------------------ | ---------------- | -------------------------------------------- |\n| `WipCommit`        | Error            | WIP markers, fixup!, squash!                 |\n| `ShortCommit`      | Warning          | Messages below threshold (default: 30 chars) |\n| `NonImperative`    | Warning          | Non-imperative mood (\"Added\" vs \"Add\")       |\n| `VagueLanguage`    | Warning          | Generic phrases (\"fix bug\", \"update code\")   |\n| `MissingReference` | Info             | No issue reference (#123, PROJ-456)          |\n| `InvalidFormat`    | Info             | Not following conventional commits           |\n\n## Usage\n\n### CLI\n\n```bash\n# Analyze all commits in current repo\nmixed-pickles\n\n# Analyze last 10 commits\nmixed-pickles --limit 10\n\n# Analyze specific repo\nmixed-pickles --path /path/to/repo\n\n# Strict mode (warnings become errors)\nmixed-pickles --strict\n\n# Customize severity\nmixed-pickles --error short,vague --ignore ref\n\n# Quiet mode (output only on issues)\nmixed-pickles --quiet\n\n# Run only on specific branches (supports glob patterns)\nmixed-pickles --branch main --branch develop\nmixed-pickles --branch \"feature/*\" --branch \"release/**\"\n```\n\n### Python API\n\n```python\nimport mixed_pickles\n\n# Basic analysis - auto-loads pyproject.toml config\nmixed_pickles.analyze_commits()\n\n# Analyze with options\nmixed_pickles.analyze_commits(\n    path=\".\",           # Repository path\n    limit=10,           # Number of commits\n    quiet=True,         # Suppress output unless issues\n    strict=True         # Treat warnings as errors\n)\n\n# Disable auto-loading of config file\nmixed_pickles.analyze_commits(use_config=False)\n\n# Load config from pyproject.toml or .mixed-pickles.toml\nconfig = mixed_pickles.ValidationConfig.discover()\nconfig = mixed_pickles.ValidationConfig.discover(\"/path/to/project\")\n\n# Load config from specific file\nconfig = mixed_pickles.ValidationConfig.from_file(\"pyproject.toml\")\nconfig = mixed_pickles.ValidationConfig.from_file(\".mixed-pickles.toml\")\n\n# Manual configuration\nconfig = mixed_pickles.ValidationConfig(\n    threshold=50,                    # Minimum message length\n    require_issue_ref=False,         # Disable issue reference check\n    require_conventional_format=False,\n    check_vague_language=True,\n    check_wip=True,\n    check_imperative=True,\n    branches=[\"main\", \"develop\"]     # Only validate on these branches\n)\nmixed_pickles.analyze_commits(config=config)\n\n# Branch filtering with glob patterns\nconfig = mixed_pickles.ValidationConfig(\n    branches=[\"main\", \"release/*\", \"hotfix/**\"]\n)\nmixed_pickles.analyze_commits(config=config)\n\n# Adjust severity levels\nconfig = mixed_pickles.ValidationConfig()\nconfig.set_severity(\n    mixed_pickles.Validation.MissingReference,\n    mixed_pickles.Severity.Error\n)\nconfig.set_severity(\n    mixed_pickles.Validation.ShortCommit,\n    mixed_pickles.Severity.Ignore\n)\nmixed_pickles.analyze_commits(config=config)\n\n# Fetch commits for custom processing\ncommits = mixed_pickles.fetch_commits(limit=5)\nfor commit in commits:\n    print(f\"{commit.short_hash}: {commit.message}\")\n```\n\n### Pre-commit Hook\n\nAdd to your `.pre-commit-config.yaml`:\n\n```yaml\nrepos:\n  - repo: local\n    hooks:\n      - id: mixed-pickles\n        name: Validate commit messages\n        entry: mixed-pickles\n        language: python\n        additional_dependencies: [mixed-pickles]\n        always_run: true\n        pass_filenames: false\n        stages: [pre-push]\n```\n\nWith uv, you can also run it directly:\n\n```yaml\nrepos:\n  - repo: local\n    hooks:\n      - id: mixed-pickles\n        name: Validate commit messages\n        entry: uv run mixed-pickles\n        language: system\n        always_run: true\n        pass_filenames: false\n        stages: [pre-push]\n```\n\n### CI/CD Integration\n\n#### GitHub Actions\n\nAdd to your workflow (`.github/workflows/lint-commits.yml`):\n\n```yaml\nname: Lint Commits\n\non:\n  pull_request:\n    branches: [main, develop]\n\njobs:\n  lint-commits:\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions/checkout@v4\n        with:\n          fetch-depth: 0  # Full history for commit analysis\n      - run: pip install mixed-pickles\n      - run: mixed-pickles --strict --quiet\n```\n\n#### GitLab CI\n\nAdd to your `.gitlab-ci.yml`:\n\n```yaml\nlint-commits:\n  stage: lint\n  image: python:3.12\n  before_script:\n    - pip install mixed-pickles\n  script:\n    - mixed-pickles --strict --quiet\n  rules:\n    - if: $CI_MERGE_REQUEST_TARGET_BRANCH_NAME == \"main\"\n    - if: $CI_MERGE_REQUEST_TARGET_BRANCH_NAME == \"develop\"\n```\n\n## CLI Options\n\n| Option             | Description                                  |\n| ------------------ | -------------------------------------------- |\n| `--path \u003cPATH\u003e`    | Repository path (default: current directory) |\n| `--limit \u003cN\u003e`      | Max commits to analyze                       |\n| `--threshold \u003cN\u003e`  | Minimum message length (default: 30)         |\n| `--branch \u003cPATTERN\u003e` | Only validate on matching branches (repeatable, supports globs) |\n| `--quiet`, `-q`    | Suppress output unless issues found          |\n| `--strict`         | Treat warnings as errors                     |\n| `--error \u003cLIST\u003e`   | Validations to treat as errors               |\n| `--warn \u003cLIST\u003e`    | Validations to treat as warnings             |\n| `--ignore \u003cLIST\u003e`  | Validations to skip reporting                |\n| `--disable \u003cLIST\u003e` | Validations to disable entirely              |\n| `--config \u003cPATH\u003e`  | Path to configuration file                   |\n| `--no-config`      | Ignore configuration file                    |\n\nValidation aliases for CLI: `short`, `ref`, `format`, `vague`, `wip`, `imperative`\n\n## Configuration\n\nConfigure mixed-pickles via `pyproject.toml` for project-specific settings:\n\n```toml\n[tool.mixed-pickles]\n# Minimum commit message length (default: 30)\nthreshold = 50\n\n# Only validate on specific branches (supports glob patterns)\n# Empty = validate on all branches (default)\nbranch = [\"main\", \"develop\", \"release/*\"]\n\n# Disable specific validations entirely\ndisable = [\"reference\", \"format\"]\n\n# Override severity levels\n[tool.mixed-pickles.severity]\nwip = \"error\"          # Block on WIP commits (default)\nshort = \"warning\"      # Warn but allow (default)\nvague = \"ignore\"       # Don't report\nreference = \"info\"     # Informational only (default)\n```\n\nOr use a dedicated `.mixed-pickles.toml` file (takes precedence over `pyproject.toml`):\n\n```toml\nthreshold = 50\nbranch = [\"main\", \"develop\"]\ndisable = [\"format\"]\n\n[severity]\nshort = \"error\"\n```\n\n### Configuration Precedence\n\nSettings are applied in this order (later overrides earlier):\n\n1. **Defaults** - Built-in default values\n2. **Config file** - `pyproject.toml` or `.mixed-pickles.toml`\n3. **CLI arguments** - Command-line flags\n\n### Available Validations\n\n| Name | Aliases | Default | Description |\n|------|---------|---------|-------------|\n| `short` | `short-commit` | warning | Message below threshold |\n| `wip` | `wip-commit` | error | WIP/fixup/squash markers |\n| `reference` | `ref`, `missing-reference` | info | Missing issue reference |\n| `format` | `invalid-format` | info | Not conventional commits |\n| `vague` | `vague-language` | warning | Generic descriptions |\n| `imperative` | `non-imperative` | warning | Past/continuous tense |\n\n## Severity Levels\n\n- **Error**: Fails the check (exit code 1)\n- **Warning**: Reported but passes (fails with `--strict`)\n- **Info**: Informational only\n- **Ignore**: Tracked but not reported\n\n## Branch Filtering\n\nRun validations only on specific branches. Useful for CI/CD pipelines where you want strict rules on `main`/`develop` but flexibility on feature branches.\n\n### Glob Patterns\n\n| Pattern | Matches | Does Not Match |\n|---------|---------|----------------|\n| `main` | `main` | `main-v2`, `feature/main` |\n| `feature/*` | `feature/login`, `feature/auth` | `feature/user/profile` |\n| `release/**` | `release/v1`, `release/v1/hotfix` | `releases/v1` |\n| `*-stable` | `v1-stable`, `prod-stable` | `stable`, `v1-stable-2` |\n| `release-?` | `release-1`, `release-2` | `release-10` |\n\n### Behavior\n\n- **Empty `branch`**: Validates on all branches (default)\n- **Detached HEAD**: Validation is skipped\n- **Non-matching branch**: Validation is skipped (exits successfully)\n\n## Contributing\n\nSee [CONTRIBUTING.md](CONTRIBUTING.md) for contribution guidelines.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frommeld%2Fmixed-pickles","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frommeld%2Fmixed-pickles","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frommeld%2Fmixed-pickles/lists"}