elisp-vcs/dvc/docs/DVC-API
2009-10-10 08:02:43 +02:00

180 lines
6.1 KiB
Plaintext

That file contains the documentation to build support for a different dvc,
using the dvc layer:
Conventions used in the document:
* <dvc> is used as placeholder for the dvc backend to implement
--------------------------------------------------------------------------------
* Base functions that are required for every supported dvc system
* That functions should be located in the <dvc>-dvc.el file
--------------------------------------------------------------------------------
When no function is provided, dvc-dvc-<postfix> is used instead.
- <dvc>-dvc-tree-root
(defun <dvc>-dvc-tree-root (&optional location no-error)
"Return the tree root for LOCATION, nil if not in a local tree.
If NO-ERROR is non-nil, don't raise an error if LOCATION is not a
<dvc> managed tree (but return nil)."
- <dvc>-dvc-log-edit-done
(defun <dvc>-dvc-log-edit-done ()
"Finish a commit for <dvc>."
- <dvc>-dvc-diff
(defun <dvc>-dvc-diff ()
"Shows the changes in the current <dvc> tree."
- <dvc>-dvc-log
(defun <dvc>-dvc-log ()
"Shows the changelog in the current <dvc> tree."
- <dvc>-dvc-command-version
(defun <dvc>-dvc-command-version ()
"Returns and/or shows the version identity string of backend command."
- <dvc>-dvc-file-has-conflict-p
(defun <dvc>-dvc-file-has-conflict-p (filename)
"Return non-nil if FILENAME is marked as having conflicts")
- <dvc>-dvc-resolved
(defun <dvc>-dvc-resolved (filename)
"Mark FILENAME as not having conflict anymore")
To handle the case of a workspace that is controlled by more than one
back-end, all dispatching interactive front-end functions dvc-foo
should have a corresponding function <dvc>-foo, that specifies which
back-end to use.
A simple way to provide <dvc>-foo is to put dvc-foo in
dvc-back-end-wrappers (in dvc-unified.el); then <dvc>-foo is
automatically generated by dvc-register-dvc. This defines
<dvc>-foo as (see dvc-register.el for the actual code):
(defun <dvc>-foo (<args>)
(interactive)
(let ((dvc-temp-current-active-dvc <dvc>))
(call-interactively 'dvc-foo)))
This means that back-ends may _not_ define a function <dvc>-foo.
Note that functions defined by dvc-define-unified-command dispatch
to <dvc>-dvc-foo. Calling <dvc>-dvc-foo is _not_ the same as
calling <dvc>-foo, since dvc-temp-current-active-dvc is not bound,
the interactive argument processing may be different, and
<dvc>-dvc-foo may not even exist (if the default dvc-dvc-foo is
sufficient).
-----------------------------------------------------------------------------
* Revision API
-----------------------------------------------------------------------------
Definition
==========
DVC deals with several RCS, with different ways to designate a
revision. We define a unified way to designate a revision in lisp,
which we call revision identifiers, or rev-id:
REVISION-ID :: (<dvc> BACK-END-ID)
;; <dvc> is one of 'tla, 'bzr, 'xhg, ...
BACK-END-ID :: (revision BACK-END-REVISION)
;; An already commited revision
;; The way to specify it depends on the back-end.
| (local-tree PATH)
;; Uncommited revision in the local tree PATH
| (last-revision PATH NUM)
;; Last commited revision in tree PATH if NUM = 1
;; Last but NUM-1 revision in tree PATH if NUM > 1
| (previous-revision BACK-END-REVISION NUM)
;; Nth Ancestor of BACK-END-ID.
(probably we'll need a (head REMOTE-BRANCH) too)
PATH :: string
;; must be a tree root directory
NUM :: number
REV-STRING :: string
For Xtla (tla and baz):
BACK-END-REVISION :: ("archive" "category" "branch" "version" "revision")
;; archive/category--branch--version--revision
For bzr:
BACK-END-REVISION :: (local "path" NUM)
| (remote "url" NUM)
| (tag REV-STRING)
For xhg:
TODO
For xgit:
BACK-END-REVISION :: (revision "sha1")
| (index)
;; content of the index (aka staging area).
Example
=======
(bzr (revision (local "/path/to/archive" 3)))
(baz (last-revision "/path/to/project" 1))
(baz (revision ("archive" "category" "branch" "version" "revision")))
(xgit (revision "c576304d512df18fa30b91bb3ac15478d5d4dfb1"))
Functions
=========
Based upon that, we define the functions:
dvc-revision-get-file-in-buffer: get the particular revision of a file
in a buffer.
-----------------------------------------------------------------------------
* Back-end specific features Vs Unification
-----------------------------------------------------------------------------
DVC provides the user an interface for multiple revision control
system, and does it using as much back-end independant code as
possible. This has several benefits :
* For the user:
- Similar user-interface, keybindings, ... for different back-ends.
- Unified interface for most operations : one menu, one set of
keybindings, and DVC detects which back-end to use automatically.
* For the developers:
- much less code to write than individual, independant interfaces.
However, some back-end features do not fit well in the DVC common
interface. For example, git differs from other common version control
systems in several regards (the index, for example, is something
probably unique to git, and it leads to a different flow to prepare a
commit).
In this case, there's nothing wrong providing additional functions,
which might not have a dvc-* dispatching command. The user can call
them with M-x <back-end>-command RET explicitly. Additionaly, one can
extend some DVC modes with additional keybindings and menus. See
`dvc-diff-mode' and `xgit-diff-mode' for an example.
-----------------------------------------------------------------------------
* External tools
-----------------------------------------------------------------------------
* 'sh' is required for dvc-run-sync and dvc-run-async.
In practice, that is not a problem for Unix users, but requires
cygwin or mingw for Windows users. 'sh' is used to separate stdout
from stderr; the Emacs function 'call-process' merges them. It may
be possible to do this with native Windows tools, if someone wants
to investigate.