# Commit Message Conventions

This document defines standards for commit messages in the Pinecone Python SDK. Good commit messages help reviewers understand changes, make git history searchable, and assist future maintainers in understanding why changes were made.

## Format: Conventional Commits

All commit messages follow the Conventional Commits specification:

```
<type>: <subject>

<body>

<footer>
```

### Structure

- **Subject line**: `type: description` (required)
- **Blank line**: Separates subject from body
- **Body**: Detailed explanation (optional but recommended)
- **Blank line**: Separates body from footer
- **Footer**: Issue references, breaking changes (optional)

## Subject Line

### Format

```
<type>: <description>
```

### Types

Use the same types as PR titles:

| Type | Usage | Example |
|------|-------|---------|
| `feat` | New features | `feat: add batch upsert support` |
| `fix` | Bug fixes | `fix: handle connection timeout errors` |
| `docs` | Documentation | `docs: update migration guide` |
| `refactor` | Code restructuring | `refactor: simplify error handling` |
| `perf` | Performance | `perf: add connection pooling` |
| `test` | Tests | `test: add integration tests` |
| `chore` | Tooling, deps | `chore: update httpx to 0.25.0` |
| `ci` | CI/CD changes | `ci: add benchmark workflow` |

### Subject Guidelines

**Do:**
- Keep under 72 characters (50 is ideal)
- Use imperative mood: "add feature" not "adds" or "added"
- Use lowercase after the colon
- Be specific about what changed
- No period at the end
- **Add `!` after type for breaking changes**: `feat!: require spec parameter`

**Don't:**
- Use past tense or present continuous
- Be vague: "fix bug", "update code"
- Include issue numbers (put in footer)
- Capitalize after colon
- Forget the `!` for breaking changes

### Examples

```
✅ Good:
feat: add serverless index configuration
fix: validate vector dimensions before upsert
docs: add batch operations guide
perf: implement connection pooling
refactor: extract HTTP client configuration
test: add unit tests for query validation
feat!: require spec parameter in create_index (breaking change)
fix!: change error response format (breaking change)

❌ Bad:
Add feature (missing type)
feat: Added support for collections (past tense, capitalized)
fix: bug (too vague)
feat: Add Support For New Feature #123 (issue in subject, weird caps)
Fixed the timeout issue in queries (no type, past tense)
feat: require spec parameter (breaking change missing !)
```

## Message Body

### When to Include Body

**Always include body for:**
- Non-trivial changes
- Features that need explanation
- Bug fixes where the cause wasn't obvious
- Changes that might be surprising
- Anything that needs "why" context

**Body optional for:**
- Trivial changes (typo fixes, formatting)
- Self-explanatory changes
- Changes where subject says it all

### Body Guidelines

**Content:**
- Explain **why** the change was made, not **what** changed (the code shows what)
- Provide context about the problem being solved
- Explain trade-offs or alternatives considered
- Mention any side effects or implications
- Keep lines wrapped at 72 characters

**Format:**
- Separate from subject with blank line
- Wrap lines at 72 characters
- Use paragraphs for readability
- Use bullet points for lists
- Write in imperative mood (like subject)

### Examples

```
✅ Good - explains why:

feat: add connection pooling to HTTP client

The SDK was creating a new connection for each request, causing
poor performance for applications making sequential queries. Users
reported 150ms average latency with 50ms spent on connection setup.

This adds connection pooling using httpx, maintaining up to 100
connections with 10 keep-alive by default. This reduces latency
by ~30% for sequential operations.

Fixes #145


✅ Good - provides context:

fix: validate vector dimensions before upsert

Previously, dimension mismatches were only caught by the API,
resulting in cryptic 400 errors. Users struggled to debug the
actual problem.

This adds client-side validation that checks vector dimensions
against the index configuration before making API calls. The
error message now clearly states expected vs actual dimensions.

Fixes #178


❌ Bad - just repeats code:

feat: add connection pooling

- Added HTTPClient class
- Added pool_connections parameter
- Added pool_maxsize parameter
- Updated tests


❌ Bad - too vague:

fix: handle errors better

Fixed some issues with error handling.
```

## Footer

### Issue References

Link related issues at the end of the commit message.

**Format:**
```
Fixes #123
Refs #456
```

**Magic Words:**
- `Fixes #123` - Closes the issue when merged
- `Closes #123` - Same as Fixes
- `Refs #456` - References without closing
- `Fixes ABC-789` - Closes Linear issue
- `Refs ABC-123` - References Linear issue

**Examples:**
```
feat: add batch upsert support

Implement batching for upsert operations to improve throughput
for bulk operations. Vectors are sent in batches of 100 by
default, configurable via batch_size parameter.

Fixes #134
Refs #120


fix: handle connection timeout in query

Add proper timeout handling with retry logic. Previously,
timeouts would crash the application instead of raising a
proper exception.

Fixes #167
Fixes SDK-456
```

### Breaking Changes

For commits that introduce breaking changes:
1. Add `!` after the type in the subject: `feat!: require spec parameter`
2. Add `BREAKING CHANGE:` to the body or footer

Both signal breaking changes to automated tooling.

**Important for Squash and Merge:** When using GitHub's squash and merge workflow, individual commit messages are replaced by the PR title and description. Use `!` in the PR title AND document breaking changes in the PR description. See [Pull Request Conventions](./pull-requests.md#breaking-changes-section) for details.

**Format:**
```
feat!: require spec parameter in create_index

BREAKING CHANGE: The spec parameter is now required in create_index
to support serverless and pod-based deployments. Code that doesn't
provide spec will raise ValidationError. Update all create_index
calls to include the spec parameter.

Migration: See docs/migration-guides/v2.md for examples.

Fixes SDK-567
```

**Alternative format (in footer):**
```
feat!: remove legacy_upsert method

The legacy_upsert method was deprecated in v1.5 and has been removed.

BREAKING CHANGE: Code using legacy_upsert will raise AttributeError.
Replace all legacy_upsert calls with upsert (API is identical).

Fixes #189
```

## Multi-line Commit Messages

### Creating Multi-line Commits

**Command line:**
```bash
git commit -m "feat: add connection pooling" -m "
The SDK was creating a new connection for each request, causing
poor performance for sequential queries.

This adds connection pooling using httpx, reducing latency by ~30%.

Fixes #145
"
```

**Using heredoc (recommended):**
```bash
git commit -m "$(cat <<'EOF'
feat: add connection pooling

The SDK was creating a new connection for each request, causing
poor performance for sequential queries.

This adds connection pooling using httpx, reducing latency by ~30%.

Fixes #145
EOF
)"
```

**Using editor:**
```bash
git commit
# Opens editor for multi-line message
```

## Complete Examples

### Feature Addition

```
feat: add serverless index configuration

Add support for serverless indexes via the spec parameter in
create_index. The API now requires explicit configuration to
distinguish between serverless and pod-based deployments.

This change makes spec required to force users to explicitly
choose deployment type. Validation ensures spec contains either
"serverless" or "pod" configuration.

BREAKING CHANGE: The spec parameter is now required. Code without
spec will raise ValidationError. Update all create_index calls:

  pc.create_index(
      name="my-index",
      dimension=128,
      spec={"serverless": {"cloud": "aws", "region": "us-east-1"}}
  )

Fixes SDK-567
Refs #234
```

### Bug Fix

```
fix: prevent memory leak in connection pool

The HTTPClient was not properly closing connections on __del__,
causing connection objects to accumulate in long-running processes.
This resulted in gradual memory growth over time.

This fix ensures connections are closed via context manager or
explicit close() call. Added __enter__ and __exit__ methods to
HTTPClient for proper resource management.

Fixes #198
Fixes SDK-445
```

### Refactoring

```
refactor: extract HTTP configuration to separate class

The HTTPClient had grown to include both client logic and
configuration management, making it harder to test and maintain.

This extracts configuration into HTTPConfig class, separating
concerns and making configuration more explicit. No functional
changes - purely structural improvement.

Refs #205
```

### Documentation

```
docs: add connection pooling guide

Add comprehensive guide explaining connection pooling, including
configuration options, performance characteristics, and best
practices for different usage patterns.

Refs #145
```

### Performance Improvement

```
perf: optimize vector serialization with msgspec

Replace json.dumps with msgspec for vector serialization. Msgspec
is 3-5x faster for large vector batches and uses less memory.

Benchmarks show:
- Small batches (10 vectors): 30% faster
- Large batches (1000 vectors): 400% faster
- Memory usage: 40% reduction

This change is backward compatible. The wire format remains JSON.

Refs #167
```

### Test Addition

```
test: add integration tests for collections

Add comprehensive integration tests covering all collection
operations: list, create, delete, and describe. Tests use mocked
HTTP responses to avoid requiring live API access.

Increases coverage from 87% to 92%.

Refs #178
```

## Atomic Commits

### One Logical Change Per Commit

Each commit should represent one logical change:

**Good (separate commits):**
```
feat: add connection pooling
test: add connection pool tests
docs: document connection pooling
```

**Bad (multiple changes in one commit):**
```
feat: add connection pooling, fix timeout bug, update docs

Added connection pooling for better performance. Also fixed a bug
with timeouts. Updated documentation.
```

### When to Combine

It's okay to combine related changes in one commit:
- Implementation + tests for the same feature
- Code change + necessary documentation update
- Refactoring + fixing related issues discovered

**Good (combined):**
```
feat: add batch upsert with tests

Implement batch upsert operations and add comprehensive unit tests.
Tests cover success cases, validation errors, and API errors.
```

## Common Patterns

### Commit Often

Make small, focused commits rather than large omnibus commits:

```
✅ Good progression:
feat: add HTTPConfig class
feat: integrate HTTPConfig with HTTPClient
test: add HTTPConfig validation tests
docs: document HTTP configuration

❌ Bad single commit:
feat: add HTTP configuration system

Added HTTPConfig class, integrated it with HTTPClient, added tests,
updated documentation, fixed some bugs, refactored error handling...
```

### Temporary Commits

Avoid committing temporary work:

**Bad:**
```
WIP
fix tests
fix tests again
address review comments
final fix
```

**Good (after squashing):**
```
feat: add batch upsert support

Implement batching for upsert operations to improve throughput.
```

Use interactive rebase to clean up commit history before pushing:
```bash
git rebase -i HEAD~5  # Clean up last 5 commits
```

## Git Command Examples

### Simple Commit

```bash
git commit -m "feat: add connection pooling"
```

### Commit with Body

```bash
git commit -m "feat: add connection pooling" -m "
Reduces latency by ~30% for sequential operations by reusing
HTTP connections instead of creating new ones for each request.

Fixes #145
"
```

### Commit with Heredoc (Recommended)

```bash
git commit -m "$(cat <<'EOF'
feat: add connection pooling

Reduces latency by ~30% for sequential operations by reusing
HTTP connections instead of creating new ones for each request.

Uses httpx built-in pooling with default settings of 10
keep-alive connections and 100 max connections.

Fixes #145
EOF
)"
```

### Amend Last Commit

```bash
# Fix last commit message
git commit --amend -m "feat: add connection pooling"

# Add forgotten files to last commit
git add forgotten-file.py
git commit --amend --no-edit
```

### Interactive Rebase

```bash
# Clean up last 3 commits
git rebase -i HEAD~3

# In editor:
# - pick: keep commit as-is
# - reword: change commit message
# - squash: combine with previous commit
# - fixup: combine with previous, discard message
# - drop: remove commit
```

## Commit Message Template

Use a git commit template for consistency:

**Create template file:**
```bash
cat > ~/.gitmessage <<'EOF'
# <type>: <subject> (max 72 chars)

# Explain why this change is needed (wrap at 72 chars)
# - What problem does it solve?
# - Why this approach?
# - Any trade-offs or side effects?

# Refs #issue-number
# Fixes #issue-number
EOF
```

**Configure git to use template:**
```bash
git config --global commit.template ~/.gitmessage
```

## Validation

### Pre-commit Hooks

The repository includes pre-commit hooks that validate commit messages.

**What's checked:**
- Conventional Commits format
- Subject line length (<72 chars)
- No period at end of subject
- Imperative mood (common patterns)
- Body line length (<72 chars)

**Bypass validation (emergencies only):**
```bash
git commit --no-verify -m "emergency fix"
```

## Review Checklist

Before committing:

- [ ] Subject follows Conventional Commits format (`type: description`)
- [ ] Subject is under 72 characters (50 is ideal)
- [ ] Subject uses imperative mood
- [ ] Subject is specific and clear
- [ ] Body explains "why" not "what" (if included)
- [ ] Body lines wrapped at 72 characters
- [ ] Issues linked with magic words (`Fixes #123`)
- [ ] Breaking changes documented (if any)
- [ ] Commit is focused on one logical change

## Anti-Patterns

### What to Avoid

❌ **Vague subjects:**
```
fix bug
update code
improvements
misc changes
```

❌ **Past tense or continuous:**
```
feat: added connection pooling
fix: fixing timeout issue
docs: updating guide
```

❌ **Too long:**
```
feat: add connection pooling support to the HTTP client for better performance in high-throughput scenarios
```

❌ **Issue number in subject:**
```
feat: add connection pooling (#145)
fix: #178 validate dimensions
```

❌ **Multiple changes:**
```
feat: add connection pooling and fix timeout bug and update docs
```

❌ **Explaining what (code shows what):**
```
feat: add connection pooling

- Added HTTPClient class
- Added pool_connections parameter
- Added pool_maxsize parameter
- Updated __init__ method
```

### What to Do Instead

✅ **Specific subjects:**
```
fix: validate vector dimensions before upsert
perf: optimize vector serialization
docs: add connection pooling guide
```

✅ **Imperative mood:**
```
feat: add connection pooling
fix: handle timeout errors
docs: update migration guide
```

✅ **Appropriate length:**
```
feat: add connection pooling to HTTP client
```

✅ **Issue in footer:**
```
feat: add connection pooling

Reduces latency for sequential operations.

Fixes #145
```

✅ **Focused changes:**
```
feat: add connection pooling
test: add connection pool tests
docs: document connection pooling
```

✅ **Explaining why:**
```
feat: add connection pooling

The SDK was creating new connections for each request, causing
poor performance. This adds pooling to reuse connections,
reducing latency by ~30%.
```

## Summary

Good commit messages:
- **Format:** `type: description` (Conventional Commits)
- **Subject:** <72 chars, imperative, specific, no period
- **Body:** Explains "why", wrapped at 72 chars (optional but recommended)
- **Footer:** Issue links with magic words, breaking changes
- **Atomic:** One logical change per commit
- **Clear:** Future maintainers can understand why change was made

Remember: commit messages are documentation. Write them for the developer
who will debug this code in six months (that developer might be you).
