Search
Full-text search across repository files, filenames, commit messages, and diff history.
Content Search
Search for text or regex patterns inside files
Filename Search
Find files by name or path pattern
Commit Message Search
Search through commit messages
Diff Search
Find content that was added or changed across commits
Content Search
Search for text or regex patterns across all files in a repository at a given revision. Returns matching lines with context, column offsets, and file metadata.
import { freestyle } from "freestyle";
const repo = freestyle.git.repos.ref({ repoId: "your-repo-id" });
const result = await repo.search({
query: "TODO",
pathPattern: "src/**/*.ts",
excludePattern: "**/*.test.ts",
});
for (const file of result.files) {
for (const match of file.matches) {
console.log(`${file.path}:${match.lineNumber} ${match.line}`);
}
}Parameters:
| Parameter | Type | Default | Description |
|---|---|---|---|
query | string | — | Required. The text or regex pattern to search for |
rev | string | "HEAD" | Git ref to search (branch name, tag, or commit SHA) |
pathPattern | string | — | Glob pattern to include only matching file paths (e.g. "src/**/*.ts") |
excludePattern | string | — | Glob pattern to exclude file paths (e.g. "node_modules/**") |
maxResults | number | 100 | Maximum number of matching files to return (max 1000) |
caseSensitive | boolean | false | Whether the search is case-sensitive |
isRegex | boolean | false | Treat the query as a regular expression |
wholeWord | boolean | false | Match whole words only |
offset | number | 0 | Number of file results to skip (for pagination) |
Response:
interface SearchResult {
totalFiles: number; // Total matching files (before pagination)
totalMatches: number; // Total matching lines across all files
hasMore: boolean; // Whether more results exist beyond this page
files: Array<{
path: string; // File path relative to repo root
extension: string | null; // File extension (e.g. "ts")
size: number; // File size in bytes
matches: Array<{
lineNumber: number; // 1-based line number
line: string; // Full text of the matching line
startColumn: number; // 0-based byte offset of match start
endColumn: number; // 0-based byte offset of match end
contextBefore: string[]; // Lines before the match
contextAfter: string[]; // Lines after the match
}>;
}>;
}Regex Search
Pass isRegex: true to use regular expression patterns:
import { freestyle } from "freestyle";
const repo = freestyle.git.repos.ref({ repoId: "your-repo-id" });
// Find all function definitions
const result = await repo.search({
query: "^(export\\s+)?(async\\s+)?function\\s+\\w+",
isRegex: true,
pathPattern: "**/*.ts",
});Pagination
Use the offset parameter along with hasMore to paginate through results:
import { freestyle } from "freestyle";
const repo = freestyle.git.repos.ref({ repoId: "your-repo-id" });
let offset = 0;
const pageSize = 50;
let allFiles = [];
while (true) {
const result = await repo.search({
query: "TODO",
maxResults: pageSize,
offset,
});
allFiles.push(...result.files);
if (!result.hasMore) break;
offset += pageSize;
}
console.log(`Found ${allFiles.length} files with TODOs`);Filename Search
Search for files by their name or path. Useful for file pickers and navigation.
import { freestyle } from "freestyle";
const repo = freestyle.git.repos.ref({ repoId: "your-repo-id" });
const result = await repo.searchFiles({
query: "index",
maxResults: 20,
});
for (const file of result.files) {
console.log(`${file.path} (${file.size} bytes)`);
}Parameters:
| Parameter | Type | Default | Description |
|---|---|---|---|
query | string | — | Required. Text or regex to match against file paths |
rev | string | "HEAD" | Git ref to search |
maxResults | number | 100 | Maximum number of results (max 1000) |
caseSensitive | boolean | false | Whether the search is case-sensitive |
isRegex | boolean | false | Treat the query as a regular expression |
Response:
interface FilenameSearchResult {
totalFiles: number;
hasMore: boolean;
files: Array<{
path: string; // Full path relative to repo root
extension: string | null; // File extension
size: number; // File size in bytes
}>;
}Commit Message Search
Search through commit messages in the repository history.
import { freestyle } from "freestyle";
const repo = freestyle.git.repos.ref({ repoId: "your-repo-id" });
const result = await repo.searchCommits({
query: "fix",
maxResults: 10,
});
for (const commit of result.commits) {
console.log(`${commit.sha.slice(0, 7)} ${commit.message} (${commit.authorName})`);
}Parameters:
| Parameter | Type | Default | Description |
|---|---|---|---|
query | string | — | Required. Text or regex to search in commit messages |
rev | string | "HEAD" | Git ref to start walking from |
maxResults | number | 100 | Maximum number of matching commits to return (max 1000) |
caseSensitive | boolean | false | Whether the search is case-sensitive |
isRegex | boolean | false | Treat the query as a regular expression |
Response:
interface CommitSearchResult {
totalCommits: number;
hasMore: boolean;
commits: Array<{
sha: string; // Full commit SHA
message: string; // First line of the commit message
fullMessage: string; // Complete commit message
authorName: string;
authorEmail: string;
timestamp: string; // ISO 8601 timestamp
}>;
}Diff Search
Search for content that was added or removed across commits — the equivalent of git log -S or git log -G. This walks the commit history and inspects each commit's diff for lines matching the query.
This is useful for finding when a specific piece of code was introduced, when a bug was added, or tracking changes to a particular pattern over time.
import { freestyle } from "freestyle";
const repo = freestyle.git.repos.ref({ repoId: "your-repo-id" });
const result = await repo.searchDiffs({
query: "DATABASE_URL",
pathPattern: "src/**",
maxResults: 5,
});
for (const commit of result.commits) {
console.log(`${commit.sha.slice(0, 7)} ${commit.message}`);
for (const file of commit.files) {
for (const match of file.matches) {
const prefix = match.isAddition ? "+" : "-";
console.log(` ${file.path}:${match.lineNumber} ${prefix} ${match.line}`);
}
}
}Parameters:
| Parameter | Type | Default | Description |
|---|---|---|---|
query | string | — | Required. Text or regex to search in changed lines |
rev | string | "HEAD" | Git ref to start walking from |
pathPattern | string | — | Glob pattern to include only matching file paths |
excludePattern | string | — | Glob pattern to exclude file paths |
maxResults | number | 100 | Maximum number of matching commits to return (max 1000) |
caseSensitive | boolean | false | Whether the search is case-sensitive |
isRegex | boolean | false | Treat the query as a regular expression |
wholeWord | boolean | false | Match whole words only |
offset | number | 0 | Number of commit results to skip (for pagination) |
Response:
interface DiffSearchResult {
totalCommits: number; // Total commits with matching changes
hasMore: boolean;
commits: Array<{
sha: string; // Commit SHA
message: string; // First line of commit message
authorName: string;
authorEmail: string;
timestamp: string; // ISO 8601
files: Array<{
path: string; // File path
matches: Array<{
line: string; // The changed line content
lineNumber: number; // Line number in the file
startColumn: number; // Match start offset
endColumn: number; // Match end offset
isAddition: boolean; // true = added, false = deleted
}>;
}>;
}>;
}Diff search walks up to 10,000 commits from the starting revision. For repositories with extensive history, use a specific rev to narrow the search window.