git.fiddlerwoaroof.com
Browse code

feat: begin introducing rich repository objects

TODO: use this new object more consistently

Ed L authored on 15/11/2020 08:09:50
Showing 6 changed files
... ...
@@ -35,7 +35,7 @@
35 35
     #+END_SRC
36 36
 
37 37
     #+RESULTS:
38
-    : #<LOOSE-REF 9d3dfa0 of ~/git_repos/cl-git/>
38
+    : #<LOOSE-REF 3df0b6f of ~/git_repos/cl-git/>
39 39
 
40 40
 
41 41
 *** Show the commit message
... ...
@@ -47,7 +47,7 @@
47 47
     #+END_SRC
48 48
 
49 49
     #+RESULTS:
50
-    : feat: start moving to ref objects instead of strings
50
+    : Merge commit 'e24e23183435b58a7d6176d848ee0f6c6b3e815a'
51 51
 
52 52
 *** Show the messages of the commit's parent
53 53
 
... ...
@@ -58,7 +58,8 @@
58 58
     #+END_SRC
59 59
 
60 60
     #+RESULTS:
61
-    : (#<PACKED-REF 2af7b67 of ~/git_repos/cl-git/>)
61
+    : (#<LOOSE-REF f4040ce of ~/git_repos/cl-git/>
62
+    :  #<LOOSE-REF e24e231 of ~/git_repos/cl-git/>)
62 63
 
63 64
 *** Show the files in a commit
64 65
 
... ...
@@ -77,7 +78,7 @@
77 78
     | .gitignore      | 100644 | 8a9fe9f77149f74fed5c05388be8e5ffd4a31678 |
78 79
     | .projectile     | 100644 | e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 |
79 80
     | LICENSE         | 100644 | 0306819e780fa57dc3bf6b99a0a059670b605ae0 |
80
-    | README.org      | 100644 | 62af1bf37cb1d91a426251ee5b09029833efe18c |
81
+    | README.org      | 100644 | 2703b3dae5a5f8bee662bcc88820b348b41a9ca5 |
81 82
     | branch.lisp     | 100644 | e06b66967fa4fa005ccf00dcbc7d839b22259593 |
82 83
     | cl-git.asd      | 100644 | 265a98fb79595e0067e53d8cf222dec4283f8525 |
83 84
     | commit.lisp     | 100644 | 197e10755343900cfbcb7fc6d863d4b3231e74d4 |
... ...
@@ -85,11 +86,11 @@
85 86
     | extract.lisp    | 100644 | 4707eca4ee0c70520ccdc57c0e831187b21271e7 |
86 87
     | git.lisp        | 100644 | c516dfc248544509c3ae58e3a8c2ab81c225aa9c |
87 88
     | graph.lisp      | 100644 | 31576396aff0fff28f69e0ef84571c0dc8cc43ec |
88
-    | model.lisp      | 100644 | a339f9dfc57b461e09d94c176fe90d90c13daf42 |
89
+    | model.lisp      | 100644 | 508861152a0ad7ebfafedd12cee7f4c0a170785c |
89 90
     | package.lisp    | 100644 | a9d12e807ab4cdf923de2b0479507910054da0d4 |
90
-    | porcelain.lisp  | 100644 | 7247e63da9cd823e5ee1e480c2863d87679ec0a3 |
91
+    | porcelain.lisp  | 100644 | d2bf143d76f597409fa729ea6095e89fe2fb9d79 |
91 92
     | protocol.lisp   | 100644 | 7e24a6a7a4349497fce06830fa132e9a8ef6fd06 |
92
-    | repository.lisp | 100644 | 9567a5825bf65b7e90d6f9a02574a00b53af9171 |
93
+    | repository.lisp | 100644 | d9fd84a83d400f416097571ae378302e4cce289b |
93 94
     | tree.lisp       | 100644 | b757bb704b4c7a54622b7bd197ad5c1ea51ef2cc |
94 95
     | undelta.lisp    | 100644 | ae0a070133d1a14d6e940a0f790f40b37e885b22 |
95 96
     | util.lisp       | 100644 | 66279b2fa08c9d0872e888b85fe14d9950e27326 |
... ...
@@ -41,9 +41,11 @@
41 41
 
42 42
 (defgeneric repository (root)
43 43
   (:method ((root string))
44
-    (fw.lu:new 'repository root))
44
+    (let ((root (parse-namestring root)))
45
+      (repository root)))
45 46
   (:method ((root pathname))
46
-    (fw.lu:new 'repository root)))
47
+    (let ((root (truename root)))
48
+      (fw.lu:new 'repository root))))
47 49
 
48 50
 (defun get-local-branches (root)
49 51
   (append (get-local-unpacked-branches root)
... ...
@@ -2,7 +2,8 @@
2 2
 
3 3
 (defpackage :fwoar.cl-git
4 4
   (:use :cl )
5
-  (:export ))
5
+  (:export
6
+   #:ensure-ref))
6 7
 
7 8
 (defpackage :cl-git-user
8 9
   (:use :cl :fwoar.cl-git))
... ...
@@ -10,10 +10,11 @@
10 10
 
11 11
 (defun git:in-repository (root)
12 12
   (setf *git-repository*
13
-        (truename root)))
13
+        (ensure-repository
14
+         (truename root))))
14 15
 
15 16
 (defmacro git:with-repository ((root) &body body)
16
-  `(let ((*git-repository* (truename ,root)))
17
+  `(let ((*git-repository* (ensure-repository ,root)))
17 18
      ,@body))
18 19
 
19 20
 (defun git:show-repository ()
... ...
@@ -120,8 +121,8 @@
120 121
 (defun git:branch (&optional (branch :master))
121 122
   #+lispworks
122 123
   (declare (notinline serapeum:assocadr))
123
-  (let ((branches (branches (repository *git-repository*))))
124
-    (ref (repository *git-repository*)
124
+  (let ((branches (branches *git-repository*)))
125
+    (ref *git-repository*
125 126
          (serapeum:assocadr (etypecase branch
126 127
                               (string branch)
127 128
                               (keyword (string-downcase branch)))
... ...
@@ -129,7 +130,7 @@
129 130
                             :test 'equal))))
130 131
 
131 132
 (defun git:branches ()
132
-  (branches (repository *git-repository*)))
133
+  (branches *git-repository*))
133 134
 
134 135
 (defun git::parents (commit)
135 136
   (alexandria:mappend (data-lens:<>1 (data-lens:over 'ensure-ref)
... ...
@@ -21,3 +21,14 @@
21 21
                            :repo repo-root
22 22
                            :offset offset
23 23
                            :pack pack))))))
24
+
25
+(defun ensure-ref (thing &optional (repo *git-repository*))
26
+  (typecase thing
27
+    (git-ref thing)
28
+    (t (ref repo thing))))
29
+
30
+(defun ensure-repository (thing)
31
+  (etypecase thing
32
+    (repository thing)
33
+    (string (repository thing))
34
+    (pathname (repository thing))))
... ...
@@ -7,12 +7,13 @@
7 7
   (fw.lu:new 'git-tree entries))
8 8
 
9 9
 (defclass tree-entry ()
10
-  ((%mode :initarg :mode :reader te-mode)
10
+  ((%repo :initarg :repo :reader repository)
11
+   (%mode :initarg :mode :reader te-mode)
11 12
    (%name :initarg :name :reader te-name)
12 13
    (%hash :initarg :hash :reader te-hash)))
13 14
 
14
-(defun tree-entry (name mode hash)
15
-  (fw.lu:new 'tree-entry name mode hash))
15
+(defun tree-entry (repo name mode hash)
16
+  (fw.lu:new 'tree-entry repo name mode hash))
16 17
 
17 18
 (defmethod print-object ((o tree-entry) s)
18 19
   (if *print-readably*
... ...
@@ -29,29 +30,30 @@
29 30
 (defun parse-tree-entry (data)
30 31
   (values-list (partition 0 data :with-offset 20)))
31 32
 
32
-(defun format-tree-entry (entry)
33
+(defun format-tree-entry (repo entry)
33 34
   (destructuring-bind (info sha) (partition 0 entry)
34
-    (destructuring-bind (mode name) (partition #\space
35
-                                               (babel:octets-to-string info :encoding *git-encoding*))
36
-      (tree-entry name mode (elt (->sha-string sha) 0)))))
35
+    (destructuring-bind (mode name)
36
+        (partition #\space
37
+                   (babel:octets-to-string info :encoding *git-encoding*))
38
+      (tree-entry repo name mode (elt (->sha-string sha) 0)))))
37 39
 
38
-(defun tree-entries (data &optional accum)
40
+(defun tree-entries (repo data &optional accum)
39 41
   (if (<= (length data) 0)
40 42
       (nreverse accum)
41 43
       (multiple-value-bind (next rest) (parse-tree-entry data)
42 44
         (tree-entries rest
43
-                      (list* (format-tree-entry next)
45
+                      (list* (format-tree-entry repo next)
44 46
                              accum)))))
45 47
 
46 48
 (defmethod -extract-object-of-type ((type (eql :tree)) s repository &key)
47
-  (git-tree (tree-entries s)))
49
+  (git-tree (tree-entries repository s)))
48 50
 
49 51
 (defmethod component ((component (eql :entries)) (object git-tree))
50 52
   (entries object))
51 53
 (defmethod component ((component string) (object git-tree))
52
-  (remove component (entries object)
53
-          :test-not #'equal
54
-          :key 'te-name))
54
+  (car (remove component (entries object)
55
+               :test-not #'equal
56
+               :key 'te-name)))
55 57
 (defmethod component ((component pathname) (object git-tree))
56 58
   (remove-if-not (lambda (it)
57 59
                    (pathname-match-p it component))
... ...
@@ -64,3 +66,6 @@
64 66
   (te-mode object))
65 67
 (defmethod component ((component (eql :hash)) (object tree-entry))
66 68
   (te-hash object))
69
+(defmethod component ((component (eql :ref)) (object tree-entry))
70
+  (ref (repository object)
71
+       (te-hash object)))