Git with a cup of tea, painless self-hosted git service



Gitea - Git with a cup of tea

View the chinese version of this document


The goal of this project is to make the easiest, fastest, and most painless way of setting up a self-hosted Git service. Using Go, this can be done with an independent binary distribution across all platforms which Go supports, including Linux, macOS, and Windows on x86, amd64, ARM and PowerPC architectures. Want to try it before doing anything else? Do it with the online demo! This project has been forked from Gogs since 2016.11 but changed a lot.


From the root of the source tree, run:

TAGS="bindata" make build

or if sqlite support is required:

TAGS="bindata sqlite sqlite_unlock_notify" make build

The build target is split into two sub-targets:

  • make backend which requires Go 1.13 or greater.
  • make frontend which requires Node.js 10.13 or greater.

If pre-built frontend files are present it is possible to only build the backend:

TAGS="bindata" make backend

Parallelism is not supported for these targets, so please don't include -j <num>.

More info:


./gitea web

NOTE: If you're interested in using our APIs, we have experimental support with documentation.


Expected workflow is: Fork -> Patch -> Push -> Pull Request


  2. If you have found a vulnerability in the project, please write privately to [email protected]. Thanks!

Further information

For more information and instructions about how to install Gitea, please look at our documentation. If you have questions that are not covered by the documentation, you can get in contact with us on our Discord server or create a post in the discourse forum.

We maintain a list of Gitea-related projects at gitea/awesome-gitea.
The hugo-based documentation theme is hosted at gitea/theme.
The official Gitea CLI is developed at gitea/tea.



Thank you to all our backers! 🙏 [Become a backer]


Support this project by becoming a sponsor. Your logo will show up here with a link to your website. [Become a sponsor]


How do you pronounce Gitea?

Gitea is pronounced /ɡɪ’ti:/ as in "gi-tea" with a hard g.

Why is this not hosted on a Gitea instance?

We're working on it.


This project is licensed under the MIT License. See the LICENSE file for the full license text.


Looking for an overview of the interface? Check it out!

Dashboard User Profile Global Issues
Branches Web Editor Activity
New Migration Migrating Pull Request View
Pull Request Dark Diff Review Dark Diff Dark
  • Kanban board

    Kanban board


    • [x] Move Issues between Boards
    • [x] add Project to current Issue
    • [x] view project
    • [x] create a project
    • [x] create Issue during viewing project
    • [x] select project during create Issue
    • [x] add Board to an existing Project
    • [x] delete Board from a project
    • [x] rename Board title
    • [x] Individual boards
    • [x] Organization boards
    • [x] Repository boards

    Definitely another PR:

    • [x] Location of cards in the project board. Right now, cards location in a board cannot be persisted - i.e move card X above card Y in the same board.

    @rudineirk UI suggestion ( from ) was used.

    Screen Shot 2020-03-17 at 23 31 20 Screen Shot 2020-03-17 at 23 31 41 Screen Shot 2020-03-17 at 23 31 51



    kind/feature lgtm/need 1 changelog 
    opened by adelowo 233
  • Support unicode emojis and remove emojify.js

    Support unicode emojis and remove emojify.js

    This PR replaces all use of emojify.js and adds unicode emoji support to various areas of gitea.

    This works in a few ways:

    First it adds emoji parsing support into gitea itself. This allows us to

    • Render emojis from valid alias (:smile:)
    • Detect unicode emojis and let us put them in their own class with proper aria-labels and styling
    • Easily allow for custom "emoji"
    • Support all emoji rendering and features without javascript
    • Uses plain unicode and lets the system render in appropriate emoji font
    • Doesn't leave us relying on external sources for updates/fixes/features

    That same list of emoji is also used to create a json file which replaces the part of emojify.js that populates the emoji search tribute.

    For custom "emoji" it uses a pretty simple scheme of just looking for /emojis/img/name.png where name is something a user has put in the "allowed reactions" setting we already have. The gitea reaction that was previously hard coded into a forked copy of emojify.js is included and works as a custom reaction under this method.

    The emoji data sourced here is from which is the gem library Github uses for their emoji rendering (and a data source for other sites). So we should be able to easily render any emoji and :alias: that Github can, removing any errors from migrated content. They also update it as well, so we can sync when there are new unicode emoji lists released.

    I've included a slimmed down and slightly modified forked copy of to make up our own emoji module. The code is pretty straight forward and again allows us to have a lot of flexibility in what happens.

    I had seen a few comments about performance in some of the other threads if we render this ourselves, but there doesn't seem to be any issue here. In a test it can parse, convert, and render 1,000 emojis inside of a large markdown table in about 100ms on my laptop (which is many more emojis than will ever be in any normal issue). This also prevents any flickering and other weirdness from using javascript to render some things while using go for others.

    Includes the optional download of a fallback emoji webfont for small number of users who don't already have one installed.

    Fixes: Fixes: Fixes: Fixes: Fixes:

    kind/enhancement kind/ui lgtm/done kind/build 
    opened by mrsdizzie 138
  • Provide releases and deb/rpm packages via Bintray

    Provide releases and deb/rpm packages via Bintray

    I would like to integrate a proper process to create real system packages and distribute them via Bintray, than users can just add a deb/rpm repository and got a clean upgrade path.

    Beside that we can also publish our releases to a static page or also to Bintray for download.

    kind/deployment kind/build reviewed/confirmed 
    opened by tboerger 113
  • Auto merge pull requests when all checks succeeded via API

    Auto merge pull requests when all checks succeeded via API

    This adds the functionality to auto merge a pull request, once all status checks succeed.

    To achieve this, it schedules a pr to merge when a user request a merge via API and set merge_when_checks_succeed to true. On every status check update, if there are scheduled merge requests for this pull and that pull pass all merge requirements, they get merged.

    I created fake statuses for testing by running curl -X POST "http://localhost:3000/api/v1/repos/kolaente/testing/statuses/ccd425c09136a411236830785c41afdc172e8208" -H "accept: application/json" -H "authorization: Basic a29sYWVudGU6anVwMjAwMA==" -H "Content-Type: application/json" -d '{"context": "test/context", "description": "description", "state": "pending", "target_url": "http://localhost"}' | jq


    • [x] Show on the pr page if a pr was scheduled for auto merge
      • [x] Add a comment {User} scheduled this pr to auto-merge
    • [x] Provide an option to bypass auto merge entirely and merge directly without waiting for status checks
    • [x] Provide an option to cancel auto merge once it's set
    • [x] Add a check to see if all checks already succeeded in routers/repo/pull.go:676 to prevent scheduling a pr for merging after all checks already passed.
    • [x] Only check if all required status checks succeeded or all if none are required in services/automerge/pull_auto_merge.go:89
    • [x] Add an event comment to the pr timeline if it was set/unset to auto merge
    • [x] Make sure to check all prs with the same head branch of a commit for merging PRs when a check succeeds
    • [x] Fix dropdown button width of the merge button
    • [x] Allow both directly merging and scheduling for merge
    • [x] Add "merge now" button next to "merge when checks succeed"
    • [x] Cleanup scheduled pr merge when it failed to get merged + log error
    • [x] Move handling to [a queue](example:
    • [x] Check permissions again right before merging
    • [x] Automerge does not respect other branch protections yet
    • [x] ~~pull_service.Merge() need a lock~~ -> move it into won pull (#19520)
    • [ ] ~~Fix UI glitch to Create AutoMerge~~ -> new issue ... new pull #19621
    • [x] API cancel auto-merge

    Optional TODOs

    • [ ] Show auto merge status on PR list

    close #3905

    kind/feature lgtm/done kind/api 
    opened by kolaente 112
  • OAuth2 auto-register

    OAuth2 auto-register


    • Refactored user creation (code deduplication, see individual commit messages: a3366c4 and 6e2ece4)
    • Added auto-registration for OAuth2 users


    A new settings section (oauth2_client) is added and documented in custom/conf/app.ini.sample and content/doc/advanced/

    Breaking changes?

    No. The default settings reflect the current behaviour. And OAuth2 auto-register needs to be manually enabled.

    Referenced Issues

    Implements #3520 und solves the secondary consideration in #1036.

    kind/feature lgtm/done changelog reviewed/confirmed 
    opened by mgjm 110
  • Added dependencies for issues (#2196)

    Added dependencies for issues (#2196)


    This PR implements dependencies for issues, as described in #2196.

    It lets you define anonther issue as a dependency for an issue. You the cannot close the issue if it has any dependent issues which aren't closed. If you try to autoclose an issue via commit message which still has dependencies left, autoclose will simply not close the issue, but the commit will not fail.

    You can disable dependencies in the repo settings.

    Example: You set #2, #3 and #4 as a dependency of #1. Now you need to close all #2, #3 and #4, before you can close #1.


    Overview of Issue Dependencies (sidebar): Overview of Issue Dependencies (sidebar):

    Comments after adding a new dependency: Comments after adding a new dependency


    Currently, i would describe this as "working, but not finished", as there are some questions i have:

    1. For now, you need the issue ID (not the index) to create a dependency. This is not very user-friendly, I'd like to have some kind of search bar where you search for the issue title/index select it, and it'll do the rest. Problem: There is no API-Endpoint to search for issues like that (Or just returns a list of all issues as JSON). I think this should be implemented first. If such thing already exists, please point me to it, I haven't found any.
    2. It is currently possible to create dependencies with issues from other repositories. Is this okay? Or should one not be able to do this, as it could create a massive overhead with all permission-checking etc.
    3. There is some work to be done with migrations etc, currently i simply put the xorm-call at the beginning of the function, which probably shouldn't be there. Where is the appropriate place to put this?

    This is my first time I've done something like this in Go, before i've only played around with Go but never really did anything bigger. So, there are probably some things I didn't got right as a novice. Looking forward to hear your improvents to be made! Also thanks to @JonasFranzDEV who has helped me a lot.

    kind/feature lgtm/done changelog 
    opened by kolaente 103
  • New git security policy `` (eg: 1.16.6 docker image) makes pushing fails

    New git security policy `` (eg: 1.16.6 docker image) makes pushing fails


    Since upgrading to 1.16.6, every push fails with the following error:

    git -c diff.mnemonicprefix=false -c core.quotepath=false --no-optional-locks push -v origin master:master
    fatal: credential-cache unavailable; no unix socket support
    POST git-receive-pack (2733 bytes)
    remote: Gitea: Internal Server Error        

    In docker console this is logged:

    Failed to open repository: Git/Data Error: exit status 128 - fatal: unsafe repository ('/data/git/repositories/git/data.git' is owned by someone else)

    Downgrading to 1.16.5 makes it work again. UI works in 1.16.6 and also allows me to browse the files in this repository (or any other, all have this push error).

    Gitea Version


    Can you reproduce the bug on the Gitea demo site?


    How are you running Gitea?

    Windows Server 2022 + Docker. Windows 10 + Docker has the same problem.

    kind/bug kind/security workaround 
    opened by Nuklon 94
  • Screenreaders unable to read Gitea's various dropdowns

    Screenreaders unable to read Gitea's various dropdowns

    • Gitea version (or commit ref): 1.8.1

    • Git version: 2.21.0

    • Operating system: windows10-1903

    • Database (use [x]):

      • [ ] PostgreSQL
      • [x] MySQL
      • [ ] MSSQL
      • [x] SQLite
    • Can you reproduce the bug at

      • [ ] Yes (provide example URL)
      • [ ] No
      • [x] Not relevant
    • Log gist: not needed


    Gitea, as with gogs which it was forked from, has many accessibility issues with screen readers including:

    1. The dropdown menus are clickables, so many screen readers do not know what to do with them as they do not use the mouse cursor.
    2. The license selection/.gitignore selection (and most other menus of that type) are inaccessible, as they all use mouse oriented actions.
    3. Possibly others I haven't seen yet.

    Unfortunately, this is caused by the toolkit you use, which does not seem interested in making their toolkit accessible. It can be worked around with aria markup, or by changing toolkits (the first of which is easier to begin with but requires more maintenance over time, the second of which is of course much harder, but once you get it done it's done pretty much forever).

    See the original issue on gogs for more info: gogs/gogs#3340

    Looking forward to seeing if anything can be done about this. -dingpengyu. tests screen reader: NVDA thank

    opened by dpy013 91
  • Slow repository browsing in 1.14.x

    Slow repository browsing in 1.14.x

    • Gitea version (or commit ref): 1.14.x
    • Git version: 2.31.1
    • Operating system: FreeBSD 13
    • Gitea built using ports collection (www/gitea)
    • Gitea started by startup script provided by www/gitea port
    • Database (use [x]):
      • [x] PostgreSQL 12.6
      • [ ] MySQL
      • [ ] MSSQL
      • [ ] SQLite
    • Can you reproduce the bug at
      • [x] Yes (
      • [ ] No
    • Log gist:


    I saw a similar thread but there is "windows" in the title so I create a new issue. Gitea 1.14.x is much slower in repository browsing than Gitea 1.13.

    Sample repo running with 1.14.1: Try to open any directory, for example: It takes between 50-150 seconds to open a page.

    The same repo running with 1.13.7: Try to open similar directory, for example: I takes about 5 seconds.

    You can see the same problem on But you have a cache so you have to find a directory which was not open before. Opening such a page takes 100-300 seconds.

    Let me know if more info is needed.

    performance/speed performance/bigrepo 
    opened by tsowa 87
  • Pastebin service

    Pastebin service

    • Gitea version (or commit ref): all
    • Git version: all
    • Operating system: all
    • Database (use [x]):
      • [x] PostgreSQL
      • [x] MySQL
      • [x] SQLite
    • Can you reproduce the bug at
      • [x] Yes (provide example URL)
      • [ ] No
      • [x] Not relevant


    I am used to Gist, the pastebin service, since it offers me the option to collect all my pasted code in one central place and that in the same interface, text editor and so on, which i use on Github, so all is very consistent.

    I suggest to implement such a service for Gitea too, as Gitlab does it with their snippets.

    This is something we all use, it provides users and developers the very same look and feel as in Gitea, is easy to implement (so far i as a newbie can see) and offer us a history of all the already posted code.

    Want to back this issue? Post a bounty on it! We accept bounties via Bountysource.

    opened by ShalokShalom 86
  • Pushing to empty repository is not reflected in web UI

    Pushing to empty repository is not reflected in web UI

    • Gitea version (or commit ref): 1.10.2
    • Git version: 2.25.0
    • Operating system: ArchLinuxARM
    • Database (use [x]):
      • [ ] PostgreSQL
      • [ ] MySQL
      • [ ] MSSQL
      • [x] SQLite
    • Can you reproduce the bug at
      • [ ] Yes (provide example URL)
      • [x] No:
      • [ ] Not relevant
    • Log gist:


    Exactly the same as in #9365, but the filesystem is mounted with exec. I think the localhost API calls are the hooks, but I'm not sure. The hooks in the repo run properly when executed manually through the terminal.

    (description copied from the previously mentioned issue)

    I created a new repo and pushed a local repository. I tried it both with --all (it has two branches) and without (pushed only master). Either way the repository is not changed to non-empty. I did it manually in the DB to set the is_empty column to 0 which fixed the problem.

    opened by kauron 84
  • Web: Automatically collapse too many push records

    Web: Automatically collapse too many push records

    Feature Description


    Too many push records will result in long pages

    This information is useless in most cases. If you can fold it to display only the latest information, the page will be much cleaner


    No response

    kind/proposal kind/feature 
    opened by aimuz 0
  • Don't display stop watch top bar icon when disabled and hidden when click other place

    Don't display stop watch top bar icon when disabled and hidden when click other place

    Fix #22286

    When timetracking is disabled, the stop watch top bar icon should be hidden. When the stop watch recording popup, it should be allowed to hide with some operation. Now click any place on this page will hide the popup window.

    kind/bug kind/ui lgtm/need 1 backport/v1.18 
    opened by lunny 0
  • Don't permanently write values from ENV to config file

    Don't permanently write values from ENV to config file


    Configuration values passed via the environment, such as GITEA__log__LEVEL and GITEA__server__USE_PROXY_PROTOCOL are written to the used app.ini. Since other values in that file are auto-generated and must be persisted, all of these ENV variables are also persisted and remain in use even if they are removed from the environment. This is highly unintuitive, as environment variable in most applications are only supposed to apply when they are present, and reset back to the default when removed.

    This manifested today in me wasting a lot of time trying to figure out why my server was failing to start (with unexpected proxy header) even after removing GITEA__server__USE_PROXY_PROTOCOL from my environment.

    Gitea Version


    Can you reproduce the bug on the Gitea demo site?


    Log Gist

    No response


    No response

    Git Version

    No response

    Operating System

    No response

    How are you running Gitea?

    Container from docker hub - 1.18-rootless



    opened by theEndBeta 0
  • 1.18.0 occur error: ! [remote rejected] master -> master (pre-receive hook declined)

    1.18.0 occur error: ! [remote rejected] master -> master (pre-receive hook declined)


    Save your time:

    1.17.4 is good but 1.18.0 has a bug: 
    dial tcp: lookup localhost on no such host


    I use 1.18.0 Gitea, when I push files, occur:

    $ git push
    Enumerating objects: 4, done.
    Counting objects: 100% (4/4), done.
    Delta compression using up to 20 threads
    Compressing objects: 100% (2/2), done.
    Writing objects: 100% (3/3), 305 bytes | 305.00 KiB/s, done.
    Total 3 (delta 0), reused 0 (delta 0), pack-reused 0
    remote: Gitea: Internal Server Error
    remote: Unable to contact gitea: Post "http://localhost:3000/api/internal/hook/pre-receive/jinyang/test": dial tcp: lookup localhost on no such host
    To http://localhost:3000/jinyang/test.git
     ! [remote rejected] master -> master (pre-receive hook declined)
    error: failed to push some refs to 'http://localhost:3000/jinyang/test.git'

    I searched some related issues but finally failed to fix this.

    Then I installed 1.17.4 Gitea and this problem gone.

    Then I re-installed 1.18.0 Gitea again and still can not push.

    Gitea Version


    Can you reproduce the bug on the Gitea demo site?


    Log Gist

    No response



    Git Version

    git version

    Operating System

    WINDOWS 11

    How are you running Gitea?

    download binary on [gitea-1.18.0-windows-4.0-amd64.exe]

    download it on my PC and move it to D:\Program Files\Gitea, then double click the gitea-1.18.0-windows-4.0-amd64.exe



    opened by jinyangcruise 5
  • add new captcha: cloudflare turnstile

    add new captcha: cloudflare turnstile

    I added a new captcha(cloudflare turnstile ) and its corresponding document. Cloudflare turnstile official instructions are here:

    Signed-off-by: ByLCY <[email protected]>

    opened by ByLCY 0
Git with a cup of tea
A tasty, self-hosted Git server for the command line🍦

Soft Serve A tasty, self-hosted Git server for the command line. ?? Configure with git Create repos on demand with git push Browse repos with an SSH-a

Charm 2.9k Jan 9, 2023
A Git RPC service for handling all the git calls made by GitLab

Quick Links: Roadmap | Want to Contribute? | GitLab Gitaly Issues | GitLab Gitaly Merge Requests | Gitaly is a Git RPC service for handling all the gi

null 1 Nov 13, 2021
ReGit: A Tiny Git-Compatible Git Implementation written in Golang

ReGit is a tiny Git implementation written in Golang. It uses the same underlying file formats as Git. Therefore, all the changes made by ReGit can be checked by Git.

null 167 Oct 31, 2022
A simple cli tool for switching git user easily inspired by Git-User-Switch

gitsu A simple cli tool for switching git user easily inspired by Git-User-Switch Installation Binary releases are here. Homebrew brew install matsuyo

Masaya Watanabe 207 Dec 31, 2022
Removes unnecessarily saved git objects to optimize the size of the .git directory.

Git Repo Cleaner Optimizes the size of the .git directory by removing all of the files that are unnecessarily-still-saved as part of the git history.

Omar Yasser 2 Mar 24, 2022
Gum - Git User Manager (GUM) - Switch between git user profiles

Git User Manager (GUM) Add your profile info to config.yaml Build project: go bu

Mehmet Tevfik YÜKSEL 6 Feb 14, 2022
Git-now-playing - Git commits are the new AIM status messages

git-now-playing git-now-playing is an attempt to bring some of the panache of th

Paddy 1 Apr 4, 2022
A highly extensible Git implementation in pure Go.

go-git is a highly extensible git implementation library written in pure Go. It can be used to manipulate git repositories at low level (plumbing) or

go-git 4.2k Jan 8, 2023
commit/branch/workdir explorer for git

gitin gitin is a commit/branch/status explorer for git gitin is a minimalist tool that lets you explore a git repository from the command line. You ca

Ibrahim Serdar Acikgoz 1.8k Dec 31, 2022
A command-line tool that makes git easier to use with GitHub.

hub is a command line tool that wraps git in order to extend it with extra features and commands that make working with GitHub easier. For an official

GitHub 22.2k Jan 1, 2023
A tool to monitor git repositories and automatically pull & push changes

git-o-matic A tool to monitor git repositories and automatically pull & push changes Installation Packages & Binaries Arch Linux: gitomatic Binaries f

Christian Muehlhaeuser 1k Dec 20, 2022
SQL interface to git repositories, written in Go.

gitbase gitbase, is a SQL database interface to Git repositories. This project is now part of source{d} Community Edition, which provides the simplest

source{d} 2k Dec 25, 2022
Fast and powerful Git hooks manager for any type of projects.

Lefthook The fastest polyglot Git hooks manager out there Fast and powerful Git hooks manager for Node.js, Ruby or any other type of projects. Fast. I

Abroskin Alexander 2.6k Jan 4, 2023
Implementation of git internals from scratch in Go language

This project is part of a learning exercise to implement a subset of "git" commands. It can be used to create and maintain git objects, such as blobs, trees, commits, references and tags.

Shyamsunder Rathi 39 Nov 27, 2022
A Simple and Comprehensive Vulnerability Scanner for Container Images, Git Repositories and Filesystems. Suitable for CI

A Simple and Comprehensive Vulnerability Scanner for Containers and other Artifacts, Suitable for CI. Abstract Trivy (tri pronounced like trigger, vy

Aqua Security 15.6k Jan 9, 2023
go mod vendor lets you check in your dependencies to git, but that's both bloaty (for developers) and tedious (remembering to update it).

go-mod-archiver Afraid of being unable to build historical versions of your Go program? go mod vendor lets you check in your dependencies to git, but

Tailscale 86 Dec 1, 2022
Quickly clone git repositories into a nested folders like GOPATH.

cl cl clones git repositories into nested folders like GOPATH and outputs the path of the cloned directory. Example: cl Is

Felix Geisendörfer 13 Nov 30, 2022
Switch between your git profiles easily

Git Profile Switcher Switch between your git profiles easily Install With Brew brew install theykk/tap/git-switcher With golang go get

Kaan Karakaya 216 Dec 11, 2022
Store private data inside a git repository.

git-private lets you store private data inside a git repo. A common use case is protecting files containing API keys et.c.

Erik Agsjö 10 Nov 13, 2022