Chapter 5
Perforce Basics:
Resolving File Conflicts
File conflicts can occur when two users edit and submit two versions of the same file.
Consider the following scenario:
- Ed opens file.c for edit in his client workspace.
- Lisa opens the same file for edit in her client workspace.
- Ed and Lisa both work on their respective versions of file.c.
- Ed submits a changelist containing his version of file.c, and the submit succeeds.
- Lisa submits a changelist with her version of file.c. Her submit fails because of a file conflict with Ed's version.
If the Perforce server were to accept Lisa's version into the depot, the head revision would contain none of Ed's changes. Therefore, Lisa's changelist is rejected and she must resolve the conflict. To resolve the conflict, she can:
- Submit her version of the file, overriding Ed's version.
- Discard her changes to the file in favor of Ed's version.
- Generate a merged version of the file that contains both sets of changes, and submit the merged version.
- Review and edit the merged version of the file before submitting it.
Resolving a file conflict is a two-step process: first, the resolve is scheduled, and after scheduling the resolve, the user who submitted the changelist that scheduled the resolve must perform the resolve.
The Perforce server automatically schedules a resolve whenever you submit a changelist fails due to a file conflict. You can also schedule a resolve manually by syncing the head revision of a file over an opened revision within your client workspace. To perform a resolve, use the p4 resolve command. Perforce also provides facilities to prevent file conflicts by locking files when they are edited.
Scheduling Resolves of Conflicting Files
Whenever you try to submit a file to the depot that is not an edit of the file's current head revision, a file conflict exists, and you must resolve the conflict.
The file revision that was most recently synced to your client workspace is the base file revision. If the base file revision for a particular file in your workspace is not the same as the head revision of the same file in the depot, you must perform a resolve the new file revision can be accepted into the depot.
Before you can perform a resolve with the p4 resolve command, you must schedule the resolve. You can schedule a resolve with p4 sync, or by submitting a changelist that contains the newly conflicting files. If a resolve is necessary, your submit fails, and the resolve is automatically scheduled for you.
Why "p4 sync" to schedule a resolve?
When you use p4 sync, you are projecting the state of the depot onto your client workspace. For each file on which p4 sync operates:
- If the file does not exist in your workspace, or it is found in your workspace but is unopened, the file is copied from the depot to your workspace.
- If the file has been deleted from the depot, it is deleted from your workspace.
- If you have opened the file in your workspace with p4 edit, the Perforce server cannot copy the file into your workspace, because doing so would overwrite any changes you had made. The Perforce server schedules a resolve between the file revision in the depot, the revision in your workspace, and the base file revision (that is, the revision you last synced to your workspace).
Example:
Scheduling resolves with p4 sync
Ed is making a series of changes to the *.guide files in the elm doc subdirectory. He has
synced the //depot/elm_proj/doc/*.guide files to his workspace and has opened the
files with p4 edit. He edits the files, but before he has a chance to submit them, Lisa submits
new versions of some of the same files to the depot. The versions Ed has been editing are no
longer the head revisions, and resolves must be scheduled and performed for each of the
conflicting files before Ed's edits can be accepted.
Ed schedules the resolves with p4 sync //edk/doc/*.guide. Because these files are
already open in his workspace, his workspace files are not overwritten. The p4 client program
schedules the resolves between Ed's workspace files and the head revisions in the depot.
Alternatively, Ed could have submitted the //depot/elm_proj/doc/*.guide files in a
changelist; the file conflicts would have caused the p4 submit to fail, and the resolves would
have been scheduled as a result of the submission failure.
How do I know when a resolve is needed?
The p4 submit command fails when it determines that any of the files in the submitted changelist need to be resolved, and displays a message that includes the names of the files that you must resolve. If the changelist provided to p4 submit was the default changelist, the changelist is assigned a number that you must use in all future references to the changelist. Numbered changelists are discussed in Chapter 7, Changelists.
Another way to determine if a resolve is needed is to run p4 sync -n filename before performing the submit, using the open files in your changelist as the arguments to the command. If resolves on files are necessary, p4 sync -n reports them. If you use this approach, the files in your default changelist remain in your default changelist (that is, you do not need to create a numbered changelist).
Performing Resolves of Conflicting Files
You resolve file conflicts with p4 resolve [filenames]. Provide files to be resolved as arguments to the p4 resolve command. Each file is resolved separately.
The p4 resolve process starts with three revisions of the same file and generates a fourth version; you can accept any of these versions in place of the file in your workspace, and you can edit the generated version before accepting it into your workspace. Whatever version of the file you choose, after you have resolved the conflict, use p4 submit to submit the file to the depot.
The p4 resolve command is interactive, and presents a series of prompts:
/usr/edk/elm/doc/answer.1 - merging //depot/elm_proj/doc/answer.1#5 Diff chunks: 4 yours + 2 theirs + 1 both + 1 conflicting Accept(a) Edit(e) Diff(d) Merge (m) Skip(s) Help(?) [e]:
|
The remainder of this section explains what this means, and how to use this dialog.
File revisions used and generated by "p4 resolve"
p4 resolve [filenames] starts with three revisions of the same file (yours, theirs, and base), generates a new version (merged) that merges elements of all three revisions, provides you with an opportunity to edit the merged file, and writes the resulting file (either yours, theirs, merged, or your edited merged file) to your client workspace.
The file revisions used by p4 resolve are as follows:
yours
|
The newly-edited revision of the file in the client workspace. This file is overwritten by result once the resolve process is complete.
|
theirs
|
The revision in the depot that the client revision conflicts with. Usually, this is the head revision, but p4 sync can be used to schedule a resolve with any revision between the head revision and base.
|
base
|
The file revision in the depot that yours was edited from. Note that base and theirs are different revisions; if they were the same, there would be no reason to perform a resolve.
|
merge
|
File variation generated by Perforce from theirs, yours, and base.
|
result
|
The file resulting from the resolve process. result is written to the client workspace, overwriting yours, and must subsequently be submitted by the user. The instructions given by the user during the resolve process determine exactly what is contained in this file. The user can simply accept theirs, yours, or merge as the result, or can edit merge to have more control over the result.
|
The remainder of this chapter will use the terms theirs, yours, base, merge, and result to refer to the corresponding file revisions. The definitions given above are somewhat different when resolve is used to integrate branched files.
Types of conflicts between file revisions
The diff program that underlies the Perforce resolve mechanism determines differences between file revisions on a line-by-line basis. After the differences are located, they are grouped into chunks: for example, three new lines that are adjacent to each other are grouped into a single chunk. Yours and theirs are both generated by a series of edits to base; for each set of lines in yours, theirs, and base, p4 resolve asks the following questions:
- Is this line set the same in yours, theirs, and base?
- Is this line set the same in theirs and base, but different in yours?
- Is this line set the same in yours and base, but different in theirs?
- Is this line set the same in yours and theirs, but different in base?
- Is this line set different in all three files?
Any line sets that are the same in all three files do not need to be resolved. The number of line sets that apply to the other four questions are reported by p4 resolve in this form:
2 yours + 3 theirs + 1 both + 5 conflicting
In this case, two line sets are identical in theirs and base but are different in yours; three line sets are identical in yours and base but are different in theirs; one line set was changed identically in yours and theirs; and five line sets are different in yours, theirs, and base.
How the merge file is generated
p4 resolve generates a preliminary version of the merge file, which can be accepted as is, edited and then accepted, or rejected. A simple algorithm is followed to generate this file: any changes found in yours, theirs, or both yours and theirs are applied to the base file and written to the merge file; and any conflicting changes will appear in the merge file in the following format:
>>>> ORIGINAL VERSION file#n (text from the original version) ==== THEIR VERSION file#m (text from their file) ==== YOUR VERSION file (text from your file) <<<<
|
Editing the Perforce-generated merge file is often as simple as opening the merge file, searching for the difference marker ">>>>", and editing that portion of the text. This isn't always the case, as it is often necessary to examine the changes made to theirs to make sure they're compatible with other changes that you made. You can speed this process by calling p4 resolve with the -v flag; p4 resolve -v tells Perforce to generate difference markers for all changes made in either file being resolved, instead of only for changes that conflict between the yours and theirs files. When resolving conflicts, remember that the absence of conflicting diff chunks does not imply correctness of code.
The "p4 resolve" options
The p4 resolve command offers the following options:
Option
|
Short Meaning
|
What it Does
|
---|
e
|
edit merged
|
Edit the preliminary merge file generated by Perforce
|
ey
|
edit yours
|
Edit the revision of the file currently in the client
|
et
|
edit theirs
|
Edit the revision in the depot that the client revision conflicts with (usually the head revision). This edit is read-only.
|
dy
|
diff yours
|
Diff line sets from yours that conflict with base
|
dt
|
diff theirs
|
Diff line sets from theirs that conflict with base
|
dm
|
diff merge
|
Diff line sets from merge that conflict with base
|
d
|
diff
|
Diff line sets from merge that conflict with yours
|
m
|
merge
|
Invoke the command P4MERGE base theirs yours merge. To use this option, you must set the environment variable P4MERGE to the name of a third-party program that merges the first three files and writes the fourth as a result.
|
?
|
help
|
Display help for p4 resolve
|
s
|
skip
|
Don't perform the resolve right now.
|
ay
|
accept yours
|
Accept yours into the client workspace as the resolved revision, ignoring any changes made in theirs.
|
at
|
accept theirs
|
Accept theirs into the client workspace as the resolved revision. The revision that was in the client workspace is overwritten.
|
am
|
accept merge
|
Accept merge into the client workspace as the resolved revision. The version originally in the client workspace is overwritten.
|
ae
|
accept edit
|
If you edited the merge file (by selecting "e" from the p4 resolve dialog), accept the edited version into the client workspace. The version originally in the client workspace is overwritten.
|
a
|
accept
|
If theirs is identical to base, accept yours,
if yours is identical to base, accept theirs,
if yours and theirs are different from base, and there are no conflicts between yours and theirs; accept merge,
otherwise, there are conflicts between yours and theirs, so skip this file
|
Only a few of these options are visible on the command line, but all options are always accessible and can be viewed by choosing help. The merge file is generated by p4d's internal diff routine, but the differences displayed by dy, dt, dm, and d are generated by a diff algorithm built into the p4 client program. To use a third-party diff utility in place of the p4 client program's diff algorithm, specify the third-party utility in the P4DIFF environment variable.
The p4 resolve prompt has the following format:
Accept(a) Edit(e) Diff(d) Merge (m) Skip(s) Help(?) [am]:
|
A recommended choice is displayed in brackets at the end of the prompt. Pressing Return or choosing Accept accepts the default option. The recommended option is chosen according the following algorithm: if there were no changes to yours, accept theirs. If there were no changes to theirs, accept yours. Otherwise, accept merge.
Example:
Resolving file conflicts
In the last example, Ed scheduled the doc/*.guide files for resolve. This was necessary
because both he and Lisa had been editing the same files; Lisa had already submitted versions,
and Ed needs to reconcile his changes with Lisa's. To perform the resolves, he types p4
resolve //depot/elm_proj/doc/*.guide, and sees the following:
/usr/edk/elm/doc/Alias.guide - merging //depot/elm_proj/doc/Alias.guide#5 Diff chunks: 4 yours + 2 theirs + 1 both + 1 conflicting Accept(a) Edit(e) Diff(d) Merge (m) Skip(s) Help(?) [e]:
|
This is the resolve dialog for doc/Alias.guide, the first of the four doc/*.guide files. Ed
sees that he's made four changes to the base file that don't conflict with any of Lisa's changes.
He also notes that Lisa has made two changes that he's unaware of. He types dt (for
"display theirs") to view Lisa's changes; he looks them over and sees that they're fine. Of
most concern to him, of course, is the one conflicting change. He types e to edit the Perforce-
generated merge file and searches for the difference marker ">>>>". The following text is
displayed:
Acme Technology Mountain View, California >>>> ORIGINAL VERSION ==== THEIR VERSION 94041 ==== YOUR VERSION 98041 <<<<
|
He and Lisa have both tried to add a zip code to an address in the file, but Ed had typed it
wrong. He edits this portion of the merge file so it reads as follows:
Acme Technology Mountain View, California 94041
|
The merge file is now acceptable to him: he's viewed Lisa's changes, seen that they're
compatible with his own, and the only line conflict has been resolved. He quits from the editor
and types am; the edited merge file is written to the client, and the resolve process continues
on the next doc/*.guide file.
When a version of the file is accepted into your workspace, your previous workspace file is overwritten, and you must still submit the revised file to the depot. It is possible for another user to have submitted yet another revision of the same file to the depot between the time p4 resolve completes and when you call p4 submit; if this has happened, you will have to perform another resolve. (You can prevent this from happening by performing a p4 lock on the file before starting the resolve. See "Preventing multiple resolves with p4 lock" on page 76 for details.)
Command line flags to automate the resolve process
Five optional p4 resolve flags tell the command to work non-interactively. When these flags are used, particular revisions of the conflicting files are automatically accepted.
"p4 resolve" flag
|
Meaning
|
---|
-ay
|
Automatically accept yours.
|
-at
|
Automatically accept theirs. Use this option with caution, as the file revision in the client workspace will be overwritten with no chance of recovery.
|
-am
|
Automatically accept the Perforce-recommended file revision:
If theirs is identical to base, accept yours,
if yours is identical to base, accept theirs,
if yours and theirs are different from base, and there are no conflicts between yours and theirs, accept merge,
otherwise, there are conflicts between yours and theirs, so skip this file.
|
-af
|
Accept the Perforce-recommended file revision, no matter what. If this option is used, the resulting file in the client should be edited to remove any difference markers.
|
-as
|
If theirs is identical to base, accept yours;
if yours is identical to base, accept theirs;
Changes that are common to theirs and yours are not considered to belong to either file, and are accepted;
otherwise skip this file.
|
Example:
Automatically accepting particular revisions of conflicting files
Ed has been editing the files in doc/*.guide, and knows that some of them will require
resolving. He types p4 sync doc/*.guide, and all of these files that conflict with files in
the depot are scheduled for resolve.
He then types p4 resolve -am, and the merge files for all scheduled resolves are generated,
and those merge files that contain no line set conflicts are written to his client workspace.
He'll still need to manually resolve all the other conflicting files, but the amount of work he
needs to do is substantially reduced.
Binary files and "p4 resolve"
If any of the three file revisions participating in the merge are binary instead of text, a three-way merge is not possible. In these circumstances, p4 resolve performs a two-way merge: the two conflicting file versions are presented, and you can edit and choose between them.
Locking Files to Minimize File Conflicts
After you have opened a file, you can lock it with p4 lock so that only you can submit the next revision of that file to the depot. After you submit a locked file, it is automatically unlocked. You can also manually unlock files you have locked by using the p4 unlock command.
The benefit of p4 lock is that after a file is locked, the user who locked it experiences no further conflicts on that file, and never needs to resolve the file. This benefit comes at a price: other users can open the file for edit, but are unable to submit changes affecting the file until the file is unlocked, and will have to do their own resolves once they submit their revision. Under most circumstances, a user who locks a file is essentially saying to other users "I don't want to deal with any resolves; you do them."
There is an exception to this rule: Perforce also supports a +l file type modifier to support exclusive-open (pessimistic locking). If you have a +l file open for edit, other users who attempt to edit the file receive an error message.
The difference between p4 lock and +l is that p4 lock permits anyone to open a file for edit, but only the person who locked the file can submit a changelist containing that file to the depot. By contrast, files of type +l can be opened for edit by only one user at a time.
Preventing multiple resolves with p4 lock
Without file locking, there is no guarantee that the resolve process will ever end. The following scenario demonstrates the problem:
- Ed opens file file for edit.
- Lisa opens the same file in her client for edit.
- Ed and Lisa both edit their client workspace versions of file.
- Ed submits a changelist containing that file, and his submit succeeds.
- Lisa submits a changelist with her version of the file; her submit fails because of file conflicts with the new depot's file.
- Lisa starts a resolve.
- Ed edits and submits a new version of the same file.
- Lisa finishes the resolve and attempts to submit; the submit fails and must now be merged with Ed's latest file.
- ...and so on
File locking can be used in conjunction with resolves to avoid this sort of headache. The sequence would be implemented as follows:
- Before scheduling a resolve, lock the file.
- Then sync the file, resolve the file, and submit the file.
As long as the locked file is open, new versions can't be submitted by other users until the resolved file is either submitted or unlocked.
Locked files appear in the output of p4 opened with an indication of *locked*. On UNIX, you can find all locked files you have open with the following command:
p4 opened | grep "*locked*"
This lists all open files you have locked with p4 lock.
Preventing multiple checkouts with +l files
If you know in advance that a certain file is only going to be worked on by a single user, you can use the +l (exclusive-open) filetype modifier to ensure that only one user at a time can work on the file.
You can change a file's type to exclusive-open by reopening it with the +l modifier. For instance:
p4 reopen -t binary+l file.gif
Although using the +l modifier prevents concurrent development, for some file types (usually binary files), merging and resolving might not be meaningful, and some sites require pessimistic locking as a matter of policy.
Your Perforce administrator can use the p4 typemap command (see the Perforce Command Reference) to ensure that all files matching a file specification (or even all files sitewide) are assigned type +l by default.
Resolves and Branching
You also use p4 resolve to integrate changes between branches; for details about resolving branched files, see Chapter 9, Branching.
Resolve Reporting
Four reporting commands are related to file conflict resolution: p4 diff, p4 diff2, p4 sync -n, and p4 resolved.
Command
|
Meaning
|
---|
p4 diff [filenames]
|
Runs a diff program between the file revision currently in the client and the revision that was last gotten from the depot. If the file is not open for edit in the client, the two file revisions should be identical, so p4 diff fails. Comparison of the revisions can be forced with p4 diff -f, even when the file in the client is not open for edit
Although p4 diff runs a diff routine internal to Perforce, this routine can be overridden by specifying an external diff in the P4DIFF environment variable.
|
p4 diff2 file1 file2
|
Runs p4d's diff subroutine on any two Perforce depot files. The specified files can be any two file revisions, even revisions of entirely different files.
The diff routine used by p4d cannot be overridden.
|
p4 sync -n [filenames]
|
Reports what the result of running p4 sync would be, without actually performing the sync. This is useful to see which files have conflicts and need to be resolved.
|
p4 resolved
|
Reports which files have been resolved but not yet submitted.
|
The reporting chapter (Chapter 11, Reporting and Data Mining) has a longer description of each of these commands. Use the p4 help command for a complete listing of the flags and options available with these reporting commands.
Please send comments and questions about this manual to
[email protected].
Copyright 1997-2005 Perforce Software. All rights reserved.
Last updated: 05/12/05