首页 Sourcegraph Code Search Cookbook
340px

入口与定位 >>>

可以把 Sourcegraph 搜索理解成“带过滤器、结果类型和代码结构意识的全局代码检索台”。实战里通常不是一上来写复杂正则,而是先缩小仓库范围,再选搜索模式,最后提取你真正要看的结果。
  • repo: patternType: select: type::管范围, 管匹配方式, / 管返回结果形态。
  • repo: file: language::先用 、、 把噪音压下去,再决定是关键词、正则还是结构化搜索。
  • 搜索模式选择:
    • patternType:keyword:默认模式,适合高频文本检索。
    • patternType:regexp:需要 RE2 正则时用。
    • patternType:structural:想按代码结构找调用、参数、包裹关系时用。
  • 结果类型选择:
    • type:content:看正文命中。
    • type:path type:repo:只看文件或仓库。
    • type:symbol:找定义、方法、类、接口。
    • type:commit type:diff:查历史和改动。
# 最小可用搜索:先限定仓库,再搜关键词
repo:sourcegraph/sourcegraph zoekt

# 先限定语言和路径,再搜函数名
repo:sourcegraph/sourcegraph language:go file:^cmd/ fmt.Errorf

# 明确告诉 Sourcegraph 你要用正则
repo:sourcegraph/sourcegraph patternType:regexp /New.*Client/

起手工作流

当你只知道一个模糊线索时,按“先收范围、再提精度、最后抽结果”的顺序走,搜索会稳定很多。
  • 先收范围:repo:myorg/monorepo file:^packages/ language:typescript
  • 再定模式:patternType:keyword | regexp | structural
  • 最后抽结果:select:repo | select:file | type:symbol
# 场景:只知道某个配置键名,先全局粗找
repo:myorg/ language:yaml timeout:20s payment_provider

# 场景:已经知道可能在后端,继续收窄
repo:myorg/backend language:go file:^internal/ payment_provider

# 场景:最后只想知道涉及哪些文件
repo:myorg/backend language:go file:^internal/ payment_provider select:file

范围控制技巧

搜索质量通常首先取决于范围控制,而不是正则写得多花。先把仓库、分支、路径、语言收准,后面的匹配才有意义。
  • 仓库过滤:repo:sourcegraph/sourcegraph repo:
  • 排除仓库:-repo:^github.com/myorg/legacy
  • 路径过滤:file:^src/ | -file:(^dist/|^vendor/) file:
  • 语言过滤:language:go | language:typescript
  • 修订范围:repo:foo@main | repo:foo@*refs/tags/* repo:
  • 上下文过滤:context:global | context:@me | context:@team/search
# 搜某团队全部 Go 服务,但排除生成代码和 vendor
context:@platform/backend language:go -file:(^vendor/|^gen/) grpc.Dial

# 搜指定标签范围
repo:sourcegraph/sourcegraph@*refs/tags/* type:diff executor

# 只在带 package.json 的仓库中搜索
repo:has.file(^package\.json$) react-router

模式与语法技巧

真正常用的不是“记住所有语法”,而是知道什么时候切换 keyword、regexp、structural,以及如何避免过滤器和正文互相冲突。
  • 关键词模式:foo bar patternType:keyword
  • 精确短语:"foo bar"
  • 正则模式:/.../ patternType:regexp
  • 大小写敏感:case:yes
  • 按字面搜索保留词:content:"repo:sourcegraph" repo: file: content:
  • 结构化搜索:patternType:structural
# 关键词:同时包含两个词
auth token

# 精确短语
"invalid token"

# 正则:查所有 get/set 风格方法
patternType:regexp /(?:get|set)[A-Z]\w+/

# literal 搜索,避免 repo: 被当成过滤器
content:"repo:sourcegraph"

# 结构化:找 Go 中包着 fmt.Errorf 的 return
repo:myorg/backend language:go patternType:structural 'return fmt.Errorf(:[args])'

布尔组合与排除

当一个线索不够时,用布尔组合表达“必须出现”“二选一”“明确排除”,比堆复杂正则更易读也更易维护。
  • AND OR
  • OR
  • NOT -
  • (...)
# 要么 http.NewRequest 要么 NewRequestWithContext
repo:myorg/ language:go (http.NewRequest OR NewRequestWithContext)

# 查真实调用点,排除测试和 mock
repo:myorg/ language:go payment NOT file:_test\.go$ NOT mock

# 查配置分支
repo:myorg/frontend file:^src/ (SENTRY_DSN OR DATADOG_CLIENT_TOKEN) -file:\.snap$

结果提取与导航

很多时候你不是想“看命中内容”,而是想快速拿到仓库名单、文件名单、符号清单或差异片段。这时 `select:` 和 `type:` 比继续收缩正文更高效。
  • select:repo
  • select:file
  • type:path
  • type:symbol
  • type:commit type:diff
  • select:commit.diff.added
# 哪些仓库还在用旧 SDK
context:global "legacy-sdk" select:repo

# 哪些文件声明了这个环境变量
repo:myorg/ file:\.(ts|tsx|js)$ NEXT_PUBLIC_API_BASE select:file

# 找某个符号定义
repo:myorg/backend type:symbol Handler

# 只看新增的 panic
repo:myorg/ type:diff select:commit.diff.added panic

常见 Recipes

下面这些是 Sourcegraph 最常见的实战套路。记住场景到查询的映射,比死背全部语法更有用。
  • 找某个能力在哪些服务里实现
context:@platform/backend language:go (RegisterRoutes OR grpc.NewServer) select:repo
  • 找某个配置从前端一路传到后端
# 前端入口
repo:myorg/web file:^src/ language:typescript "checkoutTimeout"

# 后端消费
repo:myorg/api language:go "checkoutTimeout"
  • 找最近谁引入了危险调用
repo:myorg/ type:diff after:"30 days ago" (exec.Command OR os/exec) select:commit.diff.added
  • 只看某类文件是否存在,而不看正文
repo:has.file(^Dockerfile$) select:repo
repo:has.path(^\.github/workflows/) select:repo
  • 找某个 API 的全部调用点,但排除定义
repo:myorg/sdk language:typescript createClient -file:(index\.ts$|types\.ts$)
  • 查重构是否还遗留旧命名
repo:myorg/ ("OldBillingService" OR oldBillingService) -file:(CHANGELOG|README)

提交与历史排查

当你怀疑问题是“最近改出来的”,直接切到 `type:commit` 或 `type:diff`,通常比在当前代码里猜更快。
  • author: committer:
  • before: after:
  • message:
  • repo:foo@main:^release
# 最近两周谁改过认证逻辑
repo:myorg/ type:commit after:"14 days ago" auth author:alice

# 查带 rollback 的历史提交
repo:myorg/ type:commit message:rollback

# 查主分支相对 release 分支的差异里是否出现这个关键词
repo:myorg/service@main:^release type:diff payment

高频语法速记

这一段不是完整手册,只保留最值得背下来的语法骨架,方便你在页面里快速扫一眼再开搜。
  • repo:REGEXP:按仓库过滤
  • file:REGEXP:按路径过滤
  • language:NAME:按语言过滤
  • content:"literal":按字面内容过滤
  • patternType:keyword|regexp|structural:切换匹配模式
  • type:content|path|repo|symbol|commit|diff:切换结果类型
  • select:repo|file|commit.diff.added:提取结果形态
  • case:yes:大小写敏感
  • count:1000 timeout:20s:放宽结果数和超时
  • context:global:切换搜索上下文
  • repo:has.file(...) repo:has.path(...):按仓库内文件特征过滤

常见坑与排障

Sourcegraph 查不准时,通常不是“功能不行”,而是查询的层级混了。优先检查过滤器冲突、结果类型和搜索模式。
  • repo:foo content:"repo:foo"
  • type:symbol
  • 该用 select:file 时还在看几百条正文 你如果只是想知道影响面,直接抽文件列表。
  • repo: file: language:
  • 结构化搜索没命中就怀疑语法错 先确认语言识别、代码形态和占位模式是否真的匹配目标代码。
# 误写:repo:sourcegraph    # 这是过滤器
# 正写:content:"repo:sourcegraph"

# 想看有哪些文件命中,不要继续刷正文
repo:myorg/ language:go context.Context select:file

# 超大仓库先收范围再正则
repo:myorg/ file:^internal/ patternType:regexp /New[A-Z]\w+Client/

核心场景小抄

不想每次都从头拼查询时,直接套下面这些模板,再按你的仓库名、路径和语言替换即可。
  • repo:<repo> file:^<dir>/ language:<lang> <keyword>
  • repo:<repo> language:<lang> <symbol> -file:_test\.go$
  • repo:<repo> type:symbol <symbol>
  • repo:<repo> <keyword> select:file
  • context:<ctx> <keyword> select:repo
  • repo:<repo> type:diff after:"30 days ago" <keyword>
  • repo:<repo> type:diff select:commit.diff.added <keyword>