Emacs comes with a generic version control interface called VC. It supports the ConcurrentVersionsSystem (CVS), RevisionControlSystem (RCS), SCCS, Arch, Git, Mercurial, Bzr, Monotone, MetaCVS and SubVersion (SVN). DaRcs support will appear in the next version of Emacs (does this mean 25?) with VcDarcs – and not DarcSum.

On 2007-10-03, the original author of VC mode, EricRaymond, announced a major rewrite of VC mode whose principal goal is “to change VC so that its primitive operations (notably checkin/commit) take sets of files as arguments rather than single files”. The necessary changes to the VC backend have already been added to EmacsFromCVS.

See ForceBackups for the backup system integrated in Emacs that uses the ‘version-control’ variable (and even understands the VERSION_CONTROL environment variable as recognized in other GNU programs) for making “numbered backups” for each time a file is edited.

See CategoryVersionControl for other interfaces to other version control systems. They often use similar keybindings.


    C-x v v     vc-next-action -- perform the next logical control operation on file
    C-x v i     vc-register -- add a new file to version control
    C-x v +     vc-update -- Get latest changes from version control
    C-x v ~     vc-version-other-window -- look at other revisions
    C-x v =     vc-diff -- diff with other revisions
    C-x v u     vc-revert-buffer -- undo checkout
    C-x v c     vc-cancel-version -- delete the latest revision (often it makes more sense to look at an old revision and check that in again!)
    C-x v d     vc-directory -- show all files which are not up to date
    C-x v g     vc-annotate -- show when each line in a tracked file was added and by whom
    C-x v s     vc-create-snapshot -- tag all the files with a symbolic name
    C-x v r     vc-retrieve-snapshot -- undo checkouts and return to a snapshot with a symbolic name
    C-x v l     vc-print-log -- show log (not in ChangeLog format)
    C-x v a     vc-update-change-log -- update ChangeLog
    C-x v m     vc-merge
    C-x v h     vc-insert-headers
    M-x vc-resolve-conflicts -- pop up an ediff-merge session on a file with conflict markers

The info pages have more about it: Version Control.

Also, don’t forget the powerful ediff--revision command which is part of the ediff package and uses the vc interface. See EdiffMode.

Be aware that the CVS mode will keep old revisions of your files in the current directory, even if you are using a BackupDirectory. This makes sense from a CVS point of view but can be maddening from a “no really, don’t litter my fs tree” point of view. If I can find a fix for this that doesn’t break CVS mode, I’ll post it here. – DavidBrady

Here is my two cents

   (defun my-log-view-diff (beg end)
     "Overwrite the default log-view-diff, make use of
   log-view-get-marked --lgfang"
      (if (log-view-get-marked) (log-view-get-marked)
        (list (log-view-current-tag (point))
              (log-view-current-tag (point)))))
     (when (string-equal beg end)
         (goto-char (point))               ;not marked
         (setq end (log-view-current-tag))))
      (if log-view-per-file-logs
          (list (log-view-current-file))
              beg end))
   (eval-after-load "log-view" '(fset 'log-view-diff 'my-log-view-diff))
   (defun my-log-view-revision ()
     "get marked revision (or revision at point) --lgfang"
     (let ((revision (if (log-view-get-marked) (car (log-view-get-marked))
                       (log-view-current-tag (point)))))
      (vc-find-revision (log-view-current-file) revision))))
   (eval-after-load "log-view"
     '(define-key log-view-mode-map "v" 'my-log-view-revision))

if you use colordiff in svn, maybe you need this

(add-hook 'diff-mode-hook '(lambda () (require 'ansi-color)(ansi-color-apply-on-region (point-min) (point-max))))

The above snippet may not work in newer versions of Emacs (tested on 23.4.1) where the contents of the diff buffer are acquired asynchronously through the underlying version control system. In this case, ‘ansi-color-apply-on-region’ should be run after the buffer is populated with the diff content. The following snippets does this job:

(defadvice vc-diff-finish (after handle-color-in-diff-output)
  "Run `ansi-color-apply-on-region'." 
    (require 'ansi-color)
    (ansi-color-apply-on-region (point-min) (point-max))

See also VersionControlAlways.