Skip to main content

28.1.3 Basic Editing under Version Control

Most VC commands operate on VC filesets. A VC fileset is a collection of one or more files that a VC operation acts on. When you type VC commands in a buffer visiting a version-controlled file, the VC fileset is simply that one file. When you type them in a VC Directory buffer, and some files in it are marked, the VC fileset consists of the marked files (see VC Directory Mode).

On modern changeset-based version control systems (see VCS Changesets), VC commands handle multi-file VC filesets as a group. For example, committing a multi-file VC fileset generates a single revision, containing the changes to all those files. On older file-based version control systems like CVS, each file in a multi-file VC fileset is handled individually; for example, a commit generates one revision for each changed file.

C-x v v​

Perform the next appropriate version control operation on the current VC fileset.

The principal VC command is a multi-purpose command, C-x v v (vc-next-action), which performs the most appropriate action on the current VC fileset: either registering it with a version control system, or committing it, or unlocking it, or merging changes into it. The precise actions are described in detail in the following subsections. You can use C-x v v either in a file-visiting buffer or in a VC Directory buffer.

Note that VC filesets are distinct from the named filesets used for viewing and visiting files in functional groups (see Filesets). Unlike named filesets, VC filesets are not named and don’t persist across sessions.

• VC With A Merging VCS  Without locking: default mode for CVS.
• VC With A Locking VCS  RCS in its default mode, SCCS, and optionally CVS.
• Advanced C-x v v  Advanced features available with a prefix argument.

28.1.3.1 Basic Version Control with Merging​

On a merging-based version control system (i.e., most modern ones; see VCS Merging), C-x v v does the following:

  • If there is more than one file in the VC fileset and the files have inconsistent version control statuses, signal an error. (Note, however, that a fileset is allowed to include both newly-added files and modified files; see Registering.)

  • If none of the files in the VC fileset are registered with a version control system, register the VC fileset, i.e., place it under version control. See Registering. If Emacs cannot find a system to register under, it prompts for a repository type, creates a new repository, and registers the VC fileset with it.

  • If every work file in the VC fileset is unchanged, do nothing.

  • If every work file in the VC fileset has been modified, commit the changes. To do this, Emacs pops up a *vc-log* buffer; type the desired log entry for the new revision, followed by C-c C-c to commit. See Log Buffer.

    If committing to a shared repository, the commit may fail if the repository has been changed since your last update. In that case, you must perform an update before trying again. On a decentralized version control system, use C-x v + (see Pulling / Pushing) or C-x v m (see Merging). On a centralized version control system, type C-x v v again to merge in the repository changes.

  • Finally, if you are using a centralized version control system, check if each work file in the VC fileset is up-to-date. If any file has been changed in the repository, offer to update it.

These rules also apply when you use RCS in its non-locking mode, except that changes are not automatically merged from the repository. Nothing informs you if another user has committed changes in the same file since you began editing it; when you commit your revision, that other user’s changes are removed (however, they remain in the repository and are thus not irrevocably lost). Therefore, you must verify that the current revision is unchanged before committing your changes. In addition, locking is possible with RCS even in this mode: C-x v v with an unmodified file locks the file, just as it does with RCS in its normal locking mode (see VC With A Locking VCS).

28.1.3.2 Basic Version Control with Locking​

On a locking-based version control system (such as SCCS, and RCS in its default mode), C-x v v does the following:

  • If there is more than one file in the VC fileset and the files have inconsistent version control statuses, signal an error.
  • If each file in the VC fileset is not registered with a version control system, register the VC fileset. See Registering. If Emacs cannot find a system to register under, it prompts for a repository type, creates a new repository, and registers the VC fileset with it.
  • If each file is registered and unlocked, lock it and make it writable, so that you can begin to edit it.
  • If each file is locked by you and contains changes, commit the changes. To do this, Emacs pops up a *vc-log* buffer; type the desired log entry for the new revision, followed by C-c C-c to commit (see Log Buffer).
  • If each file is locked by you, but you have not changed it, release the lock and make the file read-only again.
  • If each file is locked by another user, ask whether you want to steal the lock. If you say yes, the file becomes locked by you, and a warning message is sent to the user who had formerly locked the file.

These rules also apply when you use CVS in locking mode, except that CVS does not support stealing locks.

28.1.3.3 Advanced Control in C-x v v​

When you give a prefix argument to vc-next-action (C-u C-x v v), it still performs the next logical version control operation, but accepts additional arguments to specify precisely how to do the operation.

  • You can specify the name of a version control system. This is useful if the fileset can be managed by more than one version control system, and Emacs fails to detect the correct one.

  • Otherwise, if using CVS, RCS or SRC, you can specify a revision ID.

    If the fileset is modified (or locked), this makes Emacs commit with that revision ID. You can create a new branch by supplying an appropriate revision ID (see Branches).

    If the fileset is unmodified (and unlocked), this checks the specified revision into the working tree. You can also specify a revision on another branch by giving its revision or branch ID (see Switching Branches). An empty argument (i.e., C-u C-x v v RET) checks out the latest (head) revision on the current branch.

    This is silently ignored on a decentralized version control system. Those systems do not let you specify your own revision IDs, nor do they use the concept of checking out individual files.