|
| 1 | +# File Filtering in the Repository Comparison Page |
| 2 | + |
| 3 | +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. |
| 4 | + |
| 5 | +## Query parameter-based file filtering |
| 6 | + |
| 7 | +The comparison page supports three different query parameters to specify which files to include in the comparison: |
| 8 | + |
| 9 | +### 1. Individual file paths |
| 10 | + |
| 11 | +You can specify individual files using either of these parameters: |
| 12 | + |
| 13 | +- `filePath=path/to/file.js` - Primary parameter for specifying files |
| 14 | +- `f=path/to/file.js` - Shorthand alternative |
| 15 | + |
| 16 | +Multiple files can be included by repeating the parameter: |
| 17 | + |
| 18 | +```shell |
| 19 | +?filePath=src/index.ts&filePath=src/components/Button.tsx |
| 20 | +``` |
| 21 | + |
| 22 | +### 2. Compressed file lists |
| 23 | + |
| 24 | +For comparisons with a large number of files, the system supports compressed file lists (newline-separated): |
| 25 | + |
| 26 | +- `compressedFileList=base64EncodedCompressedData` - Efficiently packs many file paths |
| 27 | + |
| 28 | +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. |
| 29 | + |
| 30 | +```typescript |
| 31 | +// Behind the scenes, the code decompresses file lists using: |
| 32 | +const decodedData = atoburl(compressedFileList) |
| 33 | +const compressedData = Uint8Array.from([...decodedData].map(char => char.charCodeAt(0))) |
| 34 | +const decompressedData = pako.inflate(compressedData, { to: 'string' }) |
| 35 | +``` |
| 36 | + |
| 37 | +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). |
| 38 | + |
| 39 | +```shell |
| 40 | +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 |
| 41 | +``` |
| 42 | + |
| 43 | +### 3. Special focus mode |
| 44 | + |
| 45 | +You can focus on a single file using: |
| 46 | + |
| 47 | +- `focus=true&filePath=path/to/specific/file.js` - Show only this file in detail view |
| 48 | + |
| 49 | +## File filtering UI components |
| 50 | + |
| 51 | +The comparison view provides several UI components to help you filter and navigate files: |
| 52 | + |
| 53 | +### FileDiffPicker |
| 54 | + |
| 55 | +The FileDiffPicker component allows you to: |
| 56 | + |
| 57 | +- Search for files by name or path |
| 58 | +- Filter files by type/extension |
| 59 | +- Toggle between showing all files or only modified files |
| 60 | +- Sort files by different criteria (path, size of change, etc.) |
| 61 | + |
| 62 | +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. |
| 63 | + |
| 64 | +### File navigation |
| 65 | + |
| 66 | +When viewing diffs, you can: |
| 67 | + |
| 68 | +- Click on any file in the sidebar to switch to that file |
| 69 | +- Use keyboard shortcuts to navigate between files |
| 70 | +- Toggle between expanded and collapsed views of files |
| 71 | +- Show or hide specific changes (additions, deletions, etc.) |
| 72 | + |
| 73 | +### URL-based filtering |
| 74 | + |
| 75 | +Any filters you apply through the UI will update the URL with the appropriate query parameters. This means you can: |
| 76 | + |
| 77 | +1. Share specific filtered views with others |
| 78 | +2. Bookmark comparisons with specific file filters |
| 79 | +3. Navigate back and forth between different filter states using browser history |
| 80 | + |
| 81 | +## Implementation details |
| 82 | + |
| 83 | +The system makes strategic performance trade-offs to provide a smooth user experience: |
| 84 | + |
| 85 | +```typescript |
| 86 | +/* |
| 87 | + * For customers with extremely large PRs with thousands of files, |
| 88 | + * we fetch all file paths in a single API call to enable client-side filtering. |
| 89 | + * |
| 90 | + * This eliminates numerous smaller API calls for server-side filtering |
| 91 | + * when users search in the FileDiffPicker. While requiring one large |
| 92 | + * initial API call, it significantly improves subsequent search performance. |
| 93 | + */ |
| 94 | +``` |
| 95 | + |
| 96 | +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. |
| 97 | + |
| 98 | +## Usage examples |
| 99 | + |
| 100 | +1. View only JavaScript files: |
| 101 | + |
| 102 | +```bash |
| 103 | + ?filePath=src/utils.js&filePath=src/components/App.js |
| 104 | +``` |
| 105 | + |
| 106 | +2. Focus on a single file: |
| 107 | + |
| 108 | +```bash |
| 109 | + ?focus=true&filePath=src/components/Button.tsx |
| 110 | + ``` |
| 111 | + |
| 112 | +3. Use a compressed file list for many files: |
| 113 | + |
| 114 | +```bash |
| 115 | + ?compressedFileList=H4sIAAAAAAAAA2NgYGBg... |
| 116 | +``` |
| 117 | + |
| 118 | +This flexible filtering system allows you to create customized views of repository comparisons, making reviewing changes in large projects easier. |
0 commit comments