> ## Documentation Index
> Fetch the complete documentation index at: https://semgrep-ee9d73d8-mintlify-b75b9a88.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Customize Semgrep in pre-commit

Semgrep offers two standard pre-commit hooks [outlined here](/extensions/overview/#pre-commit).

* The `semgrep` hook is optimized to run with a provided set of rules, either local rules or rules from the Semgrep Registry.
* The `semgrep-ci` hook is optimized to run with the rules from your organization in the Semgrep AppSec Platform, without sending results to the platform, since results from pre-commit are temporary and not linked to the final code in the repository.
  * This hook requires the user be logged in locally to fetch the rules from the organization.

You can also create your own Semgrep hooks for pre-commit if you have particular needs or preferences, such as if you want users to see the output of the Semgrep scan even if it passed, or if you want to limit the scan to a particular Semgrep product.

## Show the scan output

By default, pre-commit does not show the scan output if the hook passes. If you want your developers to see the output even if non-blocking findings are found, you can set the `verbose` option to print the output. To limit output to findings only (no scan information or diagnostics), redirect `stderr` to `/dev/null`, or use `--quiet`.

This example is based on the `semgrep-ci` hook, but a similar adjustment would also work with the `semgrep` hook.

```yaml theme={null}
repos:
- repo: https://github.com/semgrep/pre-commit
  rev: 'v1.101.0'
  hooks:
    - id: semgrep-verbose
      entry: semgrep
      args: ["ci", "--dry-run", "--baseline-commit", "HEAD" "2>/dev/null"]
      verbose: true
      pass_filenames: false
```

To print only a portion of the scan output, consider using shell-based text tools such as `awk`:

```yaml theme={null}
repos:
- repo: https://github.com/semgrep/pre-commit
  rev: 'v1.126.0'
  hooks:
      - id: semgrep-scan-summary-only
        entry: bash
        args:
          - -c
          - |
            semgrep ci --dry-run --baseline-commit HEAD 2>&1 \
              | awk '/Scan Summary/,/^CI scan completed successfully\./'
        pass_filenames: false
        language: system
        verbose: true
```

This example only prints the scan summary portion of the scan log. Using this approach, scan debugging output on `stderr` is redirected to `stdout` so that findings and debugging information appear in the same output stream. Then, the portion to show (the Semgrep scan summary) is selected using `awk`.

## Limit the scan to a particular product

Semgrep Secrets is an ideal product to run before commit, since it can help prevent secrets from ever making it into the Git history, even locally. To run only Secrets in pre-commit, add the product flag to the `args`:

```yaml theme={null}
- repo: https://github.com/semgrep/pre-commit
  rev: 'v1.101.0'
  hooks:
    - id:  semgrep-secrets
      pass_filenames: false
      args: ["ci", "--dry-run", "--baseline-commit", "HEAD", "--secrets"]
```

## Scan with Pro rules and cross-function analysis

The `semgrep-ci` hook requires the user to be logged in locally and runs with the engine configured in the organization, but the standard `semgrep` hook can also take advantage of local login to run with Pro rules and cross-function analysis.

```yaml theme={null}
- id: semgrep
  name: semgrep
  entry: semgrep
  args: ["--pro", "--disable-version-check", "--quiet", "--skip-unknown-extensions"]
```

This provides analysis across modified files during the pre-commit scan, which may catch additional vulnerabilities, or prevent false positives.

## Customization tips

### Useful arguments

The provided hooks include useful arguments for Semgrep that you may want to include in your hooks as well.

For example, for the `semgrep` hook that runs with a provided `--config`, the arguments also include:

* `--disable-version-check`: skip checking whether there's a new version of Semgrep (speeds up the check and avoids irrelevant output)
* `--quiet`: only print findings, not other messages
* `--skip-unknown-extensions`: if files are modified that aren't in a recognized language, skip them

The `semgrep-ci` hook runs with the pre-commit option `pass_filenames: false`. This is important because `semgrep ci` doesn't expect a list of filenames; it just expects to scan the folder, so you should preserve this option in your usage.

Adding `baseline-commit HEAD` performs a diff scan; this diff scan only scans the changes being added in the current commit (as intended for a pre-commit hook). It uses `--dry-run` so that findings that have no existence except in the local filesystem aren't added to the platform, which would otherwise result in clutter.

### Entry point

Both of the default hooks use `semgrep` as the `entry`, which means the command executed is just `semgrep` with the `args` provided. However, you can write your own `entry` point. This approach is used in the less commonly used `semgrep-docker` hook also available in the [semgrep/pre-commit repository](https://github.com/semgrep/pre-commit/blob/develop/.pre-commit-hooks.yaml).

It can also be used with a standard Semgrep execution to set environment variables in addition to (or instead of) arguments:

```bash theme={null}
 entry: sh -c 'env SEMGREP_RULES=<SEMGREP_RULESET_URL> semgrep scan --code --no-suppress-errors --baseline-commit HEAD'
```

In this case, setting `SEMGREP_RULES=<SEMGREP_RULESET_URL>` substitutes for supplying `--config` and `<SEMGREP_RULESET_URL>` in the `args`.
