Skip to content
20 changes: 12 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ This wouldn't have been possible without all of you using and supporting Repomix
- **Token Counting**: Provides token counts for each file and the entire repository, useful for LLM context limits.
- **Simple to Use**: You need just one command to pack your entire repository.
- **Customizable**: Easily configure what to include or exclude.
- **Git-Aware**: Automatically respects your `.gitignore` files and `.git/info/exclude`.
- **Git-Aware**: Automatically respects your `.gitignore`, `.ignore`, and `.repomixignore` files.
- **Security-Focused**: Incorporates [Secretlint](https://github.com/secretlint/secretlint) for robust security checks to detect and prevent inclusion of sensitive information.
- **Code Compression**: The `--compress` option uses [Tree-sitter](https://github.com/tree-sitter/tree-sitter) to extract key code elements, reducing token count while preserving structure.

Expand Down Expand Up @@ -495,7 +495,7 @@ The JSON format structures the content as a hierarchical JSON object with camelC
"purpose": "This file contains a packed representation of the entire repository's contents...",
"fileFormat": "The content is organized as follows...",
"usageGuidelines": "- This file should be treated as read-only...",
"notes": "- Some files may have been excluded based on .gitignore rules..."
"notes": "- Some files may have been excluded based on .gitignore, .ignore, and .repomixignore rules..."
},
"userProvidedHeader": "Custom header text if specified",
"directoryStructure": "src/\n cli/\n cliOutput.ts\n index.ts\n config/\n configLoader.ts",
Expand Down Expand Up @@ -637,6 +637,7 @@ Instruction
- `--include <patterns>`: Include only files matching these glob patterns (comma-separated, e.g., "src/**/*.js,*.md")
- `-i, --ignore <patterns>`: Additional patterns to exclude (comma-separated, e.g., "*.test.js,docs/**")
- `--no-gitignore`: Don't use .gitignore rules for filtering files
- `--no-dot-ignore`: Don't use .ignore rules for filtering files
- `--no-default-patterns`: Don't apply built-in ignore patterns (node_modules, .git, build dirs, etc.)

#### Remote Repository Options
Expand Down Expand Up @@ -933,7 +934,7 @@ When running as an MCP server, Repomix provides the following tools:
- `directory`: Absolute path to the directory to pack
- `compress`: (Optional, default: false) Enable Tree-sitter compression to extract essential code signatures and structure while removing implementation details. Reduces token usage by ~70% while preserving semantic meaning. Generally not needed since grep_repomix_output allows incremental content retrieval. Use only when you specifically need the entire codebase content for large repositories.
- `includePatterns`: (Optional) Specify files to include using fast-glob patterns. Multiple patterns can be comma-separated (e.g., "**/*.{js,ts}", "src/**,docs/**"). Only matching files will be processed.
- `ignorePatterns`: (Optional) Specify additional files to exclude using fast-glob patterns. Multiple patterns can be comma-separated (e.g., "test/**,*.spec.js", "node_modules/**,dist/**"). These patterns supplement .gitignore and built-in exclusions.
- `ignorePatterns`: (Optional) Specify additional files to exclude using fast-glob patterns. Multiple patterns can be comma-separated (e.g., "test/**,*.spec.js", "node_modules/**,dist/**"). These patterns supplement .gitignore, .ignore, and built-in exclusions.
- `topFilesLength`: (Optional, default: 10) Number of largest files by size to display in the metrics summary for codebase analysis.

2. **attach_packed_output**: Attach an existing Repomix packed output file for AI analysis
Expand All @@ -951,7 +952,7 @@ When running as an MCP server, Repomix provides the following tools:
- `remote`: GitHub repository URL or user/repo format (e.g., "yamadashy/repomix", "https://github.com/user/repo", or "https://github.com/user/repo/tree/branch")
- `compress`: (Optional, default: false) Enable Tree-sitter compression to extract essential code signatures and structure while removing implementation details. Reduces token usage by ~70% while preserving semantic meaning. Generally not needed since grep_repomix_output allows incremental content retrieval. Use only when you specifically need the entire codebase content for large repositories.
- `includePatterns`: (Optional) Specify files to include using fast-glob patterns. Multiple patterns can be comma-separated (e.g., "**/*.{js,ts}", "src/**,docs/**"). Only matching files will be processed.
- `ignorePatterns`: (Optional) Specify additional files to exclude using fast-glob patterns. Multiple patterns can be comma-separated (e.g., "test/**,*.spec.js", "node_modules/**,dist/**"). These patterns supplement .gitignore and built-in exclusions.
- `ignorePatterns`: (Optional) Specify additional files to exclude using fast-glob patterns. Multiple patterns can be comma-separated (e.g., "test/**,*.spec.js", "node_modules/**,dist/**"). These patterns supplement .gitignore, .ignore, and built-in exclusions.
- `topFilesLength`: (Optional, default: 10) Number of largest files by size to display in the metrics summary for codebase analysis.

4. **read_repomix_output**: Read the contents of a Repomix-generated output file. Supports partial reading with line range specification for large files.
Expand Down Expand Up @@ -1208,6 +1209,7 @@ Here's an explanation of the configuration options:
| `output.git.includeLogsCount` | Number of git log commits to include | `50` |
| `include` | Patterns of files to include (using [glob patterns](https://github.com/mrmlnc/fast-glob?tab=readme-ov-file#pattern-syntax)) | `[]` |
| `ignore.useGitignore` | Whether to use patterns from the project's `.gitignore` file | `true` |
| `ignore.useDotIgnore` | Whether to use patterns from the project's `.ignore` file | `true` |
| `ignore.useDefaultPatterns` | Whether to use default ignore patterns | `true` |
| `ignore.customPatterns` | Additional patterns to ignore (using [glob patterns](https://github.com/mrmlnc/fast-glob?tab=readme-ov-file#pattern-syntax)) | `[]` |
| `security.enableSecurityCheck` | Whether to perform security checks on files | `true` |
Expand Down Expand Up @@ -1323,6 +1325,7 @@ Repomix offers multiple methods to set ignore patterns for excluding specific fi
process:

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Documentation Enhancement Suggestion

Great addition of .ignore file support documentation! Consider adding a note about compatibility/precedence when files conflict:

- **.ignore**: You can use a `.ignore` file in your project root, following the same format as `.gitignore`. This file is respected by tools like ripgrep and the silver searcher, reducing the need to maintain multiple ignore files. Patterns in `.ignore` take precedence over `.gitignore` but are overridden by `.repomixignore`. This behavior can be controlled with the `ignore.useDotIgnore` setting or the `--no-dot-ignore` cli option.

This clarifies what happens when the same pattern appears in multiple files.

- **.gitignore**: By default, patterns listed in your project's `.gitignore` files and `.git/info/exclude` are used. This behavior can be controlled with the `ignore.useGitignore` setting or the `--no-gitignore` cli option.
- **.ignore**: You can use a `.ignore` file in your project root, following the same format as `.gitignore`. This file is respected by tools like ripgrep and the silver searcher, reducing the need to maintain multiple ignore files. This behavior can be controlled with the `ignore.useDotIgnore` setting or the `--no-dot-ignore` cli option.
- **Default patterns**: Repomix includes a default list of commonly excluded files and directories (e.g., node_modules,
.git, binary files). This feature can be controlled with the `ignore.useDefaultPatterns` setting or the `--no-default-patterns` cli option. Please
see [defaultIgnore.ts](src/config/defaultIgnore.ts) for more details.
Expand All @@ -1333,10 +1336,11 @@ process:

Priority Order (from highest to lowest):

1. Custom patterns `ignore.customPatterns`
2. `.repomixignore`
3. `.gitignore` and `.git/info/exclude` (if `ignore.useGitignore` is true and `--no-gitignore` is not used)
4. Default patterns (if `ignore.useDefaultPatterns` is true and `--no-default-patterns` is not used)
1. Custom patterns (`ignore.customPatterns`)
2. Ignore files (`.repomixignore`, `.ignore`, `.gitignore`, and `.git/info/exclude`):
- When in nested directories, files in deeper directories have higher priority
- When in the same directory, these files are merged in no particular order
3. Default patterns (if `ignore.useDefaultPatterns` is true and `--no-default-patterns` is not used)

This approach allows for flexible file exclusion configuration based on your project's needs. It helps optimize the size
of the generated pack file by ensuring the exclusion of security-sensitive files and large binary files, while
Expand Down
4 changes: 4 additions & 0 deletions src/cli/actions/defaultAction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,10 @@ export const buildCliConfig = (options: CliOptions): RepomixConfigCli => {
if (options.gitignore === false) {
cliConfig.ignore = { ...cliConfig.ignore, useGitignore: options.gitignore };
}
// Only apply dotIgnore setting if explicitly set to false
if (options.dotIgnore === false) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good: Consistent with existing patterns

This implementation correctly mirrors the handling of gitignore and defaultPatterns options. The pattern of only applying when explicitly set to false allows config file values to take precedence unless overridden via CLI.

Minor suggestion: Consider adding a comment explaining this behavior for future maintainers:

// Only apply dotIgnore setting if explicitly set to false
// This allows config file values to take precedence when the flag is not specified
if (options.dotIgnore === false) {
  cliConfig.ignore = { ...cliConfig.ignore, useDotIgnore: options.dotIgnore };
}

cliConfig.ignore = { ...cliConfig.ignore, useDotIgnore: options.dotIgnore };
}
// Only apply defaultPatterns setting if explicitly set to false
if (options.defaultPatterns === false) {
cliConfig.ignore = {
Expand Down
1 change: 1 addition & 0 deletions src/cli/cliRun.ts
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,7 @@ export const run = async () => {
)
.option('-i, --ignore <patterns>', 'Additional patterns to exclude (comma-separated, e.g., "*.test.js,docs/**")')
.option('--no-gitignore', "Don't use .gitignore rules for filtering files")
.option('--no-dot-ignore', "Don't use .ignore rules for filtering files")
.option('--no-default-patterns', "Don't apply built-in ignore patterns (node_modules, .git, build dirs, etc.)")
// Remote Repository Options
.optionsGroup('Remote Repository Options')
Expand Down
1 change: 1 addition & 0 deletions src/cli/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ export interface CliOptions extends OptionValues {
include?: string;
ignore?: string;
gitignore?: boolean;
dotIgnore?: boolean;
defaultPatterns?: boolean;
stdin?: boolean;

Expand Down
2 changes: 2 additions & 0 deletions src/config/configSchema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ export const repomixConfigBaseSchema = z.object({
ignore: z
.object({
useGitignore: z.boolean().optional(),
useDotIgnore: z.boolean().optional(),
useDefaultPatterns: z.boolean().optional(),
customPatterns: z.array(z.string()).optional(),
})
Expand Down Expand Up @@ -111,6 +112,7 @@ export const repomixConfigDefaultSchema = z.object({
include: z.array(z.string()).default([]),
ignore: z.object({
useGitignore: z.boolean().default(true),
useDotIgnore: z.boolean().default(true),
useDefaultPatterns: z.boolean().default(true),
customPatterns: z.array(z.string()).default([]),
}),
Expand Down
11 changes: 11 additions & 0 deletions src/core/file/fileSearch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -295,10 +295,21 @@ export const parseIgnoreContent = (content: string): string[] => {
export const getIgnoreFilePatterns = async (config: RepomixConfigMerged): Promise<string[]> => {
const ignoreFilePatterns: string[] = [];

// Note: When ignore files are found in nested directories, files in deeper
// directories have higher priority, following the behavior of ripgrep and fd.
// For example, `src/.ignore` patterns override `./.ignore` patterns.
//
// Multiple ignore files in the same directory (.gitignore, .ignore, .repomixignore)
// are all merged together. The order in this array does not affect priority.

if (config.ignore.useGitignore) {
ignoreFilePatterns.push('**/.gitignore');
}

if (config.ignore.useDotIgnore) {
ignoreFilePatterns.push('**/.ignore');
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Critical: Verify priority order matches documentation

The array order here determines how globby processes ignore files. Please verify that this order matches the documented priority in README.md:

Documented priority (highest to lowest):

  1. .repomixignore
  2. .ignore
  3. .gitignore

Current implementation adds:

  1. .gitignore (if enabled)
  2. .ignore (if enabled) ← this line
  3. .repomixignore

If globby processes ignoreFiles such that later entries override earlier ones, then .repomixignore being last is correct. However, if earlier entries take precedence, this order needs to be reversed.

Please verify and add a comment explaining the order, e.g.:

// Order matters: globby processes these files in order,
// with later files overriding earlier ones

}

ignoreFilePatterns.push('**/.repomixignore');
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Critical Issue: Incorrect Priority Order

The current implementation adds .repomixignore last to the ignoreFilePatterns array, which means it has the lowest priority when globby processes the ignore files. However, according to the README documentation (line 1338-1342), the intended priority order is:

  1. Custom patterns (highest)
  2. .repomixignore
  3. .ignore
  4. .gitignore (lowest)

Why this is a problem:
When globby processes ignoreFiles, it typically applies them in order, with later files overriding earlier ones in terms of priority. By placing .repomixignore last, it ends up with the highest priority among the ignore files, which is correct. However, the ordering here is confusing.

Actually, I need to verify this: Looking at globby's behavior, ignore files are typically additive (patterns accumulate), not override-based. The priority should actually be controlled by the order patterns are added to the main ignore array in getIgnorePatterns, not the ignoreFiles array.

The Real Issue:
The priority ordering is actually handled correctly here for globby's ignoreFiles option (which just tells globby which files to read patterns from). The actual priority is determined by the order patterns are added in getIgnorePatterns() function (lines 311-357).

However, there's still a documentation inconsistency: The code adds .repomixignore last (line 306), but this doesn't reflect the documented priority since globby reads all ignore files and merges their patterns.

Recommendation:
For clarity and to match the documented priority, consider reordering to:

// Add in reverse priority order (highest priority last for clarity)
if (config.ignore.useGitignore) {
  ignoreFilePatterns.push('**/.gitignore');
}

if (config.ignore.useDotIgnore) {
  ignoreFilePatterns.push('**/.ignore');
}

ignoreFilePatterns.push('**/.repomixignore');

This way, the code visually reflects the intended priority order even though globby treats all ignoreFiles equally by reading and merging their patterns.


return ignoreFilePatterns;
Expand Down
27 changes: 27 additions & 0 deletions tests/cli/actions/defaultAction.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -277,5 +277,32 @@ describe('defaultAction', () => {

expect(config.output?.removeComments).toBe(true);
});

it('should handle --no-gitignore flag', () => {
const options = {
gitignore: false,
};
const config = buildCliConfig(options);

expect(config.ignore?.useGitignore).toBe(false);
});

it('should handle --no-dot-ignore flag', () => {
const options = {
dotIgnore: false,
};
const config = buildCliConfig(options);

expect(config.ignore?.useDotIgnore).toBe(false);
});

it('should handle --no-default-patterns flag', () => {
const options = {
defaultPatterns: false,
};
const config = buildCliConfig(options);

expect(config.ignore?.useDefaultPatterns).toBe(false);
});
});
});
1 change: 1 addition & 0 deletions tests/cli/actions/workers/defaultActionWorker.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ describe('defaultActionWorker', () => {
include: ['**/*'],
ignore: {
useGitignore: true,
useDotIgnore: true,
useDefaultPatterns: true,
customPatterns: [],
},
Expand Down
2 changes: 2 additions & 0 deletions tests/config/configSchema.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,7 @@ describe('configSchema', () => {
include: [],
ignore: {
useGitignore: true,
useDotIgnore: true,
useDefaultPatterns: true,
customPatterns: [],
},
Expand Down Expand Up @@ -230,6 +231,7 @@ describe('configSchema', () => {
include: ['**/*.js', '**/*.ts'],
ignore: {
useGitignore: true,
useDotIgnore: true,
useDefaultPatterns: true,
customPatterns: ['*.log'],
},
Expand Down
22 changes: 19 additions & 3 deletions tests/core/file/fileSearch.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,30 +53,46 @@ describe('fileSearch', () => {
});

describe('getIgnoreFilePaths', () => {
test('should return correct paths when .gitignore and .repomixignore exist', async () => {
test('should return correct paths when .gitignore, .ignore and .repomixignore exist', async () => {
vi.mocked(fs.access).mockResolvedValue(undefined);
const mockConfig = createMockConfig({
ignore: {
useGitignore: true,
useDotIgnore: true,
useDefaultPatterns: true,
customPatterns: [],
},
});
const filePatterns = await getIgnoreFilePatterns(mockConfig);
expect(filePatterns).toEqual(['**/.gitignore', '**/.repomixignore']);
expect(filePatterns).toEqual(['**/.gitignore', '**/.ignore', '**/.repomixignore']);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Test Coverage Issue: Order Matters

While this test verifies that all three ignore file patterns are included, it should also verify the order to ensure the priority is correct.

Consider updating to:

expect(filePatterns).toEqual(['**/.gitignore', '**/.ignore', '**/.repomixignore']);
// Or better yet, add a comment explaining why order matters:
// Order should reflect priority: .gitignore (lowest) -> .ignore -> .repomixignore (highest)

However, I need to verify if globby's ignoreFiles option respects order or just merges all patterns. If it merges, order doesn't matter for this array, and the test is fine as-is.

});

test('should not include .gitignore when useGitignore is false', async () => {
vi.mocked(fs.access).mockResolvedValue(undefined);
const mockConfig = createMockConfig({
ignore: {
useGitignore: false,
useDotIgnore: true,
useDefaultPatterns: true,
customPatterns: [],
},
});
const filePatterns = await getIgnoreFilePatterns(mockConfig);
expect(filePatterns).toEqual(['**/.repomixignore']);
expect(filePatterns).toEqual(['**/.ignore', '**/.repomixignore']);
});

test('should not include .ignore when useDotIgnore is false', async () => {
vi.mocked(fs.access).mockResolvedValue(undefined);
const mockConfig = createMockConfig({
ignore: {
useGitignore: true,
useDotIgnore: false,
useDefaultPatterns: true,
customPatterns: [],
},
});
const filePatterns = await getIgnoreFilePatterns(mockConfig);
expect(filePatterns).toEqual(['**/.gitignore', '**/.repomixignore']);
});

test('should handle empty directories when enabled', async () => {
Expand Down
1 change: 1 addition & 0 deletions tests/core/metrics/calculateGitDiffMetrics.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ describe('calculateGitDiffMetrics', () => {
include: ['**/*'],
ignore: {
useGitignore: true,
useDotIgnore: true,
useDefaultPatterns: true,
customPatterns: [],
},
Expand Down
1 change: 1 addition & 0 deletions tests/core/metrics/calculateGitLogMetrics.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ describe('calculateGitLogMetrics', () => {
include: ['**/*'],
ignore: {
useGitignore: true,
useDotIgnore: true,
useDefaultPatterns: true,
customPatterns: [],
},
Expand Down
1 change: 1 addition & 0 deletions tests/core/output/flagFullDirectoryStructure.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ const createMockConfig = (overrides: Partial<RepomixConfigMerged> = {}): Repomix
include: ['src/**/*.ts'],
ignore: {
useGitignore: true,
useDotIgnore: true,
useDefaultPatterns: true,
customPatterns: [],
},
Expand Down
1 change: 1 addition & 0 deletions tests/core/output/outputStyles/jsonStyle.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ const createMockConfig = (overrides: Partial<RepomixConfigMerged> = {}): Repomix
include: [],
ignore: {
useGitignore: true,
useDotIgnore: true,
useDefaultPatterns: true,
customPatterns: [],
},
Expand Down
1 change: 1 addition & 0 deletions website/client/src/de/guide/command-line-options.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
- `--include <patterns>`: Liste der Einschlussmuster (kommagetrennt)
- `-i, --ignore <patterns>`: Zusätzliche Ignoriermuster (kommagetrennt)
- `--no-gitignore`: .gitignore-Datei-Nutzung deaktivieren
- `--no-dot-ignore`: .ignore-Datei-Nutzung deaktivieren
- `--no-default-patterns`: Standardmuster deaktivieren

## Remote-Repository-Optionen
Expand Down
Loading
Loading