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:

    • [ ] 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
  • Enable race detector for CI

    Enable race detector for CI

    close #1430

    lgtm/done kind/testing kind/upstream-related 
    opened by typeless 115
  • 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
  • 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
  • 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 xingkong0113 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
  • Update JS dependencies

    Update JS dependencies

    • Upgrade to eslint 8 and add new plugin rules
    • Adapt to various API changes
    • Rebuild SVGs
    kind/ui lgtm/need 1 dependencies 
    opened by silverwind 0
  • Fix dashboard repolist alignment and repos listed in the repolist

    Fix dashboard repolist alignment and repos listed in the repolist

    Unfortunately #17301 broke the restriction of the dashboard repolist to the user's repos because it stopped passing in the uid for the current user. This PR restores this.

    There is also a weird alignment problem - not caused by that PR - where the menu items in the repolist spread over multiple lines. This PR simply reduces the padding on these items and switches the justification of the flex elements to space-evenly.

    Signed-off-by: Andrew Thornton [email protected]

    kind/bug lgtm/done kind/regression skip-changelog 
    opened by zeripath 0
  • Use go:embed for embedding files instead of vfsgen

    Use go:embed for embedding files instead of vfsgen

    Feature Description

    Now that we have a minimum of go1.16 set, we can use go's embed functionality to embed templates/web assets (css/js), and translations.


    No response

    good first issue Hacktoberfest 
    opened by techknowlogick 3
  • [LDAP Push] LDAP Result Code 49

    [LDAP Push] LDAP Result Code 49 "Invalid Credentials"

    Gitea Version


    Git Version


    Operating System


    How are you running Gitea?




    Can you reproduce the bug on the Gitea demo site?


    Log Gist

    No response


    gitea is configured to use LDAP for Auth.

    This happens with a user which has an Umlaut (Ä) in its password:

    • Login in WebUI WORKS!
    • A clone worked as well
    • Any push will be cancelled with: invalid credentials:
    2021/10/18 10:09:13 [I] [SQL] SELECT `id`, `lower_name`, `name`, `full_name`, `email`, `keep_email_private`, `email_notifications_preference`, `passwd`, `passwd_hash_algo`, `must_change_password`, `login_type`, `login_source`, `login_name`, `type`, `location`, `website`, `rands`, `salt`, `language`, `description`, `created_unix`, `updated_unix`, `last_login_unix`, `last_repo_visibility`, `max_repo_creation`, `is_active`, `is_admin`, `is_restricted`, `allow_git_hook`, `allow_import_local`, `allow_create_organization`, `prohibit_login`, `avatar`, `avatar_email`, `use_custom_avatar`, `num_followers`, `num_following`, `num_stars`, `num_repos`, `num_teams`, `num_members`, `visibility`, `repo_admin_change_team_access`, `diff_view_style`, `theme`, `keep_activity_private` FROM `user` WHERE `lower_name`=? LIMIT 1 [] - 95.866µs
    2021/10/18 10:09:13 ...dels/login_source.go:844:UserSignIn() [I] [SQL] SELECT `id`, `type`, `name`, `is_actived`, `is_sync_enabled`, `cfg`, `created_unix`, `updated_unix` FROM `login_source` WHERE `id`=? LIMIT 1 [1] - 53.473µs
    2021/10/18 10:09:13 [D] LDAP auth. failed for cn=User,ou=Normale Nutzer,ou=OU,dc=DC,dc=DC, reason: LDAP Result Code 49 "Invalid Credentials": 
    2021/10/18 10:09:13 ...s/context/context.go:308:HandleText() [E] invalid credentials from

    Removing the umlaut fixed the issue. Is there a problem with Umlauts and ldap.go:178:bindUser()?


    No response

    opened by Commifreak 0
  • [Feature request] Allow autosquash in merging dialog of pull request/merge request

    [Feature request] Allow autosquash in merging dialog of pull request/merge request

    Feature Description

    Squashing commits in a pull request/merge request joins every commit into a single one. There may be a reason to leave commits separate though. If so any fixup commits need to be squashed with their linked commits manually.

    Git provides autosquash option with the interactive rebase. A truly interactive rebase is not requested here, however, an interactive rebase that accepts what is proposed by autosquash automatically would have its use for fixup commits.

    A possible implementation would be to call the interactive rebase with its editor changed to something like "true" (we have aliased this as fixuprebase): git config --global alias.fixuprebase '!GIT_SEQUENCE_EDITOR=true git rebase -i --autosquash'


    No response

    opened by travnja3 0
  • Mark most UI links & buttons as `rel=

    Mark most UI links & buttons as `rel="nofollow"` to avoid constant bot traffic

    Feature Description

    Gitea is a magnet for search engines, which once they find an instance are very happy to follow all the links on the site, of which there are many, resulting in never ending indexer bot traffic. Among the links followed are UI buttons (star a page, sort by XYZ, select a UI language...), as well as pages that are expensive to render, but don't provide much value once indexed (blame, compare, commit, ...). Ideally, these would not be (attempted to be) indexed. I tried to accomplish this on my site via a robots.txt along the following lines, but was not exactly successful, probably because many bots don't understand the wildcard syntax:

    User-agent: *
    Disallow: /
    Allow: /whitelisted-user
    Disallow: /*/raw
    Disallow: /*/commit
    Disallow: /*/blame
    Disallow: /*/src
    Disallow: /*?lang=*

    A better approach would be to render most links with the rel="nofollow" attribute. I'd argue this could be applied to all links, except for links to

    • landingpage
    • user / org
    • repo
    • issue(s) / pr(s) / release(s) / wiki / yougettheidea..


    No response

    good first issue Hacktoberfest 
    opened by noerw 2
  • Remove js redundancy

    Remove js redundancy

    Removed redundancy inside components/DashboadRepoList by adding two additional methods. Additionally simplified some statements.

    I think all these actions should be idempotent, I couldn't see any difference when testing locally.

    The only thing I am uncertain about is whether it was a previously unnoticed bug that changeReposFilter did not call this.setCheckboxes();, or whether I added a bug myself with that. What exactly does setCheckboxes do?

    lgtm/need 1 kind/refactor skip-changelog 
    opened by delvh 4
  • Sync git hook paths when starting

    Sync git hook paths when starting


    Gitea writes its own AppPath into git hook scripts. If Gitea's AppPath changes, then the git push will fail. The previous PRs ( , ) seem to be difficult to resolve this problem fundamentally.

    This PR:

    1. Introduce an AppState module, it can persist app states into files, I believe will also benifit from this feature and we can drop database dependency then.
    2. During GlobalInit, Gitea will check if the current AppPath is the same as last one. If they don't match, Gitea will sync git hooks.
    3. Refactor some code to make them more clear.
    4. Also, is related, we call models.RewriteAllPublicKeys to update ssh authorized_keys file
    kind/enhancement lgtm/done 
    opened by wxiaoguang 2
  • PR checkout commands

    PR checkout commands

    Feature Description

    GitHub offers a dropdown to the right of a PR title to copy the checkout instructions for said instructions. Gitea could offer the same with the only difference being instead of the GitHub CLI, a) Agit-Flow with the command (I hope I understand the agit-flow commands correctly)

    git download $PR_ID

    b) Pure Git with the command

    # Assumes you named the remote host origin
    git fetch origin pull/$PR_ID/head:$BRANCH_NAME_AS_NAMED_BY_PR_CREATOR && git switch $BRANCH_NAME_AS_NAMED_BY_PR_CREATOR

    Alternatively, to be on the save side regarding potential name conflicts:

    # Assumes you named the remote host origin
    git fetch origin pull/$PR_ID/head:pr-$BRANCH_NAME_AS_NAMED_BY_PR_CREATOR && git switch pr-$BRANCH_NAME_AS_NAMED_BY_PR_CREATOR

    are provided.


    Display on GitHub: image

    kind/enhancement kind/ui 
    opened by delvh 2
Git with a cup of tea
Package git provides an incomplete pure Go implementation of Git core methods.

git Package git provides an incomplete pure Go implementation of Git core methods. Example Code: store := git.TempStore() defer os.RemoveAll(string(st

Daniel Skinner 26 Sep 8, 2020
Installs git repos onto your system and keeps them up-to-date

Gitfile Installs git repos onto your system and keeps them up-to-date. It's a lightweight package manager for things that haven't been published to a

Brad Urani 18 Jan 16, 2021
Lenient VCS repository URL parsing library for Go

============================================= go-vcsurl - Lenient VCS repository URL parser go-vcsurl parses VCS repository URLs in many common format

Sourcegraph 14 Dec 23, 2019
A diff tool especially for Go language.

go-diff A diff tool for Go languange. It shows the semantic differences between two Go source files. Ignored Difference Order of import statements Ord

Yi Deng 67 Feb 11, 2021
manipulate and inspect VCS repositories in Go

go-vcs - manipulate and inspect VCS repositories go-vcs is a library for manipulating and inspecting VCS repositories in Go. It currently supports Git

Sourcegraph 75 Jun 9, 2021
Git folder digger, I'm sure it's worthwhile stuff.

Gigger Git folder digger, I'm sure it's worthwhile stuff. Installation Download a prebuilt binary from releases page. or If you have recent go compile

Rıza Sabuncu 38 Aug 28, 2021