# Git Objects API

## Blobs

### Get Blob

```
GET /api/v1/repos/{owner}/{repo}/git/blobs/{sha}
```

**Query Parameters:**

| Parameter | Type | Description |
|-----------|------|-------------|
| `shas` | string | Comma-separated list of blob SHAs to retrieve (batch mode) |

```bash
# Get a single blob
curl -s "${FORGEJO_URL}/api/v1/repos/{owner}/{repo}/git/blobs/abc123def456" \
  -H "Authorization: token ${FORGEJO_PAT}"

# Batch retrieve multiple blobs
curl -s "${FORGEJO_URL}/api/v1/repos/{owner}/{repo}/git/blobs/?shas={sha1},{sha2},{sha3}" \
  -H "Authorization: token ${FORGEJO_PAT}"
```

**Response:**

```json
{
  "sha": "abc123def456...",
  "size": 1234,
  "encoding": "base64",
  "content": "cGFja2FnZSBtYWlu...",
  "url": "https://{FORGEJO_HOST}/api/v1/repos/{owner}/{repo}/git/blobs/abc123def456"
}
```

---

## Commits

### Get Commit by SHA

```
GET /api/v1/repos/{owner}/{repo}/git/commits/{sha}
```

```bash
curl -s "${FORGEJO_URL}/api/v1/repos/{owner}/{repo}/git/commits/{sha}" \
  -H "Authorization: token ${FORGEJO_PAT}"
```

### Get Commit Diff or Patch

```
GET /api/v1/repos/{owner}/{repo}/git/commits/{sha}.{diffType}
```

`diffType` can be `diff` or `patch`.

```bash
# Get diff
curl -s "${FORGEJO_URL}/api/v1/repos/{owner}/{repo}/git/commits/{sha}.diff" \
  -H "Authorization: token ${FORGEJO_PAT}"

# Get patch
curl -s "${FORGEJO_URL}/api/v1/repos/{owner}/{repo}/git/commits/{sha}.patch" \
  -H "Authorization: token ${FORGEJO_PAT}"
```

### List Commits

```
GET /api/v1/repos/{owner}/{repo}/commits
```

**Parameters:**

| Parameter | Type | Description |
|-----------|------|-------------|
| `sha` | string | SHA or branch to start from |
| `path` | string | Filter commits by file/directory path |
| `stat` | boolean | Include diff stats |
| `verification` | boolean | Include GPG verification info |
| `files` | boolean | Include list of changed files |
| `not` | string | Commits matching this specifier will not be listed (exclude pattern) |
| `page` | integer | Page number (1-based) |
| `limit` | integer | Page size |

```bash
# List recent commits on default branch
curl -s "${FORGEJO_URL}/api/v1/repos/{owner}/{repo}/commits" \
  -H "Authorization: token ${FORGEJO_PAT}"

# List commits on a specific branch
curl -s "${FORGEJO_URL}/api/v1/repos/{owner}/{repo}/commits?sha={branch_or_sha}" \
  -H "Authorization: token ${FORGEJO_PAT}"

# List commits for a specific file
curl -s "${FORGEJO_URL}/api/v1/repos/{owner}/{repo}/commits?path=src/main.go" \
  -H "Authorization: token ${FORGEJO_PAT}"

# Include diff stats and file list
curl -s "${FORGEJO_URL}/api/v1/repos/{owner}/{repo}/commits?stat=true&files=true" \
  -H "Authorization: token ${FORGEJO_PAT}"

# Include GPG verification
curl -s "${FORGEJO_URL}/api/v1/repos/{owner}/{repo}/commits?verification=true" \
  -H "Authorization: token ${FORGEJO_PAT}"

# Paginated
curl -s "${FORGEJO_URL}/api/v1/repos/{owner}/{repo}/commits?page=2&limit=20" \
  -H "Authorization: token ${FORGEJO_PAT}"
```

### Get PR Associated with Commit

```
GET /api/v1/repos/{owner}/{repo}/commits/{sha}/pull
```

```bash
curl -s "${FORGEJO_URL}/api/v1/repos/{owner}/{repo}/commits/{sha}/pull" \
  -H "Authorization: token ${FORGEJO_PAT}"
```

---

## References

### List References

```
GET /api/v1/repos/{owner}/{repo}/git/refs
```

```bash
curl -s "${FORGEJO_URL}/api/v1/repos/{owner}/{repo}/git/refs" \
  -H "Authorization: token ${FORGEJO_PAT}"
```

### Get Reference

```
GET /api/v1/repos/{owner}/{repo}/git/refs/{ref}
```

```bash
# Get a branch ref
curl -s "${FORGEJO_URL}/api/v1/repos/{owner}/{repo}/git/refs/heads/{branch}" \
  -H "Authorization: token ${FORGEJO_PAT}"

# Get a tag ref
curl -s "${FORGEJO_URL}/api/v1/repos/{owner}/{repo}/git/refs/tags/{tag}" \
  -H "Authorization: token ${FORGEJO_PAT}"
```

**Response:**

```json
{
  "ref": "refs/heads/main",
  "url": "https://{FORGEJO_HOST}/api/v1/repos/{owner}/{repo}/git/refs/heads/{branch}",
  "object": {
    "type": "commit",
    "sha": "abc123def456...",
    "url": "https://{FORGEJO_HOST}/api/v1/repos/{owner}/{repo}/git/commits/{sha}"
  }
}
```

---

## Tags

### Get Annotated Tag

```
GET /api/v1/repos/{owner}/{repo}/git/tags/{sha}
```

Returns the tag object for annotated tags (not lightweight tags).

```bash
curl -s "${FORGEJO_URL}/api/v1/repos/{owner}/{repo}/git/tags/{sha}" \
  -H "Authorization: token ${FORGEJO_PAT}"
```

**Response:**

```json
{
  "sha": "abc123def456...",
  "tag": "v1.0.0",
  "message": "Release v1.0.0",
  "url": "https://{FORGEJO_HOST}/api/v1/repos/{owner}/{repo}/git/tags/{sha}",
  "tagger": {
    "name": "{author_name}",
    "email": "{email}",
    "date": "2024-03-15T10:00:00Z"
  },
  "object": {
    "type": "commit",
    "sha": "def789...",
    "url": "https://{FORGEJO_HOST}/api/v1/repos/{owner}/{repo}/git/commits/{sha}"
  },
  "verification": {
    "verified": false
  }
}
```

---

## Trees

### Get Tree

```
GET /api/v1/repos/{owner}/{repo}/git/trees/{sha}
```

**Parameters:**

| Parameter | Type | Description |
|-----------|------|-------------|
| `recursive` | boolean | Get tree recursively |
| `page` | integer | Page number (1-based) |
| `per_page` | integer | Items per page |

```bash
# Get top-level tree
curl -s "${FORGEJO_URL}/api/v1/repos/{owner}/{repo}/git/trees/{branch_or_sha}" \
  -H "Authorization: token ${FORGEJO_PAT}"

# Get recursive tree (all files)
curl -s "${FORGEJO_URL}/api/v1/repos/{owner}/{repo}/git/trees/{branch_or_sha}?recursive=true" \
  -H "Authorization: token ${FORGEJO_PAT}"

# Paginated recursive tree
curl -s "${FORGEJO_URL}/api/v1/repos/{owner}/{repo}/git/trees/{branch_or_sha}?recursive=true&page=1&per_page=100" \
  -H "Authorization: token ${FORGEJO_PAT}"
```

**Response:**

```json
{
  "sha": "abc123...",
  "url": "https://{FORGEJO_HOST}/api/v1/repos/{owner}/{repo}/git/trees/abc123",
  "tree": [
    {
      "path": "README.md",
      "mode": "100644",
      "type": "blob",
      "size": 1234,
      "sha": "def456...",
      "url": "https://{FORGEJO_HOST}/api/v1/repos/{owner}/{repo}/git/blobs/{sha}"
    },
    {
      "path": "src",
      "mode": "040000",
      "type": "tree",
      "sha": "ghi789...",
      "url": "https://{FORGEJO_HOST}/api/v1/repos/{owner}/{repo}/git/trees/{sha}"
    }
  ],
  "truncated": false,
  "page": 1,
  "total_count": 42
}
```

---

## Git Notes

### Get Note for Commit

```
GET /api/v1/repos/{owner}/{repo}/git/notes/{sha}
```

```bash
curl -s "${FORGEJO_URL}/api/v1/repos/{owner}/{repo}/git/notes/abc123def456" \
  -H "Authorization: token ${FORGEJO_PAT}"
```

### Create or Update Note

```
POST /api/v1/repos/{owner}/{repo}/git/notes/{sha}
```

```bash
curl -s -X POST "${FORGEJO_URL}/api/v1/repos/{owner}/{repo}/git/notes/abc123def456" \
  -H "Authorization: token ${FORGEJO_PAT}" \
  -H "Content-Type: application/json" \
  -d '{"message": "Reviewed and approved by QA team"}'
```

### Delete Note

```
DELETE /api/v1/repos/{owner}/{repo}/git/notes/{sha}
```

```bash
curl -s -X DELETE "${FORGEJO_URL}/api/v1/repos/{owner}/{repo}/git/notes/abc123def456" \
  -H "Authorization: token ${FORGEJO_PAT}"
```

---

## Language Statistics

### Get Repository Languages

```
GET /api/v1/repos/{owner}/{repo}/languages
```

```bash
curl -s "${FORGEJO_URL}/api/v1/repos/{owner}/{repo}/languages" \
  -H "Authorization: token ${FORGEJO_PAT}"
```

**Response:**

```json
{
  "Go": 45678,
  "JavaScript": 12345,
  "CSS": 6789,
  "HTML": 3456,
  "Shell": 890
}
```

Values are byte counts for each language.

---

## Common Patterns

### Get full file tree for a branch

```bash
# Get the recursive tree to see all files
curl -s "${FORGEJO_URL}/api/v1/repos/{owner}/{repo}/git/trees/{branch_or_sha}?recursive=true" \
  -H "Authorization: token ${FORGEJO_PAT}" \
  | jq '.tree[] | select(.type == "blob") | .path'
```

### Get a file's content by path (via tree + blob)

```bash
# 1. Find the blob SHA from the tree
BLOB_SHA=$(curl -s "${FORGEJO_URL}/api/v1/repos/{owner}/{repo}/git/trees/{branch_or_sha}?recursive=true" \
  -H "Authorization: token ${FORGEJO_PAT}" \
  | jq -r '.tree[] | select(.path == "src/main.go") | .sha')

# 2. Get the blob content
curl -s "${FORGEJO_URL}/api/v1/repos/{owner}/{repo}/git/blobs/${BLOB_SHA}" \
  -H "Authorization: token ${FORGEJO_PAT}" \
  | jq -r '.content' | base64 -d
```

### Get commit history for a specific file

```bash
curl -s "${FORGEJO_URL}/api/v1/repos/{owner}/{repo}/commits?path=src/main.go&stat=true" \
  -H "Authorization: token ${FORGEJO_PAT}" \
  | jq '.[] | {sha: .sha, message: .commit.message, date: .commit.committer.date}'
```
