CodeVetter · Repo Unpack · Contributor handoff
redis/redis
Read `src/server.h` (the 4,976-line master header that every `.c` file includes) and `src/server.c` before touching anything — nearly all global state hangs off the `server` struct declared there. Never hand-edit `src/commands.def`; edit the JSON spec and regenerate. Prefer adding config via the `static_configs[]` table and features via the module API over touching the dispatch path. Build with `make REDIS_CFLAGS='-Werror'` to match CI, and validate with `./runtest --tags -slow` plus `./runtest-moduleapi` if you touched `src/module.c`. Be aware this tree's root `Makefile` is not upstream's: plain `make` runs `scripts/build.sh`, which builds `src/` and then every cloned external module.
- Read first, in order: `src/server.h` (all struct/constant/prototype definitions), `src/server.c` (`main`, `initServer`, `processCommand`, `call`, `beforeSleep`, `serverCron`), `src/networking.c` (client lifecycle and RESP parsing), and `src/config.c` (`static_configs[]`).
- Never edit `src/commands.def` by hand. Edit `src/commands/<cmd>.json`, run `make commands.def` (which invokes `utils/generate-command-code.py`), and commit both — CI's `validate commands.def up to date` step diffs the regenerated output and fails on drift.
- Match CI's build flags locally: `make REDIS_CFLAGS='-Werror' BUILD_TLS=yes`. Use `REDIS_CFLAGS`/`REDIS_LDFLAGS` rather than `CFLAGS`/`LDFLAGS` — the src/Makefile header notes that plain CFLAGS propagate into the `deps/` builds (jemalloc, Lua, hiredis) too.
- Test commands to run: `make -C src test` (= `./runtest`) for the default suite, `./runtest --tags -slow --dump-logs` to match CI exactly, `./runtest --single unit/type/hash` to scope, `make -C src test-modules`, `test-cluster`, `test-sentinel` for the other three harnesses.
- Trap — building Redis alone is `make -C src all`, not `make`. The root `Makefile`'s default goal is `build`, which runs `scripts/build.sh` and will additionally try to build every module cloned under `modules/*/src`. Use `make build redis` or `make build core` to skip modules.
- Trap — on macOS you must use `gmake` (GNU Make ≥ 4.x), not Apple's `/usr/bin/make` 3.81. The root Makefile explicitly `export MAKE`s so recipe shells inherit the right binary, precisely because non-interactive recipe shells otherwise PATH-resolve to make 3.81.
- Trap — adding a new object type requires coordinated edits to `rdb.c`, `aof.c`, `db.c` (`obj_type_name`, `copyCommand`), `debug.c` (`xorObjectDigest`, `serverLogObjectDebugInfo`) and `defrag.c` (`defragKey`), per the checklist comment in server.h. Nothing enforces this at compile time.
- Trap — `redis.conf` is the tracked, hand-edited core config with no markers; `redis-full.conf` is untracked and regenerated by `scripts/sync-redis-conf.sh` on every `make modules-update`. Never hand-add `loadmodule` lines to `redis.conf`.
- Safe edit boundary — prefer adding behaviour through the module API (`RM_CreateCommand`, module data types, command filters, server-event hooks) or a new `static_configs[]` entry over modifying `processCommand()`/`call()`, which carry assertions and propagation invariants.
- Do not touch `deps/` — it is vendored third-party source (jemalloc, lua, hiredis, linenoise, hdr_histogram, fpconv, xxhash, tre) built by separate targets listed in `DEPENDENCY_TARGETS`. Changes there are lost on dependency refresh.
- Style convention — the codebase is C99/gnu11 compiled with `-pedantic -Wall -W -Wstrict-prototypes -Werror=deprecated-declarations`, and falls back to `-std=c99` (also setting `SKIP_VEC_SETS=yes`) when the compiler lacks C11 `_Atomic`. New code must build under both.
- Licensing convention — every new source file carries the Redis tri-license header (RSALv2 / SSPLv1 / AGPLv3); contributions are governed by the Software Grant and CLA reproduced in full in CONTRIBUTING.md.
- Security convention — do not report vulnerabilities through normal issues; SECURITY.md directs reports to the Redis Vulnerability Disclosure Program or GitHub's 'Report a Vulnerability', and notes that 32-bit, non-Linux and outdated-toolchain findings may be ruled out of scope.
- When adding or changing a command's reply, update the reply schema in its `src/commands/*.json` — `.github/workflows/reply-schemas-linter.yml` triggers on changes to those files and validates them with ajv via `utils/reply_schema_linter.js`.
- For debugging a failing Tcl test, `./runtest --dump-logs` plus `tests/support/util.tcl`'s helpers and the `s <field>` / `S <index> <field>` INFO accessors in test_helper.tcl are the standard tools; servers spawn on ports starting at `::baseport 21111`.
- Bumping a bundled module is a one-line change: edit `ref:` in `modules/modules.yaml` then run `make modules-update <name>`. Ref kind is resolved dynamically against the remote in the order tag → branch → commit, and an unmatched ref errors out with 'unknown ref kind'.