Working with repositories
- Tags and Releases
- Branch and tag protection
- Blame File View
- README badges
- Issue and Pull Request Templates
- Merge Message Templates
- Webhooks
- Programming language detection
Tags and Releases
What are tags?
What are releases?
Releases are a feature in Forgejo, independent of Git, that allows you to attach files and release notes along with the source code at the time, and share it in Forgejo, linking to a Git tag.
Wait, what is the difference between tags and releases?
They are very similar. The difference is that tags are just the repository frozen in time and are part of Git (you can make a tag inside of Git), but releases are tags accompanied by a binary file and are not part of Git (you need to go to your repository page in the web interface to create a release).
Creating tags and releases
If you only want to create tags, using Git is recommended. If you want to create a full release, this is only possible through Forgejo's web interface, or through its API.
Creating a Tag with Git
To create a tag using Git, use the following command in your local repository:
git tag -a <tag name> -m "<my tag message>"
You can omit "<my tag message>" to write a longer tag message in an editor
window.
git push --tags <remote target, probably "origin">
git push <remote target, probably "origin"> <tag name, e.g., "v1.2.3">
Creating a Release in the Web Interface
To create a release in the web interface, first go to the Releases tab of your
repository (1), and click on New Release (2):
Here, you need to enter a version number for your new release (1), select the
branch that contains the code you want to release (2), and add a title (3).
Optionally, you can also add a description (4) or add assets to the release in
the form of attaching files (5) or adding external links (6):
You can now either save it as a draft, or publish the release outright.
You are then redirected to the Releases tab of your repository. The newly
created release is now listed there:
Here, you can edit the release if needed (1). You will also see options to
download the source code of the repository at the commit the release was created
at as .zip or .tar.gz files (2). Finally, if on the previous page you
added assets like an attached file or an external link, they will also show up
here (3).
Creating a Release through the API
All the operations accessible in the web interface are also available through the API. You can use the following endpoints to:
/repos/{owner}/{repo}/releases
Create (or modify) a release/repos/{owner}/{repo}/releases/{id}/assets
Create (or modify) release assets
Branch and tag protection
Protected branches
Protected branches enforce restrictions such as force pushing or merging unless a given number of approvals are obtained on a pull request.
To protect a branch, you need to go to the repository’s Settings > Branches page and add a new rule.
The name of the branch can be a glob where / is the separator and **
spans across separators, for instance main, release/** or precious*.
If two rules apply to the same branch, the one that has no glob takes precedence.
Protected tags
Setting up protected tags
To protect a tag, you need to follow these steps:
- Go to the repository’s Settings > Tags page.
- Type a pattern to match a name. You can use a single name, a glob pattern or a regular expression.
- Choose the allowed users and/or teams. If you leave these fields empty, no one is allowed to create or modify this tag.
- Select Save to save the configuration.
Protected tag patterns
The pattern uses glob or regular expressions to match a tag name. For regular expressions, you need to enclose the pattern in slashes.
Examples:
| Type | Protected tag pattern | Possible matching tags |
|---|---|---|
| Glob | v* |
v, v-1, version2 |
| Glob | v[0-9] |
v0, v1 up to v9 |
| Glob | *-release |
2.1-release, final-release |
| Glob | forgejo |
only forgejo |
| Glob | *forgejo* |
forgejo, 2.1-forgejo, 1_forgejo-r |
| Glob | {v,rel}-* |
v-, v-1, v-final, rel-, rel-x |
| Glob | * |
matches all possible tag names |
| Regex | /\Av/ |
v, v-1, version2 |
| Regex | /\Av[0-9]\z/ |
v0, v1 up to v9 |
| Regex | /\Av\d+\.\d+\.\d+\z/ |
v1.0.17, v2.1.0 |
| Regex | /\Av\d+(\.\d+){0,2}\z/ |
v1, v2.1, v1.2.34 |
| Regex | /-release\z/ |
2.1-release, final-release |
| Regex | /forgejo/ |
forgejo, 2.1-forgejo, 1_forgejo-r |
| Regex | /\Aforgejo\z/ |
only forgejo |
| Regex | /^forgejo$/ |
only forgejo |
| Regex | /\A(v|rel)-/ |
v-, v-1, v-final, rel-, rel-x |
| Regex | /.+/ |
matches all possible tag names |
Blame File View
Forgejo supports viewing the line-by-line revision history for a file, also known as blame view.
You can also use git blame on the command line to view the revision history of lines within a file.
Ignore commits in the blame view
All revisions specified in the .git-blame-ignore-revs file are hidden from the blame view.
This is especially useful to hide reformatting changes and keep the benefits of git blame.
Lines that were changed or added by an ignored commit will be blamed on the previous commit that changed that line or nearby lines.
The .git-blame-ignore-revs file must be located in the root directory of the repository.
For more information, like the file format, see the git blame --ignore-revs-file documentation.
Bypassing .git-blame-ignore-revs in the blame view
If the blame view for a file shows a message about ignored revisions, you can see the normal blame view by appending the URL parameter ?bypass-blame-ignore=true.
README badges
If the badges service is enabled, Forgejo makes it possible to add badges - transparently generated by a service like shields.io - to your READMEs and other documentation. These badges let you display useful information about your repository within documentation that might also be displayed elsewhere, outside of the forge itself (such as on container information pages, library documentation sites, and so on). Information such as the latest release, stars, pull request and issue information, or Actions workflow statuses.
The badges are returned in SVG format and are available under the https://forgejo.example.com/{username}/{repository}/badges path. Forgejo currently supports generating the following badges:
/release.svg: The latest release made in the repository./stars.svg: The number of stars the repository has./issues.svg: The total number of issues in the repository, open and closed combined./issues/open.svg: The number of open issues./issues/closed.svg: The number of closed issues./pulls.svg: The number of pull requests against the repository, open and closed combined./pulls/open.svg: The number of open pull requests./pulls/closed.svg: The number of closed pull requests./workflows/{workflow_file}/badge.svg: The status of the{workflow_file}workflow. Additional restrictions can be given for this badge by using thebranchand/oreventquery parameters. Thebranchquery parameter will display the status of the workflow from the given branch (defaulting to the repository's main branch if not explicitly specified), while theeventparameter will only display results if a run was triggered by the specified event.
All query parameters not known to Forgejo will be passed along to the badge generator service as is. If using the default - shields.io-based - generator, this means that query parameters such as style and color will be respected.
Issue and Pull Request Templates
Some projects have a standard list of questions that users need to answer when creating an issue or pull request. Forgejo supports adding templates to the default branch of the repository so that they can autopopulate the form when users are creating issues and pull requests. This will cut down on the initial back-and-forth of getting some clarifying details. It is currently not possible to provide generic issue/pull-request templates globally. In general, there is the choice of using either multiple or a single issue template file(s), a single pull-request template file and additionally the possibility of adding an issue config.
Additionally, the New Issue page URL can be suffixed with ?title=Issue+Title&body=Issue+Text and the form will be populated with those strings. Those strings will be used instead of the template if there is one.
Directory names
Users can create multiple template files inside a special directory and this allows different use cases: users can choose to use the template that is suited to address their specific problem. Please note that there can be multiple issue templates. However, there may only be a single pull request template in one repository.
Forgejo will check for template files in the following directories, since Forgejo checks these services to make migration from them easier:
.forgejo.gitea.githubdocs
Inside the directory can be multiple markdown (.md) or yaml (.yaml/.yml) files for templates of the form - these are the three allowed file extensions.
File names
For the three file types - issue templates, pull request templates, and issue configs, there are various possible file names that may be used in the directories listed above.
Issue templates are arbitrarily named files with any of the three file extensions mentioned above, and there may be any number of them, so they each get their dedicated subdirectory: issue_template and ISSUE_TEMPLATE are the possible names for the subdirectory that the issue templates go into.
In contrast, there may only be a single pull request template per repository, so there is no extra subdirectory for it. It can reside in any of the .<service_name> directories (with the exception of the .gitlab directory, this is not supported!) listed in the previous section. A pull request template has a fixed name (see options below) and can end with any of the three file extensions mentioned above.
Possible file names and file extensions for PR templates:
PULL_REQUEST_TEMPLATE.mdPULL_REQUEST_TEMPLATE.yamlPULL_REQUEST_TEMPLATE.ymlpull_request_template.mdpull_request_template.yamlpull_request_template.yml
Issue config template files need to go into the same subdirectory as issue template files (see above section). Possible file names and file extensions for issue config:
config.yamlconfig.yml
An example setup for a single issue template file together with a single pull request template file could look like this:
.forgejo/
ISSUE_TEMPLATE/
issue_template.yaml
pull_request_template.yml
Another example setup but with multiple issue template files instead could look like this:
.forgejo/
issue_template/
bug.yaml
config.yml
feature.yaml
pull_request_template.md
Syntax for markdown template
---
name: 'Template Name'
about: 'This template is for testing!'
title: '[TEST] '
ref: 'main'
labels:
- bug
- 'help needed'
---
This is the template!
In the above example, when a user is presented with the list of issues they can submit, this would show as Template Name with the description
This template is for testing!. When submitting an issue with the above example, the issue title would be pre-populated with
[TEST] while the issue body would be pre-populated with This is the template!. The issue would also be assigned two labels,
bug and help needed, and the issue will have a reference to main.
Syntax for yaml template
This example YAML configuration file defines an issue form using several inputs to report a bug.
name: Bug Report
about: File a bug report
title: '[Bug]: '
ref: 'main'
labels:
- bug
- 'help needed'
body:
- type: markdown
attributes:
value: |
Thanks for taking the time to fill out this bug report!
# some markdown that will only be visible once the issue has been created
- type: markdown
attributes:
value: |
This issue was created by an issue **template** :)
visible: [content]
- type: input
id: contact
attributes:
label: Contact Details
description: How can we get in touch with you if we need more info?
placeholder: ex. email@example.com
validations:
required: false
- type: textarea
id: what-happened
attributes:
label: What happened?
description: Also tell us, what did you expect to happen?
placeholder: Tell us what you see!
value: 'A bug happened!'
validations:
required: true
- type: dropdown
id: version
attributes:
label: Version
description: What version of our software are you running?
options:
- 1.0.2 (Default)
- 1.0.3 (Edge)
validations:
required: true
- type: dropdown
id: browsers
attributes:
label: What browsers are you seeing the problem on?
multiple: true
options:
- Firefox
- Chrome
- Safari
- Microsoft Edge
- type: textarea
id: logs
attributes:
label: Relevant log output
description: Please copy and paste any relevant log output. This will be automatically formatted into code, so no need for backticks.
render: shell
- type: checkboxes
id: terms
attributes:
label: Code of Conduct
description: By submitting this issue, you agree to follow our [Code of Conduct](https://example.com)
options:
- label: I agree to follow this project's Code of Conduct
required: true
- label: I have also read the CONTRIBUTION.MD
required: true
visible: [form]
- label: This is a TODO only visible after issue creation
visible: [content]
Markdown
You can use a markdown element to display Markdown in your form that provides extra context to the user, but is not submitted by default.
Attributes:
| Key | Description | Required | Type | Default | Valid values |
|---|---|---|---|---|---|
| value | The text that is rendered. Markdown formatting is supported. | Required | String | - | - |
visible: Default is [form]
Textarea
You can use a textarea element to add a multi-line text field to your form. Contributors can also attach files in textarea fields.
Attributes:
| Key | Description | Required | Type | Default | Valid values |
|---|---|---|---|---|---|
| label | A brief description of the expected user input, which is also displayed in the form. | Required | String | - | - |
| description | A description of the text area to provide context or guidance, which is displayed in the form. | Optional | String | Empty String | - |
| placeholder | A semi-opaque placeholder that renders in the text area when empty. | Optional | String | Empty String | - |
| value | Text that is pre-filled in the text area. | Optional | String | - | - |
| render | If a value is provided, submitted text will be formatted into a codeblock. When this key is provided, the text area will not expand for file attachments or Markdown editing. | Optional | String | - | Languages known to Forgejo. |
Validations:
| Key | Description | Required | Type | Default | Valid values |
|---|---|---|---|---|---|
| required | Prevents form submission until element is completed. | Optional | Boolean | false | - |
visible: Default is [form, content]
Input
You can use an input element to add a single-line text field to your form.
Attributes:
| Key | Description | Required | Type | Default | Valid values |
|---|---|---|---|---|---|
| label | A brief description of the expected user input, which is also displayed in the form. | Required | String | - | - |
| description | A description of the field to provide context or guidance, which is displayed in the form. | Optional | String | Empty String | - |
| placeholder | A semi-transparent placeholder that renders in the field when empty. | Optional | String | Empty String | - |
| value | Text that is pre-filled in the field. | Optional | String | - | - |
Validations:
| Key | Description | Required | Type | Default | Valid values |
|---|---|---|---|---|---|
| required | Prevents form submission until element is completed. | Optional | Boolean | false | - |
| is_number | Prevents form submission until element is filled with a number. | Optional | Boolean | false | - |
| regex | Prevents form submission until element is filled with a value that match the regular expression. | Optional | String | - | a regular expression |
visible: Default is [form, content]
Dropdown
You can use a dropdown element to add a dropdown menu in your form.
Attributes:
| Key | Description | Required | Type | Default | Valid values |
|---|---|---|---|---|---|
| label | A brief description of the expected user input, which is displayed in the form. | Required | String | - | - |
| description | A description of the dropdown to provide extra context or guidance, which is displayed in the form. | Optional | String | Empty String | - |
| multiple | Determines if the user can select more than one option. | Optional | Boolean | false | - |
| options | An array of options the user can choose from. Cannot be empty and all choices must be distinct. | Required | String array | - | - |
Validations:
| Key | Description | Required | Type | Default | Valid values |
|---|---|---|---|---|---|
| required | Prevents form submission until element is completed. | Optional | Boolean | false | - |
visible: Default is [form, content]
Checkboxes
You can use the checkboxes element to add a set of checkboxes to your form.
Attributes:
| Key | Description | Required | Type | Default | Valid values |
|---|---|---|---|---|---|
| label | A brief description of the expected user input, which is displayed in the form. | Required | String | - | - |
| description | A description of the set of checkboxes, which is displayed in the form. Supports Markdown formatting. | Optional | String | Empty String | - |
| options | An array of checkboxes that the user can select. For syntax, see below. | Required | Array | - | - |
For each value in the options array, you can set the following keys.
| Key | Description | Required | Type | Default | Options |
|---|---|---|---|---|---|
| label | The identifier for the option, which is displayed in the form. Markdown is supported for bold or italic text formatting, and hyperlinks. | Required | String | - | - |
| required | Prevents form submission until element is completed. | Optional | Boolean | false | - |
| visible | Whether a specific checkbox appears in the form only, in the created issue only, or both. Valid options are "form" and "content". | Optional | String array | false | - |
visible: Default is [form, content]
Syntax for issue config
This is an example for an issue config file
blank_issues_enabled: true
contact_links:
- name: Forgejo
url: https://forgejo.org/
about: Visit the Forgejo Website
Possible Options
| Key | Description | Type | Default |
|---|---|---|---|
| blank_issues_enabled | If set to false, the user is forced to use a template | Boolean | true |
| contact_links | Custom links to show in the choose box | Contact Link Array | Empty Array |
Contact Link
| Key | Description | Type | Required |
|---|---|---|---|
| name | the name of your link | String | true |
| url | The URL of your link | String | true |
| about | A short description of your link | String | true |
Merge Message Templates
File Names
Possible file names for PR (Pull Request) default merge message templates:
.forgejo/default_merge_message/MERGE_TEMPLATE.md.forgejo/default_merge_message/REBASE_TEMPLATE.md.forgejo/default_merge_message/REBASE-MERGE_TEMPLATE.md.forgejo/default_merge_message/SQUASH_TEMPLATE.md.forgejo/default_merge_message/MANUALLY-MERGED_TEMPLATE.md.forgejo/default_merge_message/REBASE-UPDATE-ONLY_TEMPLATE.md
Note: .gitea as the root directory is also recognized and kept only for compatibility reasons.
If Forgejo cannot find the file in the repository, it will search the CustomPath for a folder named default_merge_message which may contain site-wide templates.
Title/Body separation
The first line of the template creates the title, the rest makes the body of the message. Without a template, the default texts are:
- Title :
Merge pull request '[PR title]' ([PR reference]) from [head branch] into [base branch]. - Body :
Reviewed-on: [PR url].
You can customize the title and body of the default message following these rules:
- To replace each of those sections the first line of the template is used to replace the title and other lines the body.
- For the title, leading and trailing whitespace is trimmed
- For the body, trailing whitespace is trimmed from the last line
- If only the title is meant to be changed a single-line template can be used.
- To keep the default title but change the default body the template needs to start with a newline
\ncharacter. - To remove the default title (make it empty) any white-space character can be inserted in the first line of the template, as white spaces are trimmed.
Examples
Replace the default title and keep the default body:
Merge Title
Replace the default title and make the default body empty:
Merge Title\n
Keep the default title and replace the default body:
\n
Merge Body
The space in the first line makes the default title empty and replace the default body:
\n
Merge body
Variables
You can use the following variables enclosed in ${} inside these templates, which follow os.Expand syntax:
- BaseRepoOwnerName: Base repository owner name of this pull request
- BaseRepoName: Base repository name of this pull request
- BaseBranch: Base repository target branch name of this pull request
- HeadRepoOwnerName: Head repository owner name of this pull request
- HeadRepoName: Head repository name of this pull request
- HeadBranch: Head repository branch name of this pull request
- PullRequestTitle: Pull request's title
- PullRequestDescription: Pull request's description
- PullRequestPosterName: Pull request's poster name
- PullRequestIndex: Pull request's index number
- PullRequestReference: Pull request's reference character with index number, i.e., #1, !2
- ClosingIssues: A string containing all issues that will be closed by this pull request, i.e.,
close #1, close #2 - ReviewedOn: A string containing
Reviewed-on: <link>with the link to the pull request - ReviewedBy: Lines containing
Reviewed-by: <username> <<email>>with the names and emails of the reviewers
Rebase
When rebasing without a merge commit, REBASE_TEMPLATE.md modifies the message of the last commit. The following additional variables are available in this template:
- CommitTitle: Commit's title
- CommitBody: Commit's body text
Webhooks
Forgejo supports webhooks for repository events. This can be configured on the settings
page /:username/:reponame/settings/hooks by a repository admin. Webhooks can also be configured on a per-organization and whole-system basis (default webhooks on repository creation or instance-wide webhooks).
The currently supported webhook types are:
Raw event as JSON or FORM payload:
- Forgejo (GET or POST)
- Gitea (GET or POST)
- Gogs (POST)
Dedicated integration:
- Packagist: ask Packagist to refresh the given package
- SourceHut Builds: submit build manifests (only on push)
Generic notification messages in chosen channel/chat:
- Matrix
- Slack
- Discord
- Dingtalk
- Telegram
- Microsoft Teams
- Feishu / Lark Suite
- WeCom (Wechat Work)
These channels don't implement all webhook types. Those types that are implemented have to be manually tested. Try them and open an issue if they do not work for your use case.
Event information
The following is an example of event information that will be sent by Forgejo to a Payload URL:
X-Forgejo-Delivery: f6266f16-1bf3-46a5-9ea4-602e06ead473
X-Forgejo-Event: push
X-GitHub-Delivery: f6266f16-1bf3-46a5-9ea4-602e06ead473
X-GitHub-Event: push
X-Gogs-Delivery: f6266f16-1bf3-46a5-9ea4-602e06ead473
X-Gogs-Event: push
X-Gitea-Delivery: f6266f16-1bf3-46a5-9ea4-602e06ead473
X-Gitea-Event: push
{
"ref": "refs/heads/develop",
"before": "28e1879d029cb852e4844d9c718537df08844e03",
"after": "bffeb74224043ba2feb48d137756c8a9331c449a",
"compare_url": "http://localhost:3000/forgejo/webhooks/compare/28e1879d029cb852e4844d9c718537df08844e03...bffeb74224043ba2feb48d137756c8a9331c449a",
"commits": [
{
"id": "bffeb74224043ba2feb48d137756c8a9331c449a",
"message": "Webhooks Yay!",
"url": "http://localhost:3000/forgejo/webhooks/commit/bffeb74224043ba2feb48d137756c8a9331c449a",
"author": {
"name": "Forgejo",
"email": "someone@forgejo.org",
"username": "forgejo"
},
"committer": {
"name": "Forgejo",
"email": "someone@forgejo.org",
"username": "forgejo"
},
"timestamp": "2017-03-13T13:52:11-04:00"
}
],
"repository": {
"id": 140,
"owner": {
"id": 1,
"login": "forgejo",
"full_name": "Forgejo",
"email": "someone@forgejo.org",
"avatar_url": "https://localhost:3000/avatars/1",
"username": "forgejo"
},
"name": "webhooks",
"full_name": "forgejo/webhooks",
"description": "",
"private": false,
"fork": false,
"html_url": "http://localhost:3000/forgejo/webhooks",
"ssh_url": "ssh://forgejo@localhost:2222/forgejo/webhooks.git",
"clone_url": "http://localhost:3000/forgejo/webhooks.git",
"website": "",
"stars_count": 0,
"forks_count": 1,
"watchers_count": 1,
"open_issues_count": 7,
"default_branch": "master",
"created_at": "2017-02-26T04:29:06-05:00",
"updated_at": "2017-03-13T13:51:58-04:00"
},
"pusher": {
"id": 1,
"login": "forgejo",
"full_name": "Forgejo",
"email": "someone@forgejo.org",
"avatar_url": "https://localhost:3000/avatars/1",
"username": "forgejo"
},
"sender": {
"id": 1,
"login": "forgejo",
"full_name": "Forgejo",
"email": "someone@forgejo.org",
"avatar_url": "https://localhost:3000/avatars/1",
"username": "forgejo"
}
}
Example
This is an example of how to use webhooks to run a PHP script upon push requests to the repository. In your repository Settings, under Webhooks, set up a Forgejo webhook as follows:
- Target URL: http://example.com/webhook.php
- HTTP Method: POST
- POST Content Type: application/json
- Secret: 123
- Trigger On: Push Events
- Active: Checked
Now, on your server, create the PHP file webhook.php.
<?php
$secret_key = '123';
// check for POST request
if ($_SERVER['REQUEST_METHOD'] != 'POST') {
error_log('FAILED - not POST - '. $_SERVER['REQUEST_METHOD']);
exit();
}
// get content type
$content_type = isset($_SERVER['CONTENT_TYPE']) ? strtolower(trim($_SERVER['CONTENT_TYPE'])) : '';
if ($content_type != 'application/json') {
error_log('FAILED - not application/json - '. $content_type);
exit();
}
// get payload
$payload = trim(file_get_contents("php://input"));
if (empty($payload)) {
error_log('FAILED - no payload');
exit();
}
// get header signature
$header_signature = isset($_SERVER['HTTP_X_FORGEJO_SIGNATURE']) ? $_SERVER['HTTP_X_FORGEJO_SIGNATURE'] : '';
if (empty($header_signature)) {
error_log('FAILED - header signature missing');
exit();
}
// calculate payload signature
$payload_signature = hash_hmac('sha256', $payload, $secret_key, false);
// check payload signature against header signature
if ($header_signature !== $payload_signature) {
error_log('FAILED - payload signature');
exit();
}
// convert json to array
$decoded = json_decode($payload, true);
// check for json decode errors
if (json_last_error() !== JSON_ERROR_NONE) {
error_log('FAILED - json decode - '. json_last_error());
exit();
}
// success, do something
There is a Test Delivery button in the webhook settings that allows testing the configuration as well as a list of the most Recent Deliveries.
Authorization header
Forgejo webhooks can be configured to send an authorization header to the target.
The authentication string is stored encrypted in the database.
Programming language detection
Forgejo tries to detect the languages used in a repository, for each file, to use this information in a number of different ways. The most prominent use is for the display of the language statistics line at the top of the repository's home view, but the same information is also used to exclude generated and vendored files from diffs.
This comes with sensible defaults that should work for most cases, but it is not without faults or compromises, and there are scenarios where the detection needs a little guidance. Further below, we will explain how it can be influenced, but let's look at the defaults first!
Built-in language detection
Whenever the contents of a repository change, Forgejo will look at the files, and try to put them into one of the following categories: "Programming language", "Markup language", "Documentation", "Dotfile", "Configuration", "Generated", "Vendored". The sorting into categories is done by the go-enry package, please consult its documentation for the specifics. The library is mostly compatible with linguist, which is used by some other forges. The statistics are calculated based on the main branch of the repository, only update when the main branch changes, and the update may take some time.
For the repository language statistics, with the default configuration, only those files are considered that match the "Programming language" or "Markup" language categories, everything else is ignored. When viewing a diff, all files are shown, but "Generated" files are collapsed by default, and "Vendored" files are marked as such.
A short explanation of categories
While some of the categories are rather straightforward, a little explanation about them does not hurt, especially if you are considering reclassifying files into another category.
Vendored files are any file you have checked into your repository that you didn't write, but imported from elsewhere. These may include dependencies you want a local copy of, at a specific version - such as JavaScript libraries or Go packages. These may inflate your project's language stats, and may even cause it to be labeled as another language. Marking these files as vendored makes it possible to ignore them for statistics.
Generated files are - as the name implies - files that are generated, but still checked into the repository for one reason or another. These may include minified JavaScript, compiled CoffeeScript, various lock files, and so on. Similar to vendored files, you usually do not want these to show up in language stats. They're - unlike vendored files - hidden by default when viewing diffs.
Documentation are just as the name says, documentation. This includes files written in Markdown, AsciiDoc, Org Mode, and a number of others.
Configuration files are typically used to configure software, and as such, the category is not included in language statistics. Languages like JSON, TOML, YAML, SQL, and XML - among other things - are considered documentation by default.
Dotfiles are files whose name starts with a dot, which by convention, suggests they should be hidden, and as such, they are excluded from language statistics.
Programming languages and Markup languages are more or less self-explanatory. The former category includes languages like C, Go, Rust, JavaScript, and many, many others. Markup languages are CSS, HTML, Jinja templates, Jupyter Notebooks, and numerous other formats.
Please consult the enry or linguist documentation for more details.
Adjusting the language detection
Sometimes the programming language of a file is not recognized properly, or it is miscategorized. Forgejo provides a mechanism where the language detection can be told about the language of a file, and its category can be adjusted as well. The same mechanism can also force a file to be considered for language statistics, regardless of its category - or the opposite, too: to tell Forgejo never to consider it.
The way to do this is via a .gitattributes file. This file has a simple syntax where each line is made up of a pattern, followed by a space separated list of attributes. There are many attributes that git itself supports, but we're only going to talk about the custom attributes for language detection. All of these have a linguist- prefix, as that is where they originate from.
Overriding the language
In case Forgejo does not correctly recognize a file's language, you can use the linguist-language attribute to override its detection. The language names are case-insensitive, and may be specified using an alias. Spaces within language names must be replaced with hyphens.
An example showing these overrides:
# Reclassify `.pl` files as Prolog
*.pl linguist-language=Prolog
# Whitespace in language names must be replaced with hyphens
*.glyphs linguist-language=OpenStep-Property-List
# Language names are case-insensitive, and may be specified using an alias.
# All of the following three lines are equivalent:
*.es linguist-language=js
*.es linguist-language=JS
*.es linguist-language=JavaScript
Overriding the category
It is possible to mark files matching a pattern as "Documentation", "Generated", or "Vendored". This can be useful when the automatic detection of these fail, or if you want to reclassify files for some other reason. It is also possible to reclassify files that would be considered either of these, as not being "Documentation", "Generated", or "Vendored".
To achieve this, the linguist-documentation, linguist-generated, and linguist-vendored attributes can be used. All three of these are boolean, you can set them simply by listing the attribute name. You can also set an explicit value by setting them to true or false. Prefixing the attribute with a minus sign is the same as setting it to false.
It's best to illustrate this with a few examples!
# Do not consider Markdown files documentation anymore!
# Note: Both forms here are equivalent.
*.md -linguist-documentation
*.md linguist-documentation=false
# Consider files in `dist/` generated.
# Both forms here are equivalent.
/dist/**/* linguist-generated
/dist/**/* linguist-generated=true
# Do not categorize `cpplint.py` as vendored.
cpplint.py -linguist-vendored
cpplint.py linguist-vendored=false
Reclassifying a file will result in Forgejo proceeding with language detection. That may still result in the file not being considered for statistics. Take a look at this example:
*.nib -linguist-generated
*.nib linguist-language=Markdown
This will classify *.nib files as non-generated, and as Markdown. However, Markdown is considered documentation, which is, by default, excluded from language statistics.
Overriding detection
In cases where a file should be considered for language statistics, regardless of its category, the linguist-detectable attribute can be used. The same attribute can be used to hide a file from the language statistics, without reclassifying it into a category that would otherwise be hidden.
For a repository whose primary contents are documentation in Markdown format, the following override would make Forgejo consider the Markdown files for the language statistics:
*.md linguist-detectable
Similarly, to hide a file from the language statistics:
config/app.js -linguist-detectable
The above will not consider the app's configuration - in JSON, but with a .js extension - for language statistics.