Git libraries for Common Lisp common in a couple forms. Some attempt to wrap the libgit2 git library (e.g. https://github.com/russell/cl-git). Others wrap the git binary in a subprocess (e.g. http://shinmera.github.io/legit/). Such libraries work well in cases where you control the environment but not all lisp programs run in such circumstances. This library, on the contrary, attempts to implement parsers for git’s file formats as well as a thin “porcelain” interface for manipulating git objects.
This project uses (loosely) conventional-commits: https://www.conventionalcommits.org/en/v1.0.0/
Also, some use of https://github.com/fiddlerwoaroof/git-issue has been made
To run the tests in a clean environment, you can do (this will eventually be a Github Action):
docker run \
-v $PWD/docker-run:/code fiddlerwoaroof/sbcl-static:latest \
--load /code/main.lisp
% git clone https://github.com/fiddlerwoaroof/fwoar.lisputils.git "$HOME/quicklisp/local-projects/fwoar-lisputils"
% git clone https://github.com/fiddlerwoaroof/cl-git.git "$HOME/quicklisp/local-projects/cl-git"
% sbcl --load "$HOME/quicklisp/setup.lisp"
CL-USER> (ql:quickload :cl-git)
(co.fwoar.git:with-repository (".")
;; the argument to branch defaults to "master" or "main"
(co.fwoar.git:branch))
#<LOOSE-REF ba6fdb of #<GIT-REPOSITORY {70161A1853}> {70161A2893}>
(co.fwoar.git:in-repository ".")
(co.fwoar.git:component :message (co.fwoar.git:branch "main"))
feat: don't assume that the default branch is \"master\"
(co.fwoar.git:in-repository ".")
(let* ((branch (co.fwoar.git:branch "main"))
(parents (co.fwoar.git:parents branch)))
(mapcar (lambda (it)
(co.fwoar.git:component :message it))
parents))
("feat: handle bare repositories ")
(co.fwoar.git:in-repository ".")
(list* '("Name" "Mode" "Hash")
'hline
(co.fwoar.git:git (branch "main")
(component :tree :entries)
(map (juxt (component :name)
(component :mode)
(component :hash)))))
Name | Mode | Hash |
---|---|---|
.github | 40000 | beabf775f686fb2608a580b4d58dd589cf160354 |
.gitignore | 100644 | 8a9fe9f77149f74fed5c05388be8e5ffd4a31678 |
.projectile | 100644 | e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 |
LICENSE | 100644 | 0306819e780fa57dc3bf6b99a0a059670b605ae0 |
README.org | 100644 | f25aa710e8c3053f4a6618728702e41c68eb52c5 |
branch.lisp | 100644 | d82ad3bdbae4af13b5a703bf350dd2bb2c9dadd0 |
co.fwoar.cl-git.asd | 100644 | 560a0f63f48161e2ba787ed42332515de7f86f14 |
commit.lisp | 100644 | 6ff88d884da171adf49ed022decd537a5964e41c |
delta.lisp | 100644 | 1014147a1946752542c1ea7dd9700cb047055047 |
docker-run | 40000 | 4703dc01430d67c5d60f00ad412fddfa22f60764 |
docs | 40000 | 9fe62496fc4ab6debd3c5e1b26f844b5566c36d5 |
extract.lisp | 100644 | 4fc2d479ff5c37fc52a51a2cf884e5226fb3b14d |
git.lisp | 100644 | bccecfd98285f2ab98a277a3284bd98b3dd363bf |
graph.lisp | 100644 | 25596749c5bf5ee2d5a76b355821f57010beb31a |
model.lisp | 100644 | ade5096654ea6ff352354d381784a5d9dda0a3e7 |
pack.lisp | 100644 | 16b02b061756f59d615b5f1f7f473789ad86b676 |
package.lisp | 100644 | f8bd75abedd62bd51155ebd1727b5b9476d02c57 |
porcelain.lisp | 100644 | 3f044e12ae9fc5a98a5c84f2f54e6892ae42216a |
protocol.lisp | 100644 | 84a10444b7bce2b844128917cdfc79fa4df6377b |
ref.lisp | 100644 | b508a5546a0bc0b7189a8cf8cebb33a967f3ffb2 |
repository.lisp | 100644 | 4e64262b40bcd0e239276a73426d0d1ac9d0772c |
tests | 40000 | df1addf5dae76e35e84e6ded6fee14cda501f119 |
tree.lisp | 100644 | c798b0c4d0b5f552548bac98f44b5b5c19334e66 |
types.lisp | 100644 | 3f53e0f33ee260a962b97ef26de1d66b32a12a15 |
undelta.lisp | 100644 | ae0a070133d1a14d6e940a0f790f40b37e885b22 |
util.lisp | 100644 | 5374d96e5e29d836a427c40999e0f9c88fb1587a |
(co.fwoar.git:with-repository (".")
(let* ((branch (co.fwoar.git:branch "main"))
(tree (co.fwoar.git:tree branch))
(tree-entries (co.fwoar.git:filter-tree "^.....?[.]lisp" tree)))
(flet ((component (component)
(lambda (it)
(co.fwoar.git:component component it))))
(list* '("Name" "Mode" "Hash")
'hline
(mapcar (data-lens:juxt (component :name)
(component :mode)
(component :hash))
tree-entries)))))
Name | Mode | Hash |
---|---|---|
delta.lisp | 100644 | 1014147a1946752542c1ea7dd9700cb047055047 |
graph.lisp | 100644 | 25596749c5bf5ee2d5a76b355821f57010beb31a |
model.lisp | 100644 | ade5096654ea6ff352354d381784a5d9dda0a3e7 |
pack.lisp | 100644 | 16b02b061756f59d615b5f1f7f473789ad86b676 |
tree.lisp | 100644 | c798b0c4d0b5f552548bac98f44b5b5c19334e66 |
types.lisp | 100644 | 3f53e0f33ee260a962b97ef26de1d66b32a12a15 |
util.lisp | 100644 | 5374d96e5e29d836a427c40999e0f9c88fb1587a |
Git uses a delta calculation routine to compress some of the blobs in a pack file. This delta stores a reference to a base object and a sequence of commands for transforming the base object into the new object. My plan to support this is to first just extract the commands from the pack file and store them as a delta object. When this works adequately, I’ll write an interpreter to do the actual merge.
A workaround for the moment is to manually unpack the pack files:
mkdir tmp
mv .git/objects/pack/* tmp
for pack in tmp/*.pack; do
git unpack-objects < "$pack";
done
Or, you can undeltify the packs by, first unpacking the packfile as above and then doing:
git repack --window=0
I have some thoughts abound a (git:git ...)
form that can be
used as a lQuery-like DSL for manipulating git repositories, and
this is partially implemented in porcelain.lisp, but the details
need more thought before it is ready.
(mapcar (lambda (it)
(if (equal it 'HLINE)
'hline
it))
data)