{"id":29463684,"url":"https://github.com/fiddlerwoaroof/cl-git","last_synced_at":"2025-07-14T05:38:29.395Z","repository":{"id":56316333,"uuid":"196485589","full_name":"fiddlerwoaroof/cl-git","owner":"fiddlerwoaroof","description":"A Common Lisp implementation of parsers for the git object file formats","archived":false,"fork":false,"pushed_at":"2024-10-18T07:13:16.000Z","size":285,"stargazers_count":30,"open_issues_count":0,"forks_count":4,"subscribers_count":6,"default_branch":"main","last_synced_at":"2025-07-14T05:16:57.046Z","etag":null,"topics":["common-lisp","git","version-control"],"latest_commit_sha":null,"homepage":"http://cl-git.fiddlerwoaroof.com","language":"Common Lisp","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/fiddlerwoaroof.png","metadata":{"files":{"readme":"README.org","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":"2019-07-12T01:12:14.000Z","updated_at":"2025-03-17T06:34:13.000Z","dependencies_parsed_at":"2024-10-20T09:13:25.407Z","dependency_job_id":null,"html_url":"https://github.com/fiddlerwoaroof/cl-git","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/fiddlerwoaroof/cl-git","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fiddlerwoaroof%2Fcl-git","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fiddlerwoaroof%2Fcl-git/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fiddlerwoaroof%2Fcl-git/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fiddlerwoaroof%2Fcl-git/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/fiddlerwoaroof","download_url":"https://codeload.github.com/fiddlerwoaroof/cl-git/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fiddlerwoaroof%2Fcl-git/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":265246229,"owners_count":23734111,"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":["common-lisp","git","version-control"],"created_at":"2025-07-14T05:38:28.716Z","updated_at":"2025-07-14T05:38:29.367Z","avatar_url":"https://github.com/fiddlerwoaroof.png","language":"Common Lisp","funding_links":[],"categories":[],"sub_categories":[],"readme":"* CL-GIT: the pure lisp interface to Git objects\n** Introduction\n\n   Git libraries for Common Lisp common in a couple forms. Some attempt\n   to wrap the libgit2 git library\n   (e.g. https://github.com/russell/cl-git).  Others wrap the git binary\n   in a subprocess (e.g. http://shinmera.github.io/legit/).  Such\n   libraries work well in cases where you control the environment but\n   not all lisp programs run in such circumstances.  This library, on the\n   contrary, attempts to implement parsers for git's file formats as well\n   as a thin \"porcelain\" interface for manipulating git objects.\n\n** Contributing\n\n  This project uses (loosely) conventional-commits: https://www.conventionalcommits.org/en/v1.0.0/\n\n  Also, some use of https://github.com/fiddlerwoaroof/git-issue has been made\n\n  To run the tests in a clean environment, you can do (this will eventually be a Github Action):\n\n  #+BEGIN_SRC sh :noeval\n    docker run \\\n      -v $PWD/docker-run:/code fiddlerwoaroof/sbcl-static:latest \\\n      --load /code/main.lisp\n  #+END_SRC\n\n** Installation\n\n   #+BEGIN_SRC sh :noeval\n     % git clone https://github.com/fiddlerwoaroof/fwoar.lisputils.git \"$HOME/quicklisp/local-projects/fwoar-lisputils\"\n     % git clone https://github.com/fiddlerwoaroof/cl-git.git \"$HOME/quicklisp/local-projects/cl-git\"\n     % sbcl --load \"$HOME/quicklisp/setup.lisp\"\n     CL-USER\u003e (ql:quickload :cl-git)\n   #+END_SRC\n\n** Example usage\n\n*** Get the commit id of the default branch for a specific repository:\n\n    #+BEGIN_SRC lisp :exports both :results verbatim\n      (co.fwoar.git:with-repository (\".\")\n        ;; the argument to branch defaults to \"master\" or \"main\"\n        (co.fwoar.git:branch))\n    #+END_SRC\n\n    #+RESULTS:\n    : #\u003cLOOSE-REF ba6fdb of #\u003cGIT-REPOSITORY {70161A1853}\u003e {70161A2893}\u003e\n\n\n*** Show the commit message\n\n    #+BEGIN_SRC lisp :exports both :results verbatim\n      (co.fwoar.git:in-repository \".\")\n      (co.fwoar.git:component :message (co.fwoar.git:branch \"main\"))\n    #+END_SRC\n\n    #+RESULTS:\n    : feat: don't assume that the default branch is \\\"master\\\"\n\n*** Show the messages of the commit's parent\n\n    #+BEGIN_SRC lisp :exports both :results verbatim\n      (co.fwoar.git:in-repository \".\")\n      (let* ((branch (co.fwoar.git:branch \"main\"))\n             (parents (co.fwoar.git:parents branch)))\n        (mapcar (lambda (it)\n                  (co.fwoar.git:component :message it))\n                parents))\n    #+END_SRC\n\n    #+RESULTS:\n    : (\"feat: handle bare repositories\n    : \")\n\n*** Show the files in a commit\n\n    #+BEGIN_SRC lisp :exports both :results table :hlines yes :post proc(data=*this*)\n      (co.fwoar.git:in-repository \".\")\n      (list* '(\"Name\" \"Mode\" \"Hash\")\n             'hline\n             (co.fwoar.git:git (branch \"main\")\n                               (component :tree :entries)\n                               (map (juxt (component :name)\n                                          (component :mode)\n                                          (component :hash)))))\n    #+END_SRC\n\n    #+RESULTS:\n    | Name                |   Mode | Hash                                     |\n    |---------------------+--------+------------------------------------------|\n    | .github             |  40000 | beabf775f686fb2608a580b4d58dd589cf160354 |\n    | .gitignore          | 100644 | 8a9fe9f77149f74fed5c05388be8e5ffd4a31678 |\n    | .projectile         | 100644 | e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 |\n    | LICENSE             | 100644 | 0306819e780fa57dc3bf6b99a0a059670b605ae0 |\n    | README.org          | 100644 | f25aa710e8c3053f4a6618728702e41c68eb52c5 |\n    | branch.lisp         | 100644 | d82ad3bdbae4af13b5a703bf350dd2bb2c9dadd0 |\n    | co.fwoar.cl-git.asd | 100644 | 560a0f63f48161e2ba787ed42332515de7f86f14 |\n    | commit.lisp         | 100644 | 6ff88d884da171adf49ed022decd537a5964e41c |\n    | delta.lisp          | 100644 | 1014147a1946752542c1ea7dd9700cb047055047 |\n    | docker-run          |  40000 | 4703dc01430d67c5d60f00ad412fddfa22f60764 |\n    | docs                |  40000 | 9fe62496fc4ab6debd3c5e1b26f844b5566c36d5 |\n    | extract.lisp        | 100644 | 4fc2d479ff5c37fc52a51a2cf884e5226fb3b14d |\n    | git.lisp            | 100644 | bccecfd98285f2ab98a277a3284bd98b3dd363bf |\n    | graph.lisp          | 100644 | 25596749c5bf5ee2d5a76b355821f57010beb31a |\n    | model.lisp          | 100644 | ade5096654ea6ff352354d381784a5d9dda0a3e7 |\n    | pack.lisp           | 100644 | 16b02b061756f59d615b5f1f7f473789ad86b676 |\n    | package.lisp        | 100644 | f8bd75abedd62bd51155ebd1727b5b9476d02c57 |\n    | porcelain.lisp      | 100644 | 3f044e12ae9fc5a98a5c84f2f54e6892ae42216a |\n    | protocol.lisp       | 100644 | 84a10444b7bce2b844128917cdfc79fa4df6377b |\n    | ref.lisp            | 100644 | b508a5546a0bc0b7189a8cf8cebb33a967f3ffb2 |\n    | repository.lisp     | 100644 | 4e64262b40bcd0e239276a73426d0d1ac9d0772c |\n    | tests               |  40000 | df1addf5dae76e35e84e6ded6fee14cda501f119 |\n    | tree.lisp           | 100644 | c798b0c4d0b5f552548bac98f44b5b5c19334e66 |\n    | types.lisp          | 100644 | 3f53e0f33ee260a962b97ef26de1d66b32a12a15 |\n    | undelta.lisp        | 100644 | ae0a070133d1a14d6e940a0f790f40b37e885b22 |\n    | util.lisp           | 100644 | 5374d96e5e29d836a427c40999e0f9c88fb1587a |\n\n*** Show the files that match a pattern\n\n    #+BEGIN_SRC lisp :exports both :results table :hlines yes :post proc(data=*this*)\n      (co.fwoar.git:with-repository (\".\")\n        (let* ((branch (co.fwoar.git:branch \"main\"))\n               (tree (co.fwoar.git:tree branch))\n               (tree-entries (co.fwoar.git:filter-tree \"^.....?[.]lisp\" tree)))\n          (flet ((component (component)\n                   (lambda (it)\n                     (co.fwoar.git:component component it))))\n            (list* '(\"Name\" \"Mode\" \"Hash\")\n                   'hline\n                   (mapcar (data-lens:juxt (component :name)\n                                           (component :mode)\n                                           (component :hash))\n                           tree-entries)))))\n    #+END_SRC\n\n    #+RESULTS:\n    | Name       |   Mode | Hash                                     |\n    |------------+--------+------------------------------------------|\n    | delta.lisp | 100644 | 1014147a1946752542c1ea7dd9700cb047055047 |\n    | graph.lisp | 100644 | 25596749c5bf5ee2d5a76b355821f57010beb31a |\n    | model.lisp | 100644 | ade5096654ea6ff352354d381784a5d9dda0a3e7 |\n    | pack.lisp  | 100644 | 16b02b061756f59d615b5f1f7f473789ad86b676 |\n    | tree.lisp  | 100644 | c798b0c4d0b5f552548bac98f44b5b5c19334e66 |\n    | types.lisp | 100644 | 3f53e0f33ee260a962b97ef26de1d66b32a12a15 |\n    | util.lisp  | 100644 | 5374d96e5e29d836a427c40999e0f9c88fb1587a |\n\n** Partially Implemented:\n\n*** Delta refs\n    Git uses a [[https://git-scm.com/docs/pack-format#_deltified_representation][delta calculation]] routine to compress some of the blobs\n    in a pack file. This delta stores a reference to a base object and\n    a sequence of commands for transforming the base object into the\n    new object. My plan to support this is to first just extract the\n    commands from the pack file and store them as a [[file:delta.lisp::(defclass delta () ((%repository :initarg :repository :reader repository) (%base :initarg :base :reader base) (%commands :initarg :commands :reader commands)))][delta object]]. When\n    this works adequately, I'll write an interpreter to do the actual\n    merge.\n\n    A workaround for the moment is to manually unpack the pack files:\n\n    #+BEGIN_SRC sh :noeval\n      mkdir tmp\n      mv .git/objects/pack/* tmp\n      for pack in tmp/*.pack; do\n        git unpack-objects \u003c \"$pack\";\n      done\n    #+END_SRC\n\n    Or, you can undeltify the packs by, first unpacking the packfile as above and then doing:\n\n    #+BEGIN_SRC sh :noeval\n      git repack --window=0\n    #+END_SRC\n\n\n*** git:git porcelain\n    I have some thoughts abound a =(git:git ...)= form that can be\n    used as a [[https://github.com/shinmera/lquery.git][lQuery-like]] DSL for manipulating git repositories, and\n    this is partially implemented in [[file+emacs:./porcelain.lisp][porcelain.lisp]], but the details\n    need more thought before it is ready.\n\n\n** TODOs\n*** TODO start implementing Pharo-like git integration (read-only first, commits later)\n\n#+name: proc\n#+begin_src emacs-lisp :var data=()\n  (mapcar (lambda (it)\n            (if (equal it 'HLINE)\n                'hline\n              it))\n          data)\n#+end_src\n\n#+RESULTS: proc\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffiddlerwoaroof%2Fcl-git","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ffiddlerwoaroof%2Fcl-git","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffiddlerwoaroof%2Fcl-git/lists"}