Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,31 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [Unreleased]

### Added

- URL templates in the git config (`gitweb.<host>.branch-template`,
`tag-template`, `commit-template` and `merge-request-template`) to open the
repositories of self-hosted forges like Bitbucket Server (#55)
- codeberg.org as a known host, with the URLs of Gitea

### Changed

- gitlab.com opens its own URLs (`/-/tree/`, `/-/commit/`) and gitea.com its
own (`/src/branch/`, `/src/tag/`) instead of the GitHub ones
- gitea.com is the known host of Gitea instead of gitea.io, which only
redirects to gitea.com
- the merge requests URLs no longer end with a slash, but on bitbucket.org
where it is the canonical URL

### Fixed

- a repository with `.git` in its name, like `user.github.io`, is no longer
opened as `userhub.io`
- `--merge-request` on an unknown host exits with the code 7 instead of
panicking

## 0.5.0 - 2026-10-21

### Added
Expand Down
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ git-url-parse = "0.6"
git2 = { version = "0.21", features = ["vendored-openssl"] }
log = "0.4"
open = "5.4"
percent-encoding = "2.3"
thiserror = "2.0"

[dev-dependencies]
Expand Down
71 changes: 71 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -107,3 +107,74 @@ custom branch or tag you want to open in the browser.

`gitweb` will open the origin remote if it exists. You can override the behavior
by giving the `--remote` flag with the custom remote you want to open.

The remote is the name of one of the git remotes of the repository (`git remote`
lists them, usually `origin`, and `upstream` when working on a fork). It does
not change the shape of the URL that is opened, see [Custom URLs](#custom-urls)
for that.

## Custom URLs

`gitweb` knows the URLs of github.com, gitlab.com, bitbucket.org, gitea.com and
codeberg.org, and opens GitHub-like URLs for every other host (except for the
merge requests, which need a template). For a self-hosted forge with other URLs, set
URL templates for its host in your git config:

```shell
git config --global gitweb.<host>.branch-template '<template>'
git config --global gitweb.<host>.tag-template '<template>'
git config --global gitweb.<host>.commit-template '<template>'
git config --global gitweb.<host>.merge-request-template '<template>'
```

Here is the configuration for a Bitbucket Server (or Data Center), that works
with both the SSH and the HTTPS remotes:

```shell
git config --global gitweb.bitbucket.company.com.branch-template 'https://{host}/projects/{owner}/repos/{repo}/browse?at=refs%2Fheads%2F{branch_encoded}'
git config --global gitweb.bitbucket.company.com.tag-template 'https://{host}/projects/{owner}/repos/{repo}/browse?at=refs%2Ftags%2F{tag_encoded}'
git config --global gitweb.bitbucket.company.com.commit-template 'https://{host}/projects/{owner}/repos/{repo}/commits/{commit}'
git config --global gitweb.bitbucket.company.com.merge-request-template 'https://{host}/projects/{owner}/repos/{repo}/pull-requests'
```

A self-hosted GitLab has the URLs of gitlab.com, which are the built-in ones:

```shell
git config --global gitweb.gitlab.company.com.branch-template 'https://{host}/{repository}/-/tree/{branch}'
git config --global gitweb.gitlab.company.com.tag-template 'https://{host}/{repository}/-/tree/{tag}'
git config --global gitweb.gitlab.company.com.commit-template 'https://{host}/{repository}/-/commit/{commit}'
git config --global gitweb.gitlab.company.com.merge-request-template 'https://{host}/{repository}/-/merge_requests'
```

And a self-hosted Gitea or Forgejo has the URLs of gitea.com and codeberg.org:

```shell
git config --global gitweb.gitea.company.com.branch-template 'https://{host}/{repository}/src/branch/{branch}'
git config --global gitweb.gitea.company.com.tag-template 'https://{host}/{repository}/src/tag/{tag}'
git config --global gitweb.gitea.company.com.commit-template 'https://{host}/{repository}/commit/{commit}'
git config --global gitweb.gitea.company.com.merge-request-template 'https://{host}/{repository}/pulls'
```

The placeholders of the templates are:

| Placeholder | Template | Value |
| ------------------ | ----------------- | ------------------------------------------------------ |
| `{host}` | all | the host of the remote, without the port |
| `{repository}` | all | the path of the repository, like `group/subgroup/repo` |
| `{owner}` | all | the part of the path just before the repository name |
| `{repo}` | all | the repository name |
| `{branch}` | `branch-template` | the branch |
| `{branch_encoded}` | `branch-template` | the branch, percent-encoded (`/` becomes `%2F`) |
| `{tag}` | `tag-template` | the tag |
| `{tag_encoded}` | `tag-template` | the tag, percent-encoded (`/` becomes `%2F`) |
| `{commit}` | `commit-template` | the commit |

Write `{{` for a `{` that is not a placeholder. A template is a full URL, so it
can use `http://` or a port. The host is the one written in the remote: with an
SSH alias (`git@work:org/repo.git`), the config is `gitweb.work.*` and the
template has to contain the real host instead of `{host}`.

A template always wins over the built-in URL, even for github.com, and the
built-in URL is used when no template is set for what is opened. The templates
can be set per repository with `git config --local`. Run `gitweb --verbose` to
see the template that is used.
Loading
Loading