{"id":19857530,"url":"https://github.com/banach-space/gfg","last_synced_at":"2025-08-12T18:12:06.840Z","repository":{"id":88814865,"uuid":"326018907","full_name":"banach-space/gfg","owner":"banach-space","description":"A custom implementation of Git - for those curious how stuff works!","archived":false,"fork":false,"pushed_at":"2022-04-10T16:52:49.000Z","size":151,"stargazers_count":5,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-04-01T20:07:05.331Z","etag":null,"topics":["git","python","tutorial"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/banach-space.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2021-01-01T16:55:25.000Z","updated_at":"2024-11-16T07:42:49.000Z","dependencies_parsed_at":"2023-03-24T00:49:20.961Z","dependency_job_id":null,"html_url":"https://github.com/banach-space/gfg","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/banach-space/gfg","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/banach-space%2Fgfg","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/banach-space%2Fgfg/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/banach-space%2Fgfg/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/banach-space%2Fgfg/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/banach-space","download_url":"https://codeload.github.com/banach-space/gfg/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/banach-space%2Fgfg/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":270109772,"owners_count":24528899,"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","status":"online","status_checked_at":"2025-08-12T02:00:09.011Z","response_time":80,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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","python","tutorial"],"created_at":"2024-11-12T14:18:58.614Z","updated_at":"2025-08-12T18:12:06.820Z","avatar_url":"https://github.com/banach-space.png","language":"Python","readme":"Git From Glasgow\n================\n\n[![unittests](https://github.com/banach-space/gfg/workflows/Ubuntu-unittests/badge.svg?branch=main)](https://github.com/banach-space/gfg/actions?query=workflow%3AUbuntu-unittests+branch%3Amain)\n[![pylint](https://github.com/banach-space/gfg/workflows/Ubuntu-pylint/badge.svg)](https://github.com/banach-space/gfg/actions?query=workflow%3AUbuntu-pylint+branch%3Amain)\n\nA custom implementation of Git - for those curious how stuff works!\n\n**Git From Glasgow** is a collection of Python scripts that implement the key\nGit data structures and the command line user interface. It follows a\nfew basic design principles: \n\n* **Simplicity** - Only selected, most popular Git commands are available.\n* **Compatibility with Git** - Every command is fully compatible with its Git\n  equivalent.\n* **Standalone** - There are no external dependencies beyond Python.\n\nTo avoid confusion, the command-line interface in **Git From Glasgow** is\ncalled `gfg` rather than `git`.\n\n### About\n**Git From Glasgow** implements the key elements of Git:\n\n* [index file](https://git-scm.com/docs/index-format#_cache_tree) (see [git_index.py](https://github.com/banach-space/gfg/blob/main/git_index.py))\n* various [Git objects](https://matthew-brett.github.io/curious-git/git_object_types.html) (e.g. blob, commit and commit, see [git_object.py](https://github.com/banach-space/gfg/blob/main/git_object.py))\n* Git command-line interface, which in **Git From Glasgow** is called `gfg` (see [gfg](https://github.com/banach-space/gfg/blob/main/gfg))\n\nAlthough only selected Git commands are supported (see [Supported Git\nCommands](#supported-git-commands)), the available functionality is sufficient\nto:\n\n* initialise a fresh repository (`gfg init`),\n* add and commit new changes (e.g. `gfg add` and `gfg commit`),\n* read the contents of an existing repository (e.g. `gfg log` and `gfg\n  cat-file`).\n\nThe main goal of **Git From Glasgow** is to help understand _how Git works_\n(including the fine details). It is not meant as a replacement for **Git**.\nIndeed, some key and more advanced features are not available (e.g.\n[packfiles](https://git-scm.com/book/en/v2/Git-Internals-Packfiles)). For this\nreason, it is best to experiment with **GFG** in a dedicated test repository.\n\n### Table of Contents\n* [Installing and Testing](#installing-and-testing)\n* [Supported Git Commands](#supported-git-commands)\n* [Contributing](#contributing)\n* [References](#references)\n\nInstalling and Testing\n======================\nIn order to use **Git From Glasgow**, you will require Python 3 (\u003e= 3.6.9).  In\norder to run the Git conformance tests, you will also have to install\n[bats-core](https://github.com/bats-core/bats-core). Below is a full set-up\nthat should work on most Unix platforms (tested on Ubuntu and MacOS):\n```bash\n# Clone GFG, add `gfg` to your path\ngit clone https://github.com/banach-space/gfg\nexport PATH=path/to/gfg:$PATH\n# Clone bats-core so that you can run the conformance tests, add `bats` to your path\ngit clone https://github.com/bats-core/bats-core.git\nexport PATH=path/to/bats-core:$PATH\ncd gfg/test\n# Run Git conformance tests\nbats -t .\n# Run GFG unit tests\nPYTHONPATH=\"../\" python3 -m unittest\n```\nWhile I have strived to make **GFG** OS-agnostic, I have not been able to test\nit on Windows yet. Please let me know if you experience any issues!\n\nSupported Git Commands\n==================\nBelow is a list of Git options supported by **Git From Glasgow** with the\nsupported flags (note that Git equivalents of these options normally support\nmore flags):\n### Basic commands\n* `gfg init` ([documentation](https://git-scm.com/docs/git-init))\n* `gfg add \u003cfiles\u003e` ([documentation](https://git-scm.com/docs/git-add))\n* `gfg commit -m message` ([documentation](https://git-scm.com/docs/git-commit))\n* `gfg log` ([documentation](https://git-scm.com/docs/git-log))\n\n### Less basic commands\n* `git cat-file (-t | -p | \u003ctype\u003e ) \u003cobject\u003e`\n  ([documentation](https://git-scm.com/docs/git-cat-file))\n* `gfg hash-object [-w] [--stdin] \u003cfile\u003e` ([documentation](https://git-scm.com/docs/git-hash-object))\n* `gfg write-tree` ([documentation](https://git-scm.com/docs/git-write-tree))\n* `gfg commit-tree -m message \u003ctree\u003e` ([documentation](https://git-scm.com/docs/git-commit-tree))\n\nContributing\n===========\nPull requests are very welcome! If you want to make a larger contribution (e.g.\nadd a new option), please open an\n[issue](https://github.com/banach-space/gfg/issues) to track this.\n\nContributions in the form of bug reports, suggestions and general feedback are\nalso much appreciated!\n\nToDo\n======\nHere's a list of things that I would like to add support for (PRs welcome!):\n\n* testing on Windows (may require some refactoring to make **GFG** actually\n  work on Windows)\n* `gfg rm` ([documentation](https://git-scm.com/docs/git-rm))\n* `gfg branch` ([documentation](https://git-scm.com/docs/git-branch))\n* `gfg checkout` ([documentation](https://git-scm.com/docs/git-checkout))\n* `gfg push` ([documentation](https://git-scm.com/docs/git-push))\n* more tests\n\nI'm also aware that there might be some inconsistencies in the code that would\nbe nice to fix:\n\n* `hash`, `sha` and `object_hash` are used interchangeably. Choose one instead.\n* Classes in\n  [git_object.py](https://github.com/banach-space/gfg/blob/main/git_object.py)\n  have slightly inconsistent APIs.\n* Reduce the use of class variables (e.g. in `IndexEntry`).\n\nReferences\n===========\nA list of my favourite resources on Git internals. I have found these\nincredibly helpful while working on **Git From Glasgow**.\n* _\"Write yourself a Git!\"_, Thibault Polge ([link](https://wyag.thb.lt/))\n* _\"Git File format\"_,  Jelmer Vernooĳ ([link](https://www.dulwich.io/docs/tutorial/file-format.html#git-file-format))\n* _\"Git from the inside out\"_, Mary Rose Cook ([link](https://maryrosecook.com/blog/post/git-from-the-inside-out))\n* _\"Unpacking Git packfiles\"_, Aditya Mukerjee ([link](https://codewords.recurse.com/issues/three/unpacking-git-packfiles))\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbanach-space%2Fgfg","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbanach-space%2Fgfg","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbanach-space%2Fgfg/lists"}