commit - af5ef7cdaa903853a7c4ec598ecfd78a354513d3
commit + 23a0b465c39b4a1717ef71fc45bb57d7edca358e
blob - 89c6e9b0f909838fddd73de36526267dace59164
blob + ab672dcecc9b2b504bf24874b05ad159b3904833
--- vc-got.el
+++ vc-got.el
;; * working-revision DONE
;; * checkout-model DONE
;; - mode-line-string NOT IMPLEMENTED
+;;
+;; STATE-CHANGING FUNCTIONS:
+;; * create-repo NOT IMPLEMENTED
+;; I don't think got init does
+;; what this function is supposed
+;; to do.
+;; * register DONE
+;; - responsible-p DONE
+;; - receive-file NOT IMPLEMENTED
+;; - unregister NOT IMPLEMENTED
+;; use remove?
+;; * checkin DONE
+;; * find-revision DONE
;; TODO: use the idiom
;; (let (process-file-side-effects) ...)
(require 'cl-lib)
(require 'seq)
+(require 'vc)
(defvar vc-got-cmd "got"
"The got command.")
"Call `vc-got-cmd' in the `default-directory' with ARGS and put the output in the current buffer."
(apply #'process-file vc-got-cmd nil (current-buffer) nil args))
+(defun vc-got--add (files)
+ "Add FILES to got, passing `vc-register-switches' to the command invocation."
+ (with-temp-buffer
+ (apply #'vc-got--call "add" (append vc-register-switches files))))
+
(defun vc-got--log (limit path)
- "Execute the log command in the worktree of PATH, with LIMIT commits, and put the output in the current buffer.
+ "Execute the log command in the worktree of PATH.
-Return nil if the command failed or if PATH isn't included in any worktree."
+The output of the command will be put in the current-buffer.
+
+LIMIT limits the maximum number of commit returned.
+
+Return nil if the command failed or if PATH isn't included in any
+worktree."
(vc-got-with-worktree path
(zerop (vc-got--call "log" "-l" (format "%s" limit) path))))
collect (cl-destructuring-bind (status file) (split-string line " " t " ")
`(,file . ,(vc-got--parse-status-flag status)))))
+(defun vc-got--tree-parse ()
+ "Parse into an alist the output of got tree -i in the current buffer."
+ (goto-char (point-min))
+ (cl-loop
+ until (= (point) (point-max))
+ collect (let* ((obj-start (point))
+ (_ (forward-word))
+ (obj (buffer-substring obj-start (point)))
+ (_ (forward-char)) ;skip the space
+ (filename-start (point))
+ (_ (move-end-of-line nil))
+ (filename (buffer-substring filename-start (point))))
+ ;; goto the start of the next line
+ (forward-line)
+ (move-beginning-of-line nil)
+ `(,filename . ,obj))))
+
+(defun vc-got--tree (commit path)
+ (vc-got-with-worktree path
+ (with-temp-buffer
+ (vc-got--call "tree" "-c" commit "-i" path)
+ (vc-got--tree-parse))))
+
+(defun vc-got--cat (commit obj-id)
+ "Execute got cat -c COMMIT OBJ-ID in the current buffer."
+ (vc-got--call "cat" "-c" commit obj-id))
+
;; Backend properties
(defun vc-got-checkout-model (_files)
'implicit)
+
+;; state-changing functions
+
+(defun vc-got-create-repo (_backend)
+ (error "vc got: create-repo not implemented"))
+
+(defun vc-got-register (files &optional _comment)
+ "Register FILES, passing `vc-register-switches' to the backend command."
+ (vc-got--add files))
+
+(defun vc-got-responsible-p (file)
+ (vc-find-root file ".got"))
+
+(defun vc-got-checkin (files comment &optional _rev)
+ "Commit FILES with COMMENT as commit message."
+ (with-temp-buffer
+ (apply #'vc-got--call "commit" "-m" comment files)))
+
+(defun vc-got-find-revision (file rev buffer)
+ (when-let (obj-id (assoc file (vc-got--tree rev file) #'string=))
+ (with-current-buffer buffer
+ (vc-got-with-worktree file
+ (vc-got--cat rev obj-id)))))
+
(provide 'vc-got)
;;; vc-got.el ends here