Handling Conflicts
As mentioned above, the cvs update command incorporates changes made by other developers into your working directory. If both you and another developer have modified the same file, CVS merges his changes with yours.
It's straightforward to imagine how this works when the changes apply to distant regions of a file, but what happens when you and another developer have changed the same line? CVS calls this situation a conflict, and leaves it up to you to resolve it.
For example, suppose that you have just added some error checking to the host name lookup code. Before you commit your change, you must run cvs update, to bring your sources into sync:
$ cvs update cvs update: Updating . RCS file: /u/src/master/httpc/httpc.c,v retrieving revision 1.8 retrieving revision 1.9 Merging differences between 1.8 and 1.9 into httpc.c rcsmerge: warning: conflicts during merge cvs update: conflicts found in httpc.c C httpc.c $
In this case, another developer has changed the same region of the file you have, so CVS complains about a conflict. Instead of printing M httpc.c, as it usually does, it prints C httpc.c, to indicate that a conflict has occurred in that file.
To resolve the conflict, bring up the file in your editor. CVS marks the conflicting text this way:
/* Look up the IP address of the host. */ host_info = gethostbyname (hostname); <<<<<<< httpc.c if (! host_info) { fprintf (stderr, "%s: host not found: %s\n", progname, hostname); exit (1); } ======= if (! host_info) { printf ("httpc: no host"); exit (1); } >>>>>>> 1.9 sock = socket (PF_INET, SOCK_STREAM, 0);
It's important to understand what CVS does and doesn't consider a conflict. CVS does not understand the semantics of your program; it simply treats its source code as a tree of text files. If one developer adds a new argument to a function and fixes its callers, while another developer simultaneously adds a new call to that function, and does not pass the new argument, that is certainly a conflict — the two changes are incompatible — but CVS will not report it. CVS's understanding of conflicts is strictly textual.
In practice, fortunately, conflicts are rare. Usually, they seem to result from two developers attempting to address the same problem, a lack of communication between developers, or disagreement about the design of the program. Allocating tasks to developers in a reasonable way reduces the likelihood of conflicts.
Many version control systems allow a developer to lock a file, preventing others from making changes to it until she has committed her changes. While locking is appropriate in some situations, it is not clearly a better solution than the approach CVS takes. Changes can usually be merged correctly, and developers occasionally forget to release locks; in both cases, explicit locking causes unnecessary delays. Furthermore, locks prevent only textual conflicts; they do not prevent semantic conflicts of the sort described above, if the two developers make their changes to different files.