While making changes to your work file (the working copy you've checked out) and experimenting with them, you may decide at any time to revert the work file—that is, to throw away your changes and undo the check-out operation. After you've made changes to your file that you want to keep, you must check in those changes. Doing so adds them permanently to the saved change history as a new revision of the file. Under RCS and SCCS, it also removes the lock on your work file, so that other people can check it out and edit it. Under CVS and Subversion, the file was never locked; instead, the version control system tries to reconcile your changes with any other changes that might have been made since check-out time and yells for help (manual intervention) if it finds conflicts. Because you never really checked the file out in a concurrent system, the standard term for integrating your changes back into such a repository is commit rather than check in . The CVS interface also allows you to call it checking in, to accommodate people who are used to older systems, and that's what Emacs calls it too.
The register, check-out, revert, and check-in operations are the basic ones. But you may want to do other things as well. You can also retrieve any saved revision, get a difference report between any two saved versions or any saved version and your (possibly modified) work file, or even completely remove saved revisions that you want to throw away (though this is rare).
If conflicts are reported during a check-in operation, Emacs offers to help you resolve them by launching an Ediff session (described at the end of this chapter). If you decide against Ediff, you will see the conflicts as represented within the file by the version control system and you can address them manually or use whatever other tools you find convenient. If you later decide you do want help from Ediff after all, you can use M-x vc-resolve-conflicts Enterwhile you're editing the conflicted file.
Most version control systems (and all the ones we're talking about here) associate change comments with each revision. So each time you check in a registered file, you can add an explanation of the change to the change history, which won't be part of the file itself. Each revision has a revision number , which identifies its place in the history. The base revision in SCCS, RCS, and CVS is 1.1. If the history is a linear sequence of changes (which is typical for small projects), sequence numbers are two numeric fields separated by a dot. Subversion uses a simpler revision numbering scheme with which you're undoubtedly familiar: The first revision is numbered 1, the one that comes after it is 2 . . . subtle, eh?
It is possible to start branches so that variant versions of files can be maintained in parallel. In such cases, the main trunk still has two-field revision numbers, but branches have more fields. The exact naming conventions for branches are arcane and different between SCCS and RCS or CVS; if you need to know about them in detail, consult the documentation for your version control system. Once again, this is a whole lot simpler in Subversion, which versions the entire source tree as a unit and supports efficient copies of parts of the tree. In Subversion, a branch is just another directory. There is a lot more to know about version control systems than we go into here, and two excellent O'Reilly books on the topic are: Essential CVS by Jennifer Vesperman and Version Control with Subversion by Ben Collins-Sussman, Brian W. Fitzpatrick, and C. Michael Pilato.
12.3 How VC Helps with Basic Operations
Historically, you had to know three or four different shell commands to do the basic operations of version control (registration, check in, check out, and revert), and you had to do each one outside your editor (or in an editor subshell). This procedure was complicated and annoying, or at best a distraction from the flow of working on your code and changes.
VC's interface is much simpler. The simplicity comes from noticing that whatever state your version-controlled file is in, there is normally just one logical thing to do next. Here are the rules:
• If your file isn't under version control, the next logical thing to do is register it and (where relevant) check out a modifiable copy for you.
• If it's registered, but not checked out by anyone, the next thing you generally want to do is check it out so you can edit it (again, where relevant, such as if you're using CVS in a "keep files read-only unless I say I want to edit them" mode).
• If you have made changes to the file, the next logical thing is to check it back in, which may involve reconciling your changes with those made by someone else.
• Much more rarely, if you're using one of the pre-CVS systems, if someone else has a file checked out, you may want to steal the lock (notifying the lock owner that you've done so).
Indeed, VC mode has just one basic command: C-x v v(for vc-next-action), which you can think of as "do the next logical thing to this file" or, more precisely: "take the currently visited file to the next normal version control state." It follows the arrows in Figure 12-1, which describes the traditional version control cycle. [86]This command is available in every Emacs since 19; when you invoke it, it automatically fetches the rest of VC and does its job.
Figure 12-1. The traditional version control cycle
There's a little more to it than that, of course. For one thing, when you check in a set of changes to a file, VC pops up a buffer for you to enter a change comment. Similarly, if you're in an older version control environment, when you steal a lock, VC pops up a buffer requesting an explanation. This explanation is mailed to the lock owner.
VC gives you a revert operation as well: C-x v u(for vc-revert-buffer). Actually, the function that implements vc-next-actionchecks to see if the buffer is unmodified since check-out time; if so, it offers to revert the buffer and unlocks the work file rather than checking in an empty change.
Although it's worth understanding this traditional flow because it's how VC is designed, working with today's concurrent version control systems is slightly different. Luckily, it's even a little simpler. Because there is no need to obtain a lock in order to edit a document, one of the VC steps is missing (or, if you prefer, you can think of it as implicit). This is illustrated in Figure 12-2.
Figure 12-2. The concurrent version control cycle
The transition from the unmodified state to the modified state (with respect to the version in the repository) is shown as a dotted line, because you no longer perform a VC operation here. You just start editing the file you want to work with. Whenever you tell VC you want the "next action" it's able to tell whether the document is modified or not. If it is, the current version is committed ("checked in," if you will) and you're prompted for the change comments. If the file is registered but unmodified, VC simply displays a message in the minibuffer telling you that the buffer is up to date.
If you prefer to configure CVS to give you read-only versions of files until you explicitly choose to edit them, your workflow will remain that of Figure 12-1.
12.4 Editing Comment Buffers
In VC mode, three operations typically pop up a buffer to accept comment or notification text: check in, lock stealing, and (under circumstances to be explained later in the chapter) file registration. In each case, the operation is on hold until you type C-c C-cto commit the comment buffer. You can enter a comment right away and finish the operation, or you can go off and do something else. VC waits patiently to commit until you are ready. If you delete the pop-up buffer, the operation is quietly scrubbed.
Читать дальше