Blame


1 af5ef7cd 2020-11-29 op ;; vc-got.el --- Game of Tree backend for VC -*- lexical-binding: t; -*-
2 af5ef7cd 2020-11-29 op
3 af5ef7cd 2020-11-29 op ;; Copyright © 2020 Omar Polo <op@omarpolo.com>
4 af5ef7cd 2020-11-29 op
5 af5ef7cd 2020-11-29 op ;; This file is not part of GNU Emacs.
6 af5ef7cd 2020-11-29 op
7 af5ef7cd 2020-11-29 op ;; This file is free software.
8 af5ef7cd 2020-11-29 op ;;
9 af5ef7cd 2020-11-29 op ;; Permission to use, copy, modify, and distribute this software for
10 af5ef7cd 2020-11-29 op ;; any purpose with or without fee is hereby granted, provided that
11 af5ef7cd 2020-11-29 op ;; the above copyright notice and this permission notice appear in all
12 af5ef7cd 2020-11-29 op ;; copies.
13 af5ef7cd 2020-11-29 op ;;
14 af5ef7cd 2020-11-29 op ;; THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
15 af5ef7cd 2020-11-29 op ;; WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
16 af5ef7cd 2020-11-29 op ;; WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
17 af5ef7cd 2020-11-29 op ;; AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR
18 af5ef7cd 2020-11-29 op ;; CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
19 af5ef7cd 2020-11-29 op ;; OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
20 af5ef7cd 2020-11-29 op ;; NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
21 af5ef7cd 2020-11-29 op ;; CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
22 af5ef7cd 2020-11-29 op
23 af5ef7cd 2020-11-29 op ;; Author: Omar Polo <op@omarpolo.com>
24 af5ef7cd 2020-11-29 op ;; URL: https://git.omarpolo.com/vc-got
25 af5ef7cd 2020-11-29 op ;; Keywords: vc vc-backend
26 af5ef7cd 2020-11-29 op
27 af5ef7cd 2020-11-29 op ;;; Commentary
28 af5ef7cd 2020-11-29 op
29 af5ef7cd 2020-11-29 op ;; Backend implementation status
30 af5ef7cd 2020-11-29 op ;;
31 af5ef7cd 2020-11-29 op ;; Function marked with `*' are required, those with `-' are optional.
32 af5ef7cd 2020-11-29 op ;;
33 af5ef7cd 2020-11-29 op ;; FUNCTION NAME STATUS
34 af5ef7cd 2020-11-29 op ;;
35 af5ef7cd 2020-11-29 op ;; BACKEND PROPERTIES:
36 af5ef7cd 2020-11-29 op ;; * revision-granularity DONE
37 af5ef7cd 2020-11-29 op ;; - update-on-retrieve-tag XXX: what should this do?
38 af5ef7cd 2020-11-29 op ;;
39 af5ef7cd 2020-11-29 op ;; STATE-QUERYING FUNCTIONS:
40 af5ef7cd 2020-11-29 op ;; * registered DONE
41 af5ef7cd 2020-11-29 op ;; * state DONE
42 af5ef7cd 2020-11-29 op ;; - dir-status-files DONE
43 af5ef7cd 2020-11-29 op ;; - dir-extra-headers NOT IMPLEMENTED
44 af5ef7cd 2020-11-29 op ;; - dir-printer NOT IMPLEMENTED
45 af5ef7cd 2020-11-29 op ;; - status-fileinfo-extra NOT IMPLEMENTED
46 af5ef7cd 2020-11-29 op ;; * working-revision DONE
47 af5ef7cd 2020-11-29 op ;; * checkout-model DONE
48 694534b4 2020-12-05 op ;; - mode-line-string DONE
49 23a0b465 2020-11-30 op ;;
50 23a0b465 2020-11-30 op ;; STATE-CHANGING FUNCTIONS:
51 23a0b465 2020-11-30 op ;; * create-repo NOT IMPLEMENTED
52 eb85ad27 2020-12-05 op ;; I don't think got init does what this function is supposed to
53 eb85ad27 2020-12-05 op ;; do.
54 23a0b465 2020-11-30 op ;; * register DONE
55 23a0b465 2020-11-30 op ;; - responsible-p DONE
56 23a0b465 2020-11-30 op ;; - receive-file NOT IMPLEMENTED
57 23a0b465 2020-11-30 op ;; - unregister NOT IMPLEMENTED
58 eb85ad27 2020-12-05 op ;; use remove?
59 23a0b465 2020-11-30 op ;; * checkin DONE
60 23a0b465 2020-11-30 op ;; * find-revision DONE
61 eb85ad27 2020-12-05 op ;; * checkout NOT IMPLEMENTED
62 eb85ad27 2020-12-05 op ;; I'm not sure how to properly implement this. Does filling
63 eb85ad27 2020-12-05 op ;; FILE with the find-revision do the trick? Or use got update?
64 eb85ad27 2020-12-05 op ;; * revert DONE
65 eb85ad27 2020-12-05 op ;; - merge-file NOT IMPLEMENTED
66 eb85ad27 2020-12-05 op ;; - merge-branch DONE
67 eb85ad27 2020-12-05 op ;; - merge-news NOT IMPLEMENTED
68 eb85ad27 2020-12-05 op ;; - pull DONE
69 eb85ad27 2020-12-05 op ;; - steal-lock NOT IMPLEMENTED
70 eb85ad27 2020-12-05 op ;; - modify-change-comment NOT IMPLEMENTED
71 eb85ad27 2020-12-05 op ;; can be implemented via histedit, if I understood correctly
72 eb85ad27 2020-12-05 op ;; what it is supposed to do.
73 eb85ad27 2020-12-05 op ;; - mark-resolved NOT IMPLEMENTED
74 eb85ad27 2020-12-05 op ;; - find-admin-dir NOT IMPLEMENTED
75 eb85ad27 2020-12-05 op ;;
76 eb85ad27 2020-12-05 op ;; HISTORY FUNCTIONS
77 eb85ad27 2020-12-05 op ;; * print-log DONE
78 eb85ad27 2020-12-05 op ;; * log-outgoing NOT IMPLEMENTED
79 eb85ad27 2020-12-05 op ;; * log-incoming NOT IMPLEMENTED
80 eb85ad27 2020-12-05 op ;; - log-search DONE
81 eb85ad27 2020-12-05 op ;; - log-view-mode NOT IMPLEMENTED
82 af5ef7cd 2020-11-29 op
83 af5ef7cd 2020-11-29 op ;; TODO: use the idiom
84 af5ef7cd 2020-11-29 op ;; (let (process-file-side-effects) ...)
85 af5ef7cd 2020-11-29 op ;; when the got command WON'T change the file. This can enable some
86 af5ef7cd 2020-11-29 op ;; emacs optimizations
87 af5ef7cd 2020-11-29 op
88 eb85ad27 2020-12-05 op ;; TODO: vc-git has most function that starts with:
89 eb85ad27 2020-12-05 op ;;
90 eb85ad27 2020-12-05 op ;; (let* ((root (vc-git-root default-directory))
91 eb85ad27 2020-12-05 op ;; (buffer (format "*vc-git : %s*" (expand-file-name root)))
92 eb85ad27 2020-12-05 op ;; ...)
93 eb85ad27 2020-12-05 op ;; ...)
94 eb85ad27 2020-12-05 op ;;
95 eb85ad27 2020-12-05 op ;; we should 1) investigate if also other backends do something like
96 eb85ad27 2020-12-05 op ;; this (or if there is a better way) and 2) try to do the same.
97 eb85ad27 2020-12-05 op
98 af5ef7cd 2020-11-29 op ;;; Code:
99 af5ef7cd 2020-11-29 op
100 af5ef7cd 2020-11-29 op (eval-when-compile
101 af5ef7cd 2020-11-29 op (require 'subr-x))
102 af5ef7cd 2020-11-29 op
103 af5ef7cd 2020-11-29 op (require 'cl-lib)
104 518ede14 2020-12-05 op (require 'cl-seq)
105 af5ef7cd 2020-11-29 op (require 'seq)
106 23a0b465 2020-11-30 op (require 'vc)
107 af5ef7cd 2020-11-29 op
108 af5ef7cd 2020-11-29 op (defvar vc-got-cmd "got"
109 af5ef7cd 2020-11-29 op "The got command.")
110 af5ef7cd 2020-11-29 op
111 af5ef7cd 2020-11-29 op ;; helpers
112 af5ef7cd 2020-11-29 op
113 af5ef7cd 2020-11-29 op (defun vc-got-root (file)
114 af5ef7cd 2020-11-29 op "Return the work tree root for FILE, or nil."
115 f6e414a6 2020-11-30 op (or (vc-file-getprop file 'got-root)
116 f6e414a6 2020-11-30 op (vc-file-setprop file 'got-root (vc-find-root file ".got"))))
117 af5ef7cd 2020-11-29 op
118 af5ef7cd 2020-11-29 op (defmacro vc-got-with-worktree (file &rest body)
119 af5ef7cd 2020-11-29 op "Evaluate BODY in the work tree directory of FILE."
120 af5ef7cd 2020-11-29 op (declare (indent defun))
121 af5ef7cd 2020-11-29 op `(when-let (default-directory (vc-got-root ,file))
122 af5ef7cd 2020-11-29 op ,@body))
123 af5ef7cd 2020-11-29 op
124 af5ef7cd 2020-11-29 op (defun vc-got--call (&rest args)
125 af5ef7cd 2020-11-29 op "Call `vc-got-cmd' in the `default-directory' with ARGS and put the output in the current buffer."
126 af5ef7cd 2020-11-29 op (apply #'process-file vc-got-cmd nil (current-buffer) nil args))
127 af5ef7cd 2020-11-29 op
128 23a0b465 2020-11-30 op (defun vc-got--add (files)
129 23a0b465 2020-11-30 op "Add FILES to got, passing `vc-register-switches' to the command invocation."
130 23a0b465 2020-11-30 op (with-temp-buffer
131 23a0b465 2020-11-30 op (apply #'vc-got--call "add" (append vc-register-switches files))))
132 23a0b465 2020-11-30 op
133 518ede14 2020-12-05 op (defun vc-got--log (&optional path limit start-commit search-pattern)
134 23a0b465 2020-11-30 op "Execute the log command in the worktree of PATH.
135 518ede14 2020-12-05 op The output in the current buffer.
136 af5ef7cd 2020-11-29 op
137 23a0b465 2020-11-30 op LIMIT limits the maximum number of commit returned.
138 23a0b465 2020-11-30 op
139 518ede14 2020-12-05 op START-COMMIT: start traversing history at the specified commit.
140 518ede14 2020-12-05 op SEARCH-PATTERN: limit to log messages matched by the regexp given.
141 518ede14 2020-12-05 op
142 23a0b465 2020-11-30 op Return nil if the command failed or if PATH isn't included in any
143 23a0b465 2020-11-30 op worktree."
144 518ede14 2020-12-05 op (vc-got-with-worktree (or path default-directory)
145 518ede14 2020-12-05 op (zerop
146 518ede14 2020-12-05 op (apply #'vc-got--call
147 518ede14 2020-12-05 op (cl-remove-if #'null
148 518ede14 2020-12-05 op (flatten-list
149 518ede14 2020-12-05 op (list "log"
150 518ede14 2020-12-05 op (when limit (list "-l" (format "%s" limit)))
151 518ede14 2020-12-05 op (when start-commit (list "-c" start-commit))
152 518ede14 2020-12-05 op (when search-pattern (list "-s" search-pattern))
153 518ede14 2020-12-05 op path)))))))
154 af5ef7cd 2020-11-29 op
155 af5ef7cd 2020-11-29 op (defun vc-got--status (dir-or-file &rest files)
156 af5ef7cd 2020-11-29 op "Return the output of ``got status''.
157 af5ef7cd 2020-11-29 op
158 af5ef7cd 2020-11-29 op DIR-OR-FILE can be either a directory or a file. If FILES is
159 af5ef7cd 2020-11-29 op given, return the status of those files, otherwise the status of
160 af5ef7cd 2020-11-29 op DIR-OR-FILE."
161 af5ef7cd 2020-11-29 op (vc-got-with-worktree dir-or-file
162 af5ef7cd 2020-11-29 op (with-temp-buffer
163 af5ef7cd 2020-11-29 op (if files
164 af5ef7cd 2020-11-29 op (apply #'vc-got--call "status" files)
165 af5ef7cd 2020-11-29 op (vc-got--call "status" dir-or-file))
166 af5ef7cd 2020-11-29 op (buffer-string))))
167 af5ef7cd 2020-11-29 op
168 af5ef7cd 2020-11-29 op (defun vc-got--parse-status-flag (flag)
169 af5ef7cd 2020-11-29 op "Parse FLAG, see `vc-state'."
170 af5ef7cd 2020-11-29 op ;; got outputs nothing if the file is up-to-date
171 af5ef7cd 2020-11-29 op (if (string-empty-p flag)
172 af5ef7cd 2020-11-29 op 'up-to-date
173 af5ef7cd 2020-11-29 op ;; trying to follow the order of the manpage
174 af5ef7cd 2020-11-29 op (cl-case (aref flag 0)
175 af5ef7cd 2020-11-29 op (?M 'edited)
176 af5ef7cd 2020-11-29 op (?A 'added)
177 af5ef7cd 2020-11-29 op (?D 'removed)
178 af5ef7cd 2020-11-29 op (?C 'conflict)
179 af5ef7cd 2020-11-29 op (?! 'missing)
180 af5ef7cd 2020-11-29 op (?~ 'edited) ;XXX: what does it means for a file to be ``obstructed''?
181 af5ef7cd 2020-11-29 op (?? 'unregistered)
182 af5ef7cd 2020-11-29 op (?m 'edited) ;modified file modes
183 af5ef7cd 2020-11-29 op (?N nil))))
184 af5ef7cd 2020-11-29 op
185 af5ef7cd 2020-11-29 op (defun vc-got--parse-status (output)
186 af5ef7cd 2020-11-29 op "Parse the OUTPUT of got status and return an alist of (FILE . STATUS)."
187 af5ef7cd 2020-11-29 op ;; XXX: the output of got is line-oriented and will break if
188 af5ef7cd 2020-11-29 op ;; filenames contains spaces or newlines.
189 af5ef7cd 2020-11-29 op (cl-loop for line in (split-string output "\n" t)
190 af5ef7cd 2020-11-29 op collect (cl-destructuring-bind (status file) (split-string line " " t " ")
191 af5ef7cd 2020-11-29 op `(,file . ,(vc-got--parse-status-flag status)))))
192 af5ef7cd 2020-11-29 op
193 23a0b465 2020-11-30 op (defun vc-got--tree-parse ()
194 23a0b465 2020-11-30 op "Parse into an alist the output of got tree -i in the current buffer."
195 23a0b465 2020-11-30 op (goto-char (point-min))
196 23a0b465 2020-11-30 op (cl-loop
197 23a0b465 2020-11-30 op until (= (point) (point-max))
198 23a0b465 2020-11-30 op collect (let* ((obj-start (point))
199 23a0b465 2020-11-30 op (_ (forward-word))
200 23a0b465 2020-11-30 op (obj (buffer-substring obj-start (point)))
201 23a0b465 2020-11-30 op (_ (forward-char)) ;skip the space
202 23a0b465 2020-11-30 op (filename-start (point))
203 23a0b465 2020-11-30 op (_ (move-end-of-line nil))
204 23a0b465 2020-11-30 op (filename (buffer-substring filename-start (point))))
205 23a0b465 2020-11-30 op ;; goto the start of the next line
206 23a0b465 2020-11-30 op (forward-line)
207 23a0b465 2020-11-30 op (move-beginning-of-line nil)
208 23a0b465 2020-11-30 op `(,filename . ,obj))))
209 23a0b465 2020-11-30 op
210 23a0b465 2020-11-30 op (defun vc-got--tree (commit path)
211 23a0b465 2020-11-30 op (vc-got-with-worktree path
212 23a0b465 2020-11-30 op (with-temp-buffer
213 23a0b465 2020-11-30 op (vc-got--call "tree" "-c" commit "-i" path)
214 23a0b465 2020-11-30 op (vc-got--tree-parse))))
215 23a0b465 2020-11-30 op
216 23a0b465 2020-11-30 op (defun vc-got--cat (commit obj-id)
217 23a0b465 2020-11-30 op "Execute got cat -c COMMIT OBJ-ID in the current buffer."
218 23a0b465 2020-11-30 op (vc-got--call "cat" "-c" commit obj-id))
219 eb85ad27 2020-12-05 op
220 eb85ad27 2020-12-05 op (defun vc-got--revert (&rest files)
221 eb85ad27 2020-12-05 op "Execute got revert FILES..."
222 eb85ad27 2020-12-05 op (vc-got-with-worktree (car files)
223 eb85ad27 2020-12-05 op (with-temp-buffer
224 eb85ad27 2020-12-05 op (apply #'vc-got--call "revert" files))))
225 eb85ad27 2020-12-05 op
226 eb85ad27 2020-12-05 op (defun vc-got--list-branches ()
227 eb85ad27 2020-12-05 op "Return an alist of (branch . commit)."
228 eb85ad27 2020-12-05 op (with-temp-buffer
229 eb85ad27 2020-12-05 op (when (zerop (vc-got--call "branch" "-l"))
230 eb85ad27 2020-12-05 op (goto-char (point-min))
231 eb85ad27 2020-12-05 op (cl-loop
232 eb85ad27 2020-12-05 op until (= (point) (point-max))
233 eb85ad27 2020-12-05 op ;; parse the `* $branchname: $commit', from the end
234 eb85ad27 2020-12-05 op collect (let* ((_ (move-end-of-line nil))
235 eb85ad27 2020-12-05 op (end-commit (point))
236 eb85ad27 2020-12-05 op (_ (backward-word))
237 eb85ad27 2020-12-05 op (start-commit (point))
238 eb85ad27 2020-12-05 op (_ (backward-char 2))
239 eb85ad27 2020-12-05 op (end-branchname (point))
240 eb85ad27 2020-12-05 op (_ (move-beginning-of-line nil))
241 eb85ad27 2020-12-05 op (_ (forward-char 2))
242 eb85ad27 2020-12-05 op (start-branchname (point))
243 eb85ad27 2020-12-05 op (branchname (buffer-substring start-branchname end-branchname))
244 eb85ad27 2020-12-05 op (commit (buffer-substring start-commit end-commit)))
245 eb85ad27 2020-12-05 op (forward-line)
246 eb85ad27 2020-12-05 op (move-beginning-of-line nil)
247 eb85ad27 2020-12-05 op `(,branchname . ,commit))))))
248 eb85ad27 2020-12-05 op
249 694534b4 2020-12-05 op (defun vc-got--current-branch ()
250 694534b4 2020-12-05 op "Return the current branch."
251 694534b4 2020-12-05 op (with-temp-buffer
252 694534b4 2020-12-05 op (when (zerop (vc-got--call "branch"))
253 694534b4 2020-12-05 op (string-trim (buffer-string) "" "\n"))))
254 eb85ad27 2020-12-05 op
255 eb85ad27 2020-12-05 op (defun vc-got--integrate (branch)
256 eb85ad27 2020-12-05 op "Integrate BRANCH into the current one."
257 eb85ad27 2020-12-05 op (with-temp-buffer
258 eb85ad27 2020-12-05 op (vc-got--call "integrate" branch)))
259 23a0b465 2020-11-30 op
260 eb85ad27 2020-12-05 op (defun vc-got--diff (&rest args)
261 eb85ad27 2020-12-05 op "Call got diff with ARGS. The result will be stored in the current buffer."
262 345290bf 2020-12-05 op (apply #'vc-got--call "diff"
263 345290bf 2020-12-05 op (mapcar #'file-relative-name args)))
264 eb85ad27 2020-12-05 op
265 af5ef7cd 2020-11-29 op
266 af5ef7cd 2020-11-29 op ;; Backend properties
267 af5ef7cd 2020-11-29 op
268 af5ef7cd 2020-11-29 op (defun vc-got-revision-granularity ()
269 af5ef7cd 2020-11-29 op "Got has REPOSITORY granularity."
270 af5ef7cd 2020-11-29 op 'repository)
271 af5ef7cd 2020-11-29 op
272 af5ef7cd 2020-11-29 op ;; XXX: what this should do? The description is not entirely clear
273 af5ef7cd 2020-11-29 op (defun vc-got-update-on-retrieve-tag ()
274 af5ef7cd 2020-11-29 op nil)
275 af5ef7cd 2020-11-29 op
276 af5ef7cd 2020-11-29 op
277 af5ef7cd 2020-11-29 op ;; State-querying functions
278 af5ef7cd 2020-11-29 op
279 af5ef7cd 2020-11-29 op ;;;###autoload (defun vc-got-registered (file)
280 af5ef7cd 2020-11-29 op ;;;###autoload "Return non-nil if FILE is registered with got."
281 af5ef7cd 2020-11-29 op ;;;###autoload (when (vc-find-root file ".got")
282 af5ef7cd 2020-11-29 op ;;;###autoload (load "vc-got" nil t)
283 af5ef7cd 2020-11-29 op ;;;###autoload (vc-got-registered file)))
284 af5ef7cd 2020-11-29 op
285 af5ef7cd 2020-11-29 op (defun vc-got-registered (file)
286 af5ef7cd 2020-11-29 op "Return non-nil if FILE is registered with got."
287 af5ef7cd 2020-11-29 op (if (file-directory-p file)
288 af5ef7cd 2020-11-29 op nil ;got doesn't track directories
289 4093d2f9 2020-12-04 op (when (vc-find-root file ".got")
290 4093d2f9 2020-12-04 op (let ((status (vc-got--status file)))
291 4093d2f9 2020-12-04 op (not (or (string-prefix-p "?" status)
292 4093d2f9 2020-12-04 op (string-prefix-p "N" status)))))))
293 af5ef7cd 2020-11-29 op
294 af5ef7cd 2020-11-29 op ;; (vc-got-registered "/usr/ports/mystuff/net/td")
295 af5ef7cd 2020-11-29 op ;; (vc-got-registered "/usr/ports/mystuff/net/td/Makefile")
296 af5ef7cd 2020-11-29 op ;; (vc-got-registered "/usr/ports/mystuff/tmp")
297 af5ef7cd 2020-11-29 op ;; (vc-got-registered "/usr/ports/mystuff/no-existant")
298 af5ef7cd 2020-11-29 op
299 af5ef7cd 2020-11-29 op (defun vc-got-state (file)
300 af5ef7cd 2020-11-29 op "Return the current version control state of FILE. See `vc-state'."
301 af5ef7cd 2020-11-29 op (unless (file-directory-p file)
302 af5ef7cd 2020-11-29 op (vc-got--parse-status-flag (vc-got--status file))))
303 af5ef7cd 2020-11-29 op
304 af5ef7cd 2020-11-29 op ;; (vc-got-state "/usr/ports/mystuff/net/td")
305 af5ef7cd 2020-11-29 op ;; (vc-got-state "/usr/ports/mystuff/net/td/Makefile")
306 af5ef7cd 2020-11-29 op ;; (vc-got-state "/usr/ports/mystuff/tmp")
307 af5ef7cd 2020-11-29 op ;; (vc-got-state "/usr/ports/mystuff/non-existant")
308 af5ef7cd 2020-11-29 op
309 af5ef7cd 2020-11-29 op (defun vc-got-dir-status-files (dir files update-function)
310 af5ef7cd 2020-11-29 op (let* ((files (seq-filter (lambda (file)
311 af5ef7cd 2020-11-29 op (and (not (string= file ".."))
312 af5ef7cd 2020-11-29 op (not (string= file "."))
313 af5ef7cd 2020-11-29 op (not (string= file ".got"))))
314 af5ef7cd 2020-11-29 op (or files
315 af5ef7cd 2020-11-29 op (directory-files dir))))
316 af5ef7cd 2020-11-29 op (statuses (vc-got--parse-status
317 af5ef7cd 2020-11-29 op (apply #'vc-got--status dir files)))
318 af5ef7cd 2020-11-29 op (default-directory dir))
319 af5ef7cd 2020-11-29 op (cl-loop
320 af5ef7cd 2020-11-29 op with result = nil
321 af5ef7cd 2020-11-29 op for file in files
322 af5ef7cd 2020-11-29 op do (setq result
323 af5ef7cd 2020-11-29 op (cons
324 af5ef7cd 2020-11-29 op (if (file-directory-p file)
325 af5ef7cd 2020-11-29 op (list file 'unregistered nil)
326 af5ef7cd 2020-11-29 op (if-let (status (cdr (assoc file statuses #'string=)))
327 af5ef7cd 2020-11-29 op (list file status nil)
328 af5ef7cd 2020-11-29 op (list file 'up-to-date nil)))
329 af5ef7cd 2020-11-29 op result))
330 af5ef7cd 2020-11-29 op finally (funcall update-function result nil))))
331 af5ef7cd 2020-11-29 op
332 af5ef7cd 2020-11-29 op ;; (let ((dir "/usr/ports/mystuff"))
333 af5ef7cd 2020-11-29 op ;; (vc-got-dir-status-files dir nil (lambda (res _t)
334 af5ef7cd 2020-11-29 op ;; (message "got %s" res))))
335 af5ef7cd 2020-11-29 op
336 af5ef7cd 2020-11-29 op (defun vc-got-working-revision (file)
337 c0c9a339 2020-12-04 op "Return the id of the last commit that touched the FILE or \"0\" for a new (but added) file."
338 af5ef7cd 2020-11-29 op (or
339 af5ef7cd 2020-11-29 op (with-temp-buffer
340 518ede14 2020-12-05 op (when (vc-got--log file 1)
341 af5ef7cd 2020-11-29 op (let (start)
342 af5ef7cd 2020-11-29 op (goto-char (point-min))
343 af5ef7cd 2020-11-29 op (forward-line 1) ;skip the ----- line
344 af5ef7cd 2020-11-29 op (forward-word) ;skip "commit"
345 af5ef7cd 2020-11-29 op (forward-char) ;skip the space
346 af5ef7cd 2020-11-29 op (setq start (point)) ;store start of the SHA
347 af5ef7cd 2020-11-29 op (forward-word) ;goto SHA end
348 af5ef7cd 2020-11-29 op (buffer-substring start (point)))))
349 af5ef7cd 2020-11-29 op ;; special case: if this file is added but has no previous commits
350 af5ef7cd 2020-11-29 op ;; touching it, got log will fail (as expected), but we have to
351 af5ef7cd 2020-11-29 op ;; return "0".
352 af5ef7cd 2020-11-29 op (when (eq (vc-got-state file) 'added)
353 af5ef7cd 2020-11-29 op "0")))
354 af5ef7cd 2020-11-29 op
355 af5ef7cd 2020-11-29 op ;; (vc-got-working-revision "/usr/ports/mystuff/non-existant")
356 af5ef7cd 2020-11-29 op ;; (vc-got-working-revision "/usr/ports/mystuff/CVS")
357 af5ef7cd 2020-11-29 op ;; (vc-got-working-revision "/usr/ports/mystuff/tmp")
358 af5ef7cd 2020-11-29 op ;; (vc-got-working-revision "/usr/ports/mystuff/net/td/Makefile")
359 af5ef7cd 2020-11-29 op
360 af5ef7cd 2020-11-29 op (defun vc-got-checkout-model (_files)
361 af5ef7cd 2020-11-29 op 'implicit)
362 af5ef7cd 2020-11-29 op
363 694534b4 2020-12-05 op (defun vc-got-mode-line-string (file)
364 694534b4 2020-12-05 op "Return the VC mode line string for FILE."
365 694534b4 2020-12-05 op (vc-got-with-worktree file
366 694534b4 2020-12-05 op (let ((def (vc-default-mode-line-string 'Got file)))
367 694534b4 2020-12-05 op (concat (substring def 0 4) (vc-got--current-branch)))))
368 694534b4 2020-12-05 op
369 23a0b465 2020-11-30 op
370 23a0b465 2020-11-30 op ;; state-changing functions
371 23a0b465 2020-11-30 op
372 23a0b465 2020-11-30 op (defun vc-got-create-repo (_backend)
373 23a0b465 2020-11-30 op (error "vc got: create-repo not implemented"))
374 23a0b465 2020-11-30 op
375 23a0b465 2020-11-30 op (defun vc-got-register (files &optional _comment)
376 23a0b465 2020-11-30 op "Register FILES, passing `vc-register-switches' to the backend command."
377 23a0b465 2020-11-30 op (vc-got--add files))
378 23a0b465 2020-11-30 op
379 9e805da8 2020-11-30 op (defalias 'vc-got-responsible-p #'vc-got-root)
380 23a0b465 2020-11-30 op
381 23a0b465 2020-11-30 op (defun vc-got-checkin (files comment &optional _rev)
382 23a0b465 2020-11-30 op "Commit FILES with COMMENT as commit message."
383 23a0b465 2020-11-30 op (with-temp-buffer
384 30dcedec 2020-12-05 op (apply #'vc-got--call "commit" "-m"
385 30dcedec 2020-12-05 op ;; emacs add ``Summary:'' at the start of the commit
386 30dcedec 2020-12-05 op ;; message. vc-git doesn't seem to treat this specially.
387 30dcedec 2020-12-05 op ;; Since it's annoying, remove it.
388 30dcedec 2020-12-05 op (string-remove-prefix "Summary: " comment)
389 30dcedec 2020-12-05 op files)))
390 23a0b465 2020-11-30 op
391 23a0b465 2020-11-30 op (defun vc-got-find-revision (file rev buffer)
392 c0c9a339 2020-12-04 op "Fill BUFFER with the content of FILE in the given revision REV."
393 23a0b465 2020-11-30 op (when-let (obj-id (assoc file (vc-got--tree rev file) #'string=))
394 23a0b465 2020-11-30 op (with-current-buffer buffer
395 23a0b465 2020-11-30 op (vc-got-with-worktree file
396 23a0b465 2020-11-30 op (vc-got--cat rev obj-id)))))
397 23a0b465 2020-11-30 op
398 55091167 2020-12-05 op (defun vc-got-find-ignore-file (file)
399 55091167 2020-12-05 op "Return the gitignore file that controls FILE."
400 55091167 2020-12-05 op (expand-file-name ".gitignore"
401 55091167 2020-12-05 op (vc-got-root file)))
402 55091167 2020-12-05 op
403 eb85ad27 2020-12-05 op (defun vc-got-checkout (_file &optional _rev)
404 eb85ad27 2020-12-05 op "Checkout revision REV of FILE. If REV is t, checkout from the head."
405 eb85ad27 2020-12-05 op (error "vc got: checkout not implemented"))
406 eb85ad27 2020-12-05 op
407 eb85ad27 2020-12-05 op (defun vc-got-revert (file &optional _content-done)
408 eb85ad27 2020-12-05 op "Revert FILE back to working revision."
409 eb85ad27 2020-12-05 op (vc-got--revert file))
410 eb85ad27 2020-12-05 op
411 eb85ad27 2020-12-05 op (defun vc-got-merge-branch ()
412 eb85ad27 2020-12-05 op "Prompt for a branch and integrate it into the current one."
413 eb85ad27 2020-12-05 op ;; XXX: be smart and try to "got rebase" if "got integrate" fails?
414 eb85ad27 2020-12-05 op (let* ((branches (cl-loop for (branch . commit) in (vc-got--list-branches)
415 eb85ad27 2020-12-05 op collect branch))
416 eb85ad27 2020-12-05 op (branch (completing-read "Merge from branch: " branches)))
417 eb85ad27 2020-12-05 op (when branch
418 eb85ad27 2020-12-05 op (vc-got--integrate branch))))
419 eb85ad27 2020-12-05 op
420 eb85ad27 2020-12-05 op (defun vc-got-pull (prompt)
421 eb85ad27 2020-12-05 op "Execute got pull, prompting the user for the full command if PROMPT is not nil."
422 eb85ad27 2020-12-05 op (let* ((root (vc-got-root default-directory))
423 eb85ad27 2020-12-05 op (buffer (format "*vc-got : %s*" (expand-file-name root))))
424 eb85ad27 2020-12-05 op (when-let (cmd (if prompt
425 eb85ad27 2020-12-05 op (split-string
426 eb85ad27 2020-12-05 op (read-shell-command "Got pull command: " "got pull")
427 eb85ad27 2020-12-05 op " " t)
428 eb85ad27 2020-12-05 op '("got" "pull")))
429 eb85ad27 2020-12-05 op (vc-do-command buffer 0 vc-got-cmd nil (cdr cmd)))))
430 eb85ad27 2020-12-05 op
431 eb85ad27 2020-12-05 op (defun vc-got-print-log (files buffer &optional _shortlog start-revision limit)
432 eb85ad27 2020-12-05 op "Insert the revision log for FILES into BUFFER.
433 eb85ad27 2020-12-05 op
434 eb85ad27 2020-12-05 op LIMIT limits the number of commits, optionally starting at START-REVISION."
435 eb85ad27 2020-12-05 op (with-current-buffer buffer
436 eb85ad27 2020-12-05 op ;; the *vc-diff* may be read only
437 4571b1fd 2020-12-05 op (let ((inhibit-read-only t))
438 eb85ad27 2020-12-05 op (cl-loop for file in files
439 4571b1fd 2020-12-05 op do (vc-got--log (file-relative-name file) limit start-revision)))))
440 eb85ad27 2020-12-05 op
441 eb85ad27 2020-12-05 op ;; XXX: vc.el specify only pattern, but in reality this takes a buffer
442 eb85ad27 2020-12-05 op ;; and a pattern.
443 eb85ad27 2020-12-05 op (defun vc-got-log-search (buffer pattern)
444 eb85ad27 2020-12-05 op "Search commits for PATTERN and write the results found in BUFFER."
445 eb85ad27 2020-12-05 op (with-current-buffer buffer
446 eb85ad27 2020-12-05 op (let ((inhibit-read-only t))
447 eb85ad27 2020-12-05 op (vc-got--log nil nil nil pattern))))
448 eb85ad27 2020-12-05 op
449 eb85ad27 2020-12-05 op ;; TODO: async
450 eb85ad27 2020-12-05 op ;; TODO: we should append (vc-switches 'got 'diff) to the switches.
451 f18d3e11 2020-12-05 op ;; This by default is ("-u") and causes an error.
452 f18d3e11 2020-12-05 op ;; TODO: return 0 or 1
453 eb85ad27 2020-12-05 op (defun vc-got-diff (files &optional rev1 rev2 buffer _async)
454 eb85ad27 2020-12-05 op "Insert into BUFFER (or *vc-diff*) the diff for FILES from REV1 to REV2."
455 eb85ad27 2020-12-05 op (message "vc-got: debug: files is %s" files)
456 eb85ad27 2020-12-05 op (let* ((buffer (get-buffer-create (or buffer "*vc-difff*")))
457 eb85ad27 2020-12-05 op (inhibit-read-only t))
458 eb85ad27 2020-12-05 op (with-current-buffer buffer
459 eb85ad27 2020-12-05 op (vc-got-with-worktree (car files)
460 eb85ad27 2020-12-05 op (cond ((and (null rev1)
461 eb85ad27 2020-12-05 op (null rev2))
462 345290bf 2020-12-05 op (apply #'vc-got--diff files))
463 eb85ad27 2020-12-05 op (t (error "Not implemented")))))))
464 eb85ad27 2020-12-05 op
465 af5ef7cd 2020-11-29 op (provide 'vc-got)
466 af5ef7cd 2020-11-29 op ;;; vc-got.el ends here