{"id":19719981,"url":"https://github.com/timboudreau/gittattle","last_synced_at":"2025-09-12T08:42:28.737Z","repository":{"id":10091310,"uuid":"12151299","full_name":"timboudreau/gittattle","owner":"timboudreau","description":"A simple, minimal web ui for git using node.js","archived":false,"fork":false,"pushed_at":"2023-06-12T03:42:42.000Z","size":38,"stargazers_count":8,"open_issues_count":0,"forks_count":1,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-04-05T19:34:07.351Z","etag":null,"topics":["git","http-server","server"],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/timboudreau.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2013-08-16T05:22:14.000Z","updated_at":"2021-03-29T19:49:06.000Z","dependencies_parsed_at":"2022-08-30T12:20:40.743Z","dependency_job_id":null,"html_url":"https://github.com/timboudreau/gittattle","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/timboudreau%2Fgittattle","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/timboudreau%2Fgittattle/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/timboudreau%2Fgittattle/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/timboudreau%2Fgittattle/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/timboudreau","download_url":"https://codeload.github.com/timboudreau/gittattle/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":251585739,"owners_count":21613270,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["git","http-server","server"],"created_at":"2024-11-11T23:09:52.451Z","updated_at":"2025-04-29T21:30:43.783Z","avatar_url":"https://github.com/timboudreau.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"Gittattle\n=========\n\nImplements a simple, read-only REST API on top of a directory of Git repositories,\nallowing for basic browsing, and a simple single-page web UI on top of that.\nDoes not require a working directory - files are served using ``git show``.\n\nThe git repository subdirectory names must end with ``.git``.\n\nWhy?  Gitweb is awful, Cgit is painful to set up;  and for a lot of cases,\na full fledged push/pull-over-http server is more than you need.  It was \nwritten with [Gitolite](https://github.com/sitaramc/gitolite) in mind,\nbut it will work with any system that contains a folder of Git repositories. \n\nThe idea is to painlessly \nprovide a reasonable read-only UI on the web with minimum pain, and provide a REST\napi for widgets showing recent commits and such.\n\nIt's written in node.js and can be run from the command-line.  You aim it at\na folder full of Git repositories and go (make sure it runs as a user account \nthat can read them).  Then use the built-in, minimal web UI or roll your own.\n\n\nFeatures\n--------\nThe web API supports the following, returning JSON:\n\n * List repositories\n * List commits information for a repository, limiting the number of entries returned and the starting entry\n * List files for a repository, optionally specifying a branch name\n * Download an individual commit diff, specifying a repository and commit hash\n * Download an individual file, optionally specifying a branch\n * Download an archive of a repository, optionally specifying a branch, in one of\n   * ``tar.xz`` format\n   * ``tar.bz2`` format\n   * ``tar.gz`` format\n   * ``zip`` format\n\nThe web ui provides a single-page web application for doing the above in a\nweb browser.\n\n\nConfiguration\n-------------\n\nIt looks for a file named ``gittattle.json`` in the process` working directory.\nThe following properties are relevant and shown with their defaults:\n\n * ``gitdir : /var/lib/gitolite/repositories`` - Path to the parent directory \nof git repos to serve\n * ``port : 9902`` - The port to run the HTTP server on\n * ``tar : tar`` - The name of the tar command, for platforms that call GNU \ntar ``gtar``\n * ``logEntriesPerPage : 30`` - The number of log entries to return if log is \ncalled with no ``count`` URL parameter\n * ``serveIndexPage : true`` - Should the built-in HTML client be used\n * ``failOnNoDir : true`` - Exit early if the git repositories directory does \nnot exist when the program is started\n * ``blacklist : []`` - The list of repository names that must'nt be exposed to the world\n * ``whitelist : []`` - The exhaustive list of repository names that must be exposed to the world\n * ``listfilter: 'blacklist'`` - The filtering strategy (``blacklist`` by default) - \nOnly necessary to enforce ``whitelist`` when both arrays are defined\n\n\nWeb UI\n------\n\nThe application includes a simple web user interface which uses CDN-hosted\nJQuery, Twitter Bootstrap and AngularJS to create a single-page web application\nwhich uses the web API to browse Git repositories.\n\nRun it and navigate in a browser to ``/git/index.html`` for that.\n\n\nWeb API\n-------\n\nThe API aims to be simple and intuitive.  Since this is read-only, only GET and HEAD\nrequests are supported.\n\n\n### ``/git/index.html``, ``/git/``\nA minimal web ui for a git server which can show lists of commits and files for\na set of repositories which are subdirectories of the folder it was given on\nstartup.\n\n\n### ``/git/list``\n\nLists the respositories being served as a JSON array, with some info about the\nmost recent commit if available\n\n    [ { location: '/tmp/git/blog.git',\n        dir: 'blog.git',\n        name: 'blog',\n        description: 'Yet another nodejs blog engine\\n',\n        lastCommit: \n         { hash: '92cb9cb',\n           author: 'Joe Shmoe',\n           date: '2013-03-24T16:12:23.000Z',\n           email: 'joe@foo.example',\n           message: 'Fix utf8, more attempts to get working in IE8, filter obvious spam comments',\n           commitDate: '2013-03-24 12:12:23 -0400',\n           age: '5 months ago' }\n    } ]\n\n\n### ``/git/$REPO_NAME``\n\nGet a commit log for one repository.  Example data:\n\n        [{ hash: '56cbf59',\n          author: 'Tim Boudreau',\n          date: '2012-11-27T01:20:05.000Z',\n          email: 'tboudreau@chiliad.com',\n          message: 'Fix gzip length bug',\n          commitDate: '2012-11-26 20:20:05 -0500',\n          age: '9 months ago' }]\n\nOptional parameters:\n\n * skip - integer number of log records to skip\n * count - the maximum number of log records to return\n\n\n### ``/git/$REPO_NAME/list``\n\nList the files in one repository, as they would be presented by ``tar tv``, JSON-ized.\nExample data:\n\n  [{ type: '-rw-rw-r--',\n    size: 646,\n    date: '2013-03-24T16:12:00.000Z',\n    path: 'ui/package.json' }]\n\nAdd the parameter ``?branch=$BRANCH_NAME`` to download the version from a particular branch.\n\nDirectories are omitted from the file list.\n\n\n### ``/git/$REPO_NAME.tar.gz``\n\nDownload an archive of this repository, specifying the compression type with\nthe file name.  The following are supported:  .tar, .tar.gz, .tar.bz2, .tar.xz, zip\n\nAdd the parameter ``?branch=$BRANCH_NAME`` to download the version from a particular branch.\n\n\n### ``/git/$REPO_NAME/get/path/to/some.file``\n\nDownload the file ``path/to/some.file``.  Add ``?raw=true`` to have the server\nattempt to set the content-type to the MIME type suggested by the extension.\n\nAdd the parameter ``?branch=$BRANCH_NAME`` to download the version from a particular branch.\n\n\n### ``/git/$REPO_NAME/$COMMIT_HEX_ID``\n\nFetch the output of ``git diff-tree --patch-with-stat $COMMIT_HEX_ID`` - a basic\ndiff and stats output for that repository.\n\n\n## Security\n\nThe web API *does* call ``git`` in a shell with arguments passed from an HTTP\nrequest.  The usual precautions have been taken about not allowing characters\nsuch as backticks, redirects, pipes, etc.  I make no promises that there isn't\nsome way for someone to do something nasty, but I've taken the basic \nprecautions.  If you find any issues, please let me know.\n\nThe web api does not do any authentication/authorization.  It's easy enough to\nproxy it behind something that does.\n\n\n# To-Do / Issues\n\n * Would be nice to use a router and have permalinks\n * Appending ``.git`` should be optional but is actually currently required - probably some tweaks needed\n * ``git show`` on binary files such as images appears to be prepending a few bytes to output, corrupting \"raw\" links for those\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftimboudreau%2Fgittattle","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftimboudreau%2Fgittattle","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftimboudreau%2Fgittattle/lists"}