git.fiddlerwoaroof.com
Browse code

feat: intern refs

Edward Langley authored on 22/10/2023 09:17:53
Showing 6 changed files
... ...
@@ -1,8 +1,7 @@
1 1
 (in-package :fwoar.cl-git)
2 2
 
3
-(defclass git-commit ()
4
-  ((%hash :initarg :hash :reader hash)
5
-   (%metadata :initarg :metadata :reader metadata)
3
+(defclass git-commit (git-object)
4
+  ((%metadata :initarg :metadata :reader metadata)
6 5
    (%data :initarg :data :reader data)))
7 6
 
8 7
 (defmethod print-object ((o git-commit) s)
... ...
@@ -35,9 +34,6 @@
35 34
                hash))
36 35
 
37 36
 
38
-(defmethod component ((component (eql :hash)) (object git-commit))
39
-  (hash object))
40
-
41 37
 (defmethod component ((component (eql :tree)) (object git-commit))
42 38
   (ensure-ref
43 39
    (cadr
... ...
@@ -1,6 +1,6 @@
1 1
 (in-package :fwoar.cl-git)
2 2
 
3
-(defclass delta ()
3
+(defclass delta (git-object)
4 4
   ((%repository :initarg :repository :reader repository)
5 5
    (%base :initarg :base :reader base)
6 6
    (%commands :initarg :commands :reader commands)))
... ...
@@ -14,7 +14,7 @@
14 14
   ())
15 15
 
16 16
 (defclass git-object ()
17
-  ())
17
+  ((%hash :initarg :hash :accessor hash)))
18 18
 
19 19
 (defgeneric object-type->sym (object-type)
20 20
   (:documentation "Canonicalizes different representations of an
... ...
@@ -146,3 +146,6 @@
146 146
             (serapeum:string-replace (namestring (user-homedir-pathname))
147 147
                                      (root-of (ref-repo obj))
148 148
                                      "~/"))))
149
+
150
+(defmethod component ((component (eql :hash)) (object git-object))
151
+  (hash object))
... ...
@@ -1,9 +1,15 @@
1 1
 (in-package :fwoar.cl-git)
2 2
 
3
-(defclass+ blob ()
3
+(defclass+ blob (git-object)
4 4
   ((%data :reader data :initarg :data)))
5 5
 
6
-(defgeneric -extract-object-of-type (type s repository &key &allow-other-keys)
6
+(defgeneric -extract-object-of-type (type s repository &key  &allow-other-keys)
7
+  (:method :around (type s repository &key hash)
8
+    (let ((result (call-next-method)))
9
+      (prog1 result
10
+        (when (typep result 'git-object)
11
+          (setf (hash result) hash)))))
12
+
7 13
   (:method ((type (eql :blob)) s repository &key)
8 14
     (blob s))
9 15
 
... ...
@@ -27,10 +27,16 @@
27 27
                          :file object-file))
28 28
         (packed-ref repo id))))
29 29
 
30
+(defvar *ref-intern-table*
31
+  (make-hash-table :test 'equal #+sbcl :weakness #+sbcl :key-and-value))
32
+
30 33
 (defun ensure-ref (thing &optional (repo *git-repository*))
31 34
   (typecase thing
32 35
     (git-ref thing)
33
-    (t (ref repo thing))))
36
+    (t (alexandria:when-let ((maybe-result (ref repo thing)))
37
+         (alexandria:ensure-gethash (component :hash maybe-result)
38
+                                    *ref-intern-table*
39
+                                    maybe-result)))))
34 40
 
35 41
 (defun ensure-repository (thing)
36 42
   (repository thing))
... ...
@@ -6,11 +6,10 @@
6 6
 (defun git-tree (entries)
7 7
   (fw.lu:new 'git-tree entries))
8 8
 
9
-(defclass tree-entry ()
9
+(defclass tree-entry (git-object)
10 10
   ((%repo :initarg :repo :reader repository)
11 11
    (%mode :initarg :mode :reader te-mode)
12
-   (%name :initarg :name :reader te-name)
13
-   (%hash :initarg :hash :reader te-hash)))
12
+   (%name :initarg :name :reader te-name)))
14 13
 
15 14
 (defun tree-entry (repo name mode hash)
16 15
   (fw.lu:new 'tree-entry repo name mode hash))
... ...
@@ -65,8 +64,6 @@
65 64
   (te-name object))
66 65
 (defmethod component ((component (eql :mode)) (object tree-entry))
67 66
   (te-mode object))
68
-(defmethod component ((component (eql :hash)) (object tree-entry))
69
-  (te-hash object))
70 67
 (defmethod component ((component (eql :ref)) (object tree-entry))
71 68
   (ref (repository object)
72 69
        (te-hash object)))