Blame


1 406d7b4d 2020-12-26 op ;;; vc-got.el --- Game of Tree backend for VC -*- lexical-binding: t; -*-
2 af5ef7cd 2020-11-29 op
3 406d7b4d 2020-12-26 op ;; Copyright (C) 2020 Omar Polo
4 af5ef7cd 2020-11-29 op
5 76d978fa 2021-01-05 op ;; Author: Omar Polo <op@omarpolo.com>
6 406d7b4d 2020-12-26 op ;; Keywords: vc
7 af5ef7cd 2020-11-29 op
8 406d7b4d 2020-12-26 op ;; This program is free software; you can redistribute it and/or modify
9 406d7b4d 2020-12-26 op ;; it under the terms of the GNU General Public License as published by
10 406d7b4d 2020-12-26 op ;; the Free Software Foundation, either version 3 of the License, or
11 406d7b4d 2020-12-26 op ;; (at your option) any later version.
12 af5ef7cd 2020-11-29 op
13 406d7b4d 2020-12-26 op ;; This program is distributed in the hope that it will be useful,
14 406d7b4d 2020-12-26 op ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
15 406d7b4d 2020-12-26 op ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 406d7b4d 2020-12-26 op ;; GNU General Public License for more details.
17 af5ef7cd 2020-11-29 op
18 406d7b4d 2020-12-26 op ;; You should have received a copy of the GNU General Public License
19 406d7b4d 2020-12-26 op ;; along with this program. If not, see <https://www.gnu.org/licenses/>.
20 406d7b4d 2020-12-26 op
21 af5ef7cd 2020-11-29 op ;;; Commentary
22 af5ef7cd 2020-11-29 op
23 af5ef7cd 2020-11-29 op ;; Backend implementation status
24 af5ef7cd 2020-11-29 op ;;
25 af5ef7cd 2020-11-29 op ;; Function marked with `*' are required, those with `-' are optional.
26 af5ef7cd 2020-11-29 op ;;
27 af5ef7cd 2020-11-29 op ;; FUNCTION NAME STATUS
28 af5ef7cd 2020-11-29 op ;;
29 af5ef7cd 2020-11-29 op ;; BACKEND PROPERTIES:
30 af5ef7cd 2020-11-29 op ;; * revision-granularity DONE
31 af5ef7cd 2020-11-29 op ;; - update-on-retrieve-tag XXX: what should this do?
32 af5ef7cd 2020-11-29 op ;;
33 af5ef7cd 2020-11-29 op ;; STATE-QUERYING FUNCTIONS:
34 af5ef7cd 2020-11-29 op ;; * registered DONE
35 af5ef7cd 2020-11-29 op ;; * state DONE
36 af5ef7cd 2020-11-29 op ;; - dir-status-files DONE
37 a8466f02 2020-12-07 op ;; - dir-extra-headers DONE
38 2d83de2e 2021-01-05 op ;; - dir-printer DONE
39 af5ef7cd 2020-11-29 op ;; - status-fileinfo-extra NOT IMPLEMENTED
40 af5ef7cd 2020-11-29 op ;; * working-revision DONE
41 af5ef7cd 2020-11-29 op ;; * checkout-model DONE
42 694534b4 2020-12-05 op ;; - mode-line-string DONE
43 23a0b465 2020-11-30 op ;;
44 23a0b465 2020-11-30 op ;; STATE-CHANGING FUNCTIONS:
45 23a0b465 2020-11-30 op ;; * create-repo NOT IMPLEMENTED
46 eb85ad27 2020-12-05 op ;; I don't think got init does what this function is supposed to
47 eb85ad27 2020-12-05 op ;; do.
48 23a0b465 2020-11-30 op ;; * register DONE
49 23a0b465 2020-11-30 op ;; - responsible-p DONE
50 3cdb0759 2020-01-03 47739920+ ;; - receive-file NOT NEEDED, default `register' works fine
51 3d2d3c39 2020-01-03 47739920+ ;; - unregister NOT IMPLEMENTED, no use case
52 23a0b465 2020-11-30 op ;; * checkin DONE
53 23a0b465 2020-11-30 op ;; * find-revision DONE
54 eb85ad27 2020-12-05 op ;; * checkout NOT IMPLEMENTED
55 eb85ad27 2020-12-05 op ;; I'm not sure how to properly implement this. Does filling
56 eb85ad27 2020-12-05 op ;; FILE with the find-revision do the trick? Or use got update?
57 eb85ad27 2020-12-05 op ;; * revert DONE
58 eb85ad27 2020-12-05 op ;; - merge-file NOT IMPLEMENTED
59 eb85ad27 2020-12-05 op ;; - merge-branch DONE
60 eb85ad27 2020-12-05 op ;; - merge-news NOT IMPLEMENTED
61 eb85ad27 2020-12-05 op ;; - pull DONE
62 686eac9a 2020-12-07 op ;; - push DONE
63 686eac9a 2020-12-07 op ;; uses git
64 3cdb0759 2020-01-03 47739920+ ;; - steal-lock NOT NEEDED, `got' is not using locks
65 eb85ad27 2020-12-05 op ;; - modify-change-comment NOT IMPLEMENTED
66 eb85ad27 2020-12-05 op ;; can be implemented via histedit, if I understood correctly
67 eb85ad27 2020-12-05 op ;; what it is supposed to do.
68 eb85ad27 2020-12-05 op ;; - mark-resolved NOT IMPLEMENTED
69 eb85ad27 2020-12-05 op ;; - find-admin-dir NOT IMPLEMENTED
70 eb85ad27 2020-12-05 op ;;
71 eb85ad27 2020-12-05 op ;; HISTORY FUNCTIONS
72 eb85ad27 2020-12-05 op ;; * print-log DONE
73 9ad1eb5d 2020-12-07 op ;; * log-outgoing DONE
74 6eda2f1f 2020-12-26 op ;; * log-incoming DONE
75 eb85ad27 2020-12-05 op ;; - log-search DONE
76 eb85ad27 2020-12-05 op ;; - log-view-mode NOT IMPLEMENTED
77 6eda2f1f 2020-12-26 op ;; - show-log-entry NOT IMPLEMENTED
78 6eda2f1f 2020-12-26 op ;; - comment-history NOT IMPLEMENTED
79 6eda2f1f 2020-12-26 op ;; - update-changelog NOT IMPLEMENTED
80 7c257a7b 2020-12-31 noreply ;; * diff DONE
81 7c257a7b 2020-12-31 noreply ;; - revision-completion-table NOT IMPLEMENTED
82 3f25d9ff 2020-01-02 noreply ;; - annotate-command DONE
83 3f25d9ff 2020-01-02 noreply ;; - annotate-time DONE
84 7c257a7b 2020-12-31 noreply ;; - annotate-current-time NOT IMPLEMENTED
85 3f25d9ff 2020-01-02 noreply ;; - annotate-extract-revision-at-line DONE
86 7c257a7b 2020-12-31 noreply ;; - region-history NOT IMPLEMENTED
87 7c257a7b 2020-12-31 noreply ;; - region-history-mode NOT IMPLEMENTED
88 7c257a7b 2020-12-31 noreply ;; - mergebase NOT IMPLEMENTED
89 7c257a7b 2020-12-31 noreply ;;
90 7c257a7b 2020-12-31 noreply ;; TAG SYSTEM
91 7c257a7b 2020-12-31 noreply ;; - create-tag NOT IMPLEMENTED
92 7c257a7b 2020-12-31 noreply ;; - retrieve-tag NOT IMPLEMENTED
93 7c257a7b 2020-12-31 noreply ;;
94 7c257a7b 2020-12-31 noreply ;; MISCELLANEOUS NOT IMPLEMENTED
95 3cdb0759 2020-01-03 47739920+ ;; - make-version-backups-p NOT NEEDED, `got' works fine locally
96 7c257a7b 2020-12-31 noreply ;; - root DONE
97 7c257a7b 2020-12-31 noreply ;; - ignore NOT IMPLEMENTED
98 7c257a7b 2020-12-31 noreply ;; - ignore-completion-table NOT IMPLEMENTED
99 3f25d9ff 2020-01-02 noreply ;; - previous-revision DONE
100 3f25d9ff 2020-01-02 noreply ;; - next-revision DONE
101 7c257a7b 2020-12-31 noreply ;; - log-edit-mode NOT IMPLEMENTED
102 3cdb0759 2020-01-03 47739920+ ;; - check-headers NOT NEEDED, `got' does not use headers
103 a96df0e8 2020-01-03 noreply ;; - delete-file DONE
104 3cdb0759 2020-01-03 47739920+ ;; - rename-file NOT NEEDED, `delete' + `register' is enough
105 3cdb0759 2020-01-03 47739920+ ;; - find-file-hook NOT NEEDED, no need for hooks yet
106 3cdb0759 2020-01-03 47739920+ ;; - extra-menu NOT IMPLEMENTED, add `import', `integrate', `stage'?
107 3cdb0759 2020-01-03 47739920+ ;; - extra-dir-menu NOT IMPLEMENTED, same as above
108 7bb16f79 2020-01-03 op ;; - conflicted-files DONE
109 8b635a9f 2020-01-03 op ;; - repository-url DONE
110 af5ef7cd 2020-11-29 op
111 eb85ad27 2020-12-05 op ;; TODO: vc-git has most function that starts with:
112 eb85ad27 2020-12-05 op ;;
113 eb85ad27 2020-12-05 op ;; (let* ((root (vc-git-root default-directory))
114 eb85ad27 2020-12-05 op ;; (buffer (format "*vc-git : %s*" (expand-file-name root)))
115 eb85ad27 2020-12-05 op ;; ...)
116 eb85ad27 2020-12-05 op ;; ...)
117 eb85ad27 2020-12-05 op ;;
118 eb85ad27 2020-12-05 op ;; we should 1) investigate if also other backends do something like
119 eb85ad27 2020-12-05 op ;; this (or if there is a better way) and 2) try to do the same.
120 eb85ad27 2020-12-05 op
121 af5ef7cd 2020-11-29 op ;;; Code:
122 af5ef7cd 2020-11-29 op
123 af5ef7cd 2020-11-29 op (eval-when-compile
124 af5ef7cd 2020-11-29 op (require 'subr-x))
125 af5ef7cd 2020-11-29 op
126 af5ef7cd 2020-11-29 op (require 'cl-lib)
127 518ede14 2020-12-05 op (require 'cl-seq)
128 af5ef7cd 2020-11-29 op (require 'seq)
129 23a0b465 2020-11-30 op (require 'vc)
130 3f25d9ff 2020-01-02 noreply (require 'vc-annotate)
131 6b6c8a78 2021-01-04 op
132 2d83de2e 2021-01-05 op ;; FIXME: avoid loading this? We only need it for
133 2d83de2e 2021-01-05 op ;; vc-dir-filename-mouse-map in our custom printer.
134 2d83de2e 2021-01-05 op (require 'vc-dir)
135 2d83de2e 2021-01-05 op
136 6b6c8a78 2021-01-04 op (require 'vc-got-stage)
137 ba123905 2020-12-08 op
138 e79563bd 2020-12-31 noreply (defgroup vc-got nil
139 e79563bd 2020-12-31 noreply "VC GoT backend."
140 e79563bd 2020-12-31 noreply :group 'vc)
141 af5ef7cd 2020-11-29 op
142 e79563bd 2020-12-31 noreply (defcustom vc-got-program "got"
143 e79563bd 2020-12-31 noreply "Name of the Got executable (excluding any arguments)."
144 6eea6cfb 2021-01-05 op :type 'string)
145 e79563bd 2020-12-31 noreply
146 12ca62f2 2020-12-26 op (defcustom vc-got-diff-switches t
147 12ca62f2 2020-12-26 op "String or list of strings specifying switches for Got diff under VC.
148 12ca62f2 2020-12-26 op If nil, use the value of `vc-diff-switches'. If t, use no switches."
149 12ca62f2 2020-12-26 op :type '(choice (const :tag "Unspecified" nil)
150 12ca62f2 2020-12-26 op (const :tag "None" t)
151 12ca62f2 2020-12-26 op (string :tag "Argument String")
152 6eea6cfb 2021-01-05 op (repeat :tag "Argument List" :value ("") string)))
153 12ca62f2 2020-12-26 op
154 af5ef7cd 2020-11-29 op ;; helpers
155 f09d6359 2020-12-31 noreply (defun vc-got--program-version ()
156 76d978fa 2021-01-05 op "Return string representing the got version."
157 f09d6359 2020-12-31 noreply (let (process-file-side-effects)
158 f09d6359 2020-12-31 noreply (with-temp-buffer
159 f09d6359 2020-12-31 noreply (vc-got--call "-V")
160 f09d6359 2020-12-31 noreply (substring (buffer-string) 4 -1))))
161 af5ef7cd 2020-11-29 op
162 af5ef7cd 2020-11-29 op (defun vc-got-root (file)
163 af5ef7cd 2020-11-29 op "Return the work tree root for FILE, or nil."
164 f6e414a6 2020-11-30 op (or (vc-file-getprop file 'got-root)
165 f6e414a6 2020-11-30 op (vc-file-setprop file 'got-root (vc-find-root file ".got"))))
166 af5ef7cd 2020-11-29 op
167 af5ef7cd 2020-11-29 op (defmacro vc-got-with-worktree (file &rest body)
168 af5ef7cd 2020-11-29 op "Evaluate BODY in the work tree directory of FILE."
169 af5ef7cd 2020-11-29 op (declare (indent defun))
170 af5ef7cd 2020-11-29 op `(when-let (default-directory (vc-got-root ,file))
171 af5ef7cd 2020-11-29 op ,@body))
172 686eac9a 2020-12-07 op
173 686eac9a 2020-12-07 op (defun vc-got--repo-root ()
174 686eac9a 2020-12-07 op "Return the path to the repository root.
175 686eac9a 2020-12-07 op Assume `default-directory' is inside a got worktree."
176 686eac9a 2020-12-07 op (vc-got-with-worktree default-directory
177 686eac9a 2020-12-07 op (with-temp-buffer
178 686eac9a 2020-12-07 op (insert-file-contents ".got/repository")
179 76d978fa 2021-01-05 op (string-trim (buffer-string) "" "\n"))))
180 af5ef7cd 2020-11-29 op
181 af5ef7cd 2020-11-29 op (defun vc-got--call (&rest args)
182 76d978fa 2021-01-05 op "Call `vc-got-program' with ARGS.
183 76d978fa 2021-01-05 op The output will be placed in the current buffer."
184 fab791a2 2020-01-03 op (apply #'process-file vc-got-program nil (current-buffer) nil
185 fab791a2 2020-01-03 op (cl-remove-if #'null (flatten-list args))))
186 af5ef7cd 2020-11-29 op
187 23a0b465 2020-11-30 op (defun vc-got--add (files)
188 23a0b465 2020-11-30 op "Add FILES to got, passing `vc-register-switches' to the command invocation."
189 23a0b465 2020-11-30 op (with-temp-buffer
190 76d978fa 2021-01-05 op (vc-got--call "add" vc-register-switches files)))
191 23a0b465 2020-11-30 op
192 0a66694e 2020-01-02 op (defun vc-got--log (&optional path limit start-commit stop-commit
193 0a66694e 2020-01-02 op search-pattern reverse)
194 76d978fa 2021-01-05 op "Execute the log command in the worktree of PATH in the current buffer.
195 23a0b465 2020-11-30 op LIMIT limits the maximum number of commit returned.
196 23a0b465 2020-11-30 op
197 518ede14 2020-12-05 op START-COMMIT: start traversing history at the specified commit.
198 9ad1eb5d 2020-12-07 op STOP-COMMIT: stop traversing history at the specified commit.
199 518ede14 2020-12-05 op SEARCH-PATTERN: limit to log messages matched by the regexp given.
200 0a66694e 2020-01-02 op REVERSE: display the log messages in reverse order.
201 518ede14 2020-12-05 op
202 23a0b465 2020-11-30 op Return nil if the command failed or if PATH isn't included in any
203 23a0b465 2020-11-30 op worktree."
204 0a66694e 2020-01-02 op (let (process-file-side-effects)
205 0a66694e 2020-01-02 op (vc-got-with-worktree (or path default-directory)
206 0a66694e 2020-01-02 op (zerop
207 fab791a2 2020-01-03 op (vc-got--call "log"
208 fab791a2 2020-01-03 op (when limit (list "-l" (format "%s" limit)))
209 fab791a2 2020-01-03 op (when start-commit (list "-c" start-commit))
210 fab791a2 2020-01-03 op (when stop-commit (list "-x" stop-commit))
211 fab791a2 2020-01-03 op (when search-pattern (list "-s" search-pattern))
212 fab791a2 2020-01-03 op (when reverse '("-R"))
213 fab791a2 2020-01-03 op path)))))
214 af5ef7cd 2020-11-29 op
215 668dc8eb 2021-01-04 op (defun vc-got--status (status-codes dir-or-file &rest files)
216 668dc8eb 2021-01-04 op "Return a list of lists '(FILE STATUS STAGE-STATUS).
217 af5ef7cd 2020-11-29 op DIR-OR-FILE can be either a directory or a file. If FILES is
218 af5ef7cd 2020-11-29 op given, return the status of those files, otherwise the status of
219 668dc8eb 2021-01-04 op DIR-OR-FILE. STATUS-CODES is either nil, or a string that's
220 668dc8eb 2021-01-04 op passed as the -s flag to got status to limit the types of status
221 668dc8eb 2021-01-04 op to report (e.g. \"CD\" to report only conflicts and deleted
222 668dc8eb 2021-01-04 op files)."
223 af5ef7cd 2020-11-29 op (vc-got-with-worktree dir-or-file
224 af5ef7cd 2020-11-29 op (with-temp-buffer
225 76d978fa 2021-01-05 op (let (process-file-side-effects)
226 76d978fa 2021-01-05 op (when (zerop (vc-got--call "status"
227 76d978fa 2021-01-05 op (when status-codes (list "-s" status-codes))
228 76d978fa 2021-01-05 op (or files dir-or-file)))
229 76d978fa 2021-01-05 op (goto-char (point-min))
230 76d978fa 2021-01-05 op (cl-loop until (eobp)
231 76d978fa 2021-01-05 op ;; the format of each line is
232 76d978fa 2021-01-05 op ;; <status-char> <stage-char> <spc> <filename> \n
233 76d978fa 2021-01-05 op collect (let* ((file-status (prog1 (vc-got--parse-status-char
234 76d978fa 2021-01-05 op (char-after))
235 76d978fa 2021-01-05 op (forward-char)))
236 76d978fa 2021-01-05 op (stage-status (prog1 (vc-got--parse-stage-char
237 76d978fa 2021-01-05 op (char-after))
238 76d978fa 2021-01-05 op (forward-char)))
239 76d978fa 2021-01-05 op (filename (progn
240 76d978fa 2021-01-05 op (forward-char)
241 76d978fa 2021-01-05 op (buffer-substring (point)
242 76d978fa 2021-01-05 op (line-end-position)))))
243 76d978fa 2021-01-05 op (list filename
244 76d978fa 2021-01-05 op (or file-status (and stage-status 'staged))
245 76d978fa 2021-01-05 op stage-status))
246 76d978fa 2021-01-05 op do (forward-line)))))))
247 af5ef7cd 2020-11-29 op
248 668dc8eb 2021-01-04 op (defun vc-got--parse-status-char (c)
249 668dc8eb 2021-01-04 op "Parse status char C into a symbol accepted by `vc-state'."
250 668dc8eb 2021-01-04 op (cl-case c
251 668dc8eb 2021-01-04 op (?M 'edited)
252 668dc8eb 2021-01-04 op (?A 'added)
253 668dc8eb 2021-01-04 op (?D 'removed)
254 668dc8eb 2021-01-04 op (?C 'conflict)
255 668dc8eb 2021-01-04 op (?! 'missing)
256 76d978fa 2021-01-05 op (?~ 'edited) ; XXX: what does it means for a file to be ``obstructed''?
257 668dc8eb 2021-01-04 op (?? 'unregistered)
258 76d978fa 2021-01-05 op (?m 'edited) ; modified file modes
259 668dc8eb 2021-01-04 op (?N nil)))
260 af5ef7cd 2020-11-29 op
261 668dc8eb 2021-01-04 op (defun vc-got--parse-stage-char (c)
262 668dc8eb 2021-01-04 op "Parse the stage status char C into a symbol."
263 668dc8eb 2021-01-04 op (cl-case c
264 2d83de2e 2021-01-05 op (?M 'edit)
265 2d83de2e 2021-01-05 op (?A 'add)
266 2d83de2e 2021-01-05 op (?D 'remove)))
267 af5ef7cd 2020-11-29 op
268 23a0b465 2020-11-30 op (defun vc-got--tree-parse ()
269 23a0b465 2020-11-30 op "Parse into an alist the output of got tree -i in the current buffer."
270 23a0b465 2020-11-30 op (goto-char (point-min))
271 23a0b465 2020-11-30 op (cl-loop
272 23a0b465 2020-11-30 op until (= (point) (point-max))
273 23a0b465 2020-11-30 op collect (let* ((obj-start (point))
274 23a0b465 2020-11-30 op (_ (forward-word))
275 23a0b465 2020-11-30 op (obj (buffer-substring obj-start (point)))
276 76d978fa 2021-01-05 op (_ (forward-char)) ; skip the space
277 23a0b465 2020-11-30 op (filename-start (point))
278 23a0b465 2020-11-30 op (_ (move-end-of-line nil))
279 23a0b465 2020-11-30 op (filename (buffer-substring filename-start (point))))
280 23a0b465 2020-11-30 op ;; goto the start of the next line
281 23a0b465 2020-11-30 op (forward-line)
282 23a0b465 2020-11-30 op (move-beginning-of-line nil)
283 23a0b465 2020-11-30 op `(,filename . ,obj))))
284 23a0b465 2020-11-30 op
285 23a0b465 2020-11-30 op (defun vc-got--tree (commit path)
286 67332bad 2021-01-05 op "Return an alist representing the got tree command output.
287 76d978fa 2021-01-05 op The outputted tree will be localised in the given PATH at the
288 67332bad 2021-01-05 op given COMMIT."
289 23a0b465 2020-11-30 op (vc-got-with-worktree path
290 76d978fa 2021-01-05 op (let (process-file-side-effects)
291 76d978fa 2021-01-05 op (with-temp-buffer
292 76d978fa 2021-01-05 op (when (zerop (vc-got--call "tree" "-c" commit "-i" path))
293 76d978fa 2021-01-05 op (vc-got--tree-parse))))))
294 23a0b465 2020-11-30 op
295 23a0b465 2020-11-30 op (defun vc-got--cat (commit obj-id)
296 23a0b465 2020-11-30 op "Execute got cat -c COMMIT OBJ-ID in the current buffer."
297 76d978fa 2021-01-05 op (let (process-file-side-effects)
298 76d978fa 2021-01-05 op (zerop (vc-got--call "cat" "-c" commit obj-id))))
299 eb85ad27 2020-12-05 op
300 eb85ad27 2020-12-05 op (defun vc-got--revert (&rest files)
301 76d978fa 2021-01-05 op "Execute got revert FILES."
302 eb85ad27 2020-12-05 op (vc-got-with-worktree (car files)
303 eb85ad27 2020-12-05 op (with-temp-buffer
304 76d978fa 2021-01-05 op (zerop (vc-got--call "revert" files)))))
305 eb85ad27 2020-12-05 op
306 eb85ad27 2020-12-05 op (defun vc-got--list-branches ()
307 eb85ad27 2020-12-05 op "Return an alist of (branch . commit)."
308 76d978fa 2021-01-05 op (let (process-file-side-effects)
309 76d978fa 2021-01-05 op (with-temp-buffer
310 76d978fa 2021-01-05 op (when (zerop (vc-got--call "branch" "-l"))
311 76d978fa 2021-01-05 op (goto-char (point-min))
312 76d978fa 2021-01-05 op (cl-loop
313 76d978fa 2021-01-05 op until (= (point) (point-max))
314 76d978fa 2021-01-05 op ;; parse the `* $branchname: $commit', from the end
315 76d978fa 2021-01-05 op ;; XXX: use a regex?
316 76d978fa 2021-01-05 op collect (let* ((_ (move-end-of-line nil))
317 76d978fa 2021-01-05 op (end-commit (point))
318 76d978fa 2021-01-05 op (_ (backward-word))
319 76d978fa 2021-01-05 op (start-commit (point))
320 76d978fa 2021-01-05 op (_ (backward-char 2))
321 76d978fa 2021-01-05 op (end-branchname (point))
322 76d978fa 2021-01-05 op (_ (move-beginning-of-line nil))
323 76d978fa 2021-01-05 op (_ (forward-char 2))
324 76d978fa 2021-01-05 op (start-branchname (point))
325 76d978fa 2021-01-05 op (branchname (buffer-substring start-branchname end-branchname))
326 76d978fa 2021-01-05 op (commit (buffer-substring start-commit end-commit)))
327 76d978fa 2021-01-05 op (forward-line)
328 76d978fa 2021-01-05 op (move-beginning-of-line nil)
329 76d978fa 2021-01-05 op `(,branchname . ,commit)))))))
330 eb85ad27 2020-12-05 op
331 694534b4 2020-12-05 op (defun vc-got--current-branch ()
332 694534b4 2020-12-05 op "Return the current branch."
333 76d978fa 2021-01-05 op (let (process-file-side-effects)
334 76d978fa 2021-01-05 op (with-temp-buffer
335 76d978fa 2021-01-05 op (when (zerop (vc-got--call "branch"))
336 76d978fa 2021-01-05 op (string-trim (buffer-string) "" "\n")))))
337 eb85ad27 2020-12-05 op
338 eb85ad27 2020-12-05 op (defun vc-got--integrate (branch)
339 eb85ad27 2020-12-05 op "Integrate BRANCH into the current one."
340 eb85ad27 2020-12-05 op (with-temp-buffer
341 76d978fa 2021-01-05 op (zerop (vc-got--call "integrate" branch))))
342 23a0b465 2020-11-30 op
343 eb85ad27 2020-12-05 op (defun vc-got--diff (&rest args)
344 eb85ad27 2020-12-05 op "Call got diff with ARGS. The result will be stored in the current buffer."
345 76d978fa 2021-01-05 op (let (process-file-side-effects)
346 76d978fa 2021-01-05 op (zerop (vc-got--call "diff"
347 76d978fa 2021-01-05 op (vc-switches 'got 'diff)
348 76d978fa 2021-01-05 op (mapcar #'file-relative-name args)))))
349 6b6c8a78 2021-01-04 op
350 6b6c8a78 2021-01-04 op (defun vc-got--unstage (file-or-directory)
351 6b6c8a78 2021-01-04 op "Unstage all the staged hunks at or within FILE-OR-DIRECTORY.
352 6b6c8a78 2021-01-04 op If it's nil, unstage every staged changes across the entire work
353 6b6c8a78 2021-01-04 op tree."
354 76d978fa 2021-01-05 op (zerop (vc-got--call "unstage" file-or-directory)))
355 a96df0e8 2020-01-03 noreply
356 a96df0e8 2020-01-03 noreply (defun vc-got--remove (file &optional force keep-local)
357 76d978fa 2021-01-05 op "Use got to remove FILE.
358 76d978fa 2021-01-05 op If FORCE is non-nil perform the operation even if a file contains
359 76d978fa 2021-01-05 op local modification. If KEEP-LOCAL is non-nil keep the affected
360 76d978fa 2021-01-05 op files on disk."
361 a96df0e8 2020-01-03 noreply (vc-got-with-worktree (or file default-directory)
362 a96df0e8 2020-01-03 noreply (with-temp-buffer
363 76d978fa 2021-01-05 op (zerop (vc-got--call "remove"
364 76d978fa 2021-01-05 op (when force "-f")
365 76d978fa 2021-01-05 op (when keep-local "-k")
366 76d978fa 2021-01-05 op file)))))
367 eb85ad27 2020-12-05 op
368 af5ef7cd 2020-11-29 op
369 af5ef7cd 2020-11-29 op ;; Backend properties
370 af5ef7cd 2020-11-29 op
371 af5ef7cd 2020-11-29 op (defun vc-got-revision-granularity ()
372 af5ef7cd 2020-11-29 op "Got has REPOSITORY granularity."
373 af5ef7cd 2020-11-29 op 'repository)
374 af5ef7cd 2020-11-29 op
375 af5ef7cd 2020-11-29 op ;; XXX: what this should do? The description is not entirely clear
376 af5ef7cd 2020-11-29 op (defun vc-got-update-on-retrieve-tag ()
377 af5ef7cd 2020-11-29 op nil)
378 af5ef7cd 2020-11-29 op
379 af5ef7cd 2020-11-29 op
380 af5ef7cd 2020-11-29 op ;; State-querying functions
381 af5ef7cd 2020-11-29 op
382 af5ef7cd 2020-11-29 op ;;;###autoload (defun vc-got-registered (file)
383 af5ef7cd 2020-11-29 op ;;;###autoload "Return non-nil if FILE is registered with got."
384 af5ef7cd 2020-11-29 op ;;;###autoload (when (vc-find-root file ".got")
385 af5ef7cd 2020-11-29 op ;;;###autoload (load "vc-got" nil t)
386 af5ef7cd 2020-11-29 op ;;;###autoload (vc-got-registered file)))
387 af5ef7cd 2020-11-29 op
388 af5ef7cd 2020-11-29 op (defun vc-got-registered (file)
389 af5ef7cd 2020-11-29 op "Return non-nil if FILE is registered with got."
390 af5ef7cd 2020-11-29 op (if (file-directory-p file)
391 76d978fa 2021-01-05 op nil ; got doesn't track directories
392 4093d2f9 2020-12-04 op (when (vc-find-root file ".got")
393 668dc8eb 2021-01-04 op (let ((s (vc-got-state file)))
394 668dc8eb 2021-01-04 op (not (or (eq s 'unregistered)
395 668dc8eb 2021-01-04 op (null s)))))))
396 af5ef7cd 2020-11-29 op
397 af5ef7cd 2020-11-29 op (defun vc-got-state (file)
398 af5ef7cd 2020-11-29 op "Return the current version control state of FILE. See `vc-state'."
399 af5ef7cd 2020-11-29 op (unless (file-directory-p file)
400 76d978fa 2021-01-05 op (let (process-file-side-effects)
401 76d978fa 2021-01-05 op ;; Manually calling got status and checking the result inline to
402 76d978fa 2021-01-05 op ;; avoid building the data structure in vc-got--status.
403 76d978fa 2021-01-05 op (with-temp-buffer
404 76d978fa 2021-01-05 op (when (zerop (vc-got--call "status" file))
405 76d978fa 2021-01-05 op (goto-char (point-min))
406 76d978fa 2021-01-05 op (if (eobp)
407 76d978fa 2021-01-05 op 'up-to-date
408 76d978fa 2021-01-05 op (vc-got--parse-status-char (char-after))))))))
409 dcb5b83a 2021-01-08 op
410 dcb5b83a 2021-01-08 op (defun vc-got--dir-filter-files (files)
411 dcb5b83a 2021-01-08 op "Remove ., .. and .got from FILES."
412 dcb5b83a 2021-01-08 op (cl-loop for file in files
413 dcb5b83a 2021-01-08 op unless (or (string= file "..")
414 dcb5b83a 2021-01-08 op (string= file ".")
415 dcb5b83a 2021-01-08 op (string= file ".got"))
416 dcb5b83a 2021-01-08 op collect file))
417 af5ef7cd 2020-11-29 op
418 af5ef7cd 2020-11-29 op (defun vc-got-dir-status-files (dir files update-function)
419 5b4a6b90 2021-01-04 op "Build the status for FILES in DIR.
420 76d978fa 2021-01-05 op The builded result is given to the callback UPDATE-FUNCTION. If
421 5b4a6b90 2021-01-04 op FILES is nil, consider all the files in DIR."
422 dcb5b83a 2021-01-08 op (let* ((fs (vc-got--dir-filter-files (or files (directory-files dir))))
423 d346ca63 2021-01-08 op ;; XXX: we call with files, wich will probably be nil on the
424 d346ca63 2021-01-08 op ;; first run, so we catch deleted, missing and edited files
425 d346ca63 2021-01-08 op ;; in subdirectories.
426 d346ca63 2021-01-08 op (res (vc-got--status nil dir files))
427 d346ca63 2021-01-08 op double-check)
428 82289421 2020-01-02 op (cl-loop for file in fs
429 76d978fa 2021-01-05 op do (when (and (not (cdr (assoc file res #'string=)))
430 76d978fa 2021-01-05 op (not (file-directory-p file))
431 76d978fa 2021-01-05 op ;; if file doesn't exists, it's a
432 76d978fa 2021-01-05 op ;; untracked file that was removed.
433 76d978fa 2021-01-05 op (file-exists-p file))
434 d346ca63 2021-01-08 op ;; if we don't know the status of a file here, it's
435 d346ca63 2021-01-08 op ;; either up-to-date or ignored. Save it for a
436 d346ca63 2021-01-08 op ;; double check
437 d346ca63 2021-01-08 op (push file double-check)))
438 cb973832 2021-01-08 op (cl-loop with statuses = (vc-got--status nil dir double-check)
439 cb973832 2021-01-08 op for file in double-check
440 cb973832 2021-01-08 op unless (eq 'unregistered (cadr (assoc file statuses #'string=)))
441 d346ca63 2021-01-08 op do (push (list file 'up-to-date nil) res))
442 d346ca63 2021-01-08 op (funcall update-function res nil)))
443 af5ef7cd 2020-11-29 op
444 c27df03e 2020-01-03 op (defun vc-got-dir-extra-headers (dir)
445 c27df03e 2020-01-03 op "Return a string for the `vc-dir' buffer heading for directory DIR."
446 76d978fa 2021-01-05 op (let ((remote (vc-got-repository-url dir)))
447 76d978fa 2021-01-05 op (concat (propertize "Repository : " 'face 'font-lock-type-face)
448 76d978fa 2021-01-05 op (vc-got--repo-root) "\n"
449 76d978fa 2021-01-05 op (when remote
450 76d978fa 2021-01-05 op (concat
451 76d978fa 2021-01-05 op (propertize "Remote URL : " 'face 'font-lock-type-face)
452 76d978fa 2021-01-05 op (vc-got-repository-url dir) "\n"))
453 76d978fa 2021-01-05 op (propertize "Branch : " 'face 'font-lock-type-face)
454 76d978fa 2021-01-05 op (vc-got--current-branch))))
455 2d83de2e 2021-01-05 op
456 2d83de2e 2021-01-05 op (defun vc-got-dir-printer (info)
457 2d83de2e 2021-01-05 op "Pretty-printer for the vc-dir-fileinfo structure INFO."
458 2d83de2e 2021-01-05 op (let* ((isdir (vc-dir-fileinfo->directory info))
459 76d978fa 2021-01-05 op (state (if isdir "" (vc-dir-fileinfo->state info)))
460 76d978fa 2021-01-05 op (stage-state (vc-dir-fileinfo->extra info))
461 76d978fa 2021-01-05 op (filename (vc-dir-fileinfo->name info)))
462 2d83de2e 2021-01-05 op (insert
463 2d83de2e 2021-01-05 op (propertize
464 2d83de2e 2021-01-05 op (format "%c" (if (vc-dir-fileinfo->marked info) ?* ? ))
465 2d83de2e 2021-01-05 op 'face 'font-lock-type-face)
466 9e019413 2021-01-05 op " "
467 9e019413 2021-01-05 op (propertize
468 9e019413 2021-01-05 op (if stage-state
469 76d978fa 2021-01-05 op (format "staged:%-6s" stage-state)
470 76d978fa 2021-01-05 op (format "%-13s" ""))
471 9e019413 2021-01-05 op 'face (cond ((memq stage-state '(add edit)) 'font-lock-constant-face)
472 76d978fa 2021-01-05 op ((eq stage-state 'remove) 'font-lock-warning-face)
473 76d978fa 2021-01-05 op (t 'font-lock-variable-name-face)))
474 9e019413 2021-01-05 op " "
475 2d83de2e 2021-01-05 op (propertize
476 2d83de2e 2021-01-05 op (format "%-14s" state)
477 2d83de2e 2021-01-05 op 'face (cond ((eq state 'up-to-date) 'font-lock-builtin-face)
478 76d978fa 2021-01-05 op ((memq state '(missing conflict)) 'font-lock-warning-face)
479 76d978fa 2021-01-05 op ((eq state 'edited) 'font-lock-constant-face)
480 76d978fa 2021-01-05 op (t 'font-lock-variable-name-face))
481 2d83de2e 2021-01-05 op 'mouse-face 'highlight)
482 2d83de2e 2021-01-05 op " "
483 2d83de2e 2021-01-05 op (propertize
484 2d83de2e 2021-01-05 op (format "%s" filename)
485 2d83de2e 2021-01-05 op 'face
486 2d83de2e 2021-01-05 op (if isdir 'font-lock-comment-delimiter-face 'font-lock-function-name-face)
487 2d83de2e 2021-01-05 op 'help-echo
488 2d83de2e 2021-01-05 op (if isdir
489 76d978fa 2021-01-05 op "Directory\nVC operations can be applied to it\nmouse-3: Pop-up menu"
490 76d978fa 2021-01-05 op "File\nmouse-3: Pop-up menu")
491 2d83de2e 2021-01-05 op 'mouse-face 'highlight
492 2d83de2e 2021-01-05 op 'keymap vc-dir-filename-mouse-map))))
493 a8466f02 2020-12-07 op
494 af5ef7cd 2020-11-29 op (defun vc-got-working-revision (file)
495 c0c9a339 2020-12-04 op "Return the id of the last commit that touched the FILE or \"0\" for a new (but added) file."
496 af5ef7cd 2020-11-29 op (or
497 af5ef7cd 2020-11-29 op (with-temp-buffer
498 518ede14 2020-12-05 op (when (vc-got--log file 1)
499 af5ef7cd 2020-11-29 op (let (start)
500 af5ef7cd 2020-11-29 op (goto-char (point-min))
501 76d978fa 2021-01-05 op (forward-line 1) ; skip the ----- line
502 76d978fa 2021-01-05 op (forward-word) ; skip "commit"
503 76d978fa 2021-01-05 op (forward-char) ; skip the space
504 76d978fa 2021-01-05 op (setq start (point)) ; store start of the SHA
505 76d978fa 2021-01-05 op (forward-word) ; goto SHA end
506 af5ef7cd 2020-11-29 op (buffer-substring start (point)))))
507 af5ef7cd 2020-11-29 op ;; special case: if this file is added but has no previous commits
508 af5ef7cd 2020-11-29 op ;; touching it, got log will fail (as expected), but we have to
509 af5ef7cd 2020-11-29 op ;; return "0".
510 af5ef7cd 2020-11-29 op (when (eq (vc-got-state file) 'added)
511 af5ef7cd 2020-11-29 op "0")))
512 af5ef7cd 2020-11-29 op
513 af5ef7cd 2020-11-29 op (defun vc-got-checkout-model (_files)
514 5b4a6b90 2021-01-04 op "Got uses an implicit checkout model for every file."
515 af5ef7cd 2020-11-29 op 'implicit)
516 af5ef7cd 2020-11-29 op
517 694534b4 2020-12-05 op (defun vc-got-mode-line-string (file)
518 694534b4 2020-12-05 op "Return the VC mode line string for FILE."
519 694534b4 2020-12-05 op (vc-got-with-worktree file
520 694534b4 2020-12-05 op (let ((def (vc-default-mode-line-string 'Got file)))
521 694534b4 2020-12-05 op (concat (substring def 0 4) (vc-got--current-branch)))))
522 694534b4 2020-12-05 op
523 23a0b465 2020-11-30 op
524 23a0b465 2020-11-30 op ;; state-changing functions
525 23a0b465 2020-11-30 op
526 23a0b465 2020-11-30 op (defun vc-got-create-repo (_backend)
527 23a0b465 2020-11-30 op (error "vc got: create-repo not implemented"))
528 23a0b465 2020-11-30 op
529 23a0b465 2020-11-30 op (defun vc-got-register (files &optional _comment)
530 23a0b465 2020-11-30 op "Register FILES, passing `vc-register-switches' to the backend command."
531 23a0b465 2020-11-30 op (vc-got--add files))
532 23a0b465 2020-11-30 op
533 9e805da8 2020-11-30 op (defalias 'vc-got-responsible-p #'vc-got-root)
534 23a0b465 2020-11-30 op
535 daae979d 2021-01-04 op ;; XXX: generally speaking, files cannot be nil. But we have to
536 daae979d 2021-01-04 op ;; handle that case too, because vc-got-stage-commit will call
537 ffa81a1d 2021-01-04 op ;; vc-got-checkin with fileset nil to commit the current staged hunks.
538 23a0b465 2020-11-30 op (defun vc-got-checkin (files comment &optional _rev)
539 23a0b465 2020-11-30 op "Commit FILES with COMMENT as commit message."
540 23a0b465 2020-11-30 op (with-temp-buffer
541 76d978fa 2021-01-05 op (vc-got--call "commit" "-m"
542 76d978fa 2021-01-05 op ;; emacs add ``Summary:'' at the start of the commit
543 76d978fa 2021-01-05 op ;; message. vc-git doesn't seem to treat this specially.
544 76d978fa 2021-01-05 op ;; Since it's annoying, remove it.
545 76d978fa 2021-01-05 op (string-remove-prefix "Summary: " comment)
546 76d978fa 2021-01-05 op files)))
547 23a0b465 2020-11-30 op
548 23a0b465 2020-11-30 op (defun vc-got-find-revision (file rev buffer)
549 c0c9a339 2020-12-04 op "Fill BUFFER with the content of FILE in the given revision REV."
550 23a0b465 2020-11-30 op (when-let (obj-id (assoc file (vc-got--tree rev file) #'string=))
551 23a0b465 2020-11-30 op (with-current-buffer buffer
552 23a0b465 2020-11-30 op (vc-got-with-worktree file
553 23a0b465 2020-11-30 op (vc-got--cat rev obj-id)))))
554 23a0b465 2020-11-30 op
555 55091167 2020-12-05 op (defun vc-got-find-ignore-file (file)
556 55091167 2020-12-05 op "Return the gitignore file that controls FILE."
557 55091167 2020-12-05 op (expand-file-name ".gitignore"
558 55091167 2020-12-05 op (vc-got-root file)))
559 55091167 2020-12-05 op
560 eb85ad27 2020-12-05 op (defun vc-got-checkout (_file &optional _rev)
561 76d978fa 2021-01-05 op "Checkout revision REV of FILE.
562 76d978fa 2021-01-05 op If REV is t, checkout from the head."
563 eb85ad27 2020-12-05 op (error "vc got: checkout not implemented"))
564 eb85ad27 2020-12-05 op
565 eb85ad27 2020-12-05 op (defun vc-got-revert (file &optional _content-done)
566 eb85ad27 2020-12-05 op "Revert FILE back to working revision."
567 eb85ad27 2020-12-05 op (vc-got--revert file))
568 eb85ad27 2020-12-05 op
569 eb85ad27 2020-12-05 op (defun vc-got-merge-branch ()
570 eb85ad27 2020-12-05 op "Prompt for a branch and integrate it into the current one."
571 eb85ad27 2020-12-05 op ;; XXX: be smart and try to "got rebase" if "got integrate" fails?
572 eb85ad27 2020-12-05 op (let* ((branches (cl-loop for (branch . commit) in (vc-got--list-branches)
573 eb85ad27 2020-12-05 op collect branch))
574 eb85ad27 2020-12-05 op (branch (completing-read "Merge from branch: " branches)))
575 eb85ad27 2020-12-05 op (when branch
576 eb85ad27 2020-12-05 op (vc-got--integrate branch))))
577 686eac9a 2020-12-07 op
578 686eac9a 2020-12-07 op (defun vc-got--push-pull (cmd op prompt root)
579 686eac9a 2020-12-07 op "Execute CMD OP, or prompt the user if PROMPT is non-nil.
580 686eac9a 2020-12-07 op ROOT is the worktree root."
581 686eac9a 2020-12-07 op (let ((buffer (format "*vc-got : %s*" (expand-file-name root))))
582 686eac9a 2020-12-07 op (when-let (cmd (if prompt
583 686eac9a 2020-12-07 op (split-string
584 686eac9a 2020-12-07 op (read-shell-command (format "%s %s command: " cmd op)
585 686eac9a 2020-12-07 op (format "%s %s" cmd op))
586 686eac9a 2020-12-07 op " " t)
587 686eac9a 2020-12-07 op (list cmd op)))
588 686eac9a 2020-12-07 op (apply #'vc-do-command buffer 0 (car cmd) nil (cdr cmd)))))
589 eb85ad27 2020-12-05 op
590 eb85ad27 2020-12-05 op (defun vc-got-pull (prompt)
591 eb85ad27 2020-12-05 op "Execute got pull, prompting the user for the full command if PROMPT is not nil."
592 e79563bd 2020-12-31 noreply (vc-got--push-pull vc-got-program "fetch" prompt (vc-got-root default-directory)))
593 686eac9a 2020-12-07 op
594 686eac9a 2020-12-07 op (defun vc-got-push (prompt)
595 686eac9a 2020-12-07 op "Run git push (not got!) in the repository dir.
596 686eac9a 2020-12-07 op If PROMPT is non-nil, prompt for the git command to run."
597 eb85ad27 2020-12-05 op (let* ((root (vc-got-root default-directory))
598 686eac9a 2020-12-07 op (default-directory (vc-got--repo-root)))
599 686eac9a 2020-12-07 op (vc-got--push-pull "git" "push" prompt root)))
600 eb85ad27 2020-12-05 op
601 eb85ad27 2020-12-05 op (defun vc-got-print-log (files buffer &optional _shortlog start-revision limit)
602 eb85ad27 2020-12-05 op "Insert the revision log for FILES into BUFFER.
603 76d978fa 2021-01-05 op LIMIT limits the number of commits, optionally starting at
604 76d978fa 2021-01-05 op START-REVISION."
605 eb85ad27 2020-12-05 op (with-current-buffer buffer
606 eb85ad27 2020-12-05 op ;; the *vc-diff* may be read only
607 4571b1fd 2020-12-05 op (let ((inhibit-read-only t))
608 eb85ad27 2020-12-05 op (cl-loop for file in files
609 4571b1fd 2020-12-05 op do (vc-got--log (file-relative-name file) limit start-revision)))))
610 eb85ad27 2020-12-05 op
611 9ad1eb5d 2020-12-07 op ;; XXX: this includes also the latest commit in REMOTE-LOCATION.
612 9ad1eb5d 2020-12-07 op (defun vc-got-log-outgoing (buffer remote-location)
613 9ad1eb5d 2020-12-07 op "Fill BUFFER with the diff between the local worktree branch and REMOTE-LOCATION."
614 9ad1eb5d 2020-12-07 op (vc-setup-buffer buffer)
615 9ad1eb5d 2020-12-07 op (let ((rl (if (or (not remote-location) (string-empty-p remote-location))
616 9ad1eb5d 2020-12-07 op (concat "origin/" (vc-got--current-branch))
617 9ad1eb5d 2020-12-07 op remote-location))
618 9ad1eb5d 2020-12-07 op (inhibit-read-only t))
619 9ad1eb5d 2020-12-07 op (with-current-buffer buffer
620 9ad1eb5d 2020-12-07 op (vc-got--log nil nil nil rl))))
621 6eda2f1f 2020-12-26 op
622 6eda2f1f 2020-12-26 op (defun vc-got-incoming (buffer remote-location)
623 6eda2f1f 2020-12-26 op "Fill BUFFER with the diff between the REMOTE-LOCATION and the local worktree branch."
624 6eda2f1f 2020-12-26 op (let ((rl (if (or (not remote-location) (string-empty-p remote-location))
625 6eda2f1f 2020-12-26 op (concat "origin/" (vc-got--current-branch))
626 6eda2f1f 2020-12-26 op remote-location))
627 6eda2f1f 2020-12-26 op (inhibit-read-only t))
628 6eda2f1f 2020-12-26 op (with-current-buffer buffer
629 6eda2f1f 2020-12-26 op (vc-got--log nil nil (vc-got--current-branch) rl))))
630 9ad1eb5d 2020-12-07 op
631 eb85ad27 2020-12-05 op (defun vc-got-log-search (buffer pattern)
632 eb85ad27 2020-12-05 op "Search commits for PATTERN and write the results found in BUFFER."
633 eb85ad27 2020-12-05 op (with-current-buffer buffer
634 eb85ad27 2020-12-05 op (let ((inhibit-read-only t))
635 9ad1eb5d 2020-12-07 op (vc-got--log nil nil nil nil pattern))))
636 eb85ad27 2020-12-05 op
637 eb85ad27 2020-12-05 op ;; TODO: async
638 f18d3e11 2020-12-05 op ;; TODO: return 0 or 1
639 eb85ad27 2020-12-05 op (defun vc-got-diff (files &optional rev1 rev2 buffer _async)
640 eb85ad27 2020-12-05 op "Insert into BUFFER (or *vc-diff*) the diff for FILES from REV1 to REV2."
641 f457868b 2020-12-07 op (let* ((buffer (get-buffer-create (or buffer "*vc-diff*")))
642 eb85ad27 2020-12-05 op (inhibit-read-only t))
643 eb85ad27 2020-12-05 op (with-current-buffer buffer
644 eb85ad27 2020-12-05 op (vc-got-with-worktree (car files)
645 eb85ad27 2020-12-05 op (cond ((and (null rev1)
646 eb85ad27 2020-12-05 op (null rev2))
647 986bd9a0 2020-12-27 op (dolist (file files)
648 986bd9a0 2020-12-27 op (vc-got--diff file)))
649 eb85ad27 2020-12-05 op (t (error "Not implemented")))))))
650 3f25d9ff 2020-01-02 noreply
651 3f25d9ff 2020-01-02 noreply (defun vc-got-annotate-command (file buf &optional rev)
652 67332bad 2021-01-05 op "Show annotated contents of FILE in buffer BUF. If given, use revision REV."
653 3f25d9ff 2020-01-02 noreply (let (process-file-side-effects)
654 3f25d9ff 2020-01-02 noreply (with-current-buffer buf
655 3f25d9ff 2020-01-02 noreply ;; FIXME: vc-ensure-vc-buffer won't recognise this buffer as managed
656 3f25d9ff 2020-01-02 noreply ;; by got unless vc-parent-buffer points to a buffer managed by got.
657 3f25d9ff 2020-01-02 noreply ;; investigate why this is needed.
658 3f25d9ff 2020-01-02 noreply (set (make-local-variable 'vc-parent-buffer) (find-file-noselect file))
659 76d978fa 2021-01-05 op (vc-got--call "blame"
660 76d978fa 2021-01-05 op (when rev (list "-c" rev))
661 76d978fa 2021-01-05 op file))))
662 3f25d9ff 2020-01-02 noreply
663 3f25d9ff 2020-01-02 noreply (defconst vc-got--annotate-re
664 3f25d9ff 2020-01-02 noreply (concat "^[0-9]\\{1,\\}) " ; line number followed by )
665 3f25d9ff 2020-01-02 noreply "\\([a-z0-9]+\\) " ; SHA-1 of commit
666 3f25d9ff 2020-01-02 noreply "\\([0-9]\\{4\\}-[0-9]\\{2\\}-[0-9]\\{2\\}\\) " ; year-mm-dd
667 3f25d9ff 2020-01-02 noreply "\\([^ ]\\)+ ") ; author
668 3f25d9ff 2020-01-02 noreply "Regexp to match annotation output lines.
669 3f25d9ff 2020-01-02 noreply
670 3f25d9ff 2020-01-02 noreply Provides capture groups for:
671 3f25d9ff 2020-01-02 noreply 1. revision id
672 3f25d9ff 2020-01-02 noreply 2. date of commit
673 3f25d9ff 2020-01-02 noreply 3. author of commit")
674 3f25d9ff 2020-01-02 noreply
675 3f25d9ff 2020-01-02 noreply (defconst vc-got--commit-re "^commit \\([a-z0-9]+\\)"
676 3f25d9ff 2020-01-02 noreply "Regexp to match commit lines.
677 3f25d9ff 2020-01-02 noreply
678 3f25d9ff 2020-01-02 noreply Provides capture group for the commit revision id.")
679 3f25d9ff 2020-01-02 noreply
680 3f25d9ff 2020-01-02 noreply (defun vc-got-annotate-time ()
681 3f25d9ff 2020-01-02 noreply "Return the time of the next line of annotation at or after point.
682 3f25d9ff 2020-01-02 noreply Value is returned as floating point fractional number of days."
683 3f25d9ff 2020-01-02 noreply (save-excursion
684 3f25d9ff 2020-01-02 noreply (beginning-of-line)
685 3f25d9ff 2020-01-02 noreply (when (looking-at vc-got--annotate-re)
686 3f25d9ff 2020-01-02 noreply (let ((str (match-string-no-properties 2)))
687 3f25d9ff 2020-01-02 noreply (vc-annotate-convert-time
688 3f25d9ff 2020-01-02 noreply (encode-time 0 0 0
689 3f25d9ff 2020-01-02 noreply (string-to-number (substring str 8 10))
690 3f25d9ff 2020-01-02 noreply (string-to-number (substring str 5 7))
691 3f25d9ff 2020-01-02 noreply (string-to-number (substring str 0 4))))))))
692 eb85ad27 2020-12-05 op
693 3f25d9ff 2020-01-02 noreply (defun vc-got-annotate-extract-revision-at-line ()
694 67332bad 2021-01-05 op "Return revision corresponding to the current line or nil."
695 3f25d9ff 2020-01-02 noreply (save-excursion
696 3f25d9ff 2020-01-02 noreply (beginning-of-line)
697 3f25d9ff 2020-01-02 noreply (when (looking-at vc-got--annotate-re)
698 3f25d9ff 2020-01-02 noreply (match-string-no-properties 1))))
699 3f25d9ff 2020-01-02 noreply
700 3f25d9ff 2020-01-02 noreply (defun vc-got-previous-revision (file rev)
701 3f25d9ff 2020-01-02 noreply "Return the revision number that precedes REV for FILE, or nil if no such revision exists."
702 3f25d9ff 2020-01-02 noreply (with-temp-buffer
703 3f25d9ff 2020-01-02 noreply (vc-got--log file 2 rev nil nil t)
704 3f25d9ff 2020-01-02 noreply (goto-char (point-min))
705 3f25d9ff 2020-01-02 noreply (keep-lines "^commit")
706 3f25d9ff 2020-01-02 noreply (when (looking-at vc-got--commit-re)
707 3f25d9ff 2020-01-02 noreply (match-string-no-properties 1))))
708 3f25d9ff 2020-01-02 noreply
709 3f25d9ff 2020-01-02 noreply (defun vc-got-next-revision (file rev)
710 67332bad 2021-01-05 op "Return the revision number that follows REV for FILE, or nil if no such revision exists."
711 3f25d9ff 2020-01-02 noreply (with-temp-buffer
712 3f25d9ff 2020-01-02 noreply (vc-got--log file nil nil rev)
713 3f25d9ff 2020-01-02 noreply (keep-lines "^commit" (point-min) (point-max))
714 3f25d9ff 2020-01-02 noreply (goto-char (point-max))
715 76d978fa 2021-01-05 op (forward-line -1) ; return from empty line to last actual commit
716 3f25d9ff 2020-01-02 noreply (unless (= (point) (point-min))
717 3f25d9ff 2020-01-02 noreply (forward-line -1)
718 3f25d9ff 2020-01-02 noreply (when (looking-at vc-got--commit-re)
719 3f25d9ff 2020-01-02 noreply (match-string-no-properties 1)))))
720 3f25d9ff 2020-01-02 noreply
721 a96df0e8 2020-01-03 noreply (defun vc-got-delete-file (file)
722 a96df0e8 2020-01-03 noreply "Delete FILE locally and mark it deleted in work tree."
723 a96df0e8 2020-01-03 noreply (vc-got--remove file t))
724 a96df0e8 2020-01-03 noreply
725 7bb16f79 2020-01-03 op (defun vc-got-conflicted-files (dir)
726 7bb16f79 2020-01-03 op "Return the list of files with conflicts in directory DIR."
727 7bb16f79 2020-01-03 op (let* ((root (vc-got-root dir))
728 7bb16f79 2020-01-03 op (default-directory root)
729 7bb16f79 2020-01-03 op (process-file-side-effects))
730 7bb16f79 2020-01-03 op (cl-loop with conflicts = nil
731 668dc8eb 2021-01-04 op for (file status _) in (vc-got--status "C" ".")
732 7bb16f79 2020-01-03 op do (when (and (eq status 'conflict)
733 7bb16f79 2020-01-03 op (file-in-directory-p file dir))
734 7bb16f79 2020-01-03 op (push file conflicts))
735 7bb16f79 2020-01-03 op finally return conflicts)))
736 7bb16f79 2020-01-03 op
737 8b635a9f 2020-01-03 op (defun vc-got-repository-url (_file &optional remote-name)
738 8b635a9f 2020-01-03 op "Return URL for REMOTE-NAME, or for \"origin\" if nil."
739 8b635a9f 2020-01-03 op (let* ((default-directory (vc-got--repo-root))
740 8b635a9f 2020-01-03 op (remote-name (or remote-name "origin"))
741 8b635a9f 2020-01-03 op (heading (concat "[remote \"" remote-name "\"]"))
742 76d978fa 2021-01-05 op (conf (cond ((file-exists-p ".git/config") ".git/config")
743 76d978fa 2021-01-05 op ((file-exists-p ".git") nil)
744 76d978fa 2021-01-05 op ((file-exists-p "config") "config")))
745 8b635a9f 2020-01-03 op found)
746 6f42ede4 2021-01-05 op (when conf
747 6f42ede4 2021-01-05 op (with-temp-buffer
748 f8a9db56 2020-01-03 op (insert-file-contents conf)
749 f8a9db56 2020-01-03 op (goto-char (point-min))
750 f8a9db56 2020-01-03 op (when (search-forward heading nil t)
751 f8a9db56 2020-01-03 op (forward-line)
752 f8a9db56 2020-01-03 op (while (and (not found)
753 76d978fa 2021-01-05 op (looking-at ".*=") ; too broad?
754 7a5ead65 2020-01-03 op (not (= (point) (point-max))))
755 f8a9db56 2020-01-03 op (when (looking-at ".*url = \\(.*\\)")
756 7a5ead65 2020-01-03 op (setq found (match-string-no-properties 1)))
757 7a5ead65 2020-01-03 op (forward-line))
758 f8a9db56 2020-01-03 op found)))))
759 8b635a9f 2020-01-03 op
760 2d83de2e 2021-01-05 op
761 2d83de2e 2021-01-05 op ;; hacks
762 2d83de2e 2021-01-05 op (defun vc-got-fix-dir-move-to-goal-column (fn)
763 2d83de2e 2021-01-05 op "Move the cursor on the file column.
764 76d978fa 2021-01-05 op Adviced around `vc-dir-move-to-goal-column' (FN) because it hardcodes column 25."
765 2d83de2e 2021-01-05 op (if (not (vc-find-root default-directory ".got"))
766 2d83de2e 2021-01-05 op (funcall fn)
767 2d83de2e 2021-01-05 op (beginning-of-line)
768 2d83de2e 2021-01-05 op (unless (eolp)
769 9e019413 2021-01-05 op (forward-char 31))))
770 2d83de2e 2021-01-05 op (advice-add 'vc-dir-move-to-goal-column :around #'vc-got-fix-dir-move-to-goal-column)
771 2d83de2e 2021-01-05 op
772 af5ef7cd 2020-11-29 op (provide 'vc-got)
773 af5ef7cd 2020-11-29 op ;;; vc-got.el ends here