Skip to content

Commit 956e95f

Browse files
committed
Add page for compare file filtering
1 parent cc39455 commit 956e95f

File tree

1 file changed

+116
-0
lines changed

1 file changed

+116
-0
lines changed
Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
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+
```
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 uses base64-encoded, gzip-compressed data to efficiently transmit large sets of file paths. The compression makes it possible to include hundreds or thousands of files in a URL without exceeding length limits. The length limits 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 (which is smaller than base64-encoding, then url-encoding).
38+
```shell
39+
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
40+
```
41+
42+
### 3. Special Focus Mode
43+
44+
You can focus on a single file using:
45+
46+
- `focus=true&filePath=path/to/specific/file.js` - Show only this file in detail view
47+
48+
## File Filtering UI Components
49+
50+
The comparison view provides several UI components to help you filter and navigate files:
51+
52+
### FileDiffPicker
53+
54+
The FileDiffPicker component allows you to:
55+
56+
- Search for files by name or path
57+
- Filter files by type/extension
58+
- Toggle between showing all files or only modified files
59+
- Sort files by different criteria (path, size of change, etc.)
60+
61+
This component uses a dedicated file metadata query optimized for quick filtering, with results displayed instantly as you type. The component can efficiently handle repositories with thousands of files through client-side filtering.
62+
63+
### File Navigation
64+
65+
When viewing diffs, you can:
66+
67+
- Click on any file in the sidebar to switch to that file
68+
- Use keyboard shortcuts to navigate between files
69+
- Toggle between expanded and collapsed views of files
70+
- Show or hide certain types of changes (additions, deletions, etc.)
71+
72+
### URL-Based Filtering
73+
74+
Any filters you apply through the UI will update the URL with the appropriate query parameters. This means you can:
75+
76+
1. Share specific filtered views with others
77+
2. Bookmark comparisons with specific file filters
78+
3. Navigate back and forth between different filter states using browser history
79+
80+
## Implementation Details
81+
82+
The system makes strategic performance trade-offs to provide a smooth user experience:
83+
84+
```typescript
85+
/*
86+
* For customers with extremely large PRs with thousands of files,
87+
* we fetch all file paths in a single API call to enable client-side filtering.
88+
*
89+
* This eliminates numerous smaller API calls for server-side filtering
90+
* when users search in the FileDiffPicker. While requiring one large
91+
* initial API call, it significantly improves subsequent search performance.
92+
*/
93+
```
94+
95+
The file filtering system uses a specialized file metadata query that is faster and more lightweight than the comprehensive file diffs query used for displaying actual code changes.
96+
97+
## Usage Examples
98+
99+
1. View only JavaScript files:
100+
101+
```
102+
?filePath=src/utils.js&filePath=src/components/App.js
103+
```
104+
105+
2. Focus on a single file:
106+
107+
```
108+
?focus=true&filePath=src/components/Button.tsx
109+
```
110+
111+
3. Use compressed file list for many files:
112+
```
113+
?compressedFileList=H4sIAAAAAAAAA2NgYGBg...
114+
```
115+
116+
This flexible filtering system allows you to create customized views of repository comparisons, making it easier to review changes in large projects.

0 commit comments

Comments
 (0)