33564
d8c822512b62
(vc-version-diff): Bind inhibit-read-only when inserting text.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
1 ;;; vc.el --- drive a version-control system from within Emacs
|
904
|
2
|
31380
|
3 ;; Copyright (C) 1992,93,94,95,96,97,98,2000 Free Software Foundation, Inc.
|
904
|
4
|
31380
|
5 ;; Author: FSF (see below for full credits)
|
|
6 ;; Maintainer: Andre Spiegel <spiegel@gnu.org>
|
904
|
7
|
35131
|
8 ;; $Id: vc.el,v 1.292 2000/11/20 14:01:35 spiegel Exp $
|
32093
|
9
|
904
|
10 ;; This file is part of GNU Emacs.
|
|
11
|
|
12 ;; GNU Emacs is free software; you can redistribute it and/or modify
|
|
13 ;; it under the terms of the GNU General Public License as published by
|
|
14 ;; the Free Software Foundation; either version 2, or (at your option)
|
|
15 ;; any later version.
|
|
16
|
|
17 ;; GNU Emacs is distributed in the hope that it will be useful,
|
|
18 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
19 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
20 ;; GNU General Public License for more details.
|
|
21
|
|
22 ;; You should have received a copy of the GNU General Public License
|
14169
|
23 ;; along with GNU Emacs; see the file COPYING. If not, write to the
|
|
24 ;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
|
25 ;; Boston, MA 02111-1307, USA.
|
904
|
26
|
31380
|
27 ;;; Credits:
|
|
28
|
|
29 ;; VC was initially designed and implemented by Eric S. Raymond
|
|
30 ;; <esr@snark.thyrsus.com>. Over the years, many people have
|
|
31 ;; contributed substantial amounts of work to VC. These include:
|
|
32 ;; Per Cederqvist <ceder@lysator.liu.se>
|
|
33 ;; Paul Eggert <eggert@twinsun.com>
|
|
34 ;; Sebastian Kremer <sk@thp.uni-koeln.de>
|
|
35 ;; Martin Lorentzson <martinl@gnu.org>
|
32910
|
36 ;; Dave Love <fx@gnu.org>
|
31380
|
37 ;; Stefan Monnier <monnier@cs.yale.edu>
|
|
38 ;; Andre Spiegel <spiegel@gnu.org>
|
|
39 ;; Richard Stallman <rms@gnu.org>
|
|
40 ;; ttn@netcom.com
|
|
41
|
904
|
42 ;;; Commentary:
|
|
43
|
2402
61e1f8813d03
(vc-comment-to-changelog): A useful vc-checkin hook, added.
Eric S. Raymond <esr@snark.thyrsus.com>
diff
changeset
|
44 ;; This mode is fully documented in the Emacs user's manual.
|
61e1f8813d03
(vc-comment-to-changelog): A useful vc-checkin hook, added.
Eric S. Raymond <esr@snark.thyrsus.com>
diff
changeset
|
45 ;;
|
10537
|
46 ;; Supported version-control systems presently include SCCS, RCS, and CVS.
|
12943
10d0f42db2da
(vc-directory): Kill existing vc-dired buffers for this directory.
André Spiegel <spiegel@gnu.org>
diff
changeset
|
47 ;;
|
10d0f42db2da
(vc-directory): Kill existing vc-dired buffers for this directory.
André Spiegel <spiegel@gnu.org>
diff
changeset
|
48 ;; Some features will not work with old RCS versions. Where
|
10d0f42db2da
(vc-directory): Kill existing vc-dired buffers for this directory.
André Spiegel <spiegel@gnu.org>
diff
changeset
|
49 ;; appropriate, VC finds out which version you have, and allows or
|
31380
|
50 ;; disallows those features (stealing locks, for example, works only
|
12943
10d0f42db2da
(vc-directory): Kill existing vc-dired buffers for this directory.
André Spiegel <spiegel@gnu.org>
diff
changeset
|
51 ;; from 5.6.2 onwards).
|
10537
|
52 ;; Even initial checkins will fail if your RCS version is so old that ci
|
|
53 ;; doesn't understand -t-; this has been known to happen to people running
|
31380
|
54 ;; NExTSTEP 3.0.
|
904
|
55 ;;
|
31380
|
56 ;; You can support the RCS -x option by customizing vc-rcs-master-templates.
|
904
|
57 ;;
|
|
58 ;; Proper function of the SCCS diff commands requires the shellscript vcdiff
|
|
59 ;; to be installed somewhere on Emacs's path for executables.
|
|
60 ;;
|
2402
61e1f8813d03
(vc-comment-to-changelog): A useful vc-checkin hook, added.
Eric S. Raymond <esr@snark.thyrsus.com>
diff
changeset
|
61 ;; If your site uses the ChangeLog convention supported by Emacs, the
|
2464
667050db93ca
(vc-comment-to-change-log): Renamed from vc-comment-to-changelog.
Roland McGrath <roland@gnu.org>
diff
changeset
|
62 ;; function vc-comment-to-change-log should prove a useful checkin hook.
|
2402
61e1f8813d03
(vc-comment-to-changelog): A useful vc-checkin hook, added.
Eric S. Raymond <esr@snark.thyrsus.com>
diff
changeset
|
63 ;;
|
904
|
64 ;; The vc code maintains some internal state in order to reduce expensive
|
|
65 ;; version-control operations to a minimum. Some names are only computed
|
2750
|
66 ;; once. If you perform version control operations with RCS/SCCS/CVS while
|
904
|
67 ;; vc's back is turned, or move/rename master files while vc is running,
|
|
68 ;; vc may get seriously confused. Don't do these things!
|
|
69 ;;
|
|
70 ;; Developer's notes on some concurrency issues are included at the end of
|
|
71 ;; the file.
|
|
72
|
|
73 ;;; Code:
|
|
74
|
31380
|
75 ;;;;;;;;;;;;;;;;; Backend-specific functions ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
76 ;;
|
33562
|
77 ;; For each operation FUN, the backend should provide a function
|
|
78 ;; vc-BACKEND-FUN. Operations marked with a `-' instead of a `*'
|
|
79 ;; are optional.
|
|
80
|
|
81 ;;;
|
|
82 ;;; State-querying functions
|
|
83 ;;;
|
31380
|
84
|
|
85 ;; * registered (file)
|
|
86 ;; * state (file)
|
|
87 ;; - state-heuristic (file)
|
|
88 ;; The default behavior delegates to `state'.
|
|
89 ;; - dir-state (dir)
|
33562
|
90 ;; * workfile-version (file)
|
|
91 ;; * latest-on-branch-p (file)
|
31380
|
92 ;; * checkout-model (file)
|
33562
|
93 ;; - workfile-unchanged-p (file)
|
|
94 ;; Return non-nil if FILE is unchanged from its current workfile version.
|
|
95 ;; This function should do a brief comparison of FILE's contents
|
|
96 ;; with those of the master version. If the backend does not have
|
|
97 ;; such a brief-comparison feature, the default implementation of this
|
|
98 ;; function can be used, which delegates to a full vc-BACKEND-diff.
|
31380
|
99 ;; - mode-line-string (file)
|
33562
|
100 ;; - dired-state-info (file)
|
|
101
|
|
102 ;;;
|
|
103 ;;; State-changing functions
|
|
104 ;;;
|
|
105
|
31380
|
106 ;; * register (file rev comment)
|
31404
|
107 ;; - responsible-p (file)
|
31380
|
108 ;; Should also work if FILE is a directory (ends with a slash).
|
|
109 ;; - could-register (file)
|
33562
|
110 ;; - receive-file (file rev)
|
|
111 ;; - unregister (file backend)
|
|
112 ;; * checkin (file rev comment)
|
31380
|
113 ;; * checkout (file writable &optional rev destfile)
|
|
114 ;; Checkout revision REV of FILE into DESTFILE.
|
|
115 ;; DESTFILE defaults to FILE.
|
|
116 ;; The file should be made writable if WRITABLE is non-nil.
|
|
117 ;; REV can be nil (BASE) or "" (HEAD) or any other revision.
|
33562
|
118 ;; * revert (file)
|
|
119 ;; - cancel-version (file writable)
|
|
120 ;; - merge (file rev1 rev2)
|
|
121 ;; - merge-news (file)
|
|
122 ;; Only needed if state `needs-merge' is possible.
|
|
123 ;; - steal-lock (file &optional version)
|
|
124 ;; Only required if files can be locked by somebody else.
|
|
125
|
|
126 ;;;
|
|
127 ;;; History functions
|
|
128 ;;;
|
|
129
|
|
130 ;; * print-log (file)
|
|
131 ;; Insert the revision log of FILE into the current buffer.
|
|
132 ;; - show-log-entry (version)
|
|
133 ;; - wash-log (file)
|
|
134 ;; Remove all non-comment information from the output of print-log
|
31380
|
135 ;; - logentry-check ()
|
33562
|
136 ;; - comment-history (file)
|
|
137 ;; - update-changelog (files)
|
|
138 ;; Find changelog entries for FILES, or for all files at or below
|
|
139 ;; the default-directory if FILES is nil.
|
31380
|
140 ;; * diff (file &optional rev1 rev2)
|
|
141 ;; Insert the diff for FILE into the current buffer.
|
|
142 ;; REV1 should default to workfile-version.
|
|
143 ;; REV2 should default to the current workfile
|
|
144 ;; Return a status of either 0 (i.e. no diff) or 1 (i.e. either non-empty
|
|
145 ;; diff or the diff is run asynchronously).
|
33562
|
146 ;; - annotate-command (file buf rev)
|
|
147 ;; - annotate-difference (pos)
|
|
148 ;; Only required if `annotate-command' is defined for the backend.
|
|
149
|
|
150 ;;;
|
|
151 ;;; Snapshot system
|
|
152 ;;;
|
|
153
|
31380
|
154 ;; - create-snapshot (dir name branchp)
|
33562
|
155 ;; Take a snapshot of the current state of files under DIR and
|
|
156 ;; name it NAME. This should make sure that files are up-to-date
|
|
157 ;; before proceeding with the action. DIR can also be a file and
|
|
158 ;; if BRANCHP is specified, NAME should be created as a branch and
|
|
159 ;; DIR should be checked out under this new branch. The default
|
|
160 ;; behavior does not support branches but does a sanity check, a
|
|
161 ;; tree traversal and for each file calls `assign-name'.
|
31380
|
162 ;; * assign-name (file name)
|
|
163 ;; Give name NAME to the current version of FILE, assuming it is
|
|
164 ;; up-to-date. Only used by the default version of `create-snapshot'.
|
|
165 ;; - retrieve-snapshot (dir name update)
|
|
166 ;; Retrieve a named snapshot of all registered files at or below DIR.
|
31565
|
167 ;; If UPDATE is non-nil, then update buffers of any files in the snapshot
|
31380
|
168 ;; that are currently visited.
|
33562
|
169
|
|
170 ;;;
|
|
171 ;;; Miscellaneous
|
|
172 ;;;
|
|
173
|
|
174 ;; - make-version-backups-p (file)
|
|
175 ;; - check-headers ()
|
|
176 ;; - clear-headers ()
|
31404
|
177 ;; - rename-file (old new)
|
33562
|
178
|
|
179
|
|
180 ;;;;;;;;;;;;;;; End of backend-specific functions ;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
31380
|
181
|
904
|
182 (require 'vc-hooks)
|
2580
a66f7ed76416
(vc-diff): Get proper error message when you run this with no prefix
Eric S. Raymond <esr@snark.thyrsus.com>
diff
changeset
|
183 (require 'ring)
|
31380
|
184 (eval-when-compile
|
32058
|
185 (require 'cl)
|
31404
|
186 (require 'compile)
|
|
187 (require 'dired) ; for dired-map-over-marks macro
|
|
188 (require 'dired-aux)) ; for dired-kill-{line,tree}
|
2580
a66f7ed76416
(vc-diff): Get proper error message when you run this with no prefix
Eric S. Raymond <esr@snark.thyrsus.com>
diff
changeset
|
189
|
a66f7ed76416
(vc-diff): Get proper error message when you run this with no prefix
Eric S. Raymond <esr@snark.thyrsus.com>
diff
changeset
|
190 (if (not (assoc 'vc-parent-buffer minor-mode-alist))
|
a66f7ed76416
(vc-diff): Get proper error message when you run this with no prefix
Eric S. Raymond <esr@snark.thyrsus.com>
diff
changeset
|
191 (setq minor-mode-alist
|
a66f7ed76416
(vc-diff): Get proper error message when you run this with no prefix
Eric S. Raymond <esr@snark.thyrsus.com>
diff
changeset
|
192 (cons '(vc-parent-buffer vc-parent-buffer-name)
|
a66f7ed76416
(vc-diff): Get proper error message when you run this with no prefix
Eric S. Raymond <esr@snark.thyrsus.com>
diff
changeset
|
193 minor-mode-alist)))
|
904
|
194
|
|
195 ;; General customization
|
|
196
|
17672
|
197 (defgroup vc nil
|
|
198 "Version-control system in Emacs."
|
|
199 :group 'tools)
|
|
200
|
|
201 (defcustom vc-suppress-confirm nil
|
|
202 "*If non-nil, treat user as expert; suppress yes-no prompts on some things."
|
|
203 :type 'boolean
|
|
204 :group 'vc)
|
|
205
|
24477
|
206 (defcustom vc-delete-logbuf-window t
|
|
207 "*If non-nil, delete the *VC-log* buffer and window after each logical action.
|
|
208 If nil, bury that buffer instead.
|
|
209 This is most useful if you have multiple windows on a frame and would like to
|
|
210 preserve the setting."
|
|
211 :type 'boolean
|
|
212 :group 'vc)
|
|
213
|
17672
|
214 (defcustom vc-initial-comment nil
|
|
215 "*If non-nil, prompt for initial comment when a file is registered."
|
|
216 :type 'boolean
|
|
217 :group 'vc)
|
|
218
|
20988
|
219 (defcustom vc-default-init-version "1.1"
|
|
220 "*A string used as the default version number when a new file is registered.
|
31380
|
221 This can be overridden by giving a prefix argument to \\[vc-register]."
|
20988
|
222 :type 'string
|
21669
|
223 :group 'vc
|
|
224 :version "20.3")
|
20988
|
225
|
17672
|
226 (defcustom vc-command-messages nil
|
|
227 "*If non-nil, display run messages from back-end commands."
|
|
228 :type 'boolean
|
|
229 :group 'vc)
|
|
230
|
|
231 (defcustom vc-checkin-switches nil
|
|
232 "*A string or list of strings specifying extra switches for checkin.
|
|
233 These are passed to the checkin program by \\[vc-checkin]."
|
|
234 :type '(choice (const :tag "None" nil)
|
|
235 (string :tag "Argument String")
|
|
236 (repeat :tag "Argument List"
|
|
237 :value ("")
|
|
238 string))
|
|
239 :group 'vc)
|
|
240
|
|
241 (defcustom vc-checkout-switches nil
|
|
242 "*A string or list of strings specifying extra switches for checkout.
|
|
243 These are passed to the checkout program by \\[vc-checkout]."
|
|
244 :type '(choice (const :tag "None" nil)
|
|
245 (string :tag "Argument String")
|
|
246 (repeat :tag "Argument List"
|
|
247 :value ("")
|
|
248 string))
|
|
249 :group 'vc)
|
|
250
|
|
251 (defcustom vc-register-switches nil
|
|
252 "*A string or list of strings; extra switches for registering a file.
|
|
253 These are passed to the checkin program by \\[vc-register]."
|
|
254 :type '(choice (const :tag "None" nil)
|
|
255 (string :tag "Argument String")
|
|
256 (repeat :tag "Argument List"
|
|
257 :value ("")
|
|
258 string))
|
|
259 :group 'vc)
|
|
260
|
31380
|
261 (defcustom vc-dired-listing-switches "-al"
|
|
262 "*Switches passed to `ls' for vc-dired. MUST contain the `l' option."
|
|
263 :type 'string
|
|
264 :group 'vc
|
31565
|
265 :version "21.1")
|
31380
|
266
|
22437
|
267 (defcustom vc-dired-recurse t
|
|
268 "*If non-nil, show directory trees recursively in VC Dired."
|
|
269 :type 'boolean
|
|
270 :group 'vc
|
|
271 :version "20.3")
|
|
272
|
|
273 (defcustom vc-dired-terse-display t
|
|
274 "*If non-nil, show only locked files in VC Dired."
|
|
275 :type 'boolean
|
|
276 :group 'vc
|
|
277 :version "20.3")
|
|
278
|
17672
|
279 (defcustom vc-directory-exclusion-list '("SCCS" "RCS" "CVS")
|
|
280 "*List of directory names to be ignored while recursively walking file trees."
|
|
281 :type '(repeat string)
|
|
282 :group 'vc)
|
1335
|
283
|
2580
a66f7ed76416
(vc-diff): Get proper error message when you run this with no prefix
Eric S. Raymond <esr@snark.thyrsus.com>
diff
changeset
|
284 (defconst vc-maximum-comment-ring-size 32
|
a66f7ed76416
(vc-diff): Get proper error message when you run this with no prefix
Eric S. Raymond <esr@snark.thyrsus.com>
diff
changeset
|
285 "Maximum number of saved comments in the comment ring.")
|
a66f7ed76416
(vc-diff): Get proper error message when you run this with no prefix
Eric S. Raymond <esr@snark.thyrsus.com>
diff
changeset
|
286
|
2705
|
287 ;;; This is duplicated in diff.el.
|
|
288 (defvar diff-switches "-c"
|
31380
|
289 "*A string or list of strings specifying switches to be passed to diff.")
|
|
290
|
|
291 ;;;###autoload
|
|
292 (defcustom vc-checkin-hook nil
|
|
293 "*Normal hook (list of functions) run after a checkin is done.
|
|
294 See `run-hooks'."
|
|
295 :type 'hook
|
|
296 :options '(vc-comment-to-change-log)
|
|
297 :group 'vc)
|
2705
|
298
|
31380
|
299 ;;;###autoload
|
|
300 (defcustom vc-before-checkin-hook nil
|
|
301 "*Normal hook (list of functions) run before a file gets checked in.
|
|
302 See `run-hooks'."
|
|
303 :type 'hook
|
|
304 :group 'vc)
|
|
305
|
|
306 (defcustom vc-logentry-check-hook nil
|
|
307 "*Normal hook run by `vc-backend-logentry-check'.
|
|
308 Use this to impose your own rules on the entry in addition to any the
|
|
309 version control backend imposes itself."
|
|
310 :type 'hook
|
|
311 :group 'vc)
|
|
312
|
|
313 ;; Annotate customization
|
18174
|
314 (defcustom vc-annotate-color-map
|
|
315 '(( 26.3672 . "#FF0000")
|
|
316 ( 52.7344 . "#FF3800")
|
|
317 ( 79.1016 . "#FF7000")
|
|
318 (105.4688 . "#FFA800")
|
|
319 (131.8359 . "#FFE000")
|
|
320 (158.2031 . "#E7FF00")
|
|
321 (184.5703 . "#AFFF00")
|
|
322 (210.9375 . "#77FF00")
|
|
323 (237.3047 . "#3FFF00")
|
|
324 (263.6719 . "#07FF00")
|
|
325 (290.0391 . "#00FF31")
|
|
326 (316.4063 . "#00FF69")
|
|
327 (342.7734 . "#00FFA1")
|
|
328 (369.1406 . "#00FFD9")
|
|
329 (395.5078 . "#00EEFF")
|
|
330 (421.8750 . "#00B6FF")
|
|
331 (448.2422 . "#007EFF"))
|
|
332 "*Association list of age versus color, for \\[vc-annotate].
|
|
333 Ages are given in units of 2**-16 seconds.
|
|
334 Default is eighteen steps using a twenty day increment."
|
31380
|
335 :type 'alist
|
18174
|
336 :group 'vc)
|
|
337
|
|
338 (defcustom vc-annotate-very-old-color "#0046FF"
|
|
339 "*Color for lines older than CAR of last cons in `vc-annotate-color-map'."
|
|
340 :type 'string
|
|
341 :group 'vc)
|
|
342
|
|
343 (defcustom vc-annotate-background "black"
|
|
344 "*Background color for \\[vc-annotate].
|
|
345 Default color is used if nil."
|
|
346 :type 'string
|
|
347 :group 'vc)
|
|
348
|
|
349 (defcustom vc-annotate-menu-elements '(2 0.5 0.1 0.01)
|
|
350 "*Menu elements for the mode-specific menu of VC-Annotate mode.
|
|
351 List of factors, used to expand/compress the time scale. See `vc-annotate'."
|
31380
|
352 :type '(repeat number)
|
17672
|
353 :group 'vc)
|
1227
|
354
|
31380
|
355 ;; vc-annotate functionality (CVS only).
|
|
356 (defvar vc-annotate-mode nil
|
|
357 "Variable indicating if VC-Annotate mode is active.")
|
|
358
|
|
359 (defvar vc-annotate-mode-map
|
|
360 (let ((m (make-sparse-keymap)))
|
|
361 (define-key m [menu-bar] (make-sparse-keymap "VC-Annotate"))
|
|
362 m)
|
|
363 "Local keymap used for VC-Annotate mode.")
|
|
364
|
|
365 (defvar vc-annotate-mode-menu nil
|
|
366 "Local keymap used for VC-Annotate mode's menu bar menu.")
|
18174
|
367
|
904
|
368 ;; Header-insertion hair
|
|
369
|
17672
|
370 (defcustom vc-static-header-alist
|
904
|
371 '(("\\.c$" .
|
|
372 "\n#ifndef lint\nstatic char vcid[] = \"\%s\";\n#endif /* lint */\n"))
|
31380
|
373 "*Associate static header string templates with file types.
|
|
374 A \%s in the template is replaced with the first string associated with
|
31404
|
375 the file's version control type in `vc-header-alist'."
|
17672
|
376 :type '(repeat (cons :format "%v"
|
|
377 (regexp :tag "File Type")
|
|
378 (string :tag "Header String")))
|
|
379 :group 'vc)
|
2226
b2216b3b8f57
(vc-header-strings) Name changed to vc-header-alist, to match the
Eric S. Raymond <esr@snark.thyrsus.com>
diff
changeset
|
380
|
17672
|
381 (defcustom vc-comment-alist
|
904
|
382 '((nroff-mode ".\\\"" ""))
|
|
383 "*Special comment delimiters to be used in generating vc headers only.
|
31404
|
384 Add an entry in this list if you need to override the normal `comment-start'
|
|
385 and `comment-end' variables. This will only be necessary if the mode language
|
17672
|
386 is sensitive to blank lines."
|
|
387 :type '(repeat (list :format "%v"
|
|
388 (symbol :tag "Mode")
|
|
389 (string :tag "Comment Start")
|
|
390 (string :tag "Comment End")))
|
|
391 :group 'vc)
|
904
|
392
|
5201
|
393 ;; Default is to be extra careful for super-user.
|
31565
|
394 ;; TODO: This variable is no longer used; the corresponding checks
|
|
395 ;; are always done now. If that turns out to be fast enough,
|
31380
|
396 ;; the variable can be obsoleted.
|
17672
|
397 (defcustom vc-checkout-carefully (= (user-uid) 0)
|
5201
|
398 "*Non-nil means be extra-careful in checkout.
|
|
399 Verify that the file really is not locked
|
17672
|
400 and that its contents match what the master file says."
|
|
401 :type 'boolean
|
|
402 :group 'vc)
|
5201
|
403
|
31380
|
404
|
|
405 ;;; The main keymap
|
12943
10d0f42db2da
(vc-directory): Kill existing vc-dired buffers for this directory.
André Spiegel <spiegel@gnu.org>
diff
changeset
|
406
|
31380
|
407 (defvar vc-prefix-map
|
|
408 (let ((map (make-sparse-keymap)))
|
|
409 (define-key map "a" 'vc-update-change-log)
|
31810
495ca3bd372d
(vc-index-of, vc-transfer-file, vc-default-receive-file): New functions.
André Spiegel <spiegel@gnu.org>
diff
changeset
|
410 (define-key map "b" 'vc-switch-backend)
|
31380
|
411 (define-key map "c" 'vc-cancel-version)
|
|
412 (define-key map "d" 'vc-directory)
|
|
413 (define-key map "g" 'vc-annotate)
|
|
414 (define-key map "h" 'vc-insert-headers)
|
|
415 (define-key map "i" 'vc-register)
|
|
416 (define-key map "l" 'vc-print-log)
|
|
417 (define-key map "m" 'vc-merge)
|
|
418 (define-key map "r" 'vc-retrieve-snapshot)
|
|
419 (define-key map "s" 'vc-create-snapshot)
|
|
420 (define-key map "u" 'vc-revert-buffer)
|
|
421 (define-key map "v" 'vc-next-action)
|
|
422 (define-key map "=" 'vc-diff)
|
|
423 (define-key map "~" 'vc-version-other-window)
|
|
424 map))
|
|
425 (fset 'vc-prefix-map vc-prefix-map)
|
12943
10d0f42db2da
(vc-directory): Kill existing vc-dired buffers for this directory.
André Spiegel <spiegel@gnu.org>
diff
changeset
|
426
|
31380
|
427 ;; Initialization code, to be done just once at load-time
|
|
428 (defvar vc-log-mode-map
|
|
429 (let ((map (make-sparse-keymap)))
|
|
430 (define-key map "\M-n" 'vc-next-comment)
|
|
431 (define-key map "\M-p" 'vc-previous-comment)
|
|
432 (define-key map "\M-r" 'vc-comment-search-reverse)
|
|
433 (define-key map "\M-s" 'vc-comment-search-forward)
|
|
434 (define-key map "\C-c\C-c" 'vc-finish-logentry)
|
|
435 map))
|
|
436 ;; Compatibility with old name. Should we bother ?
|
|
437 (defvar vc-log-entry-mode vc-log-mode-map)
|
12943
10d0f42db2da
(vc-directory): Kill existing vc-dired buffers for this directory.
André Spiegel <spiegel@gnu.org>
diff
changeset
|
438
|
31380
|
439
|
904
|
440 ;; Variables the user doesn't need to know about.
|
|
441 (defvar vc-log-operation nil)
|
1227
|
442 (defvar vc-log-after-operation-hook nil)
|
31380
|
443 (defvar vc-annotate-buffers nil
|
31404
|
444 "Alist of current \"Annotate\" buffers and their corresponding backends.
|
|
445 The keys are \(BUFFER . BACKEND\). See also `vc-annotate-get-backend'.")
|
8350
|
446 ;; In a log entry buffer, this is a local variable
|
|
447 ;; that points to the buffer for which it was made
|
|
448 ;; (either a file, or a VC dired buffer).
|
2402
61e1f8813d03
(vc-comment-to-changelog): A useful vc-checkin hook, added.
Eric S. Raymond <esr@snark.thyrsus.com>
diff
changeset
|
449 (defvar vc-parent-buffer nil)
|
31380
|
450 (put 'vc-parent-buffer 'permanent-local t)
|
2580
a66f7ed76416
(vc-diff): Get proper error message when you run this with no prefix
Eric S. Raymond <esr@snark.thyrsus.com>
diff
changeset
|
451 (defvar vc-parent-buffer-name nil)
|
31380
|
452 (put 'vc-parent-buffer-name 'permanent-local t)
|
904
|
453
|
1494
|
454 (defvar vc-log-file)
|
|
455 (defvar vc-log-version)
|
|
456
|
2580
a66f7ed76416
(vc-diff): Get proper error message when you run this with no prefix
Eric S. Raymond <esr@snark.thyrsus.com>
diff
changeset
|
457 (defvar vc-dired-mode nil)
|
2490
70d00ecacc0d
(vc-directory. vc-start-entry, vc-next-action, vc-next-action-on-file):
Eric S. Raymond <esr@snark.thyrsus.com>
diff
changeset
|
458 (make-variable-buffer-local 'vc-dired-mode)
|
70d00ecacc0d
(vc-directory. vc-start-entry, vc-next-action, vc-next-action-on-file):
Eric S. Raymond <esr@snark.thyrsus.com>
diff
changeset
|
459
|
15036
|
460 (defvar vc-comment-ring (make-ring vc-maximum-comment-ring-size))
|
2580
a66f7ed76416
(vc-diff): Get proper error message when you run this with no prefix
Eric S. Raymond <esr@snark.thyrsus.com>
diff
changeset
|
461 (defvar vc-comment-ring-index nil)
|
31380
|
462 (defvar vc-last-comment-match "")
|
12943
10d0f42db2da
(vc-directory): Kill existing vc-dired buffers for this directory.
André Spiegel <spiegel@gnu.org>
diff
changeset
|
463
|
31380
|
464 ;;; functions that operate on RCS revision numbers. This code should
|
|
465 ;;; also be moved into the backends. It stays for now, however, since
|
|
466 ;;; it is used in code below.
|
12872
857663042672
(vc-revert-buffer1): Split part of the function into vc-buffer-context
André Spiegel <spiegel@gnu.org>
diff
changeset
|
467 (defun vc-trunk-p (rev)
|
31404
|
468 "Return t if REV is a revision on the trunk."
|
12872
857663042672
(vc-revert-buffer1): Split part of the function into vc-buffer-context
André Spiegel <spiegel@gnu.org>
diff
changeset
|
469 (not (eq nil (string-match "\\`[0-9]+\\.[0-9]+\\'" rev))))
|
857663042672
(vc-revert-buffer1): Split part of the function into vc-buffer-context
André Spiegel <spiegel@gnu.org>
diff
changeset
|
470
|
21368
|
471 (defun vc-branch-p (rev)
|
31404
|
472 "Return t if REV is a branch revision."
|
21368
|
473 (not (eq nil (string-match "\\`[0-9]+\\(\\.[0-9]+\\.[0-9]+\\)*\\'" rev))))
|
|
474
|
12872
857663042672
(vc-revert-buffer1): Split part of the function into vc-buffer-context
André Spiegel <spiegel@gnu.org>
diff
changeset
|
475 (defun vc-branch-part (rev)
|
31404
|
476 "Return the branch part of a revision number REV."
|
12872
857663042672
(vc-revert-buffer1): Split part of the function into vc-buffer-context
André Spiegel <spiegel@gnu.org>
diff
changeset
|
477 (substring rev 0 (string-match "\\.[0-9]+\\'" rev)))
|
857663042672
(vc-revert-buffer1): Split part of the function into vc-buffer-context
André Spiegel <spiegel@gnu.org>
diff
changeset
|
478
|
19055
5439070e5d46
(vc-backend-checkin): For CVS, forget the checkout model after commit.
Richard M. Stallman <rms@gnu.org>
diff
changeset
|
479 (defun vc-minor-part (rev)
|
31404
|
480 "Return the minor version number of a revision number REV."
|
19055
5439070e5d46
(vc-backend-checkin): For CVS, forget the checkout model after commit.
Richard M. Stallman <rms@gnu.org>
diff
changeset
|
481 (string-match "[0-9]+\\'" rev)
|
5439070e5d46
(vc-backend-checkin): For CVS, forget the checkout model after commit.
Richard M. Stallman <rms@gnu.org>
diff
changeset
|
482 (substring rev (match-beginning 0) (match-end 0)))
|
5439070e5d46
(vc-backend-checkin): For CVS, forget the checkout model after commit.
Richard M. Stallman <rms@gnu.org>
diff
changeset
|
483
|
5439070e5d46
(vc-backend-checkin): For CVS, forget the checkout model after commit.
Richard M. Stallman <rms@gnu.org>
diff
changeset
|
484 (defun vc-previous-version (rev)
|
31404
|
485 "Guess the version number immediately preceding REV."
|
19055
5439070e5d46
(vc-backend-checkin): For CVS, forget the checkout model after commit.
Richard M. Stallman <rms@gnu.org>
diff
changeset
|
486 (let ((branch (vc-branch-part rev))
|
5439070e5d46
(vc-backend-checkin): For CVS, forget the checkout model after commit.
Richard M. Stallman <rms@gnu.org>
diff
changeset
|
487 (minor-num (string-to-number (vc-minor-part rev))))
|
5439070e5d46
(vc-backend-checkin): For CVS, forget the checkout model after commit.
Richard M. Stallman <rms@gnu.org>
diff
changeset
|
488 (if (> minor-num 1)
|
5439070e5d46
(vc-backend-checkin): For CVS, forget the checkout model after commit.
Richard M. Stallman <rms@gnu.org>
diff
changeset
|
489 ;; version does probably not start a branch or release
|
5439070e5d46
(vc-backend-checkin): For CVS, forget the checkout model after commit.
Richard M. Stallman <rms@gnu.org>
diff
changeset
|
490 (concat branch "." (number-to-string (1- minor-num)))
|
5439070e5d46
(vc-backend-checkin): For CVS, forget the checkout model after commit.
Richard M. Stallman <rms@gnu.org>
diff
changeset
|
491 (if (vc-trunk-p rev)
|
5439070e5d46
(vc-backend-checkin): For CVS, forget the checkout model after commit.
Richard M. Stallman <rms@gnu.org>
diff
changeset
|
492 ;; we are at the beginning of the trunk --
|
5439070e5d46
(vc-backend-checkin): For CVS, forget the checkout model after commit.
Richard M. Stallman <rms@gnu.org>
diff
changeset
|
493 ;; don't know anything to return here
|
5439070e5d46
(vc-backend-checkin): For CVS, forget the checkout model after commit.
Richard M. Stallman <rms@gnu.org>
diff
changeset
|
494 ""
|
5439070e5d46
(vc-backend-checkin): For CVS, forget the checkout model after commit.
Richard M. Stallman <rms@gnu.org>
diff
changeset
|
495 ;; we are at the beginning of a branch --
|
5439070e5d46
(vc-backend-checkin): For CVS, forget the checkout model after commit.
Richard M. Stallman <rms@gnu.org>
diff
changeset
|
496 ;; return version of starting point
|
5439070e5d46
(vc-backend-checkin): For CVS, forget the checkout model after commit.
Richard M. Stallman <rms@gnu.org>
diff
changeset
|
497 (vc-branch-part branch)))))
|
5439070e5d46
(vc-backend-checkin): For CVS, forget the checkout model after commit.
Richard M. Stallman <rms@gnu.org>
diff
changeset
|
498
|
904
|
499 ;; File property caching
|
|
500
|
2580
a66f7ed76416
(vc-diff): Get proper error message when you run this with no prefix
Eric S. Raymond <esr@snark.thyrsus.com>
diff
changeset
|
501 (defun vc-clear-context ()
|
a66f7ed76416
(vc-diff): Get proper error message when you run this with no prefix
Eric S. Raymond <esr@snark.thyrsus.com>
diff
changeset
|
502 "Clear all cached file properties and the comment ring."
|
a66f7ed76416
(vc-diff): Get proper error message when you run this with no prefix
Eric S. Raymond <esr@snark.thyrsus.com>
diff
changeset
|
503 (interactive)
|
a66f7ed76416
(vc-diff): Get proper error message when you run this with no prefix
Eric S. Raymond <esr@snark.thyrsus.com>
diff
changeset
|
504 (fillarray vc-file-prop-obarray nil)
|
a66f7ed76416
(vc-diff): Get proper error message when you run this with no prefix
Eric S. Raymond <esr@snark.thyrsus.com>
diff
changeset
|
505 ;; Note: there is potential for minor lossage here if there is an open
|
a66f7ed76416
(vc-diff): Get proper error message when you run this with no prefix
Eric S. Raymond <esr@snark.thyrsus.com>
diff
changeset
|
506 ;; log buffer with a nonzero local value of vc-comment-ring-index.
|
15036
|
507 (setq vc-comment-ring (make-ring vc-maximum-comment-ring-size)))
|
2580
a66f7ed76416
(vc-diff): Get proper error message when you run this with no prefix
Eric S. Raymond <esr@snark.thyrsus.com>
diff
changeset
|
508
|
31404
|
509 (defmacro with-vc-properties (file form settings)
|
32189
921a2e8fa97e
(with-vc-properties): Use conses rather than length-2 lists.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
510 "Execute FORM, then set per-file properties for FILE,
|
921a2e8fa97e
(with-vc-properties): Use conses rather than length-2 lists.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
511 but only those that have not been set during the execution of FORM.
|
921a2e8fa97e
(with-vc-properties): Use conses rather than length-2 lists.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
512 SETTINGS is a list of two-element lists, each of which has the
|
921a2e8fa97e
(with-vc-properties): Use conses rather than length-2 lists.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
513 form (PROPERTY . VALUE)."
|
31404
|
514 `(let ((vc-touched-properties (list t))
|
|
515 (filename ,file))
|
|
516 ,form
|
|
517 (mapcar (lambda (setting)
|
32189
921a2e8fa97e
(with-vc-properties): Use conses rather than length-2 lists.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
518 (let ((property (car setting)))
|
31404
|
519 (unless (memq property vc-touched-properties)
|
32344
f91ef1141a75
(with-vc-file, edit-vc-file): Specify `indent-function' property.
Thien-Thi Nguyen <ttn@gnuvola.org>
diff
changeset
|
520 (put (intern filename vc-file-prop-obarray)
|
32189
921a2e8fa97e
(with-vc-properties): Use conses rather than length-2 lists.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
521 property (cdr setting)))))
|
31404
|
522 ,settings)))
|
|
523
|
904
|
524 ;; Random helper functions
|
|
525
|
31380
|
526 (defsubst vc-editable-p (file)
|
|
527 (or (eq (vc-checkout-model file) 'implicit)
|
32058
|
528 (memq (vc-state file) '(edited needs-merge))))
|
12872
857663042672
(vc-revert-buffer1): Split part of the function into vc-buffer-context
André Spiegel <spiegel@gnu.org>
diff
changeset
|
529
|
23635
|
530 ;;; Two macros for elisp programming
|
|
531 ;;;###autoload
|
|
532 (defmacro with-vc-file (file comment &rest body)
|
31380
|
533 "Check out a writable copy of FILE if necessary and execute the body.
|
|
534 Check in FILE with COMMENT (a string) after BODY has been executed.
|
|
535 FILE is passed through `expand-file-name'; BODY executed within
|
|
536 `save-excursion'. If FILE is not under version control, or locked by
|
23635
|
537 somebody else, signal error."
|
|
538 `(let ((file (expand-file-name ,file)))
|
32059
|
539 (or (vc-backend file)
|
23635
|
540 (error (format "File not under version control: `%s'" file)))
|
31380
|
541 (unless (vc-editable-p file)
|
|
542 (let ((state (vc-state file)))
|
|
543 (if (stringp state) (error (format "`%s' is locking `%s'" state file))
|
|
544 (vc-checkout file t))))
|
23635
|
545 (save-excursion
|
|
546 ,@body)
|
|
547 (vc-checkin file nil ,comment)))
|
32344
f91ef1141a75
(with-vc-file, edit-vc-file): Specify `indent-function' property.
Thien-Thi Nguyen <ttn@gnuvola.org>
diff
changeset
|
548 (put 'with-vc-file 'indent-function 1)
|
23635
|
549
|
|
550 ;;;###autoload
|
|
551 (defmacro edit-vc-file (file comment &rest body)
|
31380
|
552 "Edit FILE under version control, executing body.
|
|
553 Checkin with COMMENT after executing BODY.
|
23635
|
554 This macro uses `with-vc-file', passing args to it.
|
|
555 However, before executing BODY, find FILE, and after BODY, save buffer."
|
|
556 `(with-vc-file
|
|
557 ,file ,comment
|
32058
|
558 (set-buffer (find-file-noselect ,file))
|
23635
|
559 ,@body
|
|
560 (save-buffer)))
|
32344
f91ef1141a75
(with-vc-file, edit-vc-file): Specify `indent-function' property.
Thien-Thi Nguyen <ttn@gnuvola.org>
diff
changeset
|
561 (put 'edit-vc-file 'indent-function 1)
|
23635
|
562
|
21366
|
563 (defun vc-ensure-vc-buffer ()
|
31404
|
564 "Make sure that the current buffer visits a version-controlled file."
|
21366
|
565 (if vc-dired-mode
|
|
566 (set-buffer (find-file-noselect (dired-get-filename)))
|
|
567 (while vc-parent-buffer
|
|
568 (pop-to-buffer vc-parent-buffer))
|
|
569 (if (not (buffer-file-name))
|
|
570 (error "Buffer %s is not associated with a file" (buffer-name))
|
|
571 (if (not (vc-backend (buffer-file-name)))
|
|
572 (error "File %s is not under version control" (buffer-file-name))))))
|
2745
|
573
|
904
|
574 (defvar vc-binary-assoc nil)
|
22534
|
575 (defvar vc-binary-suffixes
|
|
576 (if (memq system-type '(ms-dos windows-nt))
|
|
577 '(".exe" ".com" ".bat" ".cmd" ".btm" "")
|
|
578 '("")))
|
904
|
579
|
31380
|
580 (defun vc-process-filter (p s)
|
31404
|
581 "An alternative output filter for async process P.
|
31380
|
582 The only difference with the default filter is to insert S after markers."
|
|
583 (with-current-buffer (process-buffer p)
|
|
584 (save-excursion
|
|
585 (let ((inhibit-read-only t))
|
|
586 (goto-char (process-mark p))
|
|
587 (insert s)
|
|
588 (set-marker (process-mark p) (point))))))
|
|
589
|
|
590 (defun vc-setup-buffer (&optional buf)
|
31404
|
591 "Prepare BUF for executing a VC command and make it the current buffer.
|
31380
|
592 BUF defaults to \"*vc*\", can be a string and will be created if necessary."
|
|
593 (unless buf (setq buf "*vc*"))
|
|
594 (let ((camefrom (current-buffer))
|
|
595 (olddir default-directory))
|
|
596 (set-buffer (get-buffer-create buf))
|
|
597 (kill-all-local-variables)
|
2580
a66f7ed76416
(vc-diff): Get proper error message when you run this with no prefix
Eric S. Raymond <esr@snark.thyrsus.com>
diff
changeset
|
598 (set (make-local-variable 'vc-parent-buffer) camefrom)
|
a66f7ed76416
(vc-diff): Get proper error message when you run this with no prefix
Eric S. Raymond <esr@snark.thyrsus.com>
diff
changeset
|
599 (set (make-local-variable 'vc-parent-buffer-name)
|
a66f7ed76416
(vc-diff): Get proper error message when you run this with no prefix
Eric S. Raymond <esr@snark.thyrsus.com>
diff
changeset
|
600 (concat " from " (buffer-name camefrom)))
|
10537
|
601 (setq default-directory olddir)
|
31380
|
602 (let ((inhibit-read-only t))
|
|
603 (erase-buffer))))
|
|
604
|
|
605 (defun vc-exec-after (code)
|
|
606 "Eval CODE when the current buffer's process is done.
|
|
607 If the current buffer has no process, just evaluate CODE.
|
|
608 Else, add CODE to the process' sentinel."
|
|
609 (let ((proc (get-buffer-process (current-buffer))))
|
|
610 (cond
|
|
611 ;; If there's no background process, just execute the code.
|
|
612 ((null proc) (eval code))
|
|
613 ;; If the background process has exited, reap it and try again
|
|
614 ((eq (process-status proc) 'exit)
|
|
615 (delete-process proc)
|
|
616 (vc-exec-after code))
|
|
617 ;; If a process is running, add CODE to the sentinel
|
|
618 ((eq (process-status proc) 'run)
|
|
619 (let ((sentinel (process-sentinel proc)))
|
|
620 (set-process-sentinel proc
|
|
621 `(lambda (p s)
|
|
622 (with-current-buffer ',(current-buffer)
|
|
623 (goto-char (process-mark p))
|
31565
|
624 ,@(append (cdr (cdr (cdr ;strip off `with-current-buffer buf
|
31380
|
625 ; (goto-char...)'
|
|
626 (car (cdr (cdr ;strip off `lambda (p s)'
|
|
627 sentinel))))))
|
|
628 (list `(vc-exec-after ',code))))))))
|
|
629 (t (error "Unexpected process state"))))
|
|
630 nil)
|
|
631
|
|
632 (defvar vc-post-command-functions nil
|
|
633 "Hook run at the end of `vc-do-command'.
|
|
634 Each function is called inside the buffer in which the command was run
|
|
635 and is passed 3 argument: the COMMAND, the FILE and the FLAGS.")
|
1674
|
636
|
31380
|
637 (defun vc-do-command (buffer okstatus command file &rest flags)
|
31404
|
638 "Execute a version control command, notifying user and checking for errors.
|
31380
|
639 Output from COMMAND goes to BUFFER, or *vc* if BUFFER is nil or the current
|
|
640 buffer (which is assumed to be properly setup) if BUFFER is t. The
|
|
641 command is considered successful if its exit status does not exceed
|
|
642 OKSTATUS (if OKSTATUS is nil, that means to ignore errors, if it is 'async,
|
|
643 that means not to wait for termination of the subprocess). FILE is
|
|
644 the name of the working file (may also be nil, to execute commands
|
31565
|
645 that don't expect a file name). If an optional list of FLAGS is present,
|
31380
|
646 that is inserted into the command line before the filename."
|
|
647 (and file (setq file (expand-file-name file)))
|
|
648 (if vc-command-messages
|
|
649 (message "Running %s on %s..." command file))
|
|
650 (save-current-buffer
|
|
651 (unless (eq buffer t) (vc-setup-buffer buffer))
|
|
652 (let ((squeezed nil)
|
|
653 (inhibit-read-only t)
|
|
654 (status 0))
|
|
655 (setq squeezed (delq nil (copy-sequence flags)))
|
|
656 (when file
|
|
657 ;; FIXME: file-relative-name can return a bogus result because
|
|
658 ;; it doesn't look at the actual file-system to see if symlinks
|
|
659 ;; come into play.
|
|
660 (setq squeezed (append squeezed (list (file-relative-name file)))))
|
|
661 (let ((exec-path (append vc-path exec-path))
|
|
662 ;; Add vc-path to PATH for the execution of this command.
|
|
663 (process-environment
|
|
664 (cons (concat "PATH=" (getenv "PATH")
|
|
665 path-separator
|
|
666 (mapconcat 'identity vc-path path-separator))
|
|
667 process-environment))
|
|
668 (w32-quote-process-args t))
|
|
669 (if (eq okstatus 'async)
|
|
670 (let ((proc (apply 'start-process command (current-buffer) command
|
|
671 squeezed)))
|
33553
840460ecad6f
(vc-do-command): In the asynchronous case, output messages only if the
André Spiegel <spiegel@gnu.org>
diff
changeset
|
672 (unless (active-minibuffer-window)
|
840460ecad6f
(vc-do-command): In the asynchronous case, output messages only if the
André Spiegel <spiegel@gnu.org>
diff
changeset
|
673 (message "Running %s in the background..." command))
|
31380
|
674 ;;(set-process-sentinel proc (lambda (p msg) (delete-process p)))
|
|
675 (set-process-filter proc 'vc-process-filter)
|
|
676 (vc-exec-after
|
33553
840460ecad6f
(vc-do-command): In the asynchronous case, output messages only if the
André Spiegel <spiegel@gnu.org>
diff
changeset
|
677 `(unless (active-minibuffer-window)
|
840460ecad6f
(vc-do-command): In the asynchronous case, output messages only if the
André Spiegel <spiegel@gnu.org>
diff
changeset
|
678 (message "Running %s in the background... done" ',command))))
|
31380
|
679 (setq status (apply 'call-process command nil t nil squeezed))
|
|
680 (when (or (not (integerp status)) (and okstatus (< okstatus status)))
|
|
681 (pop-to-buffer (current-buffer))
|
|
682 (goto-char (point-min))
|
|
683 (shrink-window-if-larger-than-buffer)
|
|
684 (error "Running %s...FAILED (%s)" command
|
|
685 (if (integerp status) (format "status %d" status) status))))
|
|
686 (if vc-command-messages
|
|
687 (message "Running %s...OK" command)))
|
|
688 (vc-exec-after
|
|
689 `(run-hook-with-args 'vc-post-command-functions ',command ',file ',flags))
|
|
690 status)))
|
904
|
691
|
1635
|
692 (defun vc-position-context (posn)
|
31404
|
693 "Save a bit of the text around POSN in the current buffer.
|
|
694 Used to help us find the corresponding position again later
|
|
695 if markers are destroyed or corrupted."
|
31380
|
696 ;; A lot of this was shamelessly lifted from Sebastian Kremer's
|
|
697 ;; rcs.el mode.
|
1635
|
698 (list posn
|
|
699 (buffer-size)
|
|
700 (buffer-substring posn
|
|
701 (min (point-max) (+ posn 100)))))
|
|
702
|
|
703 (defun vc-find-position-by-context (context)
|
31404
|
704 "Return the position of CONTEXT in the current buffer, or nil if not found."
|
1635
|
705 (let ((context-string (nth 2 context)))
|
|
706 (if (equal "" context-string)
|
|
707 (point-max)
|
|
708 (save-excursion
|
|
709 (let ((diff (- (nth 1 context) (buffer-size))))
|
|
710 (if (< diff 0) (setq diff (- diff)))
|
|
711 (goto-char (nth 0 context))
|
|
712 (if (or (search-forward context-string nil t)
|
|
713 ;; Can't use search-backward since the match may continue
|
|
714 ;; after point.
|
|
715 (progn (goto-char (- (point) diff (length context-string)))
|
|
716 ;; goto-char doesn't signal an error at
|
|
717 ;; beginning of buffer like backward-char would
|
|
718 (search-forward context-string nil t)))
|
|
719 ;; to beginning of OSTRING
|
|
720 (- (point) (length context-string))))))))
|
|
721
|
21113
|
722 (defun vc-context-matches-p (posn context)
|
31404
|
723 "Return t if POSN matches CONTEXT, nil otherwise."
|
21113
|
724 (let* ((context-string (nth 2 context))
|
|
725 (len (length context-string))
|
|
726 (end (+ posn len)))
|
|
727 (if (> end (1+ (buffer-size)))
|
|
728 nil
|
|
729 (string= context-string (buffer-substring posn end)))))
|
|
730
|
12872
857663042672
(vc-revert-buffer1): Split part of the function into vc-buffer-context
André Spiegel <spiegel@gnu.org>
diff
changeset
|
731 (defun vc-buffer-context ()
|
31404
|
732 "Return a list (POINT-CONTEXT MARK-CONTEXT REPARSE).
|
|
733 Used by `vc-restore-buffer-context' to later restore the context."
|
1635
|
734 (let ((point-context (vc-position-context (point)))
|
2041
|
735 ;; Use mark-marker to avoid confusion in transient-mark-mode.
|
|
736 (mark-context (if (eq (marker-buffer (mark-marker)) (current-buffer))
|
|
737 (vc-position-context (mark-marker))))
|
2554
5686672705bf
(vc-revert-buffer1): Completely rewrote compilation reparsing code.
Roland McGrath <roland@gnu.org>
diff
changeset
|
738 ;; Make the right thing happen in transient-mark-mode.
|
5686672705bf
(vc-revert-buffer1): Completely rewrote compilation reparsing code.
Roland McGrath <roland@gnu.org>
diff
changeset
|
739 (mark-active nil)
|
2490
70d00ecacc0d
(vc-directory. vc-start-entry, vc-next-action, vc-next-action-on-file):
Eric S. Raymond <esr@snark.thyrsus.com>
diff
changeset
|
740 ;; We may want to reparse the compilation buffer after revert
|
2554
5686672705bf
(vc-revert-buffer1): Completely rewrote compilation reparsing code.
Roland McGrath <roland@gnu.org>
diff
changeset
|
741 (reparse (and (boundp 'compilation-error-list) ;compile loaded
|
5686672705bf
(vc-revert-buffer1): Completely rewrote compilation reparsing code.
Roland McGrath <roland@gnu.org>
diff
changeset
|
742 (let ((curbuf (current-buffer)))
|
5686672705bf
(vc-revert-buffer1): Completely rewrote compilation reparsing code.
Roland McGrath <roland@gnu.org>
diff
changeset
|
743 ;; Construct a list; each elt is nil or a buffer
|
5686672705bf
(vc-revert-buffer1): Completely rewrote compilation reparsing code.
Roland McGrath <roland@gnu.org>
diff
changeset
|
744 ;; iff that buffer is a compilation output buffer
|
5686672705bf
(vc-revert-buffer1): Completely rewrote compilation reparsing code.
Roland McGrath <roland@gnu.org>
diff
changeset
|
745 ;; that contains markers into the current buffer.
|
5686672705bf
(vc-revert-buffer1): Completely rewrote compilation reparsing code.
Roland McGrath <roland@gnu.org>
diff
changeset
|
746 (save-excursion
|
31380
|
747 (mapcar (lambda (buffer)
|
2554
5686672705bf
(vc-revert-buffer1): Completely rewrote compilation reparsing code.
Roland McGrath <roland@gnu.org>
diff
changeset
|
748 (set-buffer buffer)
|
5686672705bf
(vc-revert-buffer1): Completely rewrote compilation reparsing code.
Roland McGrath <roland@gnu.org>
diff
changeset
|
749 (let ((errors (or
|
5686672705bf
(vc-revert-buffer1): Completely rewrote compilation reparsing code.
Roland McGrath <roland@gnu.org>
diff
changeset
|
750 compilation-old-error-list
|
5686672705bf
(vc-revert-buffer1): Completely rewrote compilation reparsing code.
Roland McGrath <roland@gnu.org>
diff
changeset
|
751 compilation-error-list))
|
5686672705bf
(vc-revert-buffer1): Completely rewrote compilation reparsing code.
Roland McGrath <roland@gnu.org>
diff
changeset
|
752 (buffer-error-marked-p nil))
|
2774
|
753 (while (and (consp errors)
|
2554
5686672705bf
(vc-revert-buffer1): Completely rewrote compilation reparsing code.
Roland McGrath <roland@gnu.org>
diff
changeset
|
754 (not buffer-error-marked-p))
|
2617
|
755 (and (markerp (cdr (car errors)))
|
2604
3a56b8caf6c9
(vc-revert-buffer1): Ignore non-marker elts of compilation-error-list.
Roland McGrath <roland@gnu.org>
diff
changeset
|
756 (eq buffer
|
3a56b8caf6c9
(vc-revert-buffer1): Ignore non-marker elts of compilation-error-list.
Roland McGrath <roland@gnu.org>
diff
changeset
|
757 (marker-buffer
|
2617
|
758 (cdr (car errors))))
|
2604
3a56b8caf6c9
(vc-revert-buffer1): Ignore non-marker elts of compilation-error-list.
Roland McGrath <roland@gnu.org>
diff
changeset
|
759 (setq buffer-error-marked-p t))
|
2554
5686672705bf
(vc-revert-buffer1): Completely rewrote compilation reparsing code.
Roland McGrath <roland@gnu.org>
diff
changeset
|
760 (setq errors (cdr errors)))
|
31380
|
761 (if buffer-error-marked-p buffer)))
|
2554
5686672705bf
(vc-revert-buffer1): Completely rewrote compilation reparsing code.
Roland McGrath <roland@gnu.org>
diff
changeset
|
762 (buffer-list)))))))
|
12872
857663042672
(vc-revert-buffer1): Split part of the function into vc-buffer-context
André Spiegel <spiegel@gnu.org>
diff
changeset
|
763 (list point-context mark-context reparse)))
|
2226
b2216b3b8f57
(vc-header-strings) Name changed to vc-header-alist, to match the
Eric S. Raymond <esr@snark.thyrsus.com>
diff
changeset
|
764
|
12872
857663042672
(vc-revert-buffer1): Split part of the function into vc-buffer-context
André Spiegel <spiegel@gnu.org>
diff
changeset
|
765 (defun vc-restore-buffer-context (context)
|
31380
|
766 "Restore point/mark, and reparse any affected compilation buffers.
|
31404
|
767 CONTEXT is that which `vc-buffer-context' returns."
|
12872
857663042672
(vc-revert-buffer1): Split part of the function into vc-buffer-context
André Spiegel <spiegel@gnu.org>
diff
changeset
|
768 (let ((point-context (nth 0 context))
|
857663042672
(vc-revert-buffer1): Split part of the function into vc-buffer-context
André Spiegel <spiegel@gnu.org>
diff
changeset
|
769 (mark-context (nth 1 context))
|
857663042672
(vc-revert-buffer1): Split part of the function into vc-buffer-context
André Spiegel <spiegel@gnu.org>
diff
changeset
|
770 (reparse (nth 2 context)))
|
2554
5686672705bf
(vc-revert-buffer1): Completely rewrote compilation reparsing code.
Roland McGrath <roland@gnu.org>
diff
changeset
|
771 ;; Reparse affected compilation buffers.
|
5686672705bf
(vc-revert-buffer1): Completely rewrote compilation reparsing code.
Roland McGrath <roland@gnu.org>
diff
changeset
|
772 (while reparse
|
5686672705bf
(vc-revert-buffer1): Completely rewrote compilation reparsing code.
Roland McGrath <roland@gnu.org>
diff
changeset
|
773 (if (car reparse)
|
31380
|
774 (with-current-buffer (car reparse)
|
2554
5686672705bf
(vc-revert-buffer1): Completely rewrote compilation reparsing code.
Roland McGrath <roland@gnu.org>
diff
changeset
|
775 (let ((compilation-last-buffer (current-buffer)) ;select buffer
|
5686672705bf
(vc-revert-buffer1): Completely rewrote compilation reparsing code.
Roland McGrath <roland@gnu.org>
diff
changeset
|
776 ;; Record the position in the compilation buffer of
|
5686672705bf
(vc-revert-buffer1): Completely rewrote compilation reparsing code.
Roland McGrath <roland@gnu.org>
diff
changeset
|
777 ;; the last error next-error went to.
|
5686672705bf
(vc-revert-buffer1): Completely rewrote compilation reparsing code.
Roland McGrath <roland@gnu.org>
diff
changeset
|
778 (error-pos (marker-position
|
5686672705bf
(vc-revert-buffer1): Completely rewrote compilation reparsing code.
Roland McGrath <roland@gnu.org>
diff
changeset
|
779 (car (car-safe compilation-error-list)))))
|
5686672705bf
(vc-revert-buffer1): Completely rewrote compilation reparsing code.
Roland McGrath <roland@gnu.org>
diff
changeset
|
780 ;; Reparse the error messages as far as they were parsed before.
|
5686672705bf
(vc-revert-buffer1): Completely rewrote compilation reparsing code.
Roland McGrath <roland@gnu.org>
diff
changeset
|
781 (compile-reinitialize-errors '(4) compilation-parsing-end)
|
5686672705bf
(vc-revert-buffer1): Completely rewrote compilation reparsing code.
Roland McGrath <roland@gnu.org>
diff
changeset
|
782 ;; Move the pointer up to find the error we were at before
|
5686672705bf
(vc-revert-buffer1): Completely rewrote compilation reparsing code.
Roland McGrath <roland@gnu.org>
diff
changeset
|
783 ;; reparsing. Now next-error should properly go to the next one.
|
5686672705bf
(vc-revert-buffer1): Completely rewrote compilation reparsing code.
Roland McGrath <roland@gnu.org>
diff
changeset
|
784 (while (and compilation-error-list
|
2558
|
785 (/= error-pos (car (car compilation-error-list))))
|
2554
5686672705bf
(vc-revert-buffer1): Completely rewrote compilation reparsing code.
Roland McGrath <roland@gnu.org>
diff
changeset
|
786 (setq compilation-error-list (cdr compilation-error-list))))))
|
5686672705bf
(vc-revert-buffer1): Completely rewrote compilation reparsing code.
Roland McGrath <roland@gnu.org>
diff
changeset
|
787 (setq reparse (cdr reparse)))
|
2490
70d00ecacc0d
(vc-directory. vc-start-entry, vc-next-action, vc-next-action-on-file):
Eric S. Raymond <esr@snark.thyrsus.com>
diff
changeset
|
788
|
21113
|
789 ;; if necessary, restore point and mark
|
|
790 (if (not (vc-context-matches-p (point) point-context))
|
|
791 (let ((new-point (vc-find-position-by-context point-context)))
|
|
792 (if new-point (goto-char new-point))))
|
21212
73a8874d25ce
(vc-restore-buffer-context): Only try to restore mark if it is active.
André Spiegel <spiegel@gnu.org>
diff
changeset
|
793 (and mark-active
|
73a8874d25ce
(vc-restore-buffer-context): Only try to restore mark if it is active.
André Spiegel <spiegel@gnu.org>
diff
changeset
|
794 mark-context
|
73a8874d25ce
(vc-restore-buffer-context): Only try to restore mark if it is active.
André Spiegel <spiegel@gnu.org>
diff
changeset
|
795 (not (vc-context-matches-p (mark) mark-context))
|
73a8874d25ce
(vc-restore-buffer-context): Only try to restore mark if it is active.
André Spiegel <spiegel@gnu.org>
diff
changeset
|
796 (let ((new-mark (vc-find-position-by-context mark-context)))
|
73a8874d25ce
(vc-restore-buffer-context): Only try to restore mark if it is active.
André Spiegel <spiegel@gnu.org>
diff
changeset
|
797 (if new-mark (set-mark new-mark))))))
|
1635
|
798
|
12872
857663042672
(vc-revert-buffer1): Split part of the function into vc-buffer-context
André Spiegel <spiegel@gnu.org>
diff
changeset
|
799 (defun vc-revert-buffer1 (&optional arg no-confirm)
|
31404
|
800 "Revert buffer, trying to keep point and mark where user expects them.
|
|
801 Tries to be clever in the face of changes due to expanded version control
|
|
802 key words. This is important for typeahead to work as expected.
|
|
803 ARG and NO-CONFIRM are passed on to `revert-buffer'."
|
12872
857663042672
(vc-revert-buffer1): Split part of the function into vc-buffer-context
André Spiegel <spiegel@gnu.org>
diff
changeset
|
804 (interactive "P")
|
857663042672
(vc-revert-buffer1): Split part of the function into vc-buffer-context
André Spiegel <spiegel@gnu.org>
diff
changeset
|
805 (widen)
|
857663042672
(vc-revert-buffer1): Split part of the function into vc-buffer-context
André Spiegel <spiegel@gnu.org>
diff
changeset
|
806 (let ((context (vc-buffer-context)))
|
21113
|
807 ;; Use save-excursion here, because it may be able to restore point
|
|
808 ;; and mark properly even in cases where vc-restore-buffer-context
|
31380
|
809 ;; would fail. However, save-excursion might also get it wrong --
|
21113
|
810 ;; in this case, vc-restore-buffer-context gives it a second try.
|
|
811 (save-excursion
|
31380
|
812 ;; t means don't call normal-mode;
|
21113
|
813 ;; that's to preserve various minor modes.
|
|
814 (revert-buffer arg no-confirm t))
|
12872
857663042672
(vc-revert-buffer1): Split part of the function into vc-buffer-context
André Spiegel <spiegel@gnu.org>
diff
changeset
|
815 (vc-restore-buffer-context context)))
|
857663042672
(vc-revert-buffer1): Split part of the function into vc-buffer-context
André Spiegel <spiegel@gnu.org>
diff
changeset
|
816
|
904
|
817
|
5338
|
818 (defun vc-buffer-sync (&optional not-urgent)
|
31404
|
819 "Make sure the current buffer and its working file are in sync.
|
31380
|
820 NOT-URGENT means it is ok to continue if the user says not to save."
|
5201
|
821 (if (buffer-modified-p)
|
5338
|
822 (if (or vc-suppress-confirm
|
|
823 (y-or-n-p (format "Buffer %s modified; save it? " (buffer-name))))
|
|
824 (save-buffer)
|
31380
|
825 (unless not-urgent
|
5338
|
826 (error "Aborted")))))
|
|
827
|
33634
|
828 (defun vc-workfile-unchanged-p (file)
|
|
829 "Has FILE changed since last checkout?"
|
|
830 (let ((checkout-time (vc-file-getprop file 'vc-checkout-time))
|
|
831 (lastmod (nth 5 (file-attributes file))))
|
|
832 (if checkout-time
|
|
833 (equal checkout-time lastmod)
|
|
834 (let ((unchanged (vc-call workfile-unchanged-p file)))
|
|
835 (vc-file-setprop file 'vc-checkout-time (if unchanged lastmod 0))
|
|
836 unchanged))))
|
|
837
|
|
838 (defun vc-default-workfile-unchanged-p (file)
|
|
839 "Default check whether FILE is unchanged: diff against master version."
|
|
840 (zerop (vc-call diff file (vc-workfile-version file))))
|
|
841
|
35131
|
842 (defun vc-default-latest-on-branch-p (file)
|
|
843 "Default check whether the current workfile version of FILE is the
|
|
844 latest on its branch."
|
|
845 t)
|
|
846
|
31380
|
847 (defun vc-recompute-state (file)
|
|
848 "Force a recomputation of the version control state of FILE.
|
|
849 The state is computed using the exact, and possibly expensive
|
|
850 function `vc-BACKEND-state', not the heuristic."
|
|
851 (vc-file-setprop file 'vc-state (vc-call state file)))
|
904
|
852
|
2490
70d00ecacc0d
(vc-directory. vc-start-entry, vc-next-action, vc-next-action-on-file):
Eric S. Raymond <esr@snark.thyrsus.com>
diff
changeset
|
853 (defun vc-next-action-on-file (file verbose &optional comment)
|
31380
|
854 "Do The Right Thing for a given version-controlled FILE.
|
|
855 If COMMENT is specified, it will be used as an admin or checkin comment.
|
|
856 If VERBOSE is non-nil, query the user rather than using default parameters."
|
|
857 (let ((visited (get-file-buffer file))
|
|
858 state version)
|
|
859 (when visited
|
|
860 ;; Check relation of buffer and file, and make sure
|
|
861 ;; user knows what he's doing. First, finding the file
|
|
862 ;; will check whether the file on disk is newer.
|
|
863 (if vc-dired-mode
|
|
864 (find-file-other-window file)
|
32058
|
865 (set-buffer (find-file-noselect file)))
|
31380
|
866 (if (not (verify-visited-file-modtime (current-buffer)))
|
|
867 (if (yes-or-no-p "Replace file on disk with buffer contents? ")
|
|
868 (write-file (buffer-file-name))
|
|
869 (error "Aborted"))
|
|
870 ;; Now, check if we have unsaved changes.
|
|
871 (vc-buffer-sync t)
|
|
872 (if (buffer-modified-p)
|
|
873 (or (y-or-n-p "Operate on disk file, keeping modified buffer? ")
|
|
874 (error "Aborted")))))
|
32344
f91ef1141a75
(with-vc-file, edit-vc-file): Specify `indent-function' property.
Thien-Thi Nguyen <ttn@gnuvola.org>
diff
changeset
|
875
|
31380
|
876 ;; Do the right thing
|
32069
4b577e4fc758
(vc-responsible-backend): Undo the previous change in the argument
André Spiegel <spiegel@gnu.org>
diff
changeset
|
877 (if (not (vc-registered file))
|
31380
|
878 (vc-register verbose comment)
|
|
879 (vc-recompute-state file)
|
32054
fef29341db1c
(vc-next-action-on-file): Update mode line only if file is visited.
André Spiegel <spiegel@gnu.org>
diff
changeset
|
880 (if visited (vc-mode-line file))
|
31380
|
881 (setq state (vc-state file))
|
|
882 (cond
|
|
883 ;; up-to-date
|
|
884 ((or (eq state 'up-to-date)
|
|
885 (and verbose (eq state 'needs-patch)))
|
|
886 (cond
|
|
887 (verbose
|
|
888 ;; go to a different version
|
32059
|
889 (setq version
|
31810
495ca3bd372d
(vc-index-of, vc-transfer-file, vc-default-receive-file): New functions.
André Spiegel <spiegel@gnu.org>
diff
changeset
|
890 (read-string "Branch, version, or backend to move to: "))
|
32059
|
891 (let ((vsym (intern-soft (upcase version))))
|
31810
495ca3bd372d
(vc-index-of, vc-transfer-file, vc-default-receive-file): New functions.
André Spiegel <spiegel@gnu.org>
diff
changeset
|
892 (if (member vsym vc-handled-backends)
|
495ca3bd372d
(vc-index-of, vc-transfer-file, vc-default-receive-file): New functions.
André Spiegel <spiegel@gnu.org>
diff
changeset
|
893 (vc-transfer-file file vsym)
|
32059
|
894 (vc-checkout file (eq (vc-checkout-model file) 'implicit)
|
31810
495ca3bd372d
(vc-index-of, vc-transfer-file, vc-default-receive-file): New functions.
André Spiegel <spiegel@gnu.org>
diff
changeset
|
895 version))))
|
31380
|
896 ((not (eq (vc-checkout-model file) 'implicit))
|
|
897 ;; check the file out
|
|
898 (vc-checkout file t))
|
|
899 (t
|
|
900 ;; do nothing
|
|
901 (message "%s is up-to-date" file))))
|
32344
f91ef1141a75
(with-vc-file, edit-vc-file): Specify `indent-function' property.
Thien-Thi Nguyen <ttn@gnuvola.org>
diff
changeset
|
902
|
31380
|
903 ;; Abnormal: edited but read-only
|
|
904 ((and visited (eq state 'edited) buffer-read-only)
|
|
905 ;; Make the file+buffer read-write. If the user really wanted to
|
|
906 ;; commit, he'll get a chance to do that next time around, anyway.
|
|
907 (message "File is edited but read-only; making it writable")
|
|
908 (set-file-modes buffer-file-name
|
|
909 (logior (file-modes buffer-file-name) 128))
|
|
910 (toggle-read-only -1))
|
32344
f91ef1141a75
(with-vc-file, edit-vc-file): Specify `indent-function' property.
Thien-Thi Nguyen <ttn@gnuvola.org>
diff
changeset
|
911
|
31380
|
912 ;; edited
|
|
913 ((eq state 'edited)
|
31565
|
914 (cond
|
31380
|
915 ;; For files with locking, if the file does not contain
|
|
916 ;; any changes, just let go of the lock, i.e. revert.
|
|
917 ((and (not (eq (vc-checkout-model file) 'implicit))
|
|
918 (vc-workfile-unchanged-p file)
|
|
919 ;; If buffer is modified, that means the user just
|
|
920 ;; said no to saving it; in that case, don't revert,
|
|
921 ;; because the user might intend to save after
|
|
922 ;; finishing the log entry.
|
|
923 (not (and visited (buffer-modified-p))))
|
|
924 ;; DO NOT revert the file without asking the user!
|
|
925 (if (not visited) (find-file-other-window file))
|
|
926 (if (yes-or-no-p "Revert to master version? ")
|
|
927 (vc-revert-buffer)))
|
|
928 (t ;; normal action
|
31810
495ca3bd372d
(vc-index-of, vc-transfer-file, vc-default-receive-file): New functions.
André Spiegel <spiegel@gnu.org>
diff
changeset
|
929 (if (not verbose)
|
495ca3bd372d
(vc-index-of, vc-transfer-file, vc-default-receive-file): New functions.
André Spiegel <spiegel@gnu.org>
diff
changeset
|
930 (vc-checkin file nil comment)
|
495ca3bd372d
(vc-index-of, vc-transfer-file, vc-default-receive-file): New functions.
André Spiegel <spiegel@gnu.org>
diff
changeset
|
931 (setq version (read-string "New version or backend: "))
|
495ca3bd372d
(vc-index-of, vc-transfer-file, vc-default-receive-file): New functions.
André Spiegel <spiegel@gnu.org>
diff
changeset
|
932 (let ((vsym (intern (upcase version))))
|
495ca3bd372d
(vc-index-of, vc-transfer-file, vc-default-receive-file): New functions.
André Spiegel <spiegel@gnu.org>
diff
changeset
|
933 (if (member vsym vc-handled-backends)
|
495ca3bd372d
(vc-index-of, vc-transfer-file, vc-default-receive-file): New functions.
André Spiegel <spiegel@gnu.org>
diff
changeset
|
934 (vc-transfer-file file vsym)
|
495ca3bd372d
(vc-index-of, vc-transfer-file, vc-default-receive-file): New functions.
André Spiegel <spiegel@gnu.org>
diff
changeset
|
935 (vc-checkin file version comment)))))))
|
32344
f91ef1141a75
(with-vc-file, edit-vc-file): Specify `indent-function' property.
Thien-Thi Nguyen <ttn@gnuvola.org>
diff
changeset
|
936
|
31380
|
937 ;; locked by somebody else
|
|
938 ((stringp state)
|
|
939 (if comment
|
|
940 (error "Sorry, you can't steal the lock on %s this way"
|
|
941 (file-name-nondirectory file)))
|
|
942 (vc-steal-lock file
|
|
943 (if verbose (read-string "Version to steal: ")
|
|
944 (vc-workfile-version file))
|
|
945 state))
|
32344
f91ef1141a75
(with-vc-file, edit-vc-file): Specify `indent-function' property.
Thien-Thi Nguyen <ttn@gnuvola.org>
diff
changeset
|
946
|
31380
|
947 ;; needs-patch
|
|
948 ((eq state 'needs-patch)
|
31565
|
949 (if (yes-or-no-p (format
|
31380
|
950 "%s is not up-to-date. Get latest version? "
|
|
951 (file-name-nondirectory file)))
|
|
952 (vc-checkout file (eq (vc-checkout-model file) 'implicit) "")
|
|
953 (if (and (not (eq (vc-checkout-model file) 'implicit))
|
|
954 (yes-or-no-p "Lock this version? "))
|
|
955 (vc-checkout file t)
|
|
956 (error "Aborted"))))
|
32344
f91ef1141a75
(with-vc-file, edit-vc-file): Specify `indent-function' property.
Thien-Thi Nguyen <ttn@gnuvola.org>
diff
changeset
|
957
|
31380
|
958 ;; needs-merge
|
|
959 ((eq state 'needs-merge)
|
31565
|
960 (if (yes-or-no-p (format
|
31380
|
961 "%s is not up-to-date. Merge in changes now? "
|
|
962 (file-name-nondirectory file)))
|
|
963 (vc-maybe-resolve-conflicts file (vc-call merge-news file))
|
|
964 (error "Aborted")))
|
32344
f91ef1141a75
(with-vc-file, edit-vc-file): Specify `indent-function' property.
Thien-Thi Nguyen <ttn@gnuvola.org>
diff
changeset
|
965
|
31380
|
966 ;; unlocked-changes
|
|
967 ((eq state 'unlocked-changes)
|
|
968 (if (not visited) (find-file-other-window file))
|
|
969 (if (save-window-excursion
|
|
970 (vc-version-diff file (vc-workfile-version file) nil)
|
|
971 (goto-char (point-min))
|
32059
|
972 (let ((inhibit-read-only t))
|
|
973 (insert-string
|
|
974 (format "Changes to %s since last lock:\n\n" file)))
|
31380
|
975 (not (beep))
|
|
976 (yes-or-no-p (concat "File has unlocked changes. "
|
|
977 "Claim lock retaining changes? ")))
|
|
978 (progn (vc-call steal-lock file)
|
|
979 ;; Must clear any headers here because they wouldn't
|
|
980 ;; show that the file is locked now.
|
|
981 (vc-clear-headers file)
|
|
982 (vc-mode-line file))
|
|
983 (if (not (yes-or-no-p
|
|
984 "Revert to checked-in version, instead? "))
|
|
985 (error "Checkout aborted")
|
|
986 (vc-revert-buffer1 t t)
|
|
987 (vc-checkout file t))))))))
|
2490
70d00ecacc0d
(vc-directory. vc-start-entry, vc-next-action, vc-next-action-on-file):
Eric S. Raymond <esr@snark.thyrsus.com>
diff
changeset
|
988
|
23792
|
989 (defvar vc-dired-window-configuration)
|
|
990
|
2490
70d00ecacc0d
(vc-directory. vc-start-entry, vc-next-action, vc-next-action-on-file):
Eric S. Raymond <esr@snark.thyrsus.com>
diff
changeset
|
991 (defun vc-next-action-dired (file rev comment)
|
31404
|
992 "Call `vc-next-action-on-file' on all the marked files.
|
|
993 Ignores FILE and REV, but passes on COMMENT."
|
21357
|
994 (let ((dired-buffer (current-buffer))
|
12968
|
995 (dired-dir default-directory))
|
10537
|
996 (dired-map-over-marks
|
22437
|
997 (let ((file (dired-get-filename)))
|
12943
10d0f42db2da
(vc-directory): Kill existing vc-dired buffers for this directory.
André Spiegel <spiegel@gnu.org>
diff
changeset
|
998 (message "Processing %s..." file)
|
31380
|
999 (vc-next-action-on-file file nil comment)
|
|
1000 (set-buffer dired-buffer)
|
21357
|
1001 (set-window-configuration vc-dired-window-configuration)
|
12943
10d0f42db2da
(vc-directory): Kill existing vc-dired buffers for this directory.
André Spiegel <spiegel@gnu.org>
diff
changeset
|
1002 (message "Processing %s...done" file))
|
21357
|
1003 nil t))
|
|
1004 (dired-move-to-filename))
|
2490
70d00ecacc0d
(vc-directory. vc-start-entry, vc-next-action, vc-next-action-on-file):
Eric S. Raymond <esr@snark.thyrsus.com>
diff
changeset
|
1005
|
927
|
1006 ;; Here's the major entry point.
|
904
|
1007
|
927
|
1008 ;;;###autoload
|
904
|
1009 (defun vc-next-action (verbose)
|
|
1010 "Do the next logical checkin or checkout operation on the current file.
|
31380
|
1011
|
|
1012 If you call this from within a VC dired buffer with no files marked,
|
11597
|
1013 it will operate on the file in the current line.
|
31380
|
1014
|
|
1015 If you call this from within a VC dired buffer, and one or more
|
11597
|
1016 files are marked, it will accept a log message and then operate on
|
|
1017 each one. The log message will be used as a comment for any register
|
|
1018 or checkin operations, but ignored when doing checkouts. Attempted
|
|
1019 lock steals will raise an error.
|
31380
|
1020
|
|
1021 A prefix argument lets you specify the version number to use.
|
9249
|
1022
|
|
1023 For RCS and SCCS files:
|
904
|
1024 If the file is not already registered, this registers it for version
|
21517
4d5cd99a3d51
(vc-next-action-on-file): Don't check out after registering. This is
André Spiegel <spiegel@gnu.org>
diff
changeset
|
1025 control.
|
904
|
1026 If the file is registered and not locked by anyone, this checks out
|
2750
|
1027 a writable and locked file ready for editing.
|
904
|
1028 If the file is checked out and locked by the calling user, this
|
|
1029 first checks to see if the file has changed since checkout. If not,
|
|
1030 it performs a revert.
|
2490
70d00ecacc0d
(vc-directory. vc-start-entry, vc-next-action, vc-next-action-on-file):
Eric S. Raymond <esr@snark.thyrsus.com>
diff
changeset
|
1031 If the file has been changed, this pops up a buffer for entry
|
70d00ecacc0d
(vc-directory. vc-start-entry, vc-next-action, vc-next-action-on-file):
Eric S. Raymond <esr@snark.thyrsus.com>
diff
changeset
|
1032 of a log message; when the message has been entered, it checks in the
|
904
|
1033 resulting changes along with the log message as change commentary. If
|
2750
|
1034 the variable `vc-keep-workfiles' is non-nil (which is its default), a
|
904
|
1035 read-only copy of the changed file is left in place afterwards.
|
|
1036 If the file is registered and locked by someone else, you are given
|
2490
70d00ecacc0d
(vc-directory. vc-start-entry, vc-next-action, vc-next-action-on-file):
Eric S. Raymond <esr@snark.thyrsus.com>
diff
changeset
|
1037 the option to steal the lock.
|
9249
|
1038
|
|
1039 For CVS files:
|
|
1040 If the file is not already registered, this registers it for version
|
|
1041 control. This does a \"cvs add\", but no \"cvs commit\".
|
|
1042 If the file is added but not committed, it is committed.
|
|
1043 If your working file is changed, but the repository file is
|
|
1044 unchanged, this pops up a buffer for entry of a log message; when the
|
|
1045 message has been entered, it checks in the resulting changes along
|
|
1046 with the logmessage as change commentary. A writable file is retained.
|
|
1047 If the repository file is changed, you are asked if you want to
|
11597
|
1048 merge in the changes into your working copy."
|
9249
|
1049
|
904
|
1050 (interactive "P")
|
2580
a66f7ed76416
(vc-diff): Get proper error message when you run this with no prefix
Eric S. Raymond <esr@snark.thyrsus.com>
diff
changeset
|
1051 (catch 'nogo
|
a66f7ed76416
(vc-diff): Get proper error message when you run this with no prefix
Eric S. Raymond <esr@snark.thyrsus.com>
diff
changeset
|
1052 (if vc-dired-mode
|
a66f7ed76416
(vc-diff): Get proper error message when you run this with no prefix
Eric S. Raymond <esr@snark.thyrsus.com>
diff
changeset
|
1053 (let ((files (dired-get-marked-files)))
|
21357
|
1054 (set (make-local-variable 'vc-dired-window-configuration)
|
|
1055 (current-window-configuration))
|
31380
|
1056 (if (string= ""
|
12968
|
1057 (mapconcat
|
31380
|
1058 (lambda (f)
|
|
1059 (if (not (vc-up-to-date-p f)) "@" ""))
|
12943
10d0f42db2da
(vc-directory): Kill existing vc-dired buffers for this directory.
André Spiegel <spiegel@gnu.org>
diff
changeset
|
1060 files ""))
|
10d0f42db2da
(vc-directory): Kill existing vc-dired buffers for this directory.
André Spiegel <spiegel@gnu.org>
diff
changeset
|
1061 (vc-next-action-dired nil nil "dummy")
|
32054
fef29341db1c
(vc-next-action-on-file): Update mode line only if file is visited.
André Spiegel <spiegel@gnu.org>
diff
changeset
|
1062 (vc-start-entry nil nil nil nil
|
12943
10d0f42db2da
(vc-directory): Kill existing vc-dired buffers for this directory.
André Spiegel <spiegel@gnu.org>
diff
changeset
|
1063 "Enter a change comment for the marked files."
|
10d0f42db2da
(vc-directory): Kill existing vc-dired buffers for this directory.
André Spiegel <spiegel@gnu.org>
diff
changeset
|
1064 'vc-next-action-dired))
|
12968
|
1065 (throw 'nogo nil)))
|
21448
1b5746e92464
(vc-next-action): Fixed bug that prevented registering files using C-x v v.
André Spiegel <spiegel@gnu.org>
diff
changeset
|
1066 (while vc-parent-buffer
|
1b5746e92464
(vc-next-action): Fixed bug that prevented registering files using C-x v v.
André Spiegel <spiegel@gnu.org>
diff
changeset
|
1067 (pop-to-buffer vc-parent-buffer))
|
1b5746e92464
(vc-next-action): Fixed bug that prevented registering files using C-x v v.
André Spiegel <spiegel@gnu.org>
diff
changeset
|
1068 (if buffer-file-name
|
1b5746e92464
(vc-next-action): Fixed bug that prevented registering files using C-x v v.
André Spiegel <spiegel@gnu.org>
diff
changeset
|
1069 (vc-next-action-on-file buffer-file-name verbose)
|
1b5746e92464
(vc-next-action): Fixed bug that prevented registering files using C-x v v.
André Spiegel <spiegel@gnu.org>
diff
changeset
|
1070 (error "Buffer %s is not associated with a file" (buffer-name)))))
|
904
|
1071
|
|
1072 ;;; These functions help the vc-next-action entry point
|
|
1073
|
927
|
1074 ;;;###autoload
|
31380
|
1075 (defun vc-register (&optional set-version comment)
|
31404
|
1076 "Register the current file into a version control system.
|
31520
|
1077 With prefix argument SET-VERSION, allow user to specify initial version
|
31380
|
1078 level. If COMMENT is present, use that as an initial comment.
|
|
1079
|
31520
|
1080 The version control system to use is found by cycling through the list
|
31380
|
1081 `vc-handled-backends'. The first backend in that list which declares
|
|
1082 itself responsible for the file (usually because other files in that
|
|
1083 directory are already registered under that backend) will be used to
|
|
1084 register the file. If no backend declares itself responsible, the
|
|
1085 first backend that could register the file is used."
|
904
|
1086 (interactive "P")
|
31404
|
1087 (unless buffer-file-name (error "No visited file"))
|
31380
|
1088 (when (vc-backend buffer-file-name)
|
|
1089 (if (vc-registered buffer-file-name)
|
|
1090 (error "This file is already registered")
|
|
1091 (unless (y-or-n-p "Previous master file has vanished. Make a new one? ")
|
|
1092 (error "Aborted"))))
|
2054
|
1093 ;; Watch out for new buffers of size 0: the corresponding file
|
|
1094 ;; does not exist yet, even though buffer-modified-p is nil.
|
|
1095 (if (and (not (buffer-modified-p))
|
|
1096 (zerop (buffer-size))
|
|
1097 (not (file-exists-p buffer-file-name)))
|
|
1098 (set-buffer-modified-p t))
|
904
|
1099 (vc-buffer-sync)
|
32344
f91ef1141a75
(with-vc-file, edit-vc-file): Specify `indent-function' property.
Thien-Thi Nguyen <ttn@gnuvola.org>
diff
changeset
|
1100
|
31380
|
1101 (vc-start-entry buffer-file-name
|
|
1102 (if set-version
|
31810
495ca3bd372d
(vc-index-of, vc-transfer-file, vc-default-receive-file): New functions.
André Spiegel <spiegel@gnu.org>
diff
changeset
|
1103 (read-string (format "Initial version level for %s: "
|
495ca3bd372d
(vc-index-of, vc-transfer-file, vc-default-receive-file): New functions.
André Spiegel <spiegel@gnu.org>
diff
changeset
|
1104 (buffer-name)))
|
31380
|
1105 ;; TODO: Use backend-specific init version.
|
|
1106 vc-default-init-version)
|
|
1107 (or comment (not vc-initial-comment))
|
32054
fef29341db1c
(vc-next-action-on-file): Update mode line only if file is visited.
André Spiegel <spiegel@gnu.org>
diff
changeset
|
1108 nil
|
31380
|
1109 "Enter initial comment."
|
|
1110 (lambda (file rev comment)
|
|
1111 (message "Registering %s... " file)
|
32069
4b577e4fc758
(vc-responsible-backend): Undo the previous change in the argument
André Spiegel <spiegel@gnu.org>
diff
changeset
|
1112 (let ((backend (vc-responsible-backend file t)))
|
31520
|
1113 (vc-file-clearprops file)
|
31380
|
1114 (vc-call-backend backend 'register file rev comment)
|
|
1115 (vc-file-setprop file 'vc-backend backend)
|
|
1116 (unless vc-make-backup-files
|
|
1117 (make-local-variable 'backup-inhibited)
|
|
1118 (setq backup-inhibited t)))
|
|
1119 (message "Registering %s... done" file))))
|
|
1120
|
32069
4b577e4fc758
(vc-responsible-backend): Undo the previous change in the argument
André Spiegel <spiegel@gnu.org>
diff
changeset
|
1121
|
4b577e4fc758
(vc-responsible-backend): Undo the previous change in the argument
André Spiegel <spiegel@gnu.org>
diff
changeset
|
1122 (defun vc-responsible-backend (file &optional register)
|
4b577e4fc758
(vc-responsible-backend): Undo the previous change in the argument
André Spiegel <spiegel@gnu.org>
diff
changeset
|
1123 "Return the name of a backend system that is responsible for FILE.
|
32344
f91ef1141a75
(with-vc-file, edit-vc-file): Specify `indent-function' property.
Thien-Thi Nguyen <ttn@gnuvola.org>
diff
changeset
|
1124 The optional argument REGISTER means that a backend suitable for
|
32069
4b577e4fc758
(vc-responsible-backend): Undo the previous change in the argument
André Spiegel <spiegel@gnu.org>
diff
changeset
|
1125 registration should be found.
|
4b577e4fc758
(vc-responsible-backend): Undo the previous change in the argument
André Spiegel <spiegel@gnu.org>
diff
changeset
|
1126
|
4b577e4fc758
(vc-responsible-backend): Undo the previous change in the argument
André Spiegel <spiegel@gnu.org>
diff
changeset
|
1127 If REGISTER is nil, then if FILE is already registered, return the
|
4b577e4fc758
(vc-responsible-backend): Undo the previous change in the argument
André Spiegel <spiegel@gnu.org>
diff
changeset
|
1128 backend of FILE. If FILE is not registered, or a directory, then the
|
4b577e4fc758
(vc-responsible-backend): Undo the previous change in the argument
André Spiegel <spiegel@gnu.org>
diff
changeset
|
1129 first backend in `vc-handled-backends' that declares itself
|
4b577e4fc758
(vc-responsible-backend): Undo the previous change in the argument
André Spiegel <spiegel@gnu.org>
diff
changeset
|
1130 responsible for FILE is returned. If no backend declares itself
|
4b577e4fc758
(vc-responsible-backend): Undo the previous change in the argument
André Spiegel <spiegel@gnu.org>
diff
changeset
|
1131 responsible, return the first backend.
|
32058
|
1132
|
32069
4b577e4fc758
(vc-responsible-backend): Undo the previous change in the argument
André Spiegel <spiegel@gnu.org>
diff
changeset
|
1133 If REGISTER is non-nil, return the first responsible backend under
|
4b577e4fc758
(vc-responsible-backend): Undo the previous change in the argument
André Spiegel <spiegel@gnu.org>
diff
changeset
|
1134 which FILE is not yet registered. If there is no such backend, return
|
4b577e4fc758
(vc-responsible-backend): Undo the previous change in the argument
André Spiegel <spiegel@gnu.org>
diff
changeset
|
1135 the first backend under which FILE is not yet registered, but could
|
4b577e4fc758
(vc-responsible-backend): Undo the previous change in the argument
André Spiegel <spiegel@gnu.org>
diff
changeset
|
1136 be registered."
|
4b577e4fc758
(vc-responsible-backend): Undo the previous change in the argument
André Spiegel <spiegel@gnu.org>
diff
changeset
|
1137 (if (not vc-handled-backends)
|
4b577e4fc758
(vc-responsible-backend): Undo the previous change in the argument
André Spiegel <spiegel@gnu.org>
diff
changeset
|
1138 (error "No handled backends"))
|
4b577e4fc758
(vc-responsible-backend): Undo the previous change in the argument
André Spiegel <spiegel@gnu.org>
diff
changeset
|
1139 (or (and (not (file-directory-p file)) (not register) (vc-backend file))
|
4b577e4fc758
(vc-responsible-backend): Undo the previous change in the argument
André Spiegel <spiegel@gnu.org>
diff
changeset
|
1140 (catch 'found
|
4b577e4fc758
(vc-responsible-backend): Undo the previous change in the argument
André Spiegel <spiegel@gnu.org>
diff
changeset
|
1141 ;; First try: find a responsible backend. If this is for registration,
|
4b577e4fc758
(vc-responsible-backend): Undo the previous change in the argument
André Spiegel <spiegel@gnu.org>
diff
changeset
|
1142 ;; it must be a backend under which FILE is not yet registered.
|
4b577e4fc758
(vc-responsible-backend): Undo the previous change in the argument
André Spiegel <spiegel@gnu.org>
diff
changeset
|
1143 (dolist (backend vc-handled-backends)
|
4b577e4fc758
(vc-responsible-backend): Undo the previous change in the argument
André Spiegel <spiegel@gnu.org>
diff
changeset
|
1144 (and (or (not register)
|
4b577e4fc758
(vc-responsible-backend): Undo the previous change in the argument
André Spiegel <spiegel@gnu.org>
diff
changeset
|
1145 (not (vc-call-backend backend 'registered file)))
|
4b577e4fc758
(vc-responsible-backend): Undo the previous change in the argument
André Spiegel <spiegel@gnu.org>
diff
changeset
|
1146 (vc-call-backend backend 'responsible-p file)
|
4b577e4fc758
(vc-responsible-backend): Undo the previous change in the argument
André Spiegel <spiegel@gnu.org>
diff
changeset
|
1147 (throw 'found backend)))
|
4b577e4fc758
(vc-responsible-backend): Undo the previous change in the argument
André Spiegel <spiegel@gnu.org>
diff
changeset
|
1148 ;; no responsible backend
|
4b577e4fc758
(vc-responsible-backend): Undo the previous change in the argument
André Spiegel <spiegel@gnu.org>
diff
changeset
|
1149 (if (not register)
|
4b577e4fc758
(vc-responsible-backend): Undo the previous change in the argument
André Spiegel <spiegel@gnu.org>
diff
changeset
|
1150 ;; if this is not for registration, the first backend must do
|
4b577e4fc758
(vc-responsible-backend): Undo the previous change in the argument
André Spiegel <spiegel@gnu.org>
diff
changeset
|
1151 (car vc-handled-backends)
|
32344
f91ef1141a75
(with-vc-file, edit-vc-file): Specify `indent-function' property.
Thien-Thi Nguyen <ttn@gnuvola.org>
diff
changeset
|
1152 ;; for registration, we need to find a new backend that
|
32069
4b577e4fc758
(vc-responsible-backend): Undo the previous change in the argument
André Spiegel <spiegel@gnu.org>
diff
changeset
|
1153 ;; could register FILE
|
4b577e4fc758
(vc-responsible-backend): Undo the previous change in the argument
André Spiegel <spiegel@gnu.org>
diff
changeset
|
1154 (dolist (backend vc-handled-backends)
|
4b577e4fc758
(vc-responsible-backend): Undo the previous change in the argument
André Spiegel <spiegel@gnu.org>
diff
changeset
|
1155 (and (not (vc-call-backend backend 'registered file))
|
4b577e4fc758
(vc-responsible-backend): Undo the previous change in the argument
André Spiegel <spiegel@gnu.org>
diff
changeset
|
1156 (vc-call-backend backend 'could-register file)
|
4b577e4fc758
(vc-responsible-backend): Undo the previous change in the argument
André Spiegel <spiegel@gnu.org>
diff
changeset
|
1157 (throw 'found backend)))
|
4b577e4fc758
(vc-responsible-backend): Undo the previous change in the argument
André Spiegel <spiegel@gnu.org>
diff
changeset
|
1158 (error "No backend that could register")))))
|
31380
|
1159
|
31404
|
1160 (defun vc-default-responsible-p (backend file)
|
32344
f91ef1141a75
(with-vc-file, edit-vc-file): Specify `indent-function' property.
Thien-Thi Nguyen <ttn@gnuvola.org>
diff
changeset
|
1161 "Indicate whether BACKEND is reponsible for FILE.
|
31404
|
1162 The default is to return nil always."
|
|
1163 nil)
|
|
1164
|
31380
|
1165 (defun vc-default-could-register (backend file)
|
31565
|
1166 "Return non-nil if BACKEND could be used to register FILE.
|
31380
|
1167 The default implementation returns t for all files."
|
|
1168 t)
|
904
|
1169
|
1478
429e23e87072
(vc-resynch-window): New arg NOQUERY. Pass it to vc-revert-buffer1.
Richard M. Stallman <rms@gnu.org>
diff
changeset
|
1170 (defun vc-resynch-window (file &optional keep noquery)
|
31404
|
1171 "If FILE is in the current buffer, either revert or unvisit it.
|
|
1172 The choice between revert (to see expanded keywords) and unvisit depends on
|
|
1173 `vc-keep-workfiles'. NOQUERY if non-nil inhibits confirmation for
|
31380
|
1174 reverting. NOQUERY should be t *only* if it is known the only
|
|
1175 difference between the buffer and the file is due to version control
|
|
1176 rather than user editing!"
|
904
|
1177 (and (string= buffer-file-name file)
|
|
1178 (if keep
|
|
1179 (progn
|
1905
|
1180 (vc-revert-buffer1 t noquery)
|
31380
|
1181 ;; TODO: Adjusting view mode might no longer be necessary
|
|
1182 ;; after RMS change to files.el of 1999-08-08. Investigate
|
|
1183 ;; this when we install the new VC.
|
20602
e8566ea47491
(vc-resynch-window): Behave properly when view-read-only is non-nil.
André Spiegel <spiegel@gnu.org>
diff
changeset
|
1184 (and view-read-only
|
e8566ea47491
(vc-resynch-window): Behave properly when view-read-only is non-nil.
André Spiegel <spiegel@gnu.org>
diff
changeset
|
1185 (if (file-writable-p file)
|
e8566ea47491
(vc-resynch-window): Behave properly when view-read-only is non-nil.
André Spiegel <spiegel@gnu.org>
diff
changeset
|
1186 (and view-mode
|
e8566ea47491
(vc-resynch-window): Behave properly when view-read-only is non-nil.
André Spiegel <spiegel@gnu.org>
diff
changeset
|
1187 (let ((view-old-buffer-read-only nil))
|
e8566ea47491
(vc-resynch-window): Behave properly when view-read-only is non-nil.
André Spiegel <spiegel@gnu.org>
diff
changeset
|
1188 (view-mode-exit)))
|
e8566ea47491
(vc-resynch-window): Behave properly when view-read-only is non-nil.
André Spiegel <spiegel@gnu.org>
diff
changeset
|
1189 (and (not view-mode)
|
e8566ea47491
(vc-resynch-window): Behave properly when view-read-only is non-nil.
André Spiegel <spiegel@gnu.org>
diff
changeset
|
1190 (not (eq (get major-mode 'mode-class) 'special))
|
e8566ea47491
(vc-resynch-window): Behave properly when view-read-only is non-nil.
André Spiegel <spiegel@gnu.org>
diff
changeset
|
1191 (view-mode-enter))))
|
904
|
1192 (vc-mode-line buffer-file-name))
|
12279
|
1193 (kill-buffer (current-buffer)))))
|
904
|
1194
|
12714
|
1195 (defun vc-resynch-buffer (file &optional keep noquery)
|
31380
|
1196 "If FILE is currently visited, resynch its buffer."
|
21113
|
1197 (if (string= buffer-file-name file)
|
|
1198 (vc-resynch-window file keep noquery)
|
|
1199 (let ((buffer (get-file-buffer file)))
|
|
1200 (if buffer
|
31380
|
1201 (with-current-buffer buffer
|
|
1202 (vc-resynch-window file keep noquery)))))
|
|
1203 (vc-dired-resynch-file file))
|
12714
|
1204
|
32054
fef29341db1c
(vc-next-action-on-file): Update mode line only if file is visited.
André Spiegel <spiegel@gnu.org>
diff
changeset
|
1205 (defun vc-start-entry (file rev comment initial-contents msg action &optional after-hook)
|
32344
f91ef1141a75
(with-vc-file, edit-vc-file): Specify `indent-function' property.
Thien-Thi Nguyen <ttn@gnuvola.org>
diff
changeset
|
1206 "Accept a comment for an operation on FILE revision REV.
|
31565
|
1207 If COMMENT is nil, pop up a VC-log buffer, emit MSG, and set the
|
32054
fef29341db1c
(vc-next-action-on-file): Update mode line only if file is visited.
André Spiegel <spiegel@gnu.org>
diff
changeset
|
1208 action on close to ACTION. If COMMENT is a string and
|
fef29341db1c
(vc-next-action-on-file): Update mode line only if file is visited.
André Spiegel <spiegel@gnu.org>
diff
changeset
|
1209 INITIAL-CONTENTS is non-nil, then COMMENT is used as the initial
|
fef29341db1c
(vc-next-action-on-file): Update mode line only if file is visited.
André Spiegel <spiegel@gnu.org>
diff
changeset
|
1210 contents of the log entry buffer. If COMMENT is a string and
|
fef29341db1c
(vc-next-action-on-file): Update mode line only if file is visited.
André Spiegel <spiegel@gnu.org>
diff
changeset
|
1211 INITIAL-CONTENTS is nil, do action immediately as if the user had
|
fef29341db1c
(vc-next-action-on-file): Update mode line only if file is visited.
André Spiegel <spiegel@gnu.org>
diff
changeset
|
1212 entered COMMENT. If COMMENT is t, also do action immediately with an
|
32344
f91ef1141a75
(with-vc-file, edit-vc-file): Specify `indent-function' property.
Thien-Thi Nguyen <ttn@gnuvola.org>
diff
changeset
|
1213 empty comment. Remember the file's buffer in `vc-parent-buffer'
|
f91ef1141a75
(with-vc-file, edit-vc-file): Specify `indent-function' property.
Thien-Thi Nguyen <ttn@gnuvola.org>
diff
changeset
|
1214 \(current one if no file). AFTER-HOOK specifies the local value
|
32054
fef29341db1c
(vc-next-action-on-file): Update mode line only if file is visited.
André Spiegel <spiegel@gnu.org>
diff
changeset
|
1215 for vc-log-operation-hook."
|
fef29341db1c
(vc-next-action-on-file): Update mode line only if file is visited.
André Spiegel <spiegel@gnu.org>
diff
changeset
|
1216 (let ((parent (or (and file (get-file-buffer file)) (current-buffer))))
|
17274
|
1217 (if vc-before-checkin-hook
|
|
1218 (if file
|
31380
|
1219 (with-current-buffer parent
|
17274
|
1220 (run-hooks 'vc-before-checkin-hook))
|
|
1221 (run-hooks 'vc-before-checkin-hook)))
|
32054
fef29341db1c
(vc-next-action-on-file): Update mode line only if file is visited.
André Spiegel <spiegel@gnu.org>
diff
changeset
|
1222 (if (and comment (not initial-contents))
|
2490
70d00ecacc0d
(vc-directory. vc-start-entry, vc-next-action, vc-next-action-on-file):
Eric S. Raymond <esr@snark.thyrsus.com>
diff
changeset
|
1223 (set-buffer (get-buffer-create "*VC-log*"))
|
70d00ecacc0d
(vc-directory. vc-start-entry, vc-next-action, vc-next-action-on-file):
Eric S. Raymond <esr@snark.thyrsus.com>
diff
changeset
|
1224 (pop-to-buffer (get-buffer-create "*VC-log*")))
|
2580
a66f7ed76416
(vc-diff): Get proper error message when you run this with no prefix
Eric S. Raymond <esr@snark.thyrsus.com>
diff
changeset
|
1225 (set (make-local-variable 'vc-parent-buffer) parent)
|
a66f7ed76416
(vc-diff): Get proper error message when you run this with no prefix
Eric S. Raymond <esr@snark.thyrsus.com>
diff
changeset
|
1226 (set (make-local-variable 'vc-parent-buffer-name)
|
a66f7ed76416
(vc-diff): Get proper error message when you run this with no prefix
Eric S. Raymond <esr@snark.thyrsus.com>
diff
changeset
|
1227 (concat " from " (buffer-name vc-parent-buffer)))
|
12393
7d4615a12286
(vc-start-entry): Prevent lossage when doing a mass checkin from
Richard M. Stallman <rms@gnu.org>
diff
changeset
|
1228 (if file (vc-mode-line file))
|
31404
|
1229 (vc-log-edit file)
|
8159
|
1230 (make-local-variable 'vc-log-after-operation-hook)
|
|
1231 (if after-hook
|
|
1232 (setq vc-log-after-operation-hook after-hook))
|
2490
70d00ecacc0d
(vc-directory. vc-start-entry, vc-next-action, vc-next-action-on-file):
Eric S. Raymond <esr@snark.thyrsus.com>
diff
changeset
|
1233 (setq vc-log-operation action)
|
70d00ecacc0d
(vc-directory. vc-start-entry, vc-next-action, vc-next-action-on-file):
Eric S. Raymond <esr@snark.thyrsus.com>
diff
changeset
|
1234 (setq vc-log-version rev)
|
32930
470147903e33
(vc-start-entry): Only erase the buffer if comment is set.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
1235 (when comment
|
470147903e33
(vc-start-entry): Only erase the buffer if comment is set.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
1236 (erase-buffer)
|
470147903e33
(vc-start-entry): Only erase the buffer if comment is set.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
1237 (when (stringp comment) (insert comment)))
|
470147903e33
(vc-start-entry): Only erase the buffer if comment is set.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
1238 (if (or (not comment) initial-contents)
|
470147903e33
(vc-start-entry): Only erase the buffer if comment is set.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
1239 (message "%s Type C-c C-c when done" msg)
|
470147903e33
(vc-start-entry): Only erase the buffer if comment is set.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
1240 (vc-finish-logentry (eq comment t)))))
|
2490
70d00ecacc0d
(vc-directory. vc-start-entry, vc-next-action, vc-next-action-on-file):
Eric S. Raymond <esr@snark.thyrsus.com>
diff
changeset
|
1241
|
11597
|
1242 (defun vc-checkout (file &optional writable rev)
|
31404
|
1243 "Retrieve a copy of the revision REV of FILE.
|
|
1244 If WRITABLE is non-nil, make sure the retrieved file is writable.
|
|
1245 REV defaults to the latest revision."
|
32126
|
1246 (and writable
|
|
1247 (not rev)
|
32748
e2cb0aef151a
(vc-checkout): Added `-p' suffix in call to vc-make-version-backups-p;
André Spiegel <spiegel@gnu.org>
diff
changeset
|
1248 (vc-call make-version-backups-p file)
|
32126
|
1249 (vc-up-to-date-p file)
|
32748
e2cb0aef151a
(vc-checkout): Added `-p' suffix in call to vc-make-version-backups-p;
André Spiegel <spiegel@gnu.org>
diff
changeset
|
1250 (vc-make-version-backup file))
|
31404
|
1251 (with-vc-properties
|
|
1252 file
|
|
1253 (condition-case err
|
|
1254 (vc-call checkout file writable rev)
|
|
1255 (file-error
|
|
1256 ;; Maybe the backend is not installed ;-(
|
|
1257 (when writable
|
|
1258 (let ((buf (get-file-buffer file)))
|
|
1259 (when buf (with-current-buffer buf (toggle-read-only -1)))))
|
|
1260 (signal (car err) (cdr err))))
|
32189
921a2e8fa97e
(with-vc-properties): Use conses rather than length-2 lists.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
1261 `((vc-state . ,(if (or (eq (vc-checkout-model file) 'implicit)
|
921a2e8fa97e
(with-vc-properties): Use conses rather than length-2 lists.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
1262 (not writable))
|
921a2e8fa97e
(with-vc-properties): Use conses rather than length-2 lists.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
1263 (if (vc-call latest-on-branch-p file)
|
921a2e8fa97e
(with-vc-properties): Use conses rather than length-2 lists.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
1264 'up-to-date
|
921a2e8fa97e
(with-vc-properties): Use conses rather than length-2 lists.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
1265 'needs-patch)
|
921a2e8fa97e
(with-vc-properties): Use conses rather than length-2 lists.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
1266 'edited))
|
921a2e8fa97e
(with-vc-properties): Use conses rather than length-2 lists.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
1267 (vc-checkout-time . ,(nth 5 (file-attributes file)))))
|
12943
10d0f42db2da
(vc-directory): Kill existing vc-dired buffers for this directory.
André Spiegel <spiegel@gnu.org>
diff
changeset
|
1268 (vc-resynch-buffer file t t))
|
904
|
1269
|
31380
|
1270 (defun vc-steal-lock (file rev owner)
|
31404
|
1271 "Steal the lock on FILE."
|
9044
|
1272 (let (file-description)
|
|
1273 (if rev
|
|
1274 (setq file-description (format "%s:%s" file rev))
|
|
1275 (setq file-description file))
|
18265
|
1276 (if (not (yes-or-no-p (format "Steal the lock on %s from %s? "
|
|
1277 file-description owner)))
|
31380
|
1278 (error "Steal canceled"))
|
|
1279 (compose-mail owner (format "Stolen lock on %s" file-description)
|
|
1280 nil nil nil nil
|
|
1281 (list (list 'vc-finish-steal file rev)))
|
9044
|
1282 (setq default-directory (expand-file-name "~/"))
|
|
1283 (goto-char (point-max))
|
|
1284 (insert
|
|
1285 (format "I stole the lock on %s, " file-description)
|
|
1286 (current-time-string)
|
|
1287 ".\n")
|
|
1288 (message "Please explain why you stole the lock. Type C-c C-c when done.")))
|
904
|
1289
|
|
1290 (defun vc-finish-steal (file version)
|
31380
|
1291 ;; This is called when the notification has been sent.
|
|
1292 (message "Stealing lock on %s..." file)
|
32344
f91ef1141a75
(with-vc-file, edit-vc-file): Specify `indent-function' property.
Thien-Thi Nguyen <ttn@gnuvola.org>
diff
changeset
|
1293 (with-vc-properties
|
31404
|
1294 file
|
|
1295 (vc-call steal-lock file version)
|
32189
921a2e8fa97e
(with-vc-properties): Use conses rather than length-2 lists.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
1296 `((vc-state . edited)))
|
31380
|
1297 (vc-resynch-buffer file t t)
|
|
1298 (message "Stealing lock on %s...done" file))
|
904
|
1299
|
32054
fef29341db1c
(vc-next-action-on-file): Update mode line only if file is visited.
André Spiegel <spiegel@gnu.org>
diff
changeset
|
1300 (defun vc-checkin (file &optional rev comment initial-contents)
|
31565
|
1301 "Check in FILE.
|
31380
|
1302 The optional argument REV may be a string specifying the new version
|
|
1303 level (if nil increment the current level). COMMENT is a comment
|
32054
fef29341db1c
(vc-next-action-on-file): Update mode line only if file is visited.
André Spiegel <spiegel@gnu.org>
diff
changeset
|
1304 string; if omitted, a buffer is popped up to accept a comment. If
|
fef29341db1c
(vc-next-action-on-file): Update mode line only if file is visited.
André Spiegel <spiegel@gnu.org>
diff
changeset
|
1305 INITIAL-CONTENTS is non-nil, then COMMENT is used as the initial contents
|
fef29341db1c
(vc-next-action-on-file): Update mode line only if file is visited.
André Spiegel <spiegel@gnu.org>
diff
changeset
|
1306 of the log entry buffer.
|
31380
|
1307
|
|
1308 If `vc-keep-workfiles' is nil, FILE is deleted afterwards, provided
|
|
1309 that the version control system supports this mode of operation.
|
20967
|
1310
|
|
1311 Runs the normal hook `vc-checkin-hook'."
|
31565
|
1312 (vc-start-entry
|
32054
fef29341db1c
(vc-next-action-on-file): Update mode line only if file is visited.
André Spiegel <spiegel@gnu.org>
diff
changeset
|
1313 file rev comment initial-contents
|
31565
|
1314 "Enter a change comment."
|
31380
|
1315 (lambda (file rev comment)
|
|
1316 (message "Checking in %s..." file)
|
|
1317 ;; "This log message intentionally left almost blank".
|
|
1318 ;; RCS 5.7 gripes about white-space-only comments too.
|
|
1319 (or (and comment (string-match "[^\t\n ]" comment))
|
|
1320 (setq comment "*** empty log message ***"))
|
32344
f91ef1141a75
(with-vc-file, edit-vc-file): Specify `indent-function' property.
Thien-Thi Nguyen <ttn@gnuvola.org>
diff
changeset
|
1321 (with-vc-properties
|
31404
|
1322 file
|
|
1323 ;; Change buffers to get local value of vc-checkin-switches.
|
|
1324 (with-current-buffer (or (get-file-buffer file) (current-buffer))
|
32126
|
1325 (let ((backup-file (vc-version-backup-file file)))
|
|
1326 (vc-call checkin file rev comment)
|
|
1327 (if backup-file (delete-file backup-file))))
|
32189
921a2e8fa97e
(with-vc-properties): Use conses rather than length-2 lists.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
1328 `((vc-state . up-to-date)
|
921a2e8fa97e
(with-vc-properties): Use conses rather than length-2 lists.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
1329 (vc-checkout-time . ,(nth 5 (file-attributes file)))
|
921a2e8fa97e
(with-vc-properties): Use conses rather than length-2 lists.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
1330 (vc-workfile-version . nil)))
|
31380
|
1331 (message "Checking in %s...done" file))
|
|
1332 'vc-checkin-hook))
|
904
|
1333
|
4155
|
1334 (defun vc-comment-to-change-log (&optional whoami file-name)
|
|
1335 "Enter last VC comment into change log file for current buffer's file.
|
|
1336 Optional arg (interactive prefix) non-nil means prompt for user name and site.
|
|
1337 Second arg is file name of change log. \
|
20967
|
1338 If nil, uses `change-log-default-name'.
|
|
1339
|
|
1340 May be useful as a `vc-checkin-hook' to update change logs automatically."
|
4158
|
1341 (interactive (if current-prefix-arg
|
|
1342 (list current-prefix-arg
|
|
1343 (prompt-for-change-log-name))))
|
5871
|
1344 ;; Make sure the defvar for add-log-current-defun-function has been executed
|
|
1345 ;; before binding it.
|
|
1346 (require 'add-log)
|
4155
|
1347 (let (;; Extract the comment first so we get any error before doing anything.
|
|
1348 (comment (ring-ref vc-comment-ring 0))
|
4158
|
1349 ;; Don't let add-change-log-entry insert a defun name.
|
4155
|
1350 (add-log-current-defun-function 'ignore)
|
|
1351 end)
|
|
1352 ;; Call add-log to do half the work.
|
4158
|
1353 (add-change-log-entry whoami file-name t t)
|
4155
|
1354 ;; Insert the VC comment, leaving point before it.
|
|
1355 (setq end (save-excursion (insert comment) (point-marker)))
|
|
1356 (if (looking-at "\\s *\\s(")
|
|
1357 ;; It starts with an open-paren, as in "(foo): Frobbed."
|
4158
|
1358 ;; So remove the ": " add-log inserted.
|
4155
|
1359 (delete-char -2))
|
|
1360 ;; Canonicalize the white space between the file name and comment.
|
|
1361 (just-one-space)
|
|
1362 ;; Indent rest of the text the same way add-log indented the first line.
|
|
1363 (let ((indentation (current-indentation)))
|
|
1364 (save-excursion
|
|
1365 (while (< (point) end)
|
|
1366 (forward-line 1)
|
|
1367 (indent-to indentation))
|
4156
0000c3af1836
(vc-comment-to-change-log): Canonicalize following whitespace after
Roland McGrath <roland@gnu.org>
diff
changeset
|
1368 (setq end (point))))
|
4155
|
1369 ;; Fill the inserted text, preserving open-parens at bol.
|
10900
5b375fee0e1f
(vc-comment-to-change-log): Remove ^ from paragraph-start & paragraph-separate.
Boris Goldowsky <boris@gnu.org>
diff
changeset
|
1370 (let ((paragraph-separate (concat paragraph-separate "\\|\\s *\\s("))
|
5b375fee0e1f
(vc-comment-to-change-log): Remove ^ from paragraph-start & paragraph-separate.
Boris Goldowsky <boris@gnu.org>
diff
changeset
|
1371 (paragraph-start (concat paragraph-start "\\|\\s *\\s(")))
|
4158
|
1372 (beginning-of-line)
|
4156
0000c3af1836
(vc-comment-to-change-log): Canonicalize following whitespace after
Roland McGrath <roland@gnu.org>
diff
changeset
|
1373 (fill-region (point) end))
|
0000c3af1836
(vc-comment-to-change-log): Canonicalize following whitespace after
Roland McGrath <roland@gnu.org>
diff
changeset
|
1374 ;; Canonicalize the white space at the end of the entry so it is
|
0000c3af1836
(vc-comment-to-change-log): Canonicalize following whitespace after
Roland McGrath <roland@gnu.org>
diff
changeset
|
1375 ;; separated from the next entry by a single blank line.
|
0000c3af1836
(vc-comment-to-change-log): Canonicalize following whitespace after
Roland McGrath <roland@gnu.org>
diff
changeset
|
1376 (skip-syntax-forward " " end)
|
0000c3af1836
(vc-comment-to-change-log): Canonicalize following whitespace after
Roland McGrath <roland@gnu.org>
diff
changeset
|
1377 (delete-char (- (skip-syntax-backward " ")))
|
0000c3af1836
(vc-comment-to-change-log): Canonicalize following whitespace after
Roland McGrath <roland@gnu.org>
diff
changeset
|
1378 (or (eobp) (looking-at "\n\n")
|
0000c3af1836
(vc-comment-to-change-log): Canonicalize following whitespace after
Roland McGrath <roland@gnu.org>
diff
changeset
|
1379 (insert "\n"))))
|
4155
|
1380
|
2580
a66f7ed76416
(vc-diff): Get proper error message when you run this with no prefix
Eric S. Raymond <esr@snark.thyrsus.com>
diff
changeset
|
1381 (defun vc-finish-logentry (&optional nocomment)
|
904
|
1382 "Complete the operation implied by the current log entry."
|
|
1383 (interactive)
|
2580
a66f7ed76416
(vc-diff): Get proper error message when you run this with no prefix
Eric S. Raymond <esr@snark.thyrsus.com>
diff
changeset
|
1384 ;; Check and record the comment, if any.
|
31380
|
1385 (unless nocomment
|
|
1386 ;; Comment too long?
|
|
1387 (vc-call-backend (or (and vc-log-file (vc-backend vc-log-file))
|
|
1388 (vc-responsible-backend default-directory))
|
|
1389 'logentry-check)
|
|
1390 (run-hooks 'vc-logentry-check-hook)
|
|
1391 ;; Record the comment in the comment ring
|
|
1392 (let ((comment (buffer-string)))
|
|
1393 (unless (and (ring-p vc-comment-ring)
|
|
1394 (not (ring-empty-p vc-comment-ring))
|
|
1395 (equal comment (ring-ref vc-comment-ring 0)))
|
|
1396 (ring-insert vc-comment-ring comment))))
|
5428
e66b058ec9f6
(vc-finish-logentry): Sync the buffer in case the user modified it while
Paul Eggert <eggert@twinsun.com>
diff
changeset
|
1397 ;; Sync parent buffer in case the user modified it while editing the comment.
|
8349
a61f6295ee0e
(vc-next-action): Even in 1-file case, get its name from FILES.
Richard M. Stallman <rms@gnu.org>
diff
changeset
|
1398 ;; But not if it is a vc-dired buffer.
|
31380
|
1399 (with-current-buffer vc-parent-buffer
|
|
1400 (or vc-dired-mode (vc-buffer-sync)))
|
12885
|
1401 (if (not vc-log-operation) (error "No log operation is pending"))
|
|
1402 ;; save the parameters held in buffer-local variables
|
|
1403 (let ((log-operation vc-log-operation)
|
|
1404 (log-file vc-log-file)
|
|
1405 (log-version vc-log-version)
|
|
1406 (log-entry (buffer-string))
|
24477
|
1407 (after-hook vc-log-after-operation-hook)
|
|
1408 (tmp-vc-parent-buffer vc-parent-buffer))
|
8237
189d7c4eaf68
(vc-finish-logentry): Use the value of vc-log-after-operation-hook of
Richard M. Stallman <rms@gnu.org>
diff
changeset
|
1409 (pop-to-buffer vc-parent-buffer)
|
12885
|
1410 ;; OK, do it to it
|
|
1411 (save-excursion
|
31380
|
1412 (funcall log-operation
|
12885
|
1413 log-file
|
|
1414 log-version
|
|
1415 log-entry))
|
20661
|
1416 ;; Remove checkin window (after the checkin so that if that fails
|
|
1417 ;; we don't zap the *VC-log* buffer and the typing therein).
|
|
1418 (let ((logbuf (get-buffer "*VC-log*")))
|
24477
|
1419 (cond ((and logbuf vc-delete-logbuf-window)
|
|
1420 (delete-windows-on logbuf (selected-frame))
|
22721
|
1421 ;; Kill buffer and delete any other dedicated windows/frames.
|
24477
|
1422 (kill-buffer logbuf))
|
32054
fef29341db1c
(vc-next-action-on-file): Update mode line only if file is visited.
André Spiegel <spiegel@gnu.org>
diff
changeset
|
1423 (logbuf (pop-to-buffer "*VC-log*")
|
fef29341db1c
(vc-next-action-on-file): Update mode line only if file is visited.
André Spiegel <spiegel@gnu.org>
diff
changeset
|
1424 (bury-buffer)
|
fef29341db1c
(vc-next-action-on-file): Update mode line only if file is visited.
André Spiegel <spiegel@gnu.org>
diff
changeset
|
1425 (pop-to-buffer tmp-vc-parent-buffer))))
|
8237
189d7c4eaf68
(vc-finish-logentry): Use the value of vc-log-after-operation-hook of
Richard M. Stallman <rms@gnu.org>
diff
changeset
|
1426 ;; Now make sure we see the expanded headers
|
32344
f91ef1141a75
(with-vc-file, edit-vc-file): Specify `indent-function' property.
Thien-Thi Nguyen <ttn@gnuvola.org>
diff
changeset
|
1427 (if log-file
|
32054
fef29341db1c
(vc-next-action-on-file): Update mode line only if file is visited.
André Spiegel <spiegel@gnu.org>
diff
changeset
|
1428 (vc-resynch-buffer log-file vc-keep-workfiles t))
|
31380
|
1429 (if vc-dired-mode
|
32054
fef29341db1c
(vc-next-action-on-file): Update mode line only if file is visited.
André Spiegel <spiegel@gnu.org>
diff
changeset
|
1430 (dired-move-to-filename))
|
17101
|
1431 (run-hooks after-hook 'vc-finish-logentry-hook)))
|
904
|
1432
|
|
1433 ;; Code for access to the comment ring
|
|
1434
|
31380
|
1435 (defun vc-new-comment-index (stride len)
|
|
1436 (mod (cond
|
|
1437 (vc-comment-ring-index (+ vc-comment-ring-index stride))
|
|
1438 ;; Initialize the index on the first use of this command
|
|
1439 ;; so that the first M-p gets index 0, and the first M-n gets
|
|
1440 ;; index -1.
|
|
1441 ((> stride 0) (1- stride))
|
|
1442 (t stride))
|
|
1443 len))
|
|
1444
|
2580
a66f7ed76416
(vc-diff): Get proper error message when you run this with no prefix
Eric S. Raymond <esr@snark.thyrsus.com>
diff
changeset
|
1445 (defun vc-previous-comment (arg)
|
a66f7ed76416
(vc-diff): Get proper error message when you run this with no prefix
Eric S. Raymond <esr@snark.thyrsus.com>
diff
changeset
|
1446 "Cycle backwards through comment history."
|
a66f7ed76416
(vc-diff): Get proper error message when you run this with no prefix
Eric S. Raymond <esr@snark.thyrsus.com>
diff
changeset
|
1447 (interactive "*p")
|
a66f7ed76416
(vc-diff): Get proper error message when you run this with no prefix
Eric S. Raymond <esr@snark.thyrsus.com>
diff
changeset
|
1448 (let ((len (ring-length vc-comment-ring)))
|
31380
|
1449 (if (<= len 0)
|
|
1450 (progn (message "Empty comment ring") (ding))
|
|
1451 (erase-buffer)
|
|
1452 (setq vc-comment-ring-index (vc-new-comment-index arg len))
|
|
1453 (message "Comment %d" (1+ vc-comment-ring-index))
|
|
1454 (insert (ring-ref vc-comment-ring vc-comment-ring-index)))))
|
904
|
1455
|
2580
a66f7ed76416
(vc-diff): Get proper error message when you run this with no prefix
Eric S. Raymond <esr@snark.thyrsus.com>
diff
changeset
|
1456 (defun vc-next-comment (arg)
|
a66f7ed76416
(vc-diff): Get proper error message when you run this with no prefix
Eric S. Raymond <esr@snark.thyrsus.com>
diff
changeset
|
1457 "Cycle forwards through comment history."
|
a66f7ed76416
(vc-diff): Get proper error message when you run this with no prefix
Eric S. Raymond <esr@snark.thyrsus.com>
diff
changeset
|
1458 (interactive "*p")
|
a66f7ed76416
(vc-diff): Get proper error message when you run this with no prefix
Eric S. Raymond <esr@snark.thyrsus.com>
diff
changeset
|
1459 (vc-previous-comment (- arg)))
|
904
|
1460
|
31380
|
1461 (defun vc-comment-search-reverse (str &optional stride)
|
32189
921a2e8fa97e
(with-vc-properties): Use conses rather than length-2 lists.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
1462 "Search backwards through comment history for substring match."
|
31380
|
1463 ;; Why substring rather than regexp ? -sm
|
|
1464 (interactive
|
|
1465 (list (read-string "Comment substring: " nil nil vc-last-comment-match)))
|
|
1466 (unless stride (setq stride 1))
|
2580
a66f7ed76416
(vc-diff): Get proper error message when you run this with no prefix
Eric S. Raymond <esr@snark.thyrsus.com>
diff
changeset
|
1467 (if (string= str "")
|
a66f7ed76416
(vc-diff): Get proper error message when you run this with no prefix
Eric S. Raymond <esr@snark.thyrsus.com>
diff
changeset
|
1468 (setq str vc-last-comment-match)
|
a66f7ed76416
(vc-diff): Get proper error message when you run this with no prefix
Eric S. Raymond <esr@snark.thyrsus.com>
diff
changeset
|
1469 (setq vc-last-comment-match str))
|
31380
|
1470 (let* ((str (regexp-quote str))
|
|
1471 (len (ring-length vc-comment-ring))
|
|
1472 (n (vc-new-comment-index stride len)))
|
|
1473 (while (progn (when (or (>= n len) (< n 0)) (error "Not found"))
|
|
1474 (not (string-match str (ring-ref vc-comment-ring n))))
|
|
1475 (setq n (+ n stride)))
|
|
1476 (setq vc-comment-ring-index n)
|
|
1477 (vc-previous-comment 0)))
|
904
|
1478
|
2580
a66f7ed76416
(vc-diff): Get proper error message when you run this with no prefix
Eric S. Raymond <esr@snark.thyrsus.com>
diff
changeset
|
1479 (defun vc-comment-search-forward (str)
|
32189
921a2e8fa97e
(with-vc-properties): Use conses rather than length-2 lists.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
1480 "Search forwards through comment history for substring match."
|
31380
|
1481 (interactive
|
|
1482 (list (read-string "Comment substring: " nil nil vc-last-comment-match)))
|
|
1483 (vc-comment-search-reverse str -1))
|
904
|
1484
|
|
1485 ;; Additional entry points for examining version histories
|
|
1486
|
927
|
1487 ;;;###autoload
|
5338
|
1488 (defun vc-diff (historic &optional not-urgent)
|
2667
|
1489 "Display diffs between file versions.
|
31380
|
1490 Normally this compares the current file and buffer with the most recent
|
2667
|
1491 checked in version of that file. This uses no arguments.
|
|
1492 With a prefix argument, it reads the file name to use
|
|
1493 and two version designators specifying which versions to compare."
|
14376
|
1494 (interactive (list current-prefix-arg t))
|
21366
|
1495 (vc-ensure-vc-buffer)
|
904
|
1496 (if historic
|
|
1497 (call-interactively 'vc-version-diff)
|
31380
|
1498 (let ((file buffer-file-name))
|
19055
5439070e5d46
(vc-backend-checkin): For CVS, forget the checkout model after commit.
Richard M. Stallman <rms@gnu.org>
diff
changeset
|
1499 (vc-buffer-sync not-urgent)
|
31380
|
1500 (if (vc-workfile-unchanged-p buffer-file-name)
|
|
1501 (message "No changes to %s since latest version" file)
|
|
1502 (vc-version-diff file nil nil)))))
|
904
|
1503
|
|
1504 (defun vc-version-diff (file rel1 rel2)
|
|
1505 "For FILE, report diffs between two stored versions REL1 and REL2 of it.
|
|
1506 If FILE is a directory, generate diffs between versions for all registered
|
|
1507 files in or below it."
|
31380
|
1508 (interactive
|
27436
|
1509 (let ((file (expand-file-name
|
|
1510 (read-file-name (if buffer-file-name
|
|
1511 "File or dir to diff: (default visited file) "
|
|
1512 "File or dir to diff: ")
|
|
1513 default-directory buffer-file-name t)))
|
19055
5439070e5d46
(vc-backend-checkin): For CVS, forget the checkout model after commit.
Richard M. Stallman <rms@gnu.org>
diff
changeset
|
1514 (rel1-default nil) (rel2-default nil))
|
5439070e5d46
(vc-backend-checkin): For CVS, forget the checkout model after commit.
Richard M. Stallman <rms@gnu.org>
diff
changeset
|
1515 ;; compute default versions based on the file state
|
5439070e5d46
(vc-backend-checkin): For CVS, forget the checkout model after commit.
Richard M. Stallman <rms@gnu.org>
diff
changeset
|
1516 (cond
|
31380
|
1517 ;; if it's a directory, don't supply any version default
|
|
1518 ((file-directory-p file)
|
19055
5439070e5d46
(vc-backend-checkin): For CVS, forget the checkout model after commit.
Richard M. Stallman <rms@gnu.org>
diff
changeset
|
1519 nil)
|
31380
|
1520 ;; if the file is not up-to-date, use current version as older version
|
|
1521 ((not (vc-up-to-date-p file))
|
19055
5439070e5d46
(vc-backend-checkin): For CVS, forget the checkout model after commit.
Richard M. Stallman <rms@gnu.org>
diff
changeset
|
1522 (setq rel1-default (vc-workfile-version file)))
|
5439070e5d46
(vc-backend-checkin): For CVS, forget the checkout model after commit.
Richard M. Stallman <rms@gnu.org>
diff
changeset
|
1523 ;; if the file is not locked, use last and previous version as default
|
5439070e5d46
(vc-backend-checkin): For CVS, forget the checkout model after commit.
Richard M. Stallman <rms@gnu.org>
diff
changeset
|
1524 (t
|
5439070e5d46
(vc-backend-checkin): For CVS, forget the checkout model after commit.
Richard M. Stallman <rms@gnu.org>
diff
changeset
|
1525 (setq rel1-default (vc-previous-version (vc-workfile-version file)))
|
31380
|
1526 (if (string= rel1-default "") (setq rel1-default nil))
|
19055
5439070e5d46
(vc-backend-checkin): For CVS, forget the checkout model after commit.
Richard M. Stallman <rms@gnu.org>
diff
changeset
|
1527 (setq rel2-default (vc-workfile-version file))))
|
5439070e5d46
(vc-backend-checkin): For CVS, forget the checkout model after commit.
Richard M. Stallman <rms@gnu.org>
diff
changeset
|
1528 ;; construct argument list
|
31380
|
1529 (list file
|
19126
|
1530 (read-string (if rel1-default
|
|
1531 (concat "Older version: (default "
|
|
1532 rel1-default ") ")
|
|
1533 "Older version: ")
|
|
1534 nil nil rel1-default)
|
|
1535 (read-string (if rel2-default
|
|
1536 (concat "Newer version: (default "
|
|
1537 rel2-default ") ")
|
19177
|
1538 "Newer version (default: current source): ")
|
19126
|
1539 nil nil rel2-default))))
|
31380
|
1540 (vc-setup-buffer "*vc-diff*")
|
904
|
1541 (if (file-directory-p file)
|
32126
|
1542 ;; recursive directory diff
|
31380
|
1543 (let ((inhibit-read-only t))
|
32126
|
1544 (if (string-equal rel1 "") (setq rel1 nil))
|
|
1545 (if (string-equal rel2 "") (setq rel2 nil))
|
2085
|
1546 (insert "Diffs between "
|
|
1547 (or rel1 "last version checked in")
|
|
1548 " and "
|
|
1549 (or rel2 "current workfile(s)")
|
|
1550 ":\n\n")
|
31380
|
1551 (setq default-directory (file-name-as-directory file))
|
|
1552 ;; FIXME: this should do a single exec in CVS.
|
904
|
1553 (vc-file-tree-walk
|
13012
|
1554 default-directory
|
31380
|
1555 (lambda (f)
|
|
1556 (vc-exec-after
|
|
1557 `(progn
|
|
1558 (message "Looking at %s" ',f)
|
|
1559 (vc-call-backend ',(vc-backend file) 'diff ',f ',rel1 ',rel2)))))
|
|
1560 (vc-exec-after `(let ((inhibit-read-only t))
|
|
1561 (insert "\nEnd of diffs.\n"))))
|
32126
|
1562 ;; single file diff
|
|
1563 (if (or (not rel1) (string-equal rel1 ""))
|
|
1564 (setq rel1 (vc-workfile-version file)))
|
|
1565 (if (string-equal rel2 "")
|
|
1566 (setq rel2 nil))
|
|
1567 (let ((file-rel1 (vc-version-backup-file file rel1))
|
32310
|
1568 (file-rel2 (if (not rel2)
|
|
1569 file
|
32126
|
1570 (vc-version-backup-file file rel2))))
|
|
1571 (if (and file-rel1 file-rel2)
|
32310
|
1572 (apply 'vc-do-command t 1 "diff" nil
|
|
1573 (append (if (listp diff-switches)
|
|
1574 diff-switches
|
|
1575 (list diff-switches))
|
|
1576 (list (file-relative-name file-rel1)
|
|
1577 (file-relative-name file-rel2))))
|
32126
|
1578 (cd (file-name-directory file))
|
|
1579 (vc-call diff file rel1 rel2))))
|
31380
|
1580 (if (and (zerop (buffer-size))
|
|
1581 (not (get-buffer-process (current-buffer))))
|
|
1582 (progn
|
|
1583 (if rel1
|
|
1584 (if rel2
|
|
1585 (message "No changes to %s between %s and %s" file rel1 rel2)
|
|
1586 (message "No changes to %s since %s" file rel1))
|
|
1587 (message "No changes to %s since latest version" file))
|
|
1588 nil)
|
|
1589 (pop-to-buffer (current-buffer))
|
|
1590 ;; Gnus-5.8.5 sets up an autoload for diff-mode, even if it's
|
|
1591 ;; not available. Work around that.
|
|
1592 (if (require 'diff-mode nil t) (diff-mode))
|
33564
d8c822512b62
(vc-version-diff): Bind inhibit-read-only when inserting text.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
1593 (vc-exec-after '(let ((inhibit-read-only t))
|
d8c822512b62
(vc-version-diff): Bind inhibit-read-only when inserting text.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
1594 (if (eq (buffer-size) 0)
|
d8c822512b62
(vc-version-diff): Bind inhibit-read-only when inserting text.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
1595 (insert "No differences found.\n"))
|
d8c822512b62
(vc-version-diff): Bind inhibit-read-only when inserting text.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
1596 (goto-char (point-min))
|
d8c822512b62
(vc-version-diff): Bind inhibit-read-only when inserting text.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
1597 (shrink-window-if-larger-than-buffer)))
|
31380
|
1598 t))
|
904
|
1599
|
4725
|
1600 ;;;###autoload
|
|
1601 (defun vc-version-other-window (rev)
|
|
1602 "Visit version REV of the current buffer in another window.
|
|
1603 If the current buffer is named `F', the version is named `F.~REV~'.
|
|
1604 If `F.~REV~' already exists, it is used instead of being re-created."
|
31380
|
1605 (interactive "sVersion to visit (default is workfile version): ")
|
21366
|
1606 (vc-ensure-vc-buffer)
|
32888
|
1607 (let* ((file buffer-file-name)
|
|
1608 (version (if (string-equal rev "")
|
|
1609 (vc-workfile-version file)
|
21366
|
1610 rev))
|
32748
e2cb0aef151a
(vc-checkout): Added `-p' suffix in call to vc-make-version-backups-p;
André Spiegel <spiegel@gnu.org>
diff
changeset
|
1611 (automatic-backup (vc-version-backup-file-name file version))
|
e2cb0aef151a
(vc-checkout): Added `-p' suffix in call to vc-make-version-backups-p;
André Spiegel <spiegel@gnu.org>
diff
changeset
|
1612 (manual-backup (vc-version-backup-file-name file version 'manual)))
|
e2cb0aef151a
(vc-checkout): Added `-p' suffix in call to vc-make-version-backups-p;
André Spiegel <spiegel@gnu.org>
diff
changeset
|
1613 (unless (file-exists-p manual-backup)
|
e2cb0aef151a
(vc-checkout): Added `-p' suffix in call to vc-make-version-backups-p;
André Spiegel <spiegel@gnu.org>
diff
changeset
|
1614 (if (file-exists-p automatic-backup)
|
32950
|
1615 (rename-file automatic-backup manual-backup nil)
|
32888
|
1616 (vc-call checkout file nil version manual-backup)))
|
32748
e2cb0aef151a
(vc-checkout): Added `-p' suffix in call to vc-make-version-backups-p;
André Spiegel <spiegel@gnu.org>
diff
changeset
|
1617 (find-file-other-window manual-backup)))
|
4725
|
1618
|
904
|
1619 ;; Header-insertion code
|
|
1620
|
927
|
1621 ;;;###autoload
|
904
|
1622 (defun vc-insert-headers ()
|
31404
|
1623 "Insert headers in a file for use with your version control system.
|
23235
|
1624 Headers desired are inserted at point, and are pulled from
|
31380
|
1625 the variable `vc-BACKEND-header'."
|
904
|
1626 (interactive)
|
21366
|
1627 (vc-ensure-vc-buffer)
|
904
|
1628 (save-excursion
|
|
1629 (save-restriction
|
|
1630 (widen)
|
|
1631 (if (or (not (vc-check-headers))
|
3227
|
1632 (y-or-n-p "Version headers already exist. Insert another set? "))
|
904
|
1633 (progn
|
|
1634 (let* ((delims (cdr (assq major-mode vc-comment-alist)))
|
|
1635 (comment-start-vc (or (car delims) comment-start "#"))
|
|
1636 (comment-end-vc (or (car (cdr delims)) comment-end ""))
|
31380
|
1637 (hdsym (vc-make-backend-sym (vc-backend (buffer-file-name))
|
|
1638 'header))
|
|
1639 (hdstrings (and (boundp hdsym) (symbol-value hdsym))))
|
|
1640 (mapcar (lambda (s)
|
|
1641 (insert comment-start-vc "\t" s "\t"
|
|
1642 comment-end-vc "\n"))
|
904
|
1643 hdstrings)
|
|
1644 (if vc-static-header-alist
|
31380
|
1645 (mapcar (lambda (f)
|
|
1646 (if (string-match (car f) buffer-file-name)
|
|
1647 (insert (format (cdr f) (car hdstrings)))))
|
904
|
1648 vc-static-header-alist))
|
|
1649 )
|
|
1650 )))))
|
|
1651
|
31380
|
1652 (defun vc-clear-headers (&optional file)
|
31404
|
1653 "Clear all version headers in the current buffer (or FILE).
|
|
1654 I.e. reset them to the non-expanded form."
|
31380
|
1655 (let* ((filename (or file buffer-file-name))
|
|
1656 (visited (find-buffer-visiting filename))
|
|
1657 (backend (vc-backend filename)))
|
|
1658 (when (vc-find-backend-function backend 'clear-headers)
|
31565
|
1659 (if visited
|
31380
|
1660 (let ((context (vc-buffer-context)))
|
|
1661 ;; save-excursion may be able to relocate point and mark
|
|
1662 ;; properly. If it fails, vc-restore-buffer-context
|
|
1663 ;; will give it a second try.
|
|
1664 (save-excursion
|
|
1665 (vc-call-backend backend 'clear-headers))
|
|
1666 (vc-restore-buffer-context context))
|
32058
|
1667 (set-buffer (find-file-noselect filename))
|
31380
|
1668 (vc-call-backend backend 'clear-headers)
|
|
1669 (kill-buffer filename)))))
|
12872
857663042672
(vc-revert-buffer1): Split part of the function into vc-buffer-context
André Spiegel <spiegel@gnu.org>
diff
changeset
|
1670
|
21366
|
1671 ;;;###autoload
|
31404
|
1672 (defun vc-merge ()
|
|
1673 "Merge changes between two versions into the current buffer's file.
|
|
1674 This asks for two versions to merge from in the minibuffer. If the
|
|
1675 first version is a branch number, then merge all changes from that
|
|
1676 branch. If the first version is empty, merge news, i.e. recent changes
|
|
1677 from the current branch.
|
31380
|
1678
|
|
1679 See Info node `Merging'."
|
31404
|
1680 (interactive)
|
21368
|
1681 (vc-ensure-vc-buffer)
|
|
1682 (vc-buffer-sync)
|
|
1683 (let* ((file buffer-file-name)
|
|
1684 (backend (vc-backend file))
|
31380
|
1685 (state (vc-state file))
|
31404
|
1686 first-version second-version status)
|
31380
|
1687 (cond
|
|
1688 ((stringp state)
|
|
1689 (error "File is locked by %s" state))
|
|
1690 ((not (vc-editable-p file))
|
|
1691 (if (y-or-n-p
|
|
1692 "File must be checked out for merging. Check out now? ")
|
|
1693 (vc-checkout file t)
|
|
1694 (error "Merge aborted"))))
|
32344
f91ef1141a75
(with-vc-file, edit-vc-file): Specify `indent-function' property.
Thien-Thi Nguyen <ttn@gnuvola.org>
diff
changeset
|
1695 (setq first-version
|
31404
|
1696 (read-string (concat "Branch or version to merge from "
|
|
1697 "(default: news on current branch): ")))
|
|
1698 (if (string= first-version "")
|
|
1699 (if (not (vc-find-backend-function backend 'merge-news))
|
|
1700 (error "Sorry, merging news is not implemented for %s" backend)
|
|
1701 (setq status (vc-call merge-news file)))
|
|
1702 (if (not (vc-find-backend-function backend 'merge))
|
|
1703 (error "Sorry, merging is not implemented for %s" backend)
|
|
1704 (if (not (vc-branch-p first-version))
|
32344
f91ef1141a75
(with-vc-file, edit-vc-file): Specify `indent-function' property.
Thien-Thi Nguyen <ttn@gnuvola.org>
diff
changeset
|
1705 (setq second-version
|
f91ef1141a75
(with-vc-file, edit-vc-file): Specify `indent-function' property.
Thien-Thi Nguyen <ttn@gnuvola.org>
diff
changeset
|
1706 (read-string "Second version: "
|
31404
|
1707 (concat (vc-branch-part first-version) ".")))
|
|
1708 ;; We want to merge an entire branch. Set versions
|
|
1709 ;; accordingly, so that vc-BACKEND-merge understands us.
|
|
1710 (setq second-version first-version)
|
|
1711 ;; first-version must be the starting point of the branch
|
|
1712 (setq first-version (vc-branch-part first-version)))
|
|
1713 (setq status (vc-call merge file first-version second-version))))
|
|
1714 (vc-maybe-resolve-conflicts file status "WORKFILE" "MERGE SOURCE")))
|
31380
|
1715
|
|
1716 (defun vc-maybe-resolve-conflicts (file status &optional name-A name-B)
|
|
1717 (vc-resynch-buffer file t (not (buffer-modified-p)))
|
|
1718 (if (zerop status) (message "Merge successful")
|
|
1719 (if (fboundp 'smerge-mode) (smerge-mode 1))
|
|
1720 (if (y-or-n-p "Conflicts detected. Resolve them now? ")
|
|
1721 (if (fboundp 'smerge-ediff)
|
|
1722 (smerge-ediff)
|
|
1723 (vc-resolve-conflicts name-A name-B))
|
|
1724 (message "File contains conflict markers"))))
|
21368
|
1725
|
23792
|
1726 (defvar vc-ediff-windows)
|
|
1727 (defvar vc-ediff-result)
|
31380
|
1728 (eval-when-compile
|
|
1729 (defvar ediff-buffer-A)
|
|
1730 (defvar ediff-buffer-B)
|
|
1731 (defvar ediff-buffer-C)
|
|
1732 (require 'ediff-util))
|
21368
|
1733 ;;;###autoload
|
|
1734 (defun vc-resolve-conflicts (&optional name-A name-B)
|
21324
|
1735 "Invoke ediff to resolve conflicts in the current buffer.
|
|
1736 The conflicts must be marked with rcsmerge conflict markers."
|
|
1737 (interactive)
|
21366
|
1738 (vc-ensure-vc-buffer)
|
21324
|
1739 (let* ((found nil)
|
|
1740 (file-name (file-name-nondirectory buffer-file-name))
|
31380
|
1741 (your-buffer (generate-new-buffer
|
|
1742 (concat "*" file-name
|
21368
|
1743 " " (or name-A "WORKFILE") "*")))
|
31380
|
1744 (other-buffer (generate-new-buffer
|
|
1745 (concat "*" file-name
|
21368
|
1746 " " (or name-B "CHECKED-IN") "*")))
|
21324
|
1747 (result-buffer (current-buffer)))
|
31380
|
1748 (save-excursion
|
21324
|
1749 (set-buffer your-buffer)
|
|
1750 (erase-buffer)
|
|
1751 (insert-buffer result-buffer)
|
|
1752 (goto-char (point-min))
|
31380
|
1753 (while (re-search-forward (concat "^<<<<<<< "
|
21324
|
1754 (regexp-quote file-name) "\n") nil t)
|
|
1755 (setq found t)
|
|
1756 (replace-match "")
|
|
1757 (if (not (re-search-forward "^=======\n" nil t))
|
|
1758 (error "Malformed conflict marker"))
|
|
1759 (replace-match "")
|
|
1760 (let ((start (point)))
|
|
1761 (if (not (re-search-forward "^>>>>>>> [0-9.]+\n" nil t))
|
|
1762 (error "Malformed conflict marker"))
|
|
1763 (delete-region start (point))))
|
|
1764 (if (not found)
|
|
1765 (progn
|
|
1766 (kill-buffer your-buffer)
|
|
1767 (kill-buffer other-buffer)
|
|
1768 (error "No conflict markers found")))
|
|
1769 (set-buffer other-buffer)
|
|
1770 (erase-buffer)
|
|
1771 (insert-buffer result-buffer)
|
|
1772 (goto-char (point-min))
|
31380
|
1773 (while (re-search-forward (concat "^<<<<<<< "
|
21324
|
1774 (regexp-quote file-name) "\n") nil t)
|
|
1775 (let ((start (match-beginning 0)))
|
|
1776 (if (not (re-search-forward "^=======\n" nil t))
|
|
1777 (error "Malformed conflict marker"))
|
|
1778 (delete-region start (point))
|
|
1779 (if (not (re-search-forward "^>>>>>>> [0-9.]+\n" nil t))
|
|
1780 (error "Malformed conflict marker"))
|
|
1781 (replace-match "")))
|
|
1782 (let ((config (current-window-configuration))
|
|
1783 (ediff-default-variant 'default-B))
|
|
1784
|
|
1785 ;; Fire up ediff.
|
|
1786
|
|
1787 (set-buffer (ediff-merge-buffers your-buffer other-buffer))
|
|
1788
|
|
1789 ;; Ediff is now set up, and we are in the control buffer.
|
|
1790 ;; Do a few further adjustments and take precautions for exit.
|
|
1791
|
|
1792 (make-local-variable 'vc-ediff-windows)
|
|
1793 (setq vc-ediff-windows config)
|
|
1794 (make-local-variable 'vc-ediff-result)
|
31380
|
1795 (setq vc-ediff-result result-buffer)
|
21324
|
1796 (make-local-variable 'ediff-quit-hook)
|
31565
|
1797 (setq ediff-quit-hook
|
31380
|
1798 (lambda ()
|
|
1799 (let ((buffer-A ediff-buffer-A)
|
|
1800 (buffer-B ediff-buffer-B)
|
|
1801 (buffer-C ediff-buffer-C)
|
|
1802 (result vc-ediff-result)
|
|
1803 (windows vc-ediff-windows))
|
|
1804 (ediff-cleanup-mess)
|
|
1805 (set-buffer result)
|
|
1806 (erase-buffer)
|
|
1807 (insert-buffer buffer-C)
|
|
1808 (kill-buffer buffer-A)
|
|
1809 (kill-buffer buffer-B)
|
|
1810 (kill-buffer buffer-C)
|
|
1811 (set-window-configuration windows)
|
|
1812 (message "Conflict resolution finished; you may save the buffer"))))
|
21324
|
1813 (message "Please resolve conflicts now; exit ediff when done")
|
|
1814 nil))))
|
|
1815
|
13012
|
1816 ;; The VC directory major mode. Coopt Dired for this.
|
2490
70d00ecacc0d
(vc-directory. vc-start-entry, vc-next-action, vc-next-action-on-file):
Eric S. Raymond <esr@snark.thyrsus.com>
diff
changeset
|
1817 ;; All VC commands get mapped into logical equivalents.
|
70d00ecacc0d
(vc-directory. vc-start-entry, vc-next-action, vc-next-action-on-file):
Eric S. Raymond <esr@snark.thyrsus.com>
diff
changeset
|
1818
|
23792
|
1819 (defvar vc-dired-switches)
|
|
1820 (defvar vc-dired-terse-mode)
|
|
1821
|
31380
|
1822 (defvar vc-dired-mode-map
|
|
1823 (let ((map (make-sparse-keymap))
|
|
1824 (vmap (make-sparse-keymap)))
|
|
1825 (define-key map "\C-xv" vc-prefix-map)
|
31404
|
1826 ;; Emacs-20 has a lousy keymap inheritance that won't work here.
|
|
1827 ;; Emacs-21's is still lousy but just better enough that it'd work. -sm
|
|
1828 ;; (set-keymap-parent vmap vc-prefix-map)
|
|
1829 (setq vmap vc-prefix-map)
|
31380
|
1830 (define-key map "v" vmap)
|
|
1831 (define-key vmap "t" 'vc-dired-toggle-terse-mode)
|
|
1832 map))
|
|
1833
|
13012
|
1834 (define-derived-mode vc-dired-mode dired-mode "Dired under VC"
|
31380
|
1835 "The major mode used in VC directory buffers.
|
|
1836
|
|
1837 It works like Dired, but lists only files under version control, with
|
|
1838 the current VC state of each file being indicated in the place of the
|
|
1839 file's link count, owner, group and size. Subdirectories are also
|
|
1840 listed, and you may insert them into the buffer as desired, like in
|
|
1841 Dired.
|
|
1842
|
|
1843 All Dired commands operate normally, with the exception of `v', which
|
|
1844 is redefined as the version control prefix, so that you can type
|
21357
|
1845 `vl', `v=' etc. to invoke `vc-print-log', `vc-diff', and the like on
|
|
1846 the file named in the current Dired buffer line. `vv' invokes
|
|
1847 `vc-next-action' on this file, or on all files currently marked.
|
|
1848 There is a special command, `*l', to mark all files currently locked."
|
31404
|
1849 ;; define-derived-mode does it for us in Emacs-21, but not in Emacs-20.
|
|
1850 ;; We do it here because dired might not be loaded yet
|
|
1851 ;; when vc-dired-mode-map is initialized.
|
|
1852 (set-keymap-parent vc-dired-mode-map dired-mode-map)
|
21370
e8224143df73
(vc-dired-mode): Make dired-after-readin-hook a local hook, not a local variable.
André Spiegel <spiegel@gnu.org>
diff
changeset
|
1853 (make-local-hook 'dired-after-readin-hook)
|
e8224143df73
(vc-dired-mode): Make dired-after-readin-hook a local hook, not a local variable.
André Spiegel <spiegel@gnu.org>
diff
changeset
|
1854 (add-hook 'dired-after-readin-hook 'vc-dired-hook nil t)
|
21560
|
1855 ;; The following is slightly modified from dired.el,
|
|
1856 ;; because file lines look a bit different in vc-dired-mode.
|
|
1857 (set (make-local-variable 'dired-move-to-filename-regexp)
|
31380
|
1858 (let*
|
21560
|
1859 ((l "\\([A-Za-z]\\|[^\0-\177]\\)")
|
|
1860 ;; In some locales, month abbreviations are as short as 2 letters,
|
|
1861 ;; and they can be padded on the right with spaces.
|
|
1862 (month (concat l l "+ *"))
|
31380
|
1863 ;; Recognize any non-ASCII character.
|
21560
|
1864 ;; The purpose is to match a Kanji character.
|
|
1865 (k "[^\0-\177]")
|
|
1866 ;; (k "[^\x00-\x7f\x80-\xff]")
|
|
1867 (s " ")
|
|
1868 (yyyy "[0-9][0-9][0-9][0-9]")
|
|
1869 (mm "[ 0-1][0-9]")
|
|
1870 (dd "[ 0-3][0-9]")
|
|
1871 (HH:MM "[ 0-2][0-9]:[0-5][0-9]")
|
|
1872 (western (concat "\\(" month s dd "\\|" dd s month "\\)"
|
24852
|
1873 s "\\(" HH:MM "\\|" s yyyy"\\|" yyyy s "\\)"))
|
21560
|
1874 (japanese (concat mm k s dd k s "\\(" s HH:MM "\\|" yyyy k "\\)")))
|
31380
|
1875 ;; the .* below ensures that we find the last match on a line
|
|
1876 (concat ".*" s "\\(" western "\\|" japanese "\\)" s)))
|
22356
a1f8c5a5c3e1
(vc-directory): Bind vc-dired-switches in order to pass switches to vc-dired-mode.
André Spiegel <spiegel@gnu.org>
diff
changeset
|
1877 (and (boundp 'vc-dired-switches)
|
a1f8c5a5c3e1
(vc-directory): Bind vc-dired-switches in order to pass switches to vc-dired-mode.
André Spiegel <spiegel@gnu.org>
diff
changeset
|
1878 vc-dired-switches
|
a1f8c5a5c3e1
(vc-directory): Bind vc-dired-switches in order to pass switches to vc-dired-mode.
André Spiegel <spiegel@gnu.org>
diff
changeset
|
1879 (set (make-local-variable 'dired-actual-switches)
|
a1f8c5a5c3e1
(vc-directory): Bind vc-dired-switches in order to pass switches to vc-dired-mode.
André Spiegel <spiegel@gnu.org>
diff
changeset
|
1880 vc-dired-switches))
|
22437
|
1881 (set (make-local-variable 'vc-dired-terse-mode) vc-dired-terse-display)
|
13012
|
1882 (setq vc-dired-mode t))
|
|
1883
|
22437
|
1884 (defun vc-dired-toggle-terse-mode ()
|
|
1885 "Toggle terse display in VC Dired."
|
|
1886 (interactive)
|
|
1887 (if (not vc-dired-mode)
|
|
1888 nil
|
|
1889 (setq vc-dired-terse-mode (not vc-dired-terse-mode))
|
|
1890 (if vc-dired-terse-mode
|
|
1891 (vc-dired-hook)
|
|
1892 (revert-buffer))))
|
|
1893
|
21357
|
1894 (defun vc-dired-mark-locked ()
|
|
1895 "Mark all files currently locked."
|
|
1896 (interactive)
|
|
1897 (dired-mark-if (let ((f (dired-get-filename nil t)))
|
|
1898 (and f
|
|
1899 (not (file-directory-p f))
|
31380
|
1900 (not (vc-up-to-date-p f))))
|
21357
|
1901 "locked file"))
|
|
1902
|
|
1903 (define-key vc-dired-mode-map "*l" 'vc-dired-mark-locked)
|
|
1904
|
31380
|
1905 (defun vc-default-dired-state-info (backend file)
|
|
1906 (let ((state (vc-state file)))
|
|
1907 (cond
|
|
1908 ((stringp state) (concat "(" state ")"))
|
|
1909 ((eq state 'edited) (concat "(" (vc-user-login-name) ")"))
|
|
1910 ((eq state 'needs-merge) "(merge)")
|
|
1911 ((eq state 'needs-patch) "(patch)")
|
|
1912 ((eq state 'unlocked-changes) "(stale)"))))
|
12943
10d0f42db2da
(vc-directory): Kill existing vc-dired buffers for this directory.
André Spiegel <spiegel@gnu.org>
diff
changeset
|
1913
|
2580
a66f7ed76416
(vc-diff): Get proper error message when you run this with no prefix
Eric S. Raymond <esr@snark.thyrsus.com>
diff
changeset
|
1914 (defun vc-dired-reformat-line (x)
|
31380
|
1915 "Reformat a directory-listing line.
|
|
1916 Replace various columns with version control information.
|
|
1917 This code, like dired, assumes UNIX -l format."
|
21357
|
1918 (beginning-of-line)
|
21560
|
1919 (let ((pos (point)) limit perm date-and-file)
|
13012
|
1920 (end-of-line)
|
|
1921 (setq limit (point))
|
|
1922 (goto-char pos)
|
21560
|
1923 (when
|
|
1924 (or
|
|
1925 (re-search-forward ;; owner and group
|
|
1926 "^\\(..[drwxlts-]+ \\) *[0-9]+ [^ ]+ +[^ ]+ +[0-9]+\\( .*\\)"
|
31380
|
1927 limit t)
|
21560
|
1928 (re-search-forward ;; only owner displayed
|
31380
|
1929 "^\\(..[drwxlts-]+ \\) *[0-9]+ [^ ]+ +[0-9]+\\( .*\\)"
|
21560
|
1930 limit t)
|
|
1931 (re-search-forward ;; OS/2 -l format, no links, owner, group
|
|
1932 "^\\(..[drwxlts-]+ \\) *[0-9]+\\( .*\\)"
|
|
1933 limit t))
|
13012
|
1934 (setq perm (match-string 1)
|
21560
|
1935 date-and-file (match-string 2))
|
|
1936 (setq x (substring (concat x " ") 0 10))
|
|
1937 (replace-match (concat perm x date-and-file)))))
|
2580
a66f7ed76416
(vc-diff): Get proper error message when you run this with no prefix
Eric S. Raymond <esr@snark.thyrsus.com>
diff
changeset
|
1938
|
21357
|
1939 (defun vc-dired-hook ()
|
31380
|
1940 "Reformat the listing according to version control.
|
|
1941 Called by dired after any portion of a vc-dired buffer has been read in."
|
21357
|
1942 (message "Getting version information... ")
|
21908
|
1943 (let (subdir filename (buffer-read-only nil) cvs-dir)
|
21357
|
1944 (goto-char (point-min))
|
31380
|
1945 (while (not (eobp))
|
|
1946 (cond
|
21357
|
1947 ;; subdir header line
|
|
1948 ((setq subdir (dired-get-subdir))
|
31380
|
1949 ;; if the backend supports it, get the state
|
|
1950 ;; of all files in this directory at once
|
|
1951 (let ((backend (vc-responsible-backend subdir)))
|
|
1952 (if (vc-find-backend-function backend 'dir-state)
|
|
1953 (vc-call-backend backend 'dir-state subdir)))
|
21357
|
1954 (forward-line 1)
|
|
1955 ;; erase (but don't remove) the "total" line
|
31380
|
1956 (delete-region (point) (line-end-position))
|
|
1957 (beginning-of-line)
|
|
1958 (forward-line 1))
|
|
1959 ;; file line
|
21357
|
1960 ((setq filename (dired-get-filename nil t))
|
|
1961 (cond
|
22437
|
1962 ;; subdir
|
21357
|
1963 ((file-directory-p filename)
|
31380
|
1964 (cond
|
|
1965 ((member (file-name-nondirectory filename)
|
22437
|
1966 vc-directory-exclusion-list)
|
|
1967 (let ((pos (point)))
|
|
1968 (dired-kill-tree filename)
|
|
1969 (goto-char pos)
|
|
1970 (dired-kill-line)))
|
|
1971 (vc-dired-terse-mode
|
22453
9d9df85eb7fb
(vc-dired-hook): Don't use dired-kill-line to remove directory lines
André Spiegel <spiegel@gnu.org>
diff
changeset
|
1972 ;; Don't show directories in terse mode. Don't use
|
9d9df85eb7fb
(vc-dired-hook): Don't use dired-kill-line to remove directory lines
André Spiegel <spiegel@gnu.org>
diff
changeset
|
1973 ;; dired-kill-line to remove it, because in recursive listings,
|
9d9df85eb7fb
(vc-dired-hook): Don't use dired-kill-line to remove directory lines
André Spiegel <spiegel@gnu.org>
diff
changeset
|
1974 ;; that would remove the directory contents as well.
|
31380
|
1975 (delete-region (line-beginning-position)
|
22453
9d9df85eb7fb
(vc-dired-hook): Don't use dired-kill-line to remove directory lines
André Spiegel <spiegel@gnu.org>
diff
changeset
|
1976 (progn (forward-line 1) (point))))
|
22437
|
1977 ((string-match "\\`\\.\\.?\\'" (file-name-nondirectory filename))
|
|
1978 (dired-kill-line))
|
|
1979 (t
|
21357
|
1980 (vc-dired-reformat-line nil)
|
22437
|
1981 (forward-line 1))))
|
|
1982 ;; ordinary file
|
31380
|
1983 ((and (vc-backend filename)
|
|
1984 (not (and vc-dired-terse-mode
|
|
1985 (vc-up-to-date-p filename))))
|
|
1986 (vc-dired-reformat-line (vc-call dired-state-info filename))
|
21357
|
1987 (forward-line 1))
|
31380
|
1988 (t
|
21357
|
1989 (dired-kill-line))))
|
|
1990 ;; any other line
|
22437
|
1991 (t (forward-line 1))))
|
|
1992 (vc-dired-purge))
|
|
1993 (message "Getting version information... done")
|
|
1994 (save-restriction
|
|
1995 (widen)
|
22453
9d9df85eb7fb
(vc-dired-hook): Don't use dired-kill-line to remove directory lines
André Spiegel <spiegel@gnu.org>
diff
changeset
|
1996 (cond ((eq (count-lines (point-min) (point-max)) 1)
|
9d9df85eb7fb
(vc-dired-hook): Don't use dired-kill-line to remove directory lines
André Spiegel <spiegel@gnu.org>
diff
changeset
|
1997 (goto-char (point-min))
|
9d9df85eb7fb
(vc-dired-hook): Don't use dired-kill-line to remove directory lines
André Spiegel <spiegel@gnu.org>
diff
changeset
|
1998 (message "No files locked under %s" default-directory)))))
|
22437
|
1999
|
|
2000 (defun vc-dired-purge ()
|
31380
|
2001 "Remove empty subdirs."
|
22437
|
2002 (let (subdir)
|
|
2003 (goto-char (point-min))
|
|
2004 (while (setq subdir (dired-get-subdir))
|
|
2005 (forward-line 2)
|
|
2006 (if (dired-get-filename nil t)
|
|
2007 (if (not (dired-next-subdir 1 t))
|
|
2008 (goto-char (point-max)))
|
|
2009 (forward-line -2)
|
|
2010 (if (not (string= (dired-current-directory) default-directory))
|
|
2011 (dired-do-kill-lines t "")
|
22453
9d9df85eb7fb
(vc-dired-hook): Don't use dired-kill-line to remove directory lines
André Spiegel <spiegel@gnu.org>
diff
changeset
|
2012 ;; We cannot remove the top level directory.
|
9d9df85eb7fb
(vc-dired-hook): Don't use dired-kill-line to remove directory lines
André Spiegel <spiegel@gnu.org>
diff
changeset
|
2013 ;; Just make it look a little nicer.
|
9d9df85eb7fb
(vc-dired-hook): Don't use dired-kill-line to remove directory lines
André Spiegel <spiegel@gnu.org>
diff
changeset
|
2014 (forward-line 1)
|
9d9df85eb7fb
(vc-dired-hook): Don't use dired-kill-line to remove directory lines
André Spiegel <spiegel@gnu.org>
diff
changeset
|
2015 (kill-line)
|
22437
|
2016 (if (not (dired-next-subdir 1 t))
|
|
2017 (goto-char (point-max))))))
|
|
2018 (goto-char (point-min))))
|
13012
|
2019
|
31380
|
2020 (defun vc-dired-buffers-for-dir (dir)
|
|
2021 "Return a list of all vc-dired buffers that currently display DIR."
|
|
2022 (let (result)
|
31404
|
2023 ;; Check whether dired is loaded.
|
|
2024 (when (fboundp 'dired-buffers-for-dir)
|
|
2025 (mapcar (lambda (buffer)
|
|
2026 (with-current-buffer buffer
|
|
2027 (if vc-dired-mode
|
|
2028 (setq result (append result (list buffer))))))
|
|
2029 (dired-buffers-for-dir dir)))
|
31380
|
2030 result))
|
|
2031
|
|
2032 (defun vc-dired-resynch-file (file)
|
|
2033 "Update the entries for FILE in any VC Dired buffers that list it."
|
|
2034 (let ((buffers (vc-dired-buffers-for-dir (file-name-directory file))))
|
|
2035 (when buffers
|
|
2036 (mapcar (lambda (buffer)
|
|
2037 (with-current-buffer buffer
|
|
2038 (if (dired-goto-file file)
|
|
2039 ;; bind vc-dired-terse-mode to nil so that
|
|
2040 ;; files won't vanish when they are checked in
|
|
2041 (let ((vc-dired-terse-mode nil))
|
|
2042 (dired-do-redisplay 1)))))
|
|
2043 buffers))))
|
|
2044
|
927
|
2045 ;;;###autoload
|
31380
|
2046 (defun vc-directory (dir read-switches)
|
|
2047 "Create a buffer in VC Dired Mode for directory DIR.
|
|
2048
|
|
2049 See Info node `VC Dired Mode'.
|
|
2050
|
|
2051 With prefix arg READ-SWITCHES, specify a value to override
|
|
2052 `dired-listing-switches' when generating the listing."
|
13012
|
2053 (interactive "DDired under VC (directory): \nP")
|
31380
|
2054 (let ((vc-dired-switches (concat vc-dired-listing-switches
|
22437
|
2055 (if vc-dired-recurse "R" ""))))
|
31380
|
2056 (if read-switches
|
22437
|
2057 (setq vc-dired-switches
|
|
2058 (read-string "Dired listing switches: "
|
|
2059 vc-dired-switches)))
|
21357
|
2060 (require 'dired)
|
|
2061 (require 'dired-aux)
|
31380
|
2062 (switch-to-buffer
|
|
2063 (dired-internal-noselect (expand-file-name (file-name-as-directory dir))
|
|
2064 vc-dired-switches
|
21357
|
2065 'vc-dired-mode))))
|
10475
|
2066
|
904
|
2067
|
|
2068 ;; Named-configuration entry points
|
|
2069
|
31380
|
2070 (defun vc-snapshot-precondition (dir)
|
31404
|
2071 "Scan the tree below DIR, looking for non-uptodate files.
|
|
2072 If any file is not up-to-date, return the name of the first such file.
|
|
2073 \(This means, neither snapshot creation nor retrieval is allowed.\)
|
|
2074 If one or more of the files are currently visited, return `visited'.
|
|
2075 Otherwise, return nil."
|
12714
|
2076 (let ((status nil))
|
|
2077 (catch 'vc-locked-example
|
|
2078 (vc-file-tree-walk
|
31380
|
2079 dir
|
|
2080 (lambda (f)
|
|
2081 (if (not (vc-up-to-date-p f)) (throw 'vc-locked-example f)
|
|
2082 (if (get-file-buffer f) (setq status 'visited)))))
|
12714
|
2083 status)))
|
904
|
2084
|
927
|
2085 ;;;###autoload
|
31380
|
2086 (defun vc-create-snapshot (dir name branchp)
|
31565
|
2087 "Descending recursively from DIR, make a snapshot called NAME.
|
31380
|
2088 For each registered file, the version level of its latest version
|
|
2089 becomes part of the named configuration. If the prefix argument
|
|
2090 BRANCHP is given, the snapshot is made as a new branch and the files
|
|
2091 are checked out in that new branch."
|
|
2092 (interactive
|
|
2093 (list (read-file-name "Directory: " default-directory default-directory t)
|
|
2094 (read-string "New snapshot name: ")
|
|
2095 current-prefix-arg))
|
|
2096 (message "Making %s... " (if branchp "branch" "snapshot"))
|
|
2097 (if (file-directory-p dir) (setq dir (file-name-as-directory dir)))
|
|
2098 (vc-call-backend (vc-responsible-backend dir)
|
|
2099 'create-snapshot dir name branchp)
|
|
2100 (message "Making %s... done" (if branchp "branch" "snapshot")))
|
|
2101
|
|
2102 (defun vc-default-create-snapshot (backend dir name branchp)
|
31565
|
2103 (when branchp
|
31380
|
2104 (error "VC backend %s does not support module branches" backend))
|
|
2105 (let ((result (vc-snapshot-precondition dir)))
|
12714
|
2106 (if (stringp result)
|
31380
|
2107 (error "File %s is not up-to-date" result)
|
4656
29bd5f3d0059
(vc-locked-example): Renamed from vc-quiescent-p. Now yields example of
Paul Eggert <eggert@twinsun.com>
diff
changeset
|
2108 (vc-file-tree-walk
|
31380
|
2109 dir
|
|
2110 (lambda (f)
|
|
2111 (vc-call assign-name f name))))))
|
904
|
2112
|
927
|
2113 ;;;###autoload
|
31380
|
2114 (defun vc-retrieve-snapshot (dir name)
|
31404
|
2115 "Descending recursively from DIR, retrieve the snapshot called NAME.
|
|
2116 If NAME is empty, it refers to the latest versions.
|
|
2117 If locking is used for the files in DIR, then there must not be any
|
|
2118 locked files at or below DIR (but if NAME is empty, locked files are
|
|
2119 allowed and simply skipped)."
|
31380
|
2120 (interactive
|
|
2121 (list (read-file-name "Directory: " default-directory default-directory t)
|
|
2122 (read-string "Snapshot name to retrieve (default latest versions): ")))
|
|
2123 (let ((update (yes-or-no-p "Update any affected buffers? "))
|
|
2124 (msg (if (or (not name) (string= name ""))
|
|
2125 (format "Updating %s... " (abbreviate-file-name dir))
|
|
2126 (format "Retrieving snapshot into %s... "
|
|
2127 (abbreviate-file-name dir)))))
|
|
2128 (message msg)
|
|
2129 (vc-call-backend (vc-responsible-backend dir)
|
|
2130 'retrieve-snapshot dir name update)
|
|
2131 (message (concat msg "done"))))
|
|
2132
|
|
2133 (defun vc-default-retrieve-snapshot (backend dir name update)
|
|
2134 (if (string= name "")
|
|
2135 (progn
|
|
2136 (vc-file-tree-walk
|
|
2137 dir
|
|
2138 (lambda (f) (and
|
|
2139 (vc-up-to-date-p f)
|
|
2140 (vc-error-occurred
|
|
2141 (vc-call checkout f nil "")
|
|
2142 (if update (vc-resynch-buffer f t t)))))))
|
|
2143 (let ((result (vc-snapshot-precondition dir)))
|
|
2144 (if (stringp result)
|
|
2145 (error "File %s is locked" result)
|
|
2146 (setq update (and (eq result 'visited) update))
|
|
2147 (vc-file-tree-walk
|
|
2148 dir
|
|
2149 (lambda (f) (and
|
|
2150 (vc-error-occurred
|
|
2151 (vc-call checkout f nil name)
|
|
2152 (if update (vc-resynch-buffer f t t))))))))))
|
904
|
2153
|
|
2154 ;; Miscellaneous other entry points
|
|
2155
|
927
|
2156 ;;;###autoload
|
904
|
2157 (defun vc-print-log ()
|
|
2158 "List the change log of the current buffer in a window."
|
|
2159 (interactive)
|
21366
|
2160 (vc-ensure-vc-buffer)
|
|
2161 (let ((file buffer-file-name))
|
31380
|
2162 (vc-setup-buffer nil)
|
21366
|
2163 (setq default-directory (file-name-directory file))
|
31380
|
2164 (vc-call print-log file)
|
|
2165 (pop-to-buffer (current-buffer))
|
|
2166 (if (fboundp 'log-view-mode) (log-view-mode))
|
|
2167 (vc-exec-after
|
|
2168 `(progn
|
|
2169 (goto-char (point-max)) (forward-line -1)
|
|
2170 (while (looking-at "=*\n")
|
|
2171 (delete-char (- (match-end 0) (match-beginning 0)))
|
|
2172 (forward-line -1))
|
|
2173 (goto-char (point-min))
|
|
2174 (if (looking-at "[\b\t\n\v\f\r ]+")
|
|
2175 (delete-char (- (match-end 0) (match-beginning 0))))
|
|
2176 (shrink-window-if-larger-than-buffer)
|
|
2177 ;; move point to the log entry for the current version
|
|
2178 (if (fboundp 'log-view-goto-rev)
|
|
2179 (log-view-goto-rev ',(vc-workfile-version file))
|
|
2180 (if (vc-find-backend-function ',(vc-backend file) 'show-log-entry)
|
31565
|
2181 (vc-call-backend ',(vc-backend file)
|
|
2182 'show-log-entry
|
31380
|
2183 ',(vc-workfile-version file))))))))
|
904
|
2184
|
32054
fef29341db1c
(vc-next-action-on-file): Update mode line only if file is visited.
André Spiegel <spiegel@gnu.org>
diff
changeset
|
2185 (defun vc-default-comment-history (backend file)
|
fef29341db1c
(vc-next-action-on-file): Update mode line only if file is visited.
André Spiegel <spiegel@gnu.org>
diff
changeset
|
2186 "Return a string with all log entries that were made under BACKEND for FILE."
|
fef29341db1c
(vc-next-action-on-file): Update mode line only if file is visited.
André Spiegel <spiegel@gnu.org>
diff
changeset
|
2187 (if (vc-find-backend-function backend 'print-log)
|
fef29341db1c
(vc-next-action-on-file): Update mode line only if file is visited.
André Spiegel <spiegel@gnu.org>
diff
changeset
|
2188 (with-temp-buffer
|
fef29341db1c
(vc-next-action-on-file): Update mode line only if file is visited.
André Spiegel <spiegel@gnu.org>
diff
changeset
|
2189 (vc-call print-log file)
|
fef29341db1c
(vc-next-action-on-file): Update mode line only if file is visited.
André Spiegel <spiegel@gnu.org>
diff
changeset
|
2190 (vc-call wash-log file)
|
fef29341db1c
(vc-next-action-on-file): Update mode line only if file is visited.
André Spiegel <spiegel@gnu.org>
diff
changeset
|
2191 (buffer-string))))
|
fef29341db1c
(vc-next-action-on-file): Update mode line only if file is visited.
André Spiegel <spiegel@gnu.org>
diff
changeset
|
2192
|
fef29341db1c
(vc-next-action-on-file): Update mode line only if file is visited.
André Spiegel <spiegel@gnu.org>
diff
changeset
|
2193 (defun vc-default-wash-log (backend file)
|
fef29341db1c
(vc-next-action-on-file): Update mode line only if file is visited.
André Spiegel <spiegel@gnu.org>
diff
changeset
|
2194 "Remove all non-comment information from log output.
|
fef29341db1c
(vc-next-action-on-file): Update mode line only if file is visited.
André Spiegel <spiegel@gnu.org>
diff
changeset
|
2195 This default implementation works for RCS logs; backends should override
|
fef29341db1c
(vc-next-action-on-file): Update mode line only if file is visited.
André Spiegel <spiegel@gnu.org>
diff
changeset
|
2196 it if their logs are not in RCS format."
|
fef29341db1c
(vc-next-action-on-file): Update mode line only if file is visited.
André Spiegel <spiegel@gnu.org>
diff
changeset
|
2197 (let ((separator (concat "^-+\nrevision [0-9.]+\ndate: .*\n"
|
fef29341db1c
(vc-next-action-on-file): Update mode line only if file is visited.
André Spiegel <spiegel@gnu.org>
diff
changeset
|
2198 "\\(branches: .*;\n\\)?"
|
fef29341db1c
(vc-next-action-on-file): Update mode line only if file is visited.
André Spiegel <spiegel@gnu.org>
diff
changeset
|
2199 "\\(\\*\\*\\* empty log message \\*\\*\\*\n\\)?")))
|
fef29341db1c
(vc-next-action-on-file): Update mode line only if file is visited.
André Spiegel <spiegel@gnu.org>
diff
changeset
|
2200 (goto-char (point-max)) (forward-line -1)
|
fef29341db1c
(vc-next-action-on-file): Update mode line only if file is visited.
André Spiegel <spiegel@gnu.org>
diff
changeset
|
2201 (while (looking-at "=*\n")
|
fef29341db1c
(vc-next-action-on-file): Update mode line only if file is visited.
André Spiegel <spiegel@gnu.org>
diff
changeset
|
2202 (delete-char (- (match-end 0) (match-beginning 0)))
|
fef29341db1c
(vc-next-action-on-file): Update mode line only if file is visited.
André Spiegel <spiegel@gnu.org>
diff
changeset
|
2203 (forward-line -1))
|
fef29341db1c
(vc-next-action-on-file): Update mode line only if file is visited.
André Spiegel <spiegel@gnu.org>
diff
changeset
|
2204 (goto-char (point-min))
|
fef29341db1c
(vc-next-action-on-file): Update mode line only if file is visited.
André Spiegel <spiegel@gnu.org>
diff
changeset
|
2205 (if (looking-at "[\b\t\n\v\f\r ]+")
|
fef29341db1c
(vc-next-action-on-file): Update mode line only if file is visited.
André Spiegel <spiegel@gnu.org>
diff
changeset
|
2206 (delete-char (- (match-end 0) (match-beginning 0))))
|
fef29341db1c
(vc-next-action-on-file): Update mode line only if file is visited.
André Spiegel <spiegel@gnu.org>
diff
changeset
|
2207 (goto-char (point-min))
|
fef29341db1c
(vc-next-action-on-file): Update mode line only if file is visited.
André Spiegel <spiegel@gnu.org>
diff
changeset
|
2208 (re-search-forward separator nil t)
|
fef29341db1c
(vc-next-action-on-file): Update mode line only if file is visited.
André Spiegel <spiegel@gnu.org>
diff
changeset
|
2209 (delete-region (point-min) (point))
|
fef29341db1c
(vc-next-action-on-file): Update mode line only if file is visited.
André Spiegel <spiegel@gnu.org>
diff
changeset
|
2210 (while (re-search-forward separator nil t)
|
fef29341db1c
(vc-next-action-on-file): Update mode line only if file is visited.
André Spiegel <spiegel@gnu.org>
diff
changeset
|
2211 (delete-region (match-beginning 0) (match-end 0)))))
|
fef29341db1c
(vc-next-action-on-file): Update mode line only if file is visited.
André Spiegel <spiegel@gnu.org>
diff
changeset
|
2212
|
927
|
2213 ;;;###autoload
|
904
|
2214 (defun vc-revert-buffer ()
|
21324
|
2215 "Revert the current buffer's file back to the version it was based on.
|
952
|
2216 This asks for confirmation if the buffer contents are not identical
|
32058
|
2217 to that version. This function does not automatically pick up newer
|
|
2218 changes found in the master file; use \\[universal-argument] \\[vc-next-action] to do so."
|
904
|
2219 (interactive)
|
21366
|
2220 (vc-ensure-vc-buffer)
|
904
|
2221 (let ((file buffer-file-name)
|
13536
|
2222 ;; This operation should always ask for confirmation.
|
|
2223 (vc-suppress-confirm nil)
|
32126
|
2224 (obuf (current-buffer))
|
|
2225 status)
|
33548
714a4c4917cd
(vc-revert-buffer): Ask for confirmation if file seems up-to-date.
André Spiegel <spiegel@gnu.org>
diff
changeset
|
2226 (if (vc-up-to-date-p file)
|
714a4c4917cd
(vc-revert-buffer): Ask for confirmation if file seems up-to-date.
André Spiegel <spiegel@gnu.org>
diff
changeset
|
2227 (unless (yes-or-no-p "File seems up-to-date. Revert anyway? ")
|
714a4c4917cd
(vc-revert-buffer): Ask for confirmation if file seems up-to-date.
André Spiegel <spiegel@gnu.org>
diff
changeset
|
2228 (error "Revert canceled")))
|
31380
|
2229 (unless (vc-workfile-unchanged-p file)
|
32189
921a2e8fa97e
(with-vc-properties): Use conses rather than length-2 lists.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
2230 ;; vc-diff selects the new window, which is not what we want:
|
921a2e8fa97e
(with-vc-properties): Use conses rather than length-2 lists.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
2231 ;; if the new window is on another frame, that'd require the user
|
921a2e8fa97e
(with-vc-properties): Use conses rather than length-2 lists.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
2232 ;; moving her mouse to answer the yes-or-no-p question.
|
921a2e8fa97e
(with-vc-properties): Use conses rather than length-2 lists.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
2233 (let ((win (save-selected-window
|
921a2e8fa97e
(with-vc-properties): Use conses rather than length-2 lists.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
2234 (setq status (vc-diff nil t)) (selected-window))))
|
921a2e8fa97e
(with-vc-properties): Use conses rather than length-2 lists.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
2235 (vc-exec-after `(message nil))
|
921a2e8fa97e
(with-vc-properties): Use conses rather than length-2 lists.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
2236 (when status
|
921a2e8fa97e
(with-vc-properties): Use conses rather than length-2 lists.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
2237 (unwind-protect
|
921a2e8fa97e
(with-vc-properties): Use conses rather than length-2 lists.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
2238 (unless (yes-or-no-p "Discard changes? ")
|
32126
|
2239 (error "Revert canceled"))
|
32189
921a2e8fa97e
(with-vc-properties): Use conses rather than length-2 lists.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
2240 (select-window win)
|
921a2e8fa97e
(with-vc-properties): Use conses rather than length-2 lists.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
2241 (if (one-window-p t)
|
921a2e8fa97e
(with-vc-properties): Use conses rather than length-2 lists.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
2242 (if (window-dedicated-p (selected-window))
|
921a2e8fa97e
(with-vc-properties): Use conses rather than length-2 lists.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
2243 (make-frame-invisible))
|
921a2e8fa97e
(with-vc-properties): Use conses rather than length-2 lists.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
2244 (delete-window))))))
|
21329
|
2245 (set-buffer obuf)
|
31380
|
2246 ;; Do the reverting
|
|
2247 (message "Reverting %s..." file)
|
32093
|
2248 (vc-revert-file file)
|
31380
|
2249 (message "Reverting %s...done" file)))
|
904
|
2250
|
32126
|
2251 (defun vc-version-backup-file (file &optional rev)
|
33564
d8c822512b62
(vc-version-diff): Bind inhibit-read-only when inserting text.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
2252 "Return name of backup file for revision REV of FILE.
|
d8c822512b62
(vc-version-diff): Bind inhibit-read-only when inserting text.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
2253 If version backups should be used for FILE, and there exists
|
32126
|
2254 such a backup for REV or the current workfile version of file,
|
33564
d8c822512b62
(vc-version-diff): Bind inhibit-read-only when inserting text.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
2255 return its name; otherwise return nil."
|
32748
e2cb0aef151a
(vc-checkout): Added `-p' suffix in call to vc-make-version-backups-p;
André Spiegel <spiegel@gnu.org>
diff
changeset
|
2256 (when (vc-call make-version-backups-p file)
|
32126
|
2257 (let ((backup-file (vc-version-backup-file-name file rev)))
|
32748
e2cb0aef151a
(vc-checkout): Added `-p' suffix in call to vc-make-version-backups-p;
André Spiegel <spiegel@gnu.org>
diff
changeset
|
2258 (if (file-exists-p backup-file)
|
e2cb0aef151a
(vc-checkout): Added `-p' suffix in call to vc-make-version-backups-p;
André Spiegel <spiegel@gnu.org>
diff
changeset
|
2259 backup-file
|
e2cb0aef151a
(vc-checkout): Added `-p' suffix in call to vc-make-version-backups-p;
André Spiegel <spiegel@gnu.org>
diff
changeset
|
2260 ;; there is no automatic backup, but maybe the user made one manually
|
e2cb0aef151a
(vc-checkout): Added `-p' suffix in call to vc-make-version-backups-p;
André Spiegel <spiegel@gnu.org>
diff
changeset
|
2261 (setq backup-file (vc-version-backup-file-name file rev 'manual))
|
e2cb0aef151a
(vc-checkout): Added `-p' suffix in call to vc-make-version-backups-p;
André Spiegel <spiegel@gnu.org>
diff
changeset
|
2262 (if (file-exists-p backup-file)
|
e2cb0aef151a
(vc-checkout): Added `-p' suffix in call to vc-make-version-backups-p;
André Spiegel <spiegel@gnu.org>
diff
changeset
|
2263 backup-file)))))
|
32126
|
2264
|
32093
|
2265 (defun vc-revert-file (file)
|
|
2266 "Revert FILE back to the version it was based on."
|
|
2267 (with-vc-properties
|
|
2268 file
|
32126
|
2269 (let ((backup-file (vc-version-backup-file file)))
|
|
2270 (if (not backup-file)
|
|
2271 (vc-call revert file)
|
|
2272 (copy-file backup-file file 'ok-if-already-exists 'keep-date)
|
32748
e2cb0aef151a
(vc-checkout): Added `-p' suffix in call to vc-make-version-backups-p;
André Spiegel <spiegel@gnu.org>
diff
changeset
|
2273 (vc-delete-automatic-version-backups file)))
|
32189
921a2e8fa97e
(with-vc-properties): Use conses rather than length-2 lists.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
2274 `((vc-state . up-to-date)
|
921a2e8fa97e
(with-vc-properties): Use conses rather than length-2 lists.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
2275 (vc-checkout-time . ,(nth 5 (file-attributes file)))))
|
32093
|
2276 (vc-resynch-buffer file t t))
|
|
2277
|
927
|
2278 ;;;###autoload
|
904
|
2279 (defun vc-cancel-version (norevert)
|
2750
|
2280 "Get rid of most recently checked in version of this file.
|
31404
|
2281 A prefix argument NOREVERT means do not revert the buffer afterwards."
|
904
|
2282 (interactive "P")
|
21366
|
2283 (vc-ensure-vc-buffer)
|
31404
|
2284 (let* ((file (buffer-file-name))
|
|
2285 (backend (vc-backend file))
|
|
2286 (target (vc-workfile-version file))
|
13934
|
2287 (config (current-window-configuration)) done)
|
31380
|
2288 (cond
|
31404
|
2289 ((not (vc-find-backend-function backend 'cancel-version))
|
31380
|
2290 (error "Sorry, canceling versions is not supported under %s" backend))
|
31404
|
2291 ((not (vc-call latest-on-branch-p file))
|
31380
|
2292 (error "This is not the latest version; VC cannot cancel it"))
|
31404
|
2293 ((not (vc-up-to-date-p file))
|
31380
|
2294 (error (substitute-command-keys "File is not up to date; use \\[vc-revert-buffer] to discard changes"))))
|
13934
|
2295 (if (null (yes-or-no-p (format "Remove version %s from master? " target)))
|
31404
|
2296 (error "Aborted")
|
31380
|
2297 (setq norevert (or norevert (not
|
|
2298 (yes-or-no-p "Revert buffer to most recent remaining version? "))))
|
|
2299
|
31404
|
2300 (message "Removing last change from %s..." file)
|
|
2301 (with-vc-properties
|
|
2302 file
|
|
2303 (vc-call cancel-version file norevert)
|
32189
921a2e8fa97e
(with-vc-properties): Use conses rather than length-2 lists.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
2304 `((vc-state . ,(if norevert 'edited 'up-to-date))
|
32344
f91ef1141a75
(with-vc-file, edit-vc-file): Specify `indent-function' property.
Thien-Thi Nguyen <ttn@gnuvola.org>
diff
changeset
|
2305 (vc-checkout-time . ,(if norevert
|
f91ef1141a75
(with-vc-file, edit-vc-file): Specify `indent-function' property.
Thien-Thi Nguyen <ttn@gnuvola.org>
diff
changeset
|
2306 0
|
31404
|
2307 (nth 5 (file-attributes file))))
|
32189
921a2e8fa97e
(with-vc-properties): Use conses rather than length-2 lists.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
2308 (vc-workfile-version . nil)))
|
31404
|
2309 (message "Removing last change from %s...done" file)
|
31380
|
2310
|
31404
|
2311 (cond
|
|
2312 (norevert ;; clear version headers and mark the buffer modified
|
|
2313 (set-visited-file-name file)
|
|
2314 (when (not vc-make-backup-files)
|
|
2315 ;; inhibit backup for this buffer
|
|
2316 (make-local-variable 'backup-inhibited)
|
|
2317 (setq backup-inhibited t))
|
|
2318 (setq buffer-read-only nil)
|
|
2319 (vc-clear-headers)
|
|
2320 (vc-mode-line file)
|
|
2321 (vc-dired-resynch-file file))
|
|
2322 (t ;; revert buffer to file on disk
|
|
2323 (vc-resynch-buffer file t t)))
|
31380
|
2324 (message "Version %s has been removed from the master" target))))
|
|
2325
|
31810
495ca3bd372d
(vc-index-of, vc-transfer-file, vc-default-receive-file): New functions.
André Spiegel <spiegel@gnu.org>
diff
changeset
|
2326 ;;;autoload
|
495ca3bd372d
(vc-index-of, vc-transfer-file, vc-default-receive-file): New functions.
André Spiegel <spiegel@gnu.org>
diff
changeset
|
2327 (defun vc-switch-backend (file backend)
|
32058
|
2328 "Make BACKEND the current version control system for FILE.
|
31810
495ca3bd372d
(vc-index-of, vc-transfer-file, vc-default-receive-file): New functions.
André Spiegel <spiegel@gnu.org>
diff
changeset
|
2329 FILE must already be registered in BACKEND. The change is not
|
495ca3bd372d
(vc-index-of, vc-transfer-file, vc-default-receive-file): New functions.
André Spiegel <spiegel@gnu.org>
diff
changeset
|
2330 permanent, only for the current session. This function only changes
|
32058
|
2331 VC's perspective on FILE, it does not register or unregister it.
|
|
2332 By default, this command cycles through the registered backends.
|
|
2333 To get a prompt, use a prefix argument."
|
|
2334 (interactive
|
31810
495ca3bd372d
(vc-index-of, vc-transfer-file, vc-default-receive-file): New functions.
André Spiegel <spiegel@gnu.org>
diff
changeset
|
2335 (list
|
495ca3bd372d
(vc-index-of, vc-transfer-file, vc-default-receive-file): New functions.
André Spiegel <spiegel@gnu.org>
diff
changeset
|
2336 buffer-file-name
|
32058
|
2337 (let ((backend (vc-backend buffer-file-name))
|
|
2338 (backends nil))
|
|
2339 ;; Find the registered backends.
|
|
2340 (dolist (backend vc-handled-backends)
|
|
2341 (when (vc-call-backend backend 'registered buffer-file-name)
|
|
2342 (push backend backends)))
|
|
2343 ;; Find the next backend.
|
32059
|
2344 (let ((def (car (delq backend (append (memq backend backends) backends))))
|
32058
|
2345 (others (delete backend backends)))
|
|
2346 (cond
|
|
2347 ((null others) (error "No other backend to switch to"))
|
|
2348 (current-prefix-arg
|
|
2349 (intern
|
|
2350 (upcase
|
|
2351 (completing-read
|
|
2352 (format "Switch to backend [%s]: " def)
|
|
2353 (mapcar (lambda (b) (list (downcase (symbol-name b)))) backends)
|
|
2354 nil t nil nil (downcase (symbol-name def))))))
|
|
2355 (t def))))))
|
32059
|
2356 (unless (eq backend (vc-backend file))
|
|
2357 (vc-file-clearprops file)
|
|
2358 (vc-file-setprop file 'vc-backend backend)
|
|
2359 ;; Force recomputation of the state
|
32189
921a2e8fa97e
(with-vc-properties): Use conses rather than length-2 lists.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
2360 (unless (vc-call-backend backend 'registered file)
|
921a2e8fa97e
(with-vc-properties): Use conses rather than length-2 lists.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
2361 (vc-file-clearprops file)
|
921a2e8fa97e
(with-vc-properties): Use conses rather than length-2 lists.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
2362 (error "%s is not registered in %s" file backend))
|
32059
|
2363 (vc-mode-line file)))
|
31810
495ca3bd372d
(vc-index-of, vc-transfer-file, vc-default-receive-file): New functions.
André Spiegel <spiegel@gnu.org>
diff
changeset
|
2364
|
495ca3bd372d
(vc-index-of, vc-transfer-file, vc-default-receive-file): New functions.
André Spiegel <spiegel@gnu.org>
diff
changeset
|
2365 ;;;autoload
|
495ca3bd372d
(vc-index-of, vc-transfer-file, vc-default-receive-file): New functions.
André Spiegel <spiegel@gnu.org>
diff
changeset
|
2366 (defun vc-transfer-file (file new-backend)
|
32059
|
2367 "Transfer FILE to another version control system NEW-BACKEND.
|
31810
495ca3bd372d
(vc-index-of, vc-transfer-file, vc-default-receive-file): New functions.
André Spiegel <spiegel@gnu.org>
diff
changeset
|
2368 If NEW-BACKEND has a higher precedence than FILE's current backend
|
32059
|
2369 \(i.e. it comes earlier in `vc-handled-backends'), then register FILE in
|
31810
495ca3bd372d
(vc-index-of, vc-transfer-file, vc-default-receive-file): New functions.
André Spiegel <spiegel@gnu.org>
diff
changeset
|
2370 NEW-BACKEND, using the version number from the current backend as the
|
495ca3bd372d
(vc-index-of, vc-transfer-file, vc-default-receive-file): New functions.
André Spiegel <spiegel@gnu.org>
diff
changeset
|
2371 base level. If NEW-BACKEND has a lower precedence than the current
|
495ca3bd372d
(vc-index-of, vc-transfer-file, vc-default-receive-file): New functions.
André Spiegel <spiegel@gnu.org>
diff
changeset
|
2372 backend, then commit all changes that were made under the current
|
495ca3bd372d
(vc-index-of, vc-transfer-file, vc-default-receive-file): New functions.
André Spiegel <spiegel@gnu.org>
diff
changeset
|
2373 backend to NEW-BACKEND, and unregister FILE from the current backend.
|
495ca3bd372d
(vc-index-of, vc-transfer-file, vc-default-receive-file): New functions.
André Spiegel <spiegel@gnu.org>
diff
changeset
|
2374 \(If FILE is not yet registered under NEW-BACKEND, register it.)"
|
32097
adf341c172af
(vc-transfer-file, vc-default-receive-file): Rewritten to factorize
André Spiegel <spiegel@gnu.org>
diff
changeset
|
2375 (let* ((old-backend (vc-backend file))
|
adf341c172af
(vc-transfer-file, vc-default-receive-file): Rewritten to factorize
André Spiegel <spiegel@gnu.org>
diff
changeset
|
2376 (edited (memq (vc-state file) '(edited needs-merge)))
|
adf341c172af
(vc-transfer-file, vc-default-receive-file): Rewritten to factorize
André Spiegel <spiegel@gnu.org>
diff
changeset
|
2377 (registered (vc-call-backend new-backend 'registered file))
|
adf341c172af
(vc-transfer-file, vc-default-receive-file): Rewritten to factorize
André Spiegel <spiegel@gnu.org>
diff
changeset
|
2378 (move
|
adf341c172af
(vc-transfer-file, vc-default-receive-file): Rewritten to factorize
André Spiegel <spiegel@gnu.org>
diff
changeset
|
2379 (and registered ; Never move if not registered in new-backend yet.
|
adf341c172af
(vc-transfer-file, vc-default-receive-file): Rewritten to factorize
André Spiegel <spiegel@gnu.org>
diff
changeset
|
2380 ;; move if new-backend comes later in vc-handled-backends
|
adf341c172af
(vc-transfer-file, vc-default-receive-file): Rewritten to factorize
André Spiegel <spiegel@gnu.org>
diff
changeset
|
2381 (or (memq new-backend (memq old-backend vc-handled-backends))
|
32126
|
2382 (y-or-n-p "Final transfer? "))))
|
32097
adf341c172af
(vc-transfer-file, vc-default-receive-file): Rewritten to factorize
André Spiegel <spiegel@gnu.org>
diff
changeset
|
2383 (comment nil))
|
31810
495ca3bd372d
(vc-index-of, vc-transfer-file, vc-default-receive-file): New functions.
André Spiegel <spiegel@gnu.org>
diff
changeset
|
2384 (if (eq old-backend new-backend)
|
32097
adf341c172af
(vc-transfer-file, vc-default-receive-file): Rewritten to factorize
André Spiegel <spiegel@gnu.org>
diff
changeset
|
2385 (error "%s is the current backend of %s" new-backend file))
|
adf341c172af
(vc-transfer-file, vc-default-receive-file): Rewritten to factorize
André Spiegel <spiegel@gnu.org>
diff
changeset
|
2386 (if registered
|
adf341c172af
(vc-transfer-file, vc-default-receive-file): Rewritten to factorize
André Spiegel <spiegel@gnu.org>
diff
changeset
|
2387 (set-file-modes file (logior (file-modes file) 128))
|
adf341c172af
(vc-transfer-file, vc-default-receive-file): Rewritten to factorize
André Spiegel <spiegel@gnu.org>
diff
changeset
|
2388 ;; `registered' might have switched under us.
|
adf341c172af
(vc-transfer-file, vc-default-receive-file): Rewritten to factorize
André Spiegel <spiegel@gnu.org>
diff
changeset
|
2389 (vc-switch-backend file old-backend)
|
32126
|
2390 (let* ((rev (vc-workfile-version file))
|
|
2391 (modified-file (and edited (make-temp-name file)))
|
|
2392 (unmodified-file (and modified-file (vc-version-backup-file file))))
|
32097
adf341c172af
(vc-transfer-file, vc-default-receive-file): Rewritten to factorize
André Spiegel <spiegel@gnu.org>
diff
changeset
|
2393 ;; Go back to the base unmodified file.
|
adf341c172af
(vc-transfer-file, vc-default-receive-file): Rewritten to factorize
André Spiegel <spiegel@gnu.org>
diff
changeset
|
2394 (unwind-protect
|
adf341c172af
(vc-transfer-file, vc-default-receive-file): Rewritten to factorize
André Spiegel <spiegel@gnu.org>
diff
changeset
|
2395 (progn
|
32126
|
2396 (when modified-file
|
|
2397 (copy-file file modified-file)
|
|
2398 ;; If we have a local copy of the unmodified file, handle that
|
|
2399 ;; here and not in vc-revert-file because we don't want to
|
|
2400 ;; delete that copy -- it is still useful for OLD-BACKEND.
|
|
2401 (if unmodified-file
|
|
2402 (copy-file unmodified-file file 'ok-if-already-exists)
|
|
2403 (if (y-or-n-p "Get base version from master? ")
|
|
2404 (vc-revert-file file))))
|
32097
adf341c172af
(vc-transfer-file, vc-default-receive-file): Rewritten to factorize
André Spiegel <spiegel@gnu.org>
diff
changeset
|
2405 (vc-call-backend new-backend 'receive-file file rev))
|
32126
|
2406 (when modified-file
|
32097
adf341c172af
(vc-transfer-file, vc-default-receive-file): Rewritten to factorize
André Spiegel <spiegel@gnu.org>
diff
changeset
|
2407 (vc-switch-backend file new-backend)
|
adf341c172af
(vc-transfer-file, vc-default-receive-file): Rewritten to factorize
André Spiegel <spiegel@gnu.org>
diff
changeset
|
2408 (unless (eq (vc-checkout-model file) 'implicit)
|
adf341c172af
(vc-transfer-file, vc-default-receive-file): Rewritten to factorize
André Spiegel <spiegel@gnu.org>
diff
changeset
|
2409 (vc-checkout file t nil))
|
32126
|
2410 (rename-file modified-file file 'ok-if-already-exists)
|
|
2411 (vc-file-setprop file 'vc-checkout-time nil)))))
|
32097
adf341c172af
(vc-transfer-file, vc-default-receive-file): Rewritten to factorize
André Spiegel <spiegel@gnu.org>
diff
changeset
|
2412 (when move
|
adf341c172af
(vc-transfer-file, vc-default-receive-file): Rewritten to factorize
André Spiegel <spiegel@gnu.org>
diff
changeset
|
2413 (vc-switch-backend file old-backend)
|
adf341c172af
(vc-transfer-file, vc-default-receive-file): Rewritten to factorize
André Spiegel <spiegel@gnu.org>
diff
changeset
|
2414 (setq comment (vc-call comment-history file))
|
adf341c172af
(vc-transfer-file, vc-default-receive-file): Rewritten to factorize
André Spiegel <spiegel@gnu.org>
diff
changeset
|
2415 (vc-call unregister file))
|
adf341c172af
(vc-transfer-file, vc-default-receive-file): Rewritten to factorize
André Spiegel <spiegel@gnu.org>
diff
changeset
|
2416 (vc-switch-backend file new-backend)
|
adf341c172af
(vc-transfer-file, vc-default-receive-file): Rewritten to factorize
André Spiegel <spiegel@gnu.org>
diff
changeset
|
2417 (when (or move edited)
|
31810
495ca3bd372d
(vc-index-of, vc-transfer-file, vc-default-receive-file): New functions.
André Spiegel <spiegel@gnu.org>
diff
changeset
|
2418 (vc-file-setprop file 'vc-state 'edited)
|
32126
|
2419 (vc-mode-line file)
|
32054
fef29341db1c
(vc-next-action-on-file): Update mode line only if file is visited.
André Spiegel <spiegel@gnu.org>
diff
changeset
|
2420 (vc-checkin file nil comment (stringp comment)))))
|
31810
495ca3bd372d
(vc-index-of, vc-transfer-file, vc-default-receive-file): New functions.
André Spiegel <spiegel@gnu.org>
diff
changeset
|
2421
|
32097
adf341c172af
(vc-transfer-file, vc-default-receive-file): Rewritten to factorize
André Spiegel <spiegel@gnu.org>
diff
changeset
|
2422 (defun vc-default-unregister (backend file)
|
adf341c172af
(vc-transfer-file, vc-default-receive-file): Rewritten to factorize
André Spiegel <spiegel@gnu.org>
diff
changeset
|
2423 "Default implementation of `vc-unregister', signals an error."
|
adf341c172af
(vc-transfer-file, vc-default-receive-file): Rewritten to factorize
André Spiegel <spiegel@gnu.org>
diff
changeset
|
2424 (error "Unregistering files is not supported for %s" backend))
|
adf341c172af
(vc-transfer-file, vc-default-receive-file): Rewritten to factorize
André Spiegel <spiegel@gnu.org>
diff
changeset
|
2425
|
adf341c172af
(vc-transfer-file, vc-default-receive-file): Rewritten to factorize
André Spiegel <spiegel@gnu.org>
diff
changeset
|
2426 (defun vc-default-receive-file (backend file rev)
|
adf341c172af
(vc-transfer-file, vc-default-receive-file): Rewritten to factorize
André Spiegel <spiegel@gnu.org>
diff
changeset
|
2427 "Let BACKEND receive FILE from another version control system."
|
adf341c172af
(vc-transfer-file, vc-default-receive-file): Rewritten to factorize
André Spiegel <spiegel@gnu.org>
diff
changeset
|
2428 (vc-call-backend backend 'register file rev ""))
|
adf341c172af
(vc-transfer-file, vc-default-receive-file): Rewritten to factorize
André Spiegel <spiegel@gnu.org>
diff
changeset
|
2429
|
31380
|
2430 (defun vc-rename-master (oldmaster newfile templates)
|
|
2431 "Rename OLDMASTER to be the master file for NEWFILE based on TEMPLATES."
|
|
2432 (let* ((dir (file-name-directory (expand-file-name oldmaster)))
|
|
2433 (newdir (or (file-name-directory newfile) ""))
|
|
2434 (newbase (file-name-nondirectory newfile))
|
|
2435 (masters
|
|
2436 ;; List of potential master files for `newfile'
|
|
2437 (mapcar
|
|
2438 (lambda (s) (vc-possible-master s newdir newbase))
|
|
2439 templates)))
|
|
2440 (if (or (file-symlink-p oldmaster)
|
|
2441 (file-symlink-p (file-name-directory oldmaster)))
|
|
2442 (error "This unsafe in the presence of symbolic links"))
|
|
2443 (rename-file
|
|
2444 oldmaster
|
|
2445 (catch 'found
|
|
2446 ;; If possible, keep the master file in the same directory.
|
|
2447 (mapcar (lambda (f)
|
|
2448 (if (and f (string= (file-name-directory (expand-file-name f))
|
|
2449 dir))
|
|
2450 (throw 'found f)))
|
|
2451 masters)
|
|
2452 ;; If not, just use the first possible place.
|
|
2453 (mapcar (lambda (f)
|
|
2454 (and f
|
|
2455 (or (not (setq dir (file-name-directory f)))
|
|
2456 (file-directory-p dir))
|
|
2457 (throw 'found f)))
|
|
2458 masters)
|
|
2459 (error "New file lacks a version control directory")))))
|
904
|
2460
|
9044
|
2461 ;;;###autoload
|
904
|
2462 (defun vc-rename-file (old new)
|
2750
|
2463 "Rename file OLD to NEW, and rename its master file likewise."
|
|
2464 (interactive "fVC rename file: \nFRename to: ")
|
9249
|
2465 ;; There are several ways of renaming files under CVS 1.3, but they all
|
|
2466 ;; have serious disadvantages. See the FAQ (available from think.com in
|
|
2467 ;; pub/cvs/). I'd rather send the user an error, than do something he might
|
|
2468 ;; consider to be wrong. When the famous, long-awaited rename database is
|
|
2469 ;; implemented things might change for the better. This is unlikely to occur
|
|
2470 ;; until CVS 2.0 is released. --ceder 1994-01-23 21:27:51
|
31380
|
2471 (let ((oldbuf (get-file-buffer old))
|
|
2472 (backend (vc-backend old)))
|
|
2473 (unless (or (null backend) (vc-find-backend-function backend 'rename-file))
|
|
2474 (error "Renaming files under %s is not supported in VC" backend))
|
4991
|
2475 (if (and oldbuf (buffer-modified-p oldbuf))
|
3804
|
2476 (error "Please save files before moving them"))
|
904
|
2477 (if (get-file-buffer new)
|
3804
|
2478 (error "Already editing new file name"))
|
4991
|
2479 (if (file-exists-p new)
|
|
2480 (error "New file already exists"))
|
31380
|
2481 (when backend
|
|
2482 (if (and backend (not (vc-up-to-date-p old)))
|
|
2483 (error "Please check in files before moving them"))
|
|
2484 (vc-call-backend backend 'rename-file old new))
|
|
2485 ;; Move the actual file (unless the backend did it already)
|
|
2486 (if (or (not backend) (file-exists-p old))
|
|
2487 (rename-file old new))
|
|
2488 ;; ?? Renaming a file might change its contents due to keyword expansion.
|
|
2489 ;; We should really check out a new copy if the old copy was precisely equal
|
|
2490 ;; to some checked in version. However, testing for this is tricky....
|
904
|
2491 (if oldbuf
|
31380
|
2492 (with-current-buffer oldbuf
|
15227
|
2493 (let ((buffer-read-only buffer-read-only))
|
|
2494 (set-visited-file-name new))
|
|
2495 (vc-backend new)
|
|
2496 (vc-mode-line new)
|
31380
|
2497 (set-buffer-modified-p nil)))))
|
|
2498
|
|
2499 ;; Only defined in very recent Emacsen
|
|
2500 (defvar small-temporary-file-directory nil)
|
904
|
2501
|
927
|
2502 ;;;###autoload
|
1226
573df03a54d8
(vc-update-change-log): Use shell-command, not shell-command-on-region.
Roland McGrath <roland@gnu.org>
diff
changeset
|
2503 (defun vc-update-change-log (&rest args)
|
31380
|
2504 "Find change log file and add entries from recent version control logs.
|
15989
|
2505 Normally, find log entries for all registered files in the default
|
31380
|
2506 directory.
|
15989
|
2507
|
31404
|
2508 With prefix arg of \\[universal-argument], only find log entries for the current buffer's file.
|
15989
|
2509
|
|
2510 With any numeric prefix arg, find log entries for all currently visited
|
|
2511 files that are under version control. This puts all the entries in the
|
|
2512 log for the default directory, which may not be appropriate.
|
|
2513
|
31404
|
2514 From a program, any ARGS are assumed to be filenames for which
|
31380
|
2515 log entries should be gathered."
|
1227
|
2516 (interactive
|
|
2517 (cond ((consp current-prefix-arg) ;C-u
|
|
2518 (list buffer-file-name))
|
|
2519 (current-prefix-arg ;Numeric argument.
|
|
2520 (let ((files nil)
|
|
2521 (buffers (buffer-list))
|
|
2522 file)
|
|
2523 (while buffers
|
|
2524 (setq file (buffer-file-name (car buffers)))
|
11605
|
2525 (and file (vc-backend file)
|
3939
1b954eb0f249
(vc-update-change-log): Ensure that file names inserted into a ChangeLog
Paul Eggert <eggert@twinsun.com>
diff
changeset
|
2526 (setq files (cons file files)))
|
1227
|
2527 (setq buffers (cdr buffers)))
|
3939
1b954eb0f249
(vc-update-change-log): Ensure that file names inserted into a ChangeLog
Paul Eggert <eggert@twinsun.com>
diff
changeset
|
2528 files))
|
1b954eb0f249
(vc-update-change-log): Ensure that file names inserted into a ChangeLog
Paul Eggert <eggert@twinsun.com>
diff
changeset
|
2529 (t
|
31380
|
2530 ;; Don't supply any filenames to backend; this means
|
|
2531 ;; it should find all relevant files relative to
|
|
2532 ;; the default-directory.
|
15977
|
2533 nil)))
|
31380
|
2534 (vc-call-backend (vc-responsible-backend default-directory)
|
|
2535 'update-changelog args))
|
|
2536
|
|
2537 (defun vc-default-update-changelog (backend files)
|
31404
|
2538 "Default implementation of update-changelog.
|
|
2539 Uses `rcs2log' which only works for RCS and CVS."
|
31380
|
2540 ;; FIXME: We (c|sh)ould add support for cvs2cl
|
14053
|
2541 (let ((odefault default-directory)
|
17410
|
2542 (changelog (find-change-log))
|
|
2543 ;; Presumably not portable to non-Unixy systems, along with rcs2log:
|
31380
|
2544 (tempfile (funcall
|
|
2545 (if (fboundp 'make-temp-file) 'make-temp-file 'make-temp-name)
|
25488
48c997ce6c8d
(vc-update-change-log): Use small-temporary-file-directory when non-nil.
Eli Zaretskii <eliz@gnu.org>
diff
changeset
|
2546 (expand-file-name "vc"
|
48c997ce6c8d
(vc-update-change-log): Use small-temporary-file-directory when non-nil.
Eli Zaretskii <eliz@gnu.org>
diff
changeset
|
2547 (or small-temporary-file-directory
|
48c997ce6c8d
(vc-update-change-log): Use small-temporary-file-directory when non-nil.
Eli Zaretskii <eliz@gnu.org>
diff
changeset
|
2548 temporary-file-directory))))
|
14855
|
2549 (full-name (or add-log-full-name
|
16743
|
2550 (user-full-name)
|
|
2551 (user-login-name)
|
|
2552 (format "uid%d" (number-to-string (user-uid)))))
|
14855
|
2553 (mailing-address (or add-log-mailing-address
|
|
2554 user-mail-address)))
|
17410
|
2555 (find-file-other-window changelog)
|
3905
|
2556 (barf-if-buffer-read-only)
|
|
2557 (vc-buffer-sync)
|
|
2558 (undo-boundary)
|
|
2559 (goto-char (point-min))
|
|
2560 (push-mark)
|
|
2561 (message "Computing change log entries...")
|
3939
1b954eb0f249
(vc-update-change-log): Ensure that file names inserted into a ChangeLog
Paul Eggert <eggert@twinsun.com>
diff
changeset
|
2562 (message "Computing change log entries... %s"
|
17410
|
2563 (unwind-protect
|
|
2564 (progn
|
31380
|
2565 (setq default-directory odefault)
|
31565
|
2566 (if (eq 0 (apply 'call-process
|
|
2567 (expand-file-name "rcs2log"
|
|
2568 exec-directory)
|
31380
|
2569 nil (list t tempfile) nil
|
|
2570 "-c" changelog
|
|
2571 "-u" (concat (vc-user-login-name)
|
|
2572 "\t" full-name
|
|
2573 "\t" mailing-address)
|
|
2574 (mapcar
|
|
2575 (lambda (f)
|
|
2576 (file-relative-name
|
|
2577 (if (file-name-absolute-p f)
|
|
2578 f
|
|
2579 (concat odefault f))))
|
|
2580 files)))
|
|
2581 "done"
|
17410
|
2582 (pop-to-buffer
|
|
2583 (set-buffer (get-buffer-create "*vc*")))
|
|
2584 (erase-buffer)
|
|
2585 (insert-file tempfile)
|
|
2586 "failed"))
|
31380
|
2587 (setq default-directory (file-name-directory changelog))
|
17410
|
2588 (delete-file tempfile)))))
|
18174
|
2589
|
31380
|
2590 ;;; Annotate functionality
|
18174
|
2591
|
18246
|
2592 ;; Declare globally instead of additional parameter to
|
|
2593 ;; temp-buffer-show-function (not possible to pass more than one
|
|
2594 ;; parameter).
|
31404
|
2595 (defvar vc-annotate-ratio nil "Global variable.")
|
|
2596 (defvar vc-annotate-backend nil "Global variable.")
|
18246
|
2597
|
31380
|
2598 (defun vc-annotate-get-backend (buffer)
|
31404
|
2599 "Return the backend matching \"Annotate\" buffer BUFFER.
|
|
2600 Return NIL if no match made. Associations are made based on
|
31380
|
2601 `vc-annotate-buffers'."
|
|
2602 (cdr (assoc buffer vc-annotate-buffers)))
|
18174
|
2603
|
31380
|
2604 (define-derived-mode vc-annotate-mode fundamental-mode "Annotate"
|
|
2605 "Major mode for buffers displaying output from the `annotate' command.
|
18174
|
2606
|
|
2607 You can use the mode-specific menu to alter the time-span of the used
|
|
2608 colors. See variable `vc-annotate-menu-elements' for customizing the
|
|
2609 menu items."
|
|
2610 (vc-annotate-add-menu))
|
|
2611
|
|
2612 (defun vc-annotate-display-default (&optional event)
|
|
2613 "Use the default color spectrum for VC Annotate mode."
|
31380
|
2614 (interactive "e")
|
18246
|
2615 (message "Redisplaying annotation...")
|
31380
|
2616 (vc-annotate-display (current-buffer)
|
31565
|
2617 nil
|
31380
|
2618 (vc-annotate-get-backend (current-buffer)))
|
18246
|
2619 (message "Redisplaying annotation...done"))
|
18174
|
2620
|
|
2621 (defun vc-annotate-add-menu ()
|
31380
|
2622 "Add the menu 'Annotate' to the menu bar in VC-Annotate mode."
|
|
2623 (setq vc-annotate-mode-menu (make-sparse-keymap "Annotate"))
|
|
2624 (define-key vc-annotate-mode-map [menu-bar vc-annotate-mode]
|
|
2625 (cons "VC-Annotate" vc-annotate-mode-menu))
|
18174
|
2626 (define-key vc-annotate-mode-menu [default]
|
|
2627 '("Default" . vc-annotate-display-default))
|
|
2628 (let ((menu-elements vc-annotate-menu-elements))
|
|
2629 (while menu-elements
|
|
2630 (let* ((element (car menu-elements))
|
31380
|
2631 (days (round (* element
|
|
2632 (vc-annotate-car-last-cons vc-annotate-color-map)
|
18174
|
2633 0.7585))))
|
|
2634 (setq menu-elements (cdr menu-elements))
|
|
2635 (define-key vc-annotate-mode-menu
|
|
2636 (vector days)
|
|
2637 (cons (format "Span %d days"
|
|
2638 days)
|
|
2639 `(lambda ()
|
|
2640 ,(format "Use colors spanning %d days" days)
|
18246
|
2641 (interactive)
|
|
2642 (message "Redisplaying annotation...")
|
|
2643 (vc-annotate-display
|
|
2644 (get-buffer (buffer-name))
|
31380
|
2645 (vc-annotate-time-span vc-annotate-color-map ,element)
|
|
2646 (vc-annotate-get-backend (current-buffer)))
|
18246
|
2647 (message "Redisplaying annotation...done"))))))))
|
18174
|
2648
|
31380
|
2649
|
|
2650 ;;;; (defun vc-BACKEND-annotate-command (file buffer) ...)
|
|
2651 ;;;; Execute "annotate" on FILE by using `call-process' and insert
|
|
2652 ;;;; the contents in BUFFER.
|
|
2653
|
18174
|
2654 ;;;###autoload
|
33546
|
2655 (defun vc-annotate (prefix)
|
31380
|
2656 "Display the result of the \"Annotate\" command using colors.
|
|
2657 \"Annotate\" is defined by `vc-BACKEND-annotate-command'. New lines
|
33546
|
2658 are displayed in red, old in blue. When given a prefix argument, asks
|
|
2659 for a version to annotate from, and a factor for stretching the time
|
|
2660 scale.
|
18174
|
2661
|
|
2662 `vc-annotate-menu-elements' customizes the menu elements of the
|
|
2663 mode-specific menu. `vc-annotate-color-map' and
|
|
2664 `vc-annotate-very-old-color' defines the mapping of time to
|
|
2665 colors. `vc-annotate-background' specifies the background color."
|
33546
|
2666 (interactive "P")
|
21366
|
2667 (vc-ensure-vc-buffer)
|
31380
|
2668 (let ((temp-buffer-name (concat "*Annotate " (buffer-name) "*"))
|
33546
|
2669 (temp-buffer-show-function 'vc-annotate-display)
|
|
2670 (vc-annotate-version
|
|
2671 (if prefix (read-string
|
|
2672 (format "Annotate from version: (default %s) "
|
|
2673 (vc-workfile-version (buffer-file-name)))
|
|
2674 nil nil (vc-workfile-version (buffer-file-name)))))
|
|
2675 (vc-annotate-ratio
|
|
2676 (if prefix (string-to-number
|
|
2677 (read-string "Annotate ratio: (default 1.0) "
|
|
2678 nil nil "1.0"))))
|
|
2679 (vc-annotate-backend (vc-backend (buffer-file-name))))
|
|
2680 (message "Annotating...")
|
31404
|
2681 (if (not (vc-find-backend-function vc-annotate-backend 'annotate-command))
|
|
2682 (error "Sorry, annotating is not implemented for %s"
|
|
2683 vc-annotate-backend))
|
32344
f91ef1141a75
(with-vc-file, edit-vc-file): Specify `indent-function' property.
Thien-Thi Nguyen <ttn@gnuvola.org>
diff
changeset
|
2684 (with-output-to-temp-buffer temp-buffer-name
|
31380
|
2685 (vc-call-backend vc-annotate-backend 'annotate-command
|
|
2686 (file-name-nondirectory (buffer-file-name))
|
33546
|
2687 (get-buffer temp-buffer-name)
|
|
2688 vc-annotate-version))
|
31380
|
2689 ;; Don't use the temp-buffer-name until the buffer is created
|
|
2690 ;; (only after `with-output-to-temp-buffer'.)
|
31565
|
2691 (setq vc-annotate-buffers
|
31380
|
2692 (append vc-annotate-buffers
|
|
2693 (list (cons (get-buffer temp-buffer-name) vc-annotate-backend)))))
|
18174
|
2694 (message "Annotating... done"))
|
|
2695
|
31380
|
2696
|
20752
|
2697 (defun vc-annotate-car-last-cons (a-list)
|
|
2698 "Return car of last cons in association list A-LIST."
|
|
2699 (if (not (eq nil (cdr a-list)))
|
|
2700 (vc-annotate-car-last-cons (cdr a-list))
|
|
2701 (car (car a-list))))
|
18174
|
2702
|
20752
|
2703 (defun vc-annotate-time-span (a-list span &optional quantize)
|
31565
|
2704 "Apply factor SPAN to the time-span of association list A-LIST.
|
31380
|
2705 Return the new alist.
|
|
2706 Optionally quantize to the factor of QUANTIZE."
|
18174
|
2707 ;; Apply span to each car of every cons
|
31380
|
2708 (if (not (eq nil a-list))
|
20752
|
2709 (append (list (cons (* (car (car a-list)) span)
|
|
2710 (cdr (car a-list))))
|
31380
|
2711 (vc-annotate-time-span (nthcdr (or quantize ; optional
|
|
2712 1) ; Default to cdr
|
20752
|
2713 a-list) span quantize))))
|
18174
|
2714
|
20752
|
2715 (defun vc-annotate-compcar (threshold a-list)
|
31380
|
2716 "Test successive cons cells of association list A-LIST against THRESHOLD.
|
|
2717 Return the first cons cell which car is not less than THRESHOLD,
|
|
2718 nil otherwise"
|
20752
|
2719 (let ((i 1)
|
|
2720 (tmp-cons (car a-list)))
|
|
2721 (while (and tmp-cons (< (car tmp-cons) threshold))
|
|
2722 (setq tmp-cons (car (nthcdr i a-list)))
|
|
2723 (setq i (+ i 1)))
|
|
2724 tmp-cons)) ; Return the appropriate value
|
|
2725
|
18174
|
2726
|
31380
|
2727 ;;;; (defun vc-BACKEND-annotate-difference (point) ...)
|
|
2728 ;;;;
|
|
2729 ;;;; Return the difference between the age of the line at point and
|
|
2730 ;;;; the current time. Return NIL if there is no more comparison to
|
|
2731 ;;;; be made in the buffer. Return value as defined for
|
|
2732 ;;;; `current-time'. You can safely assume that point is placed at
|
|
2733 ;;;; the beginning of each line, starting at `point-min'. The buffer
|
|
2734 ;;;; that point is placed in is the Annotate output, as defined by
|
|
2735 ;;;; the relevant backend.
|
|
2736
|
|
2737 (defun vc-annotate-display (buffer &optional color-map backend)
|
31404
|
2738 "Do the VC-Annotate display in BUFFER using COLOR-MAP.
|
|
2739 The original annotating file is supposed to be handled by BACKEND.
|
|
2740 If BACKEND is NIL, variable VC-ANNOTATE-BACKEND is used instead.
|
|
2741 This function is destructive on VC-ANNOTATE-BACKEND when BACKEND is non-nil."
|
18174
|
2742
|
18246
|
2743 ;; Handle the case of the global variable vc-annotate-ratio being
|
|
2744 ;; set. This variable is used to pass information from function
|
|
2745 ;; vc-annotate since it is not possible to use another parameter
|
31380
|
2746 ;; (see temp-buffer-show-function).
|
18174
|
2747 (if (and (not color-map) vc-annotate-ratio)
|
18246
|
2748 ;; This will only be true if called from vc-annotate with ratio
|
|
2749 ;; being non-nil.
|
|
2750 (setq color-map (vc-annotate-time-span vc-annotate-color-map
|
|
2751 vc-annotate-ratio)))
|
31380
|
2752 (set-buffer buffer)
|
|
2753 (display-buffer buffer)
|
|
2754 (if (not vc-annotate-mode) ; Turn on vc-annotate-mode if not done
|
|
2755 (vc-annotate-mode))
|
|
2756 (goto-char (point-min)) ; Position at the top of the buffer.
|
|
2757 ;; Delete old overlays
|
|
2758 (mapcar
|
|
2759 (lambda (overlay)
|
|
2760 (if (overlay-get overlay 'vc-annotation)
|
|
2761 (delete-overlay overlay)))
|
|
2762 (overlays-in (point-min) (point-max)))
|
|
2763 (goto-char (point-min)) ; Position at the top of the buffer.
|
|
2764
|
|
2765 (if backend (setq vc-annotate-backend backend)) ; Destructive on `vc-annotate-backend'
|
18174
|
2766
|
31380
|
2767 (let ((difference (vc-call-backend vc-annotate-backend 'annotate-difference (point))))
|
|
2768 (while difference
|
|
2769 (let*
|
|
2770 ((color (or (vc-annotate-compcar
|
|
2771 difference (or color-map vc-annotate-color-map))
|
|
2772 (cons nil vc-annotate-very-old-color)))
|
|
2773 ;; substring from index 1 to remove any leading `#' in the name
|
|
2774 (face-name (concat "vc-annotate-face-" (substring (cdr color) 1)))
|
|
2775 ;; Make the face if not done.
|
|
2776 (face (or (intern-soft face-name)
|
|
2777 (let ((tmp-face (make-face (intern face-name))))
|
|
2778 (set-face-foreground tmp-face (cdr color))
|
|
2779 (if vc-annotate-background
|
|
2780 (set-face-background tmp-face vc-annotate-background))
|
|
2781 tmp-face))) ; Return the face
|
|
2782 (point (point))
|
|
2783 overlay)
|
20752
|
2784 (forward-line 1)
|
24139
2b3e32c0fc18
(vc-annotate-display): Delete old overlays. Fix check for major-mode.
André Spiegel <spiegel@gnu.org>
diff
changeset
|
2785 (setq overlay (make-overlay point (point)))
|
2b3e32c0fc18
(vc-annotate-display): Delete old overlays. Fix check for major-mode.
André Spiegel <spiegel@gnu.org>
diff
changeset
|
2786 (overlay-put overlay 'face face)
|
31380
|
2787 (overlay-put overlay 'vc-annotation t))
|
|
2788 (setq difference (vc-call-backend vc-annotate-backend 'annotate-difference (point))))))
|
20752
|
2789
|
18174
|
2790
|
11597
|
2791 ;; Collect back-end-dependent stuff here
|
904
|
2792
|
31380
|
2793 (defalias 'vc-default-logentry-check 'ignore)
|
11597
|
2794
|
904
|
2795 (defun vc-check-headers ()
|
|
2796 "Check if the current file has any headers in it."
|
|
2797 (interactive)
|
31380
|
2798 (vc-call-backend (vc-backend buffer-file-name) 'check-headers))
|
904
|
2799
|
33562
|
2800 (defun vc-default-check-headers (backend)
|
|
2801 "Default implementation of check-headers; always returns nil."
|
|
2802 nil)
|
|
2803
|
904
|
2804 ;; Back-end-dependent stuff ends here.
|
|
2805
|
|
2806 ;; Set up key bindings for use while editing log messages
|
|
2807
|
31404
|
2808 (define-derived-mode vc-log-mode text-mode "VC-Log"
|
31380
|
2809 "Major mode for editing VC log entries.
|
904
|
2810 These bindings are added to the global keymap when you enter this mode:
|
|
2811 \\[vc-next-action] perform next logical version-control operation on current file
|
31380
|
2812 \\[vc-register] register current file
|
904
|
2813 \\[vc-toggle-read-only] like next-action, but won't register files
|
|
2814 \\[vc-insert-headers] insert version-control headers in current file
|
|
2815 \\[vc-print-log] display change history of current file
|
|
2816 \\[vc-revert-buffer] revert buffer to latest version
|
|
2817 \\[vc-cancel-version] undo latest checkin
|
|
2818 \\[vc-diff] show diffs between file versions
|
4725
|
2819 \\[vc-version-other-window] visit old version in another window
|
904
|
2820 \\[vc-directory] show all files locked by any user in or below .
|
31380
|
2821 \\[vc-annotate] colorful display of the cvs annotate command
|
904
|
2822 \\[vc-update-change-log] add change log entry from recent checkins
|
|
2823
|
|
2824 While you are entering a change log message for a version, the following
|
|
2825 additional bindings will be in effect.
|
|
2826
|
|
2827 \\[vc-finish-logentry] proceed with check in, ending log message entry
|
|
2828
|
|
2829 Whenever you do a checkin, your log comment is added to a ring of
|
|
2830 saved comments. These can be recalled as follows:
|
|
2831
|
|
2832 \\[vc-next-comment] replace region with next message in comment ring
|
|
2833 \\[vc-previous-comment] replace region with previous message in comment ring
|
2580
a66f7ed76416
(vc-diff): Get proper error message when you run this with no prefix
Eric S. Raymond <esr@snark.thyrsus.com>
diff
changeset
|
2834 \\[vc-comment-search-reverse] search backward for regexp in the comment ring
|
a66f7ed76416
(vc-diff): Get proper error message when you run this with no prefix
Eric S. Raymond <esr@snark.thyrsus.com>
diff
changeset
|
2835 \\[vc-comment-search-forward] search backward for regexp in the comment ring
|
904
|
2836
|
31380
|
2837 Entry to the change-log submode calls the value of `text-mode-hook', then
|
|
2838 the value of `vc-log-mode-hook'.
|
904
|
2839
|
|
2840 Global user options:
|
31380
|
2841 `vc-initial-comment' If non-nil, require user to enter a change
|
904
|
2842 comment upon first checkin of the file.
|
|
2843
|
31380
|
2844 `vc-keep-workfiles' Non-nil value prevents workfiles from being
|
904
|
2845 deleted when changes are checked in
|
|
2846
|
33548
714a4c4917cd
(vc-revert-buffer): Ask for confirmation if file seems up-to-date.
André Spiegel <spiegel@gnu.org>
diff
changeset
|
2847 `vc-suppress-confirm' Suppresses some confirmation prompts.
|
904
|
2848
|
31380
|
2849 vc-BACKEND-header Which keywords to insert when adding headers
|
904
|
2850 with \\[vc-insert-headers]. Defaults to
|
31380
|
2851 '(\"\%\W\%\") under SCCS, '(\"\$Id\$\") under
|
9249
|
2852 RCS and CVS.
|
904
|
2853
|
31380
|
2854 `vc-static-header-alist' By default, version headers inserted in C files
|
904
|
2855 get stuffed in a static string area so that
|
9249
|
2856 ident(RCS/CVS) or what(SCCS) can see them in
|
|
2857 the compiled object code. You can override
|
|
2858 this by setting this variable to nil, or change
|
904
|
2859 the header template by changing it.
|
|
2860
|
31380
|
2861 `vc-command-messages' if non-nil, display run messages from the
|
904
|
2862 actual version-control utilities (this is
|
|
2863 intended primarily for people hacking vc
|
31404
|
2864 itself)."
|
|
2865 (make-local-variable 'vc-comment-ring-index))
|
904
|
2866
|
31380
|
2867 (defun vc-log-edit (file)
|
31404
|
2868 "Set up `log-edit' for use with VC on FILE.
|
|
2869 If `log-edit' is not available, resort to `vc-log-mode'."
|
|
2870 (setq default-directory
|
|
2871 (if file (file-name-directory file)
|
|
2872 (with-current-buffer vc-parent-buffer default-directory)))
|
|
2873 (if (fboundp 'log-edit)
|
|
2874 (log-edit 'vc-finish-logentry nil
|
|
2875 (if file `(lambda () ',(list (file-name-nondirectory file)))
|
|
2876 ;; If FILE is nil, we were called from vc-dired.
|
|
2877 (lambda ()
|
|
2878 (with-current-buffer vc-parent-buffer
|
|
2879 (dired-get-marked-files t)))))
|
|
2880 (vc-log-mode))
|
31380
|
2881 (set (make-local-variable 'vc-log-file) file)
|
|
2882 (make-local-variable 'vc-log-version)
|
31404
|
2883 (set-buffer-modified-p nil)
|
31380
|
2884 (setq buffer-file-name nil))
|
904
|
2885
|
|
2886 ;;; These things should probably be generally available
|
|
2887
|
13012
|
2888 (defun vc-file-tree-walk (dirname func &rest args)
|
|
2889 "Walk recursively through DIRNAME.
|
31380
|
2890 Invoke FUNC f ARGS on each VC-managed file f underneath it."
|
13012
|
2891 (vc-file-tree-walk-internal (expand-file-name dirname) func args)
|
|
2892 (message "Traversing directory %s...done" dirname))
|
2054
|
2893
|
|
2894 (defun vc-file-tree-walk-internal (file func args)
|
|
2895 (if (not (file-directory-p file))
|
31380
|
2896 (if (vc-backend file) (apply func file args))
|
12311
|
2897 (message "Traversing directory %s..." (abbreviate-file-name file))
|
2054
|
2898 (let ((dir (file-name-as-directory file)))
|
|
2899 (mapcar
|
31380
|
2900 (lambda (f) (or
|
|
2901 (string-equal f ".")
|
|
2902 (string-equal f "..")
|
|
2903 (member f vc-directory-exclusion-list)
|
|
2904 (let ((dirf (expand-file-name f dir)))
|
|
2905 (or
|
|
2906 (file-symlink-p dirf);; Avoid possible loops
|
|
2907 (vc-file-tree-walk-internal dirf func args)))))
|
2054
|
2908 (directory-files dir)))))
|
904
|
2909
|
|
2910 (provide 'vc)
|
|
2911
|
|
2912 ;;; DEVELOPER'S NOTES ON CONCURRENCY PROBLEMS IN THIS CODE
|
|
2913 ;;;
|
|
2914 ;;; These may be useful to anyone who has to debug or extend the package.
|
11597
|
2915 ;;; (Note that this information corresponds to versions 5.x. Some of it
|
|
2916 ;;; might have been invalidated by the additions to support branching
|
|
2917 ;;; and RCS keyword lookup. AS, 1995/03/24)
|
31380
|
2918 ;;;
|
904
|
2919 ;;; A fundamental problem in VC is that there are time windows between
|
|
2920 ;;; vc-next-action's computations of the file's version-control state and
|
|
2921 ;;; the actions that change it. This is a window open to lossage in a
|
|
2922 ;;; multi-user environment; someone else could nip in and change the state
|
|
2923 ;;; of the master during it.
|
31380
|
2924 ;;;
|
904
|
2925 ;;; The performance problem is that rlog/prs calls are very expensive; we want
|
|
2926 ;;; to avoid them as much as possible.
|
31380
|
2927 ;;;
|
904
|
2928 ;;; ANALYSIS:
|
31380
|
2929 ;;;
|
904
|
2930 ;;; The performance problem, it turns out, simplifies in practice to the
|
31380
|
2931 ;;; problem of making vc-state fast. The two other functions that call
|
904
|
2932 ;;; prs/rlog will not be so commonly used that the slowdown is a problem; one
|
|
2933 ;;; makes snapshots, the other deletes the calling user's last change in the
|
|
2934 ;;; master.
|
31380
|
2935 ;;;
|
904
|
2936 ;;; The race condition implies that we have to either (a) lock the master
|
|
2937 ;;; during the entire execution of vc-next-action, or (b) detect and
|
|
2938 ;;; recover from errors resulting from dispatch on an out-of-date state.
|
31380
|
2939 ;;;
|
14040
|
2940 ;;; Alternative (a) appears to be infeasible. The problem is that we can't
|
904
|
2941 ;;; guarantee that the lock will ever be removed. Suppose a user starts a
|
|
2942 ;;; checkin, the change message buffer pops up, and the user, having wandered
|
|
2943 ;;; off to do something else, simply forgets about it?
|
31380
|
2944 ;;;
|
904
|
2945 ;;; Alternative (b), on the other hand, works well with a cheap way to speed up
|
31380
|
2946 ;;; vc-state. Usually, if a file is registered, we can read its locked/
|
904
|
2947 ;;; unlocked state and its current owner from its permissions.
|
31380
|
2948 ;;;
|
904
|
2949 ;;; This shortcut will fail if someone has manually changed the workfile's
|
|
2950 ;;; permissions; also if developers are munging the workfile in several
|
|
2951 ;;; directories, with symlinks to a master (in this latter case, the
|
|
2952 ;;; permissions shortcut will fail to detect a lock asserted from another
|
|
2953 ;;; directory).
|
31380
|
2954 ;;;
|
904
|
2955 ;;; Note that these cases correspond exactly to the errors which could happen
|
|
2956 ;;; because of a competing checkin/checkout race in between two instances of
|
|
2957 ;;; vc-next-action.
|
31380
|
2958 ;;;
|
904
|
2959 ;;; For VC's purposes, a workfile/master pair may have the following states:
|
31380
|
2960 ;;;
|
904
|
2961 ;;; A. Unregistered. There is a workfile, there is no master.
|
31380
|
2962 ;;;
|
904
|
2963 ;;; B. Registered and not locked by anyone.
|
31380
|
2964 ;;;
|
904
|
2965 ;;; C. Locked by calling user and unchanged.
|
31380
|
2966 ;;;
|
904
|
2967 ;;; D. Locked by the calling user and changed.
|
31380
|
2968 ;;;
|
904
|
2969 ;;; E. Locked by someone other than the calling user.
|
31380
|
2970 ;;;
|
904
|
2971 ;;; This makes for 25 states and 20 error conditions. Here's the matrix:
|
31380
|
2972 ;;;
|
904
|
2973 ;;; VC's idea of state
|
|
2974 ;;; |
|
|
2975 ;;; V Actual state RCS action SCCS action Effect
|
|
2976 ;;; A B C D E
|
|
2977 ;;; A . 1 2 3 4 ci -u -t- admin -fb -i<file> initial admin
|
|
2978 ;;; B 5 . 6 7 8 co -l get -e checkout
|
|
2979 ;;; C 9 10 . 11 12 co -u unget; get revert
|
|
2980 ;;; D 13 14 15 . 16 ci -u -m<comment> delta -y<comment>; get checkin
|
12943
10d0f42db2da
(vc-directory): Kill existing vc-dired buffers for this directory.
André Spiegel <spiegel@gnu.org>
diff
changeset
|
2981 ;;; E 17 18 19 20 . rcs -u -M -l unget -n ; get -g steal lock
|
31380
|
2982 ;;;
|
904
|
2983 ;;; All commands take the master file name as a last argument (not shown).
|
31380
|
2984 ;;;
|
904
|
2985 ;;; In the discussion below, a "self-race" is a pathological situation in
|
|
2986 ;;; which VC operations are being attempted simultaneously by two or more
|
|
2987 ;;; Emacsen running under the same username.
|
31380
|
2988 ;;;
|
904
|
2989 ;;; The vc-next-action code has the following windows:
|
31380
|
2990 ;;;
|
904
|
2991 ;;; Window P:
|
|
2992 ;;; Between the check for existence of a master file and the call to
|
|
2993 ;;; admin/checkin in vc-buffer-admin (apparent state A). This window may
|
|
2994 ;;; never close if the initial-comment feature is on.
|
31380
|
2995 ;;;
|
904
|
2996 ;;; Window Q:
|
|
2997 ;;; Between the call to vc-workfile-unchanged-p in and the immediately
|
|
2998 ;;; following revert (apparent state C).
|
31380
|
2999 ;;;
|
904
|
3000 ;;; Window R:
|
|
3001 ;;; Between the call to vc-workfile-unchanged-p in and the following
|
|
3002 ;;; checkin (apparent state D). This window may never close.
|
31380
|
3003 ;;;
|
904
|
3004 ;;; Window S:
|
|
3005 ;;; Between the unlock and the immediately following checkout during a
|
|
3006 ;;; revert operation (apparent state C). Included in window Q.
|
31380
|
3007 ;;;
|
904
|
3008 ;;; Window T:
|
31380
|
3009 ;;; Between vc-state and the following checkout (apparent state B).
|
|
3010 ;;;
|
904
|
3011 ;;; Window U:
|
31380
|
3012 ;;; Between vc-state and the following revert (apparent state C).
|
904
|
3013 ;;; Includes windows Q and S.
|
31380
|
3014 ;;;
|
904
|
3015 ;;; Window V:
|
31380
|
3016 ;;; Between vc-state and the following checkin (apparent state
|
904
|
3017 ;;; D). This window may never be closed if the user fails to complete the
|
|
3018 ;;; checkin message. Includes window R.
|
31380
|
3019 ;;;
|
904
|
3020 ;;; Window W:
|
31380
|
3021 ;;; Between vc-state and the following steal-lock (apparent
|
2750
|
3022 ;;; state E). This window may never close if the user fails to complete
|
904
|
3023 ;;; the steal-lock message. Includes window X.
|
31380
|
3024 ;;;
|
904
|
3025 ;;; Window X:
|
|
3026 ;;; Between the unlock and the immediately following re-lock during a
|
31380
|
3027 ;;; steal-lock operation (apparent state E). This window may never close
|
904
|
3028 ;;; if the user fails to complete the steal-lock message.
|
31380
|
3029 ;;;
|
904
|
3030 ;;; Errors:
|
31380
|
3031 ;;;
|
904
|
3032 ;;; Apparent state A ---
|
|
3033 ;;;
|
|
3034 ;;; 1. File looked unregistered but is actually registered and not locked.
|
31380
|
3035 ;;;
|
904
|
3036 ;;; Potential cause: someone else's admin during window P, with
|
|
3037 ;;; caller's admin happening before their checkout.
|
31380
|
3038 ;;;
|
12943
10d0f42db2da
(vc-directory): Kill existing vc-dired buffers for this directory.
André Spiegel <spiegel@gnu.org>
diff
changeset
|
3039 ;;; RCS: Prior to version 5.6.4, ci fails with message
|
10d0f42db2da
(vc-directory): Kill existing vc-dired buffers for this directory.
André Spiegel <spiegel@gnu.org>
diff
changeset
|
3040 ;;; "no lock set by <user>". From 5.6.4 onwards, VC uses the new
|
10d0f42db2da
(vc-directory): Kill existing vc-dired buffers for this directory.
André Spiegel <spiegel@gnu.org>
diff
changeset
|
3041 ;;; ci -i option and the message is "<file>,v: already exists".
|
904
|
3042 ;;; SCCS: admin will fail with error (ad19).
|
31380
|
3043 ;;;
|
904
|
3044 ;;; We can let these errors be passed up to the user.
|
31380
|
3045 ;;;
|
904
|
3046 ;;; 2. File looked unregistered but is actually locked by caller, unchanged.
|
31380
|
3047 ;;;
|
904
|
3048 ;;; Potential cause: self-race during window P.
|
31380
|
3049 ;;;
|
12943
10d0f42db2da
(vc-directory): Kill existing vc-dired buffers for this directory.
André Spiegel <spiegel@gnu.org>
diff
changeset
|
3050 ;;; RCS: Prior to version 5.6.4, reverts the file to the last saved
|
10d0f42db2da
(vc-directory): Kill existing vc-dired buffers for this directory.
André Spiegel <spiegel@gnu.org>
diff
changeset
|
3051 ;;; version and unlocks it. From 5.6.4 onwards, VC uses the new
|
10d0f42db2da
(vc-directory): Kill existing vc-dired buffers for this directory.
André Spiegel <spiegel@gnu.org>
diff
changeset
|
3052 ;;; ci -i option, failing with message "<file>,v: already exists".
|
904
|
3053 ;;; SCCS: will fail with error (ad19).
|
31380
|
3054 ;;;
|
904
|
3055 ;;; Either of these consequences is acceptable.
|
31380
|
3056 ;;;
|
904
|
3057 ;;; 3. File looked unregistered but is actually locked by caller, changed.
|
31380
|
3058 ;;;
|
904
|
3059 ;;; Potential cause: self-race during window P.
|
31380
|
3060 ;;;
|
|
3061 ;;; RCS: Prior to version 5.6.4, VC registers the caller's workfile as
|
|
3062 ;;; a delta with a null change comment (the -t- switch will be
|
12943
10d0f42db2da
(vc-directory): Kill existing vc-dired buffers for this directory.
André Spiegel <spiegel@gnu.org>
diff
changeset
|
3063 ;;; ignored). From 5.6.4 onwards, VC uses the new ci -i option,
|
10d0f42db2da
(vc-directory): Kill existing vc-dired buffers for this directory.
André Spiegel <spiegel@gnu.org>
diff
changeset
|
3064 ;;; failing with message "<file>,v: already exists".
|
904
|
3065 ;;; SCCS: will fail with error (ad19).
|
31380
|
3066 ;;;
|
904
|
3067 ;;; 4. File looked unregistered but is locked by someone else.
|
31380
|
3068 ;;;
|
904
|
3069 ;;; Potential cause: someone else's admin during window P, with
|
|
3070 ;;; caller's admin happening *after* their checkout.
|
31380
|
3071 ;;;
|
|
3072 ;;; RCS: Prior to version 5.6.4, ci fails with a
|
|
3073 ;;; "no lock set by <user>" message. From 5.6.4 onwards,
|
|
3074 ;;; VC uses the new ci -i option, failing with message
|
12943
10d0f42db2da
(vc-directory): Kill existing vc-dired buffers for this directory.
André Spiegel <spiegel@gnu.org>
diff
changeset
|
3075 ;;; "<file>,v: already exists".
|
904
|
3076 ;;; SCCS: will fail with error (ad19).
|
31380
|
3077 ;;;
|
904
|
3078 ;;; We can let these errors be passed up to the user.
|
31380
|
3079 ;;;
|
904
|
3080 ;;; Apparent state B ---
|
|
3081 ;;;
|
|
3082 ;;; 5. File looked registered and not locked, but is actually unregistered.
|
31380
|
3083 ;;;
|
904
|
3084 ;;; Potential cause: master file got nuked during window P.
|
31380
|
3085 ;;;
|
904
|
3086 ;;; RCS: will fail with "RCS/<file>: No such file or directory"
|
|
3087 ;;; SCCS: will fail with error ut4.
|
31380
|
3088 ;;;
|
904
|
3089 ;;; We can let these errors be passed up to the user.
|
31380
|
3090 ;;;
|
904
|
3091 ;;; 6. File looked registered and not locked, but is actually locked by the
|
|
3092 ;;; calling user and unchanged.
|
31380
|
3093 ;;;
|
904
|
3094 ;;; Potential cause: self-race during window T.
|
31380
|
3095 ;;;
|
904
|
3096 ;;; RCS: in the same directory as the previous workfile, co -l will fail
|
|
3097 ;;; with "co error: writable foo exists; checkout aborted". In any other
|
|
3098 ;;; directory, checkout will succeed.
|
|
3099 ;;; SCCS: will fail with ge17.
|
31380
|
3100 ;;;
|
904
|
3101 ;;; Either of these consequences is acceptable.
|
31380
|
3102 ;;;
|
904
|
3103 ;;; 7. File looked registered and not locked, but is actually locked by the
|
|
3104 ;;; calling user and changed.
|
31380
|
3105 ;;;
|
904
|
3106 ;;; As case 6.
|
31380
|
3107 ;;;
|
904
|
3108 ;;; 8. File looked registered and not locked, but is actually locked by another
|
|
3109 ;;; user.
|
31380
|
3110 ;;;
|
904
|
3111 ;;; Potential cause: someone else checks it out during window T.
|
31380
|
3112 ;;;
|
904
|
3113 ;;; RCS: co error: revision 1.3 already locked by <user>
|
|
3114 ;;; SCCS: fails with ge4 (in directory) or ut7 (outside it).
|
31380
|
3115 ;;;
|
904
|
3116 ;;; We can let these errors be passed up to the user.
|
31380
|
3117 ;;;
|
904
|
3118 ;;; Apparent state C ---
|
|
3119 ;;;
|
|
3120 ;;; 9. File looks locked by calling user and unchanged, but is unregistered.
|
31380
|
3121 ;;;
|
904
|
3122 ;;; As case 5.
|
31380
|
3123 ;;;
|
904
|
3124 ;;; 10. File looks locked by calling user and unchanged, but is actually not
|
|
3125 ;;; locked.
|
31380
|
3126 ;;;
|
904
|
3127 ;;; Potential cause: a self-race in window U, or by the revert's
|
|
3128 ;;; landing during window X of some other user's steal-lock or window S
|
|
3129 ;;; of another user's revert.
|
31380
|
3130 ;;;
|
904
|
3131 ;;; RCS: succeeds, refreshing the file from the identical version in
|
|
3132 ;;; the master.
|
|
3133 ;;; SCCS: fails with error ut4 (p file nonexistent).
|
|
3134 ;;;
|
|
3135 ;;; Either of these consequences is acceptable.
|
31380
|
3136 ;;;
|
904
|
3137 ;;; 11. File is locked by calling user. It looks unchanged, but is actually
|
|
3138 ;;; changed.
|
31380
|
3139 ;;;
|
904
|
3140 ;;; Potential cause: the file would have to be touched by a self-race
|
|
3141 ;;; during window Q.
|
31380
|
3142 ;;;
|
904
|
3143 ;;; The revert will succeed, removing whatever changes came with
|
|
3144 ;;; the touch. It is theoretically possible that work could be lost.
|
31380
|
3145 ;;;
|
904
|
3146 ;;; 12. File looks like it's locked by the calling user and unchanged, but
|
|
3147 ;;; it's actually locked by someone else.
|
31380
|
3148 ;;;
|
904
|
3149 ;;; Potential cause: a steal-lock in window V.
|
31380
|
3150 ;;;
|
904
|
3151 ;;; RCS: co error: revision <rev> locked by <user>; use co -r or rcs -u
|
|
3152 ;;; SCCS: fails with error un2
|
31380
|
3153 ;;;
|
904
|
3154 ;;; We can pass these errors up to the user.
|
31380
|
3155 ;;;
|
904
|
3156 ;;; Apparent state D ---
|
|
3157 ;;;
|
|
3158 ;;; 13. File looks like it's locked by the calling user and changed, but it's
|
|
3159 ;;; actually unregistered.
|
31380
|
3160 ;;;
|
904
|
3161 ;;; Potential cause: master file got nuked during window P.
|
31380
|
3162 ;;;
|
|
3163 ;;; RCS: Prior to version 5.6.4, checks in the user's version as an
|
12943
10d0f42db2da
(vc-directory): Kill existing vc-dired buffers for this directory.
André Spiegel <spiegel@gnu.org>
diff
changeset
|
3164 ;;; initial delta. From 5.6.4 onwards, VC uses the new ci -j
|
10d0f42db2da
(vc-directory): Kill existing vc-dired buffers for this directory.
André Spiegel <spiegel@gnu.org>
diff
changeset
|
3165 ;;; option, failing with message "no such file or directory".
|
904
|
3166 ;;; SCCS: will fail with error ut4.
|
|
3167 ;;;
|
12943
10d0f42db2da
(vc-directory): Kill existing vc-dired buffers for this directory.
André Spiegel <spiegel@gnu.org>
diff
changeset
|
3168 ;;; This case is kind of nasty. Under RCS prior to version 5.6.4,
|
10d0f42db2da
(vc-directory): Kill existing vc-dired buffers for this directory.
André Spiegel <spiegel@gnu.org>
diff
changeset
|
3169 ;;; VC may fail to detect the loss of previous version information.
|
31380
|
3170 ;;;
|
904
|
3171 ;;; 14. File looks like it's locked by the calling user and changed, but it's
|
|
3172 ;;; actually unlocked.
|
31380
|
3173 ;;;
|
904
|
3174 ;;; Potential cause: self-race in window V, or the checkin happening
|
|
3175 ;;; during the window X of someone else's steal-lock or window S of
|
|
3176 ;;; someone else's revert.
|
31380
|
3177 ;;;
|
904
|
3178 ;;; RCS: ci will fail with "no lock set by <user>".
|
|
3179 ;;; SCCS: delta will fail with error ut4.
|
31380
|
3180 ;;;
|
904
|
3181 ;;; 15. File looks like it's locked by the calling user and changed, but it's
|
|
3182 ;;; actually locked by the calling user and unchanged.
|
31380
|
3183 ;;;
|
904
|
3184 ;;; Potential cause: another self-race --- a whole checkin/checkout
|
|
3185 ;;; sequence by the calling user would have to land in window R.
|
31380
|
3186 ;;;
|
904
|
3187 ;;; SCCS: checks in a redundant delta and leaves the file unlocked as usual.
|
|
3188 ;;; RCS: reverts to the file state as of the second user's checkin, leaving
|
|
3189 ;;; the file unlocked.
|
|
3190 ;;;
|
|
3191 ;;; It is theoretically possible that work could be lost under RCS.
|
31380
|
3192 ;;;
|
904
|
3193 ;;; 16. File looks like it's locked by the calling user and changed, but it's
|
|
3194 ;;; actually locked by a different user.
|
31380
|
3195 ;;;
|
904
|
3196 ;;; RCS: ci error: no lock set by <user>
|
|
3197 ;;; SCCS: unget will fail with error un2
|
31380
|
3198 ;;;
|
904
|
3199 ;;; We can pass these errors up to the user.
|
31380
|
3200 ;;;
|
904
|
3201 ;;; Apparent state E ---
|
|
3202 ;;;
|
|
3203 ;;; 17. File looks like it's locked by some other user, but it's actually
|
|
3204 ;;; unregistered.
|
31380
|
3205 ;;;
|
904
|
3206 ;;; As case 13.
|
31380
|
3207 ;;;
|
904
|
3208 ;;; 18. File looks like it's locked by some other user, but it's actually
|
|
3209 ;;; unlocked.
|
31380
|
3210 ;;;
|
904
|
3211 ;;; Potential cause: someone released a lock during window W.
|
31380
|
3212 ;;;
|
904
|
3213 ;;; RCS: The calling user will get the lock on the file.
|
|
3214 ;;; SCCS: unget -n will fail with cm4.
|
31380
|
3215 ;;;
|
904
|
3216 ;;; Either of these consequences will be OK.
|
31380
|
3217 ;;;
|
904
|
3218 ;;; 19. File looks like it's locked by some other user, but it's actually
|
|
3219 ;;; locked by the calling user and unchanged.
|
31380
|
3220 ;;;
|
904
|
3221 ;;; Potential cause: the other user relinquishing a lock followed by
|
|
3222 ;;; a self-race, both in window W.
|
31380
|
3223 ;;;
|
904
|
3224 ;;; Under both RCS and SCCS, both unlock and lock will succeed, making
|
|
3225 ;;; the sequence a no-op.
|
31380
|
3226 ;;;
|
904
|
3227 ;;; 20. File looks like it's locked by some other user, but it's actually
|
|
3228 ;;; locked by the calling user and changed.
|
31380
|
3229 ;;;
|
904
|
3230 ;;; As case 19.
|
31380
|
3231 ;;;
|
904
|
3232 ;;; PROBLEM CASES:
|
31380
|
3233 ;;;
|
904
|
3234 ;;; In order of decreasing severity:
|
31380
|
3235 ;;;
|
12943
10d0f42db2da
(vc-directory): Kill existing vc-dired buffers for this directory.
André Spiegel <spiegel@gnu.org>
diff
changeset
|
3236 ;;; Cases 11 and 15 are the only ones that potentially lose work.
|
904
|
3237 ;;; They would require a self-race for this to happen.
|
31380
|
3238 ;;;
|
904
|
3239 ;;; Case 13 in RCS loses information about previous deltas, retaining
|
|
3240 ;;; only the information in the current workfile. This can only happen
|
|
3241 ;;; if the master file gets nuked in window P.
|
31380
|
3242 ;;;
|
904
|
3243 ;;; Case 3 in RCS and case 15 under SCCS insert a redundant delta with
|
|
3244 ;;; no change comment in the master. This would require a self-race in
|
|
3245 ;;; window P or R respectively.
|
31380
|
3246 ;;;
|
904
|
3247 ;;; Cases 2, 10, 19 and 20 do extra work, but make no changes.
|
31380
|
3248 ;;;
|
904
|
3249 ;;; Unfortunately, it appears to me that no recovery is possible in these
|
|
3250 ;;; cases. They don't yield error messages, so there's no way to tell that
|
|
3251 ;;; a race condition has occurred.
|
31380
|
3252 ;;;
|
904
|
3253 ;;; All other cases don't change either the workfile or the master, and
|
|
3254 ;;; trigger command errors which the user will see.
|
31380
|
3255 ;;;
|
904
|
3256 ;;; Thus, there is no explicit recovery code.
|
|
3257
|
|
3258 ;;; vc.el ends here
|