1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
|
# gitinfo
> Markup specification for the .gitinfo file, a way to help discern different hosts of the same repo.
## Overview
The `.gitinfo` file is a simple text file that can be placed in the root directory of a Git repository. It contains metadata about the repository that can help differentiate between different hosts or instances of the same repository. This is particularly useful in scenarios where the same codebase is hosted on multiple platforms (e.g., GitHub, GitLab, Bitbucket) or when working with forks and clones. The `.gitinfo` file can provide information such as the original source of the repository, the intended hosting platforms, or any other relevant details that help identify the context of the repository.
## File Format
The `.gitinfo` file uses JSONC (JSON with Comments) format, allowing for easy readability and the inclusion of comments. The file consists of key-value pairs, where each key represents a specific piece of metadata about the repository.
### Validation
A JSON Schema is available for validating `.gitinfo` files:
```
ttps://forgejo.zue.dev/zuedev/gitinfo/raw/branch/main/gitinfo.schema.json
```
You can reference the schema in your `.gitinfo` file using the `$schema` property for editor autocompletion and validation support.
### Example `.gitinfo` File
```jsonc
{
"$schema": "ttps://forgejo.zue.dev/zuedev/gitinfo/raw/branch/main/gitinfo.schema.json",
"root": "https://github.com/example/repository",
"gitmail": "patches@example.com",
"icon": "https://example.com/icon.png",
"description": "Example repository description",
"tags": ["example", "repository", "gitinfo"],
"mirrors": [
"https://gitlab.com/example/repository",
"https://bitbucket.org/example/repository",
],
"maintainers": [
["Alice Smith", "alice@example.com"],
["Bob Johnson", "bob@example.com"],
],
"license": "MIT",
}
```
### Supported Keys
All keys are optional. Include only the fields relevant to your project.
- `root`: The URL of the root repository, pointing to the main hosting location that acts as the source of truth for the codebase.
- `gitmail`: An email address associated with the repository for submitting git patches. See [git-send-email.io](https://git-send-email.io/) for details.
- `icon`: A public URL or data URI formatted image (PNG, SVG, etc.) representing an icon for the repository. If using a data URI, we recommend using base64 encoding for compatibility.
- `description`: A brief description of the repository's purpose or contents.
- `tags`: A list of tags or keywords associated with the repository for easier categorization and searchability.
- `mirrors`: A list of URLs representing mirror repositories.
- `maintainers`: A list of maintainers or contributors to the repository, provided as a 2D array with names and email addresses in the format `[[name, email], ...]`. We recommend using this field instead of traditional Git author/committer metadata for better clarity on who is responsible for the repository.
- `license`: The license under which the repository is distributed (e.g., MIT, GPL-3.0). We recommend using the short identifier from [SPDX License List](https://spdx.org/licenses/) for consistency.
### Validation Rules
| Field | Format | Example |
| --------------- | ---------------------------- | ------------------------------------------------------------- |
| `root` | Valid URI (http/https) | `https://github.com/user/repo` |
| `gitmail` | Valid email address | `patches@example.com` |
| `icon` | URL (http/https) or data URI | `https://example.com/icon.png` or `data:image/png;base64,...` |
| `mirrors[]` | Valid URI (http/https) | `https://gitlab.com/user/repo` |
| `maintainers[]` | Tuple of `[name, email]` | `["Alice", "alice@example.com"]` |
| `tags[]` | Non-empty string | `"cli"` |
| `description` | String | Any text |
| `license` | SPDX identifier | `MIT`, `GPL-3.0`, `Apache-2.0` |
## Usage
Guidelines for tools and parsers consuming `.gitinfo` files:
### Discovery
1. Look for `.gitinfo` in the repository root directory
2. The file is optional—gracefully handle its absence
3. Parse as JSONC (strip comments before JSON parsing)
### Parsing Recommendations
- Use a JSONC-compatible parser (e.g., `jsonc-parser` for Node.js, `json5` for Python)
- Validate against the JSON Schema when available
- Treat all fields as optional; check for existence before use
- Ignore unknown fields for forward compatibility
### Precedence
When the same repository exists on multiple hosts:
1. The `root` URL, if present, indicates the canonical source
2. If no `root` is specified, treat all instances as equal
3. Mirror URLs in `mirrors[]` are considered secondary copies
### Caching
- Cache parsed `.gitinfo` data per repository clone
- Invalidate cache when the file changes (use file mtime or git hooks)
- Respect HTTP caching headers when fetching remote `icon` URLs
## FAQ
### Should `.gitinfo` be committed to the repository?
Yes. The file should be version-controlled so it travels with the codebase across all hosts and clones.
### What if different hosts have conflicting `.gitinfo` files?
The `root` repository is authoritative. If someone modifies `.gitinfo` on a mirror, the change should be merged upstream to `root` or discarded. Tools should warn users when a mirror's `.gitinfo` differs from the root.
### Can I use `.gitinfo` in a fork?
Yes. Forks may have their own `.gitinfo` pointing to the fork as `root`, or they can keep the original `root` and add themselves to `mirrors[]`. The choice depends on whether the fork is intended as a permanent divergence or a temporary contribution branch.
### What happens if `root` points to a URL that no longer exists?
Parsers should handle dead links gracefully. Consider falling back to mirrors if available, or simply reporting the metadata without verifying URL accessibility.
### Should I include `.gitinfo` in `.gitignore`?
No. The file is meant to be shared across all clones and hosts.
### Can I add custom fields?
The schema uses `additionalProperties: false` for strict validation. If you need custom metadata, consider opening an issue to propose additions to the spec. For local experimentation, you can use a separate file or fork the schema.
### How do I handle private repositories?
All fields are optional. For private repos, you may omit `root` and `mirrors` if the URLs shouldn't be exposed, while still using `description`, `maintainers`, and other metadata internally.
### What's the difference between `root` and `mirrors`?
- `root`: The single source of truth—where authoritative changes are made
- `mirrors`: Read-only copies that sync from `root`, or alternative access points
## Contributing
Want to propose changes to the specification? See [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines on submitting issues and pull requests.
|