Browse code
Handle :tree and :blob objects
Ed Langley authored on 07/05/2019 07:13:25
Showing 6 changed files
Showing 6 changed files
... | ... |
@@ -42,18 +42,55 @@ |
42 | 42 |
(return-from find-object-in-pack-files |
43 | 43 |
(values pack mid)))))) |
44 | 44 |
|
45 |
-(defgeneric extract-object-of-type (type s) |
|
46 |
- (:method ((type integer) s) |
|
45 |
+(defun behead (data) |
|
46 |
+ (elt (partition 0 data) |
|
47 |
+ 1)) |
|
48 |
+ |
|
49 |
+(defun tree-entry (data) |
|
50 |
+ (values-list (partition 0 data :with-offset 20))) |
|
51 |
+ |
|
52 |
+(defun format-tree-entry (entry) |
|
53 |
+ (destructuring-bind (info sha) (partition 0 entry) |
|
54 |
+ (concatenate 'vector |
|
55 |
+ (apply #'concatenate 'vector |
|
56 |
+ (serapeum:intersperse (vector (char-code #\tab)) |
|
57 |
+ (reverse |
|
58 |
+ (partition (char-code #\space) |
|
59 |
+ info)))) |
|
60 |
+ (list (char-code #\tab)) |
|
61 |
+ (babel:string-to-octets (elt (->sha-string sha) 0) :encoding *git-encoding*)))) |
|
62 |
+ |
|
63 |
+(defun tree-entries (data &optional accum) |
|
64 |
+ (if (<= (length data) 0) |
|
65 |
+ (apply #'concatenate 'vector |
|
66 |
+ (serapeum:intersperse (vector (char-code #\newline)) |
|
67 |
+ (nreverse accum))) |
|
68 |
+ (multiple-value-bind (next rest) (tree-entry data) |
|
69 |
+ (tree-entries rest |
|
70 |
+ (list* (format-tree-entry next) |
|
71 |
+ accum))))) |
|
72 |
+ |
|
73 |
+(defgeneric extract-object-of-type (type s repository) |
|
74 |
+ (:method ((type integer) s repository) |
|
47 | 75 |
(extract-object-of-type (object-type->sym type) |
48 |
- s)) |
|
49 |
- (:method ((type (eql :commit)) (s stream)) |
|
50 |
- (chipz:decompress nil (chipz:make-dstate 'chipz:zlib) s))) |
|
76 |
+ s |
|
77 |
+ repository)) |
|
78 |
+ |
|
79 |
+ (:method ((type (eql :commit)) (s stream) repository) |
|
80 |
+ (chipz:decompress nil (chipz:make-dstate 'chipz:zlib) s)) |
|
81 |
+ |
|
82 |
+ (:method ((type (eql :blob)) (s stream) repository) |
|
83 |
+ (chipz:decompress nil (chipz:make-dstate 'chipz:zlib) s)) |
|
84 |
+ |
|
85 |
+ (:method ((type (eql :tree)) (s stream) repository) |
|
86 |
+ (let* ((data (chipz:decompress nil (chipz:make-dstate 'chipz:zlib) s))) |
|
87 |
+ (tree-entries data)))) |
|
51 | 88 |
|
52 |
-(defun read-object-from-pack (s) |
|
89 |
+(defun read-object-from-pack (s repository) |
|
53 | 90 |
(let* ((metadata (fwoar.bin-parser:extract-high s)) |
54 | 91 |
(type (get-object-type metadata)) |
55 | 92 |
(size (get-object-size metadata)) |
56 |
- (object-data (extract-object-of-type type s))) |
|
93 |
+ (object-data (extract-object-of-type type s repository))) |
|
57 | 94 |
(list (cons :type (object-type->sym type)) |
58 | 95 |
(cons :decompressed-size size) |
59 | 96 |
(cons :object-data object-data) |
... | ... |
@@ -67,7 +104,7 @@ |
67 | 104 |
(file-position s (+ offset-offset (* 4 obj-number))) |
68 | 105 |
(let ((object-offset-in-pack (read-bytes 4 'fwoar.bin-parser:be->int s))) |
69 | 106 |
(file-position p object-offset-in-pack) |
70 |
- (read-object-from-pack p)))))) |
|
107 |
+ (read-object-from-pack p (repository pack))))))) |
|
71 | 108 |
|
72 | 109 |
(defun extract-loose-object (repo id) |
73 | 110 |
(with-open-file (s (object repo id) |
... | ... |
@@ -5,7 +5,8 @@ |
5 | 5 |
|
6 | 6 |
(defclass pack () |
7 | 7 |
((%pack :initarg :pack :reader pack-file) |
8 |
- (%index :initarg :index :reader index-file))) |
|
8 |
+ (%index :initarg :index :reader index-file) |
|
9 |
+ (%repository :initarg :repository :reader repository))) |
|
9 | 10 |
|
10 | 11 |
(defclass repository () |
11 | 12 |
((%root :initarg :root :reader root))) |
... | ... |
@@ -25,8 +26,11 @@ |
25 | 26 |
(6 :ofs-delta) |
26 | 27 |
(7 :ref-delta))) |
27 | 28 |
|
28 |
-(defun repository (root) |
|
29 |
- (fw.lu:new 'repository root)) |
|
29 |
+(defgeneric repository (root) |
|
30 |
+ (:method ((root string)) |
|
31 |
+ (fw.lu:new 'repository root)) |
|
32 |
+ (:method ((root pathname)) |
|
33 |
+ (fw.lu:new 'repository root))) |
|
30 | 34 |
|
31 | 35 |
(defun get-local-branches (root) |
32 | 36 |
(append (get-local-unpacked-branches root) |
... | ... |
@@ -36,11 +40,12 @@ |
36 | 40 |
(let ((obj-path (fwoar.string-utils:insert-at 2 #\/ sha))) |
37 | 41 |
(merge-pathnames obj-path ".git/objects/"))) |
38 | 42 |
|
39 |
-(defun pack (index pack) |
|
40 |
- (fw.lu:new 'pack index pack)) |
|
43 |
+(defun pack (index pack repository) |
|
44 |
+ (fw.lu:new 'pack index pack repository)) |
|
41 | 45 |
|
42 | 46 |
(defun pack-files (repo) |
43 |
- (mapcar 'pack |
|
47 |
+ (mapcar (serapeum:op |
|
48 |
+ (pack _ _ (repository repo))) |
|
44 | 49 |
(uiop:directory* |
45 | 50 |
(merge-pathnames ".git/objects/pack/*.idx" |
46 | 51 |
repo)) |
... | ... |
@@ -12,13 +12,34 @@ |
12 | 12 |
(defun git:show-repository () |
13 | 13 |
*git-repository*) |
14 | 14 |
|
15 |
+(defmacro git:git (&rest commands) |
|
16 |
+ `(uiop:nest ,@(reverse |
|
17 |
+ (mapcar (serapeum:op (case (car _1) |
|
18 |
+ ((<<=) (list* 'mapcan |
|
19 |
+ (list 'quote |
|
20 |
+ (intern (symbol-name (cadadr _1)) |
|
21 |
+ :git)) |
|
22 |
+ (cddr _1))) |
|
23 |
+ ((map) (list* 'mapcar |
|
24 |
+ (list 'quote |
|
25 |
+ (intern (symbol-name (cadadr _1)) |
|
26 |
+ :git)) |
|
27 |
+ (cddr _1))) |
|
28 |
+ (t (cons (intern (symbol-name (car _1)) |
|
29 |
+ :git) |
|
30 |
+ (cdr _1))))) |
|
31 |
+ commands)))) |
|
32 |
+ |
|
15 | 33 |
(defun git:show (object) |
16 | 34 |
(babel:octets-to-string |
17 |
- (extract-object (repository *git-repository*) |
|
18 |
- object) |
|
35 |
+ (coerce (extract-object (repository *git-repository*) |
|
36 |
+ object) |
|
37 |
+ '(vector serapeum:octet)) |
|
19 | 38 |
:encoding *git-encoding*)) |
20 | 39 |
|
21 | 40 |
(defun git:branch (&optional (branch "master")) |
41 |
+ #+lispworks |
|
42 |
+ (declare (notinline serapeum:assocadr)) |
|
22 | 43 |
(let ((branches (branches (repository *git-repository*)))) |
23 | 44 |
(nth-value 0 (serapeum:assocadr branch branches |
24 | 45 |
:test 'equal)))) |
... | ... |
@@ -28,11 +28,14 @@ |
28 | 28 |
(inspect- *trace-output* |
29 | 29 |
(apply fn args)))) |
30 | 30 |
|
31 |
-(defun partition (char string &key from-end) |
|
31 |
+(defun partition (char string &key from-end (with-offset nil wo-p)) |
|
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))) |
|
34 |
+ (if wo-p |
|
35 |
+ (list (subseq string 0 (+ pos with-offset 1)) |
|
36 |
+ (subseq string (+ pos 1 with-offset))) |
|
37 |
+ (list (subseq string 0 pos) |
|
38 |
+ (subseq string (1+ pos)))) |
|
36 | 39 |
(list string |
37 | 40 |
nil)))) |
38 | 41 |
|