# File Filtering in the Repository Comparison Page

The repository comparison page provides powerful file filtering capabilities that allow you to focus on specific files in a comparison. The system supports multiple ways to specify which files you want to view when comparing branches, tags, or commits.

## Query parameter-based file filtering

The comparison page supports three different query parameters to specify which files to include in the comparison:

### 1. Individual file paths

You can specify individual files using either of these parameters:

-   `filePath=path/to/file.js` - Primary parameter for specifying files
-   `f=path/to/file.js` - Shorthand alternative

Multiple files can be included by repeating the parameter:

```shell
?filePath=src/index.ts&filePath=src/components/Button.tsx
```

### 2. Compressed file lists

For comparisons with a large number of files, the system supports compressed file lists (newline-separated):

-   `compressedFileList=base64EncodedCompressedData` - Efficiently packs many file paths

This parameter efficiently transmits large file paths using base64-encoded, gzip-compressed data. The compression allows hundreds or thousands of files to be included in a URL without exceeding length limits, which vary depending on the browser, HTTP server, and other services involved, like Cloudflare.

```typescript
// Behind the scenes, the code decompresses file lists using:
const decodedData = atoburl(compressedFileList);
const compressedData = Uint8Array.from(
	[...decodedData].map(char => char.charCodeAt(0))
);
const decompressedData = pako.inflate(compressedData, {to: 'string'});
```

One way to create a list of files for the `compressedFileList` parameter is to use Python's built-in libraries to compress and encode using url-safe base64 encoding (smaller than base64-encoding, then url-encoding).

```shell
python3 -c "import sys, zlib, base64; sys.stdout.write(base64.urlsafe_b64encode(zlib.compress(sys.stdin.buffer.read())).decode().rstrip('='))" < list.of.files > list.of.files.deflated.b64url
```

### 3. Special focus mode

You can focus on a single file using:

-   `focus=true&filePath=path/to/specific/file.js` - Show only this file in detail view

## File filtering UI components

The comparison view provides several UI components to help you filter and navigate files:

### FileDiffPicker

The FileDiffPicker component allows you to:

-   Search for files by name or path
-   Filter files by type/extension
-   Toggle between showing all files or only modified files
-   Sort files by different criteria (path, size of change, etc.)

This component uses a dedicated file metadata query optimized for quick filtering. Results are displayed as you type. Through client-side filtering, the component can efficiently handle repositories with thousands of files.

### File navigation

When viewing diffs, you can:

-   Click on any file in the sidebar to switch to that file
-   Use keyboard shortcuts to navigate between files
-   Toggle between expanded and collapsed views of files
-   Show or hide specific changes (additions, deletions, etc.)

### URL-based filtering

Any filters you apply through the UI will update the URL with the appropriate query parameters. This means you can:

1. Share specific filtered views with others
2. Bookmark comparisons with specific file filters
3. Navigate back and forth between different filter states using browser history

## Implementation details

The system makes strategic performance trade-offs to provide a smooth user experience:

```typescript
/*
 * For customers with extremely large PRs with thousands of files,
 * we fetch all file paths in a single API call to enable client-side filtering.
 *
 * This eliminates numerous smaller API calls for server-side filtering
 * when users search in the FileDiffPicker. While requiring one large
 * initial API call, it significantly improves subsequent search performance.
 */
```

The file filtering system uses a specialized file metadata query that is faster and lighter than the comprehensive file diffs query used to display actual code changes.

## Usage examples

1. View only JavaScript files:

```bash
 ?filePath=src/utils.js&filePath=src/components/App.js
```

2. Focus on a single file:

```bash
 ?focus=true&filePath=src/components/Button.tsx
```

3. Use a compressed file list for many files:

```bash
 ?compressedFileList=H4sIAAAAAAAAA2NgYGBg...
```

This flexible filtering system allows you to create customized views of repository comparisons, making reviewing changes in large projects easier.
