*cough, cough*
For those who don't know, Jim designed a lot of Subversion, in
particular the repository, and wrote the first libsvn_fs, much of
which still remains.  Then he had to go back to his day job as a GDB
hacker at RedHat, which is why you haven't seen him much on this list
recently.
He also invented the word "baton" :-).
Anyway, three cheers for Emacs VC support!  Especially since what's
currently in tools/dev/svn-dev.el doesn't try to integrate with VC
yet.  I sense a code merge in the near future...
Branko will be pleased to note that Jim runs `svn st' under the hood.
(Branko doesn't like the idea of Emacs reading the .svn area like it
owns the place :-) ).
-K
Jim Blandy <jimb@red-bean.com> writes:
> Ben said he'd be happy just to have revision numbers in his modeline.
> This is enough to do that, with ':' for locally modified files vs.
> '-' for unmodified files, but not much else.  :)
> 
> If anyone is interested, maybe this could find a place in the
> Subversion tree!
> 
> ;;;; vc-svn.el --- a VC backend for Subversion
> ;;;; Jim Blandy <jimb@red-bean.com> --- July 2002
> 
> ;;; To do:
> ;;; Provide more of the optional VC backend functions: 
> ;;; - vc-svn-dir-state
> ;;;
> ;;; Some are unnecessary; for example,
> ;;; `vc-BACKEND-workfile-unchanged-p' defaults to calling the full
> ;;; `vc-BACKEND-diff' function, which is actually fine for Subversion,
> ;;; since it has a copy of the base revision cached locally.
> ;;; 
> ;;; VC passes the vc-svn-register function a COMMENT argument, which
> ;;; is like the file description in CVS and RCS.  Could we store the
> ;;; COMMENT as a Subversion property?  Would that show up in fancy DAV
> ;;; web folder displays, or would it just languish in obscurity, the
> ;;; way CVS and RCS descriptions do?
> 
> (add-value 'vc-handled-backends 'SVN)
> 
> (defvar vc-svn-program-name "svn"
>   "*Name of Subversion client program, for use by Emacs's VC package.")
> 
> 
> (defun vc-svn-registered (file)
>   "Return true if FILE is registered under Subversion."
>   ;; First, a quick false positive test: is there a `.svn/entries' file?
>   (and (file-exists-p (expand-file-name ".svn/entries"
>                                         (file-name-directory file)))
>        (not (null (vc-svn-run-status file)))))
> 
> 
> (put 'vc-svn-with-output-buffer 'lisp-indent-function 0)
> (defmacro vc-svn-with-output-buffer (&rest body)
>   "Save excursion, switch to buffer ` *Subversion Output*', and erase it."
>   `(save-excursion
>      ;; Let's not delete this buffer when we're done --- leave
>      ;; it around for debugging.
>      (set-buffer (get-buffer-create " *Subversion Output*"))
>      (erase-buffer)
>      ,@body))
> 
> 
> (defun vc-svn-run-status (file &optional update)
>   "Run `svn status -v' on FILE, and return the result.
> If optional arg UPDATE is true, pass the `-u' flag to check against
> the repository, across the network.
> See `vc-svn-parse-status' for a description of the result."
>   (vc-svn-with-output-buffer
>     (let ((status (apply 'call-process vc-svn-program-name nil t nil
>                          (append '("status" "-v")
>                                  (if update '("-u") '())
>                                  (list file)))))
>       (goto-char (point-min))
>       (if (not (zerop status))
>           ;; If you ask for the status of a file that isn't even in a
>           ;; Subversion-controlled directory, then Subversion exits with
>           ;; this error.
>           (if (or (looking-at "\\(.*\n\\)*.*is not a working copy directory")
>                   (looking-at "\\(.*\n\\)*.*is not a versioned resource"))
>               nil
>             ;; Other errors we should actually report to the user.
>             (display-buffer (current-buffer))
>             (error "Error running Subversion to check status of `%s'"
>                    (file-name-nondirectory file)))
> 
>         ;; Otherwise, we've got valid status output in the buffer, so
>         ;; just parse that.
>         (vc-svn-parse-status)))))
> 
> 
> (defun vc-svn-parse-status ()
>   "Parse the output from `svn status -v' at point.
> We return nil for a file not under Subversion's control,
> or (STATE LOCAL CHANGED) for files that are, where:
> STATE is the file's VC state (see the documentation for `vc-state'),
> LOCAL is the base revision in the working copy, and
> CHANGED is the last revision in which it was changed.  If we passed
>   `svn status' the `-u' flag, then CHANGED might be greater than LOCAL."
>   (let ((state (vc-svn-parse-state-only)))
>     (and state
>          (if (looking-at
>               "\\S-+\\s-+\\(\\*\\s-+\\)?\\([0-9]+\\)\\s-+\\([0-9]+\\)")
>              (list state
>                    (string-to-number (match-string 2))
>                    (string-to-number (match-string 3)))
>            (error "Couldn't parse output from `svn status -v'")))))
> 
> 
> (defun vc-svn-parse-state-only ()
>   "Parse the output from `svn status -v' at point, and return a state.
> The documentation for the function `vc-state' describes the possible values."
>   (cond
>    ;; Be careful --- some of the later clauses here could yield false
>    ;; positives, if the clauses preceding them didn't screen those
>    ;; out.  Making a pattern more selective could break something.
> 
>    ;; nil                 The given file is not under version control.
>    ((looking-at "\\?") nil)
> 
>    ;; 'needs-patch        The file has not been edited by the
>    ;;                     user, but there is a more recent version
>    ;;                     on the current branch stored in the
>    ;;                     master file.
>    ((looking-at "_[_ ]..\\s-+\\*") 'needs-patch)
> 
>    ;; 'up-to-date         The working file is unmodified with
>    ;;                     respect to the latest version on the
>    ;;                     current branch, and not locked.
>    ((looking-at "_[_ ]") 'up-to-date)
> 
>    ;; 'needs-merge        The file has been edited by the user,
>    ;;                     and there is also a more recent version
>    ;;                     on the current branch stored in the
>    ;;                     master file.  This state can only occur
>    ;;                     if locking is not used for the file.
>    ((looking-at "\\S-+\\s-+\\*") 'needs-merge)
> 
>    ;; 'edited             The working file has been edited by the
>    ;;                     user.  If locking is used for the file,
>    ;;                     this state means that the current
>    ;;                     version is locked by the calling user.
>    (t 'edited)))
> 
> 
> (defun vc-svn-state (file)
>   "Return the current version control state of FILE.
> For a list of possible return values, see `vc-state'.
> This function should do a full and reliable state computation; it is
> usually called immediately after `C-x v v'.  `vc-svn-state-heuristic'
> provides a faster heuristic when visiting a file."
>   (car (vc-svn-run-status file 'update)))
> 
> 
> (defun vc-svn-state-heuristic (file)
>   "Estimate the version control state of FILE at visiting time.
> For a list of possible values, see the doc string of `vc-state'.
> This is supposed to be considerably faster than `vc-svn-state'.  It
> just runs `svn status -v', without the `-u' flag, so it's a strictly
> local operation."
>   (car (vc-svn-run-status file)))
> 
> 
> 
> (defun vc-svn-workfile-version (file)
>   "Return the current workfile version of FILE."
>   (number-to-string (cadr (vc-svn-run-status file))))
> 
> 
> (defun vc-svn-checkout-model (file)
>   'implicit)
> 
> (provide 'vc-svn)
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: dev-unsubscribe@subversion.tigris.org
> For additional commands, e-mail: dev-help@subversion.tigris.org
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@subversion.tigris.org
For additional commands, e-mail: dev-help@subversion.tigris.org
Received on Fri Jul 12 06:52:40 2002