With a modern merging-based version control system (such as Git and Hg; see Merge-based vs Lock-based Version Control), C-x v v does the following when invoked from a buffer that visits a version-controlled file or a VC Directory or Dired buffer:
If C-x v v is invoked from a buffer under Diff mode, the command treats the buffer as holding a set of patches for one or more files. It then applies the changes to the respective files and commits the changes after popping up the *vc-log* buffer to allow you to type a suitable commit log message.
Once you type C-x v v, the fileset or patches cannot be changed without first canceling the commit by typing C-c C-k in the *vc-log* buffer. For example, if you change which files are marked in the *vc-dir* buffer after Emacs has already popped up the *vc-log* buffer, the old fileset will remain in effect for this commit. (This is in contrast to changes made to the contents of files in the fileset when not committing patches: all such changes will be included in the commit even if they are made after Emacs has popped up the *vc-log* buffer.)
When you cancel a commit, Emacs saves your log message. This means that if you need to adjust the fileset or patches, it is easy to restart the commit operation again: type C-c C-k C-x v v M-p. Here C-c C-k cancels the commit, C-x v v initiates another with the new fileset or patches, and finally M-p recalls your previous log message.
With modern decentralized version control systems (Git, Mercurial, etc.), the changes are committed locally and not automatically propagated to the upstream repository (which is usually on a remote host). In these cases, if the repository has been changed since your last update, the commit may fail. In that case, you must update from upstream and then try again. Use C-x v + (see Pulling/Pushing Changes into/from a Branch) or C-x v m (see Merging Branches) for that.
With a centralized version control system, if the commit fails due to upstream changes, type C-x v v again to merge in the upstream repository changes.
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 Basic Version Control with Locking).