git.fiddlerwoaroof.com
Browse code

Update git code to handle packed refs

Ed Langley authored on 06/05/2019 05:52:41
Showing 3 changed files
... ...
@@ -68,8 +68,9 @@
68 68
 (defun extract-loose-object (repo id)
69 69
   (with-open-file (s (object repo id)
70 70
                      :element-type '(unsigned-byte 8))
71
-    (chipz:decompress nil (chipz:make-dstate 'chipz:zlib)
72
-                      s)))
71
+    (alexandria:when-let ((result (chipz:decompress nil (chipz:make-dstate 'chipz:zlib)
72
+                                                    s)))
73
+      (babel:octets-to-string result))))
73 74
 
74 75
 (defun extract-object (repo id)
75 76
   (if (object repo id)
76 77
new file mode 100644
... ...
@@ -0,0 +1,73 @@
1
+(in-package :fwoar.cl-git)
2
+
3
+(defparameter *object-data-lens*
4
+  (data-lens.lenses:make-alist-lens :object-data))
5
+
6
+(defclass pack ()
7
+  ((%pack :initarg :pack :reader pack-file)
8
+   (%index :initarg :index :reader index-file)))
9
+
10
+(defclass repository ()
11
+  ((%root :initarg :root :reader root)))
12
+
13
+(defclass git-object ()
14
+  ())
15
+
16
+(defclass commit (git-object)
17
+  ())
18
+
19
+(defun object-type->sym (object-type)
20
+  (ecase object-type
21
+    (1 :commit)
22
+    (2 :tree)
23
+    (3 :blob)
24
+    (4 :tag)
25
+    (6 :ofs-delta)
26
+    (7 :ref-delta)))
27
+
28
+(defun repository (root)
29
+  (fw.lu:new 'repository root))
30
+
31
+(defun get-local-unpacked-branches (root)
32
+  (mapcar (data-lens:juxt #'pathname-name
33
+                          (alexandria:compose #'serapeum:trim-whitespace
34
+                                              #'alexandria:read-file-into-string))
35
+          (uiop:directory*
36
+           (merge-pathnames ".git/refs/heads/*"
37
+                            root))))
38
+
39
+(defun get-local-packed-branches (root)
40
+  (let* ((packed-ref-file-name (merge-pathnames ".git/packed-refs"
41
+                                                root)))
42
+    (when (probe-file packed-ref-file-name)
43
+      (with-open-file (s packed-ref-file-name)
44
+        (loop for line = (read-line s nil)
45
+              for parts = (partition #\space line)
46
+              for branch-name = (second parts)
47
+              while line
48
+              unless (alexandria:starts-with-subseq "#" line)
49
+              when (alexandria:starts-with-subseq "refs/heads" branch-name)
50
+              collect (list (subseq branch-name
51
+                                    (1+ (position #\/ branch-name
52
+                                                  :from-end t)))
53
+                            (first parts)))))))
54
+
55
+(defun get-local-branches (root)
56
+  (append (get-local-unpacked-branches root)
57
+          (get-local-packed-branches root)))
58
+
59
+(defun loose-object-path (sha)
60
+  (let ((obj-path (fwoar.string-utils:insert-at 2 #\/ sha)))
61
+    (merge-pathnames obj-path ".git/objects/")))
62
+
63
+(defun pack (index pack)
64
+  (fw.lu:new 'pack index pack))
65
+
66
+(defun pack-files (repo)
67
+  (mapcar 'pack
68
+          (uiop:directory*
69
+           (merge-pathnames ".git/objects/pack/*.idx"
70
+                            repo))
71
+          (uiop:directory*
72
+           (merge-pathnames ".git/objects/pack/*.pack"
73
+                            repo))))
... ...
@@ -31,25 +31,25 @@
31 31
 (defun partition (char string &key from-end)
32 32
   (let ((pos (position char string :from-end from-end)))
33 33
     (if pos
34
-	      (list (subseq string 0 pos)
35
-	            (subseq string (1+ pos)))
36
-	      (list string
37
-	            nil))))
34
+        (list (subseq string 0 pos)
35
+              (subseq string (1+ pos)))
36
+      (list string
37
+            nil))))
38 38
 
39 39
 (defun partition-subseq (subseq string &key from-end)
40 40
   (let ((pos (search subseq string :from-end from-end)))
41 41
     (if pos
42
-	      (list (subseq string 0 pos)
43
-	            (subseq string (+ (length subseq) pos)))
44
-	      (list string
45
-	            nil))))
42
+        (list (subseq string 0 pos)
43
+              (subseq string (+ (length subseq) pos)))
44
+      (list string
45
+            nil))))
46 46
 
47 47
 (serapeum:defalias ->sha-string
48 48
   (data-lens:<>1 (data-lens:over 'fwoar.bin-parser:byte-array-to-hex-string)
49 49
                  'batch-20))
50 50
 
51 51
 (defun read-bytes (count format stream)
52
-  (let ((seq (make-array count)))
52
+  (let ((seq (make-array count :element-type 'serapeum:octet)))
53 53
     (read-sequence seq stream)
54 54
     (funcall format
55 55
              seq)))
... ...
@@ -74,4 +74,5 @@
74 74
       (partition-subseq #(#\newline #\newline)
75 75
                         commit #+(or)(babel:octets-to-string commit :encoding :latin1))
76 76
     (values message
77
-            (fwoar.string-utils:split #\newline metadata))))
77
+            (map 'vector (serapeum:op (partition #\space _))
78
+                 (fwoar.string-utils:split #\newline metadata)))))