August 12, 2013

Resolve in the Face of Adversity

Healthcare
Traceability

p4-identifierSince the 2013.2 release adds a new piece of file metadata that may need to be resolved when merging (charset, associated with the undoc server.filecharset setting), this seems like a good time for a quick review of all of the different things that "p4 resolve" might ask you about.

The function of resolve, at its heart, is to take changes from a depot file and make sure you've accounted for them in your workspace file. Different commands will schedule resolves for different reasons:

  • "p4 sync" will schedule a resolve against a depot revision that was submitted while you were editing your workspace file
  • "p4 unshelve" will schedule a resolve against a shelved file that needs to be merged into your workspace file
  • "p4 integrate" will schedule a resolve against a file in one branch that needs to be merged into your workspace file in another branch

In all of these cases, you will end up with a resolve whose job is to take some set of changes from some file in the depot("theirs") and propagate them into the file in your workspace("yours"). To make sure this is done correctly, the resolve command will ask you to make a choice. The default action for the resolve will be to merge "their" changes with "your" changes, but you can also opt to overwrite your changes with their changes ("copy"), or to leave your file unchanged without taking any actions ("ignore") -- regardless of which option you choose, it will be recorded that "your" file has taken "their" changes into consideration and is okay to submit.

Once upon a time (prior to 2011.1), the only purpose of "p4 resolve" was to merge file contents. Any other differences generally needed to be handled manually -- if sets of files in two branches had been renamed, for example, the branch view would need to be modified so that they mapped into each other and could be merged correctly. Newer versions of the server can handle a wider variety of situations by scheduling a resolve and prompting you to decide how different types of change should be handled.

The following examples use the command line client, but the basic behavior is the same in other UIs.

A content resolve handles content differences between files. When doing a content resolve between text files, a three-way merge is performed (if there is a base to use for the merge) and presented to you.

 c:\test\resolve\yours - merging //depot/resolve/theirs#2
 Diff chunks: 2 yours + 1 theirs + 0 both + 0 conflicting
 Accept(a) Edit(e) Diff(d) Merge (m) Skip(s) Help(?) am: 

Content resolves are the trickiest since they have the widest array of possible outcomes -- in addition to "theirs" and "yours", you might choose to accept "merged" (an automatic merge result), or you might choose to "edit" the merged file (this might be necessary in order to handle conflicts), or you might run an external merge application instead.

The action taken by a content resolve is to modify your workspace file to incorporate content changes made in their file.

A filename resolve handles files that have been moved. Filename resolves are different from other types of resolve in that "theirs" may not be an actual depot file -- it instead represents a depot path that you can choose to move "your" file to, which in many cases does not yet have an actual file in it (it might be a path that was mapped from a moved file in another branch, for example).

 c:\test\resolve\B\2\foo - resolving move to //depot/resolve/B/1/bar
 Filename resolve:
 at: //depot/resolve/B/1/bar
 ay: //depot/resolve/B/2/foo
 am: //depot/resolve/B/2/bar
 Accept(a) Skip(s) Help(?) am:

Note that as of 2013.2, a filename resolve is used to handle the case where a file was moved while you were editing it -- in this case, "theirs" is an existing depot file, and when your file is moved to that path it will have the effect of reopening that file for edit rather than opening it for move (since it has already been moved).

The action taken by a filename resolve is to move your workspace file to incorporate filename changes made in their file.

A branch resolve handles files that may or may not need to be branched. Branch resolves are typically scheduled when you're attempting to merge from an existing file into a file that does not exist, and you might want to either copy the existing file in its entirety or ignore it. The file will start off being opened for "delete" and a branch resolve will be scheduled.

 c:\test\resolve\nosuchfile - resolving branch from //depot/resolve/theirs#2
 Branch resolve:
 at: branch
 ay: ignore
 Accept(at/ay) Skip(s) Help(?) s:

The action taken by a branch resolve is to reopen your workspace file for "branch" so that it matches their file.

A delete resolve handles files that may or may not need to be deleted. Delete resolves are typically scheduled when you're attempting to merge from a deleted file into an existing file, and you might want to either delete the existing file or leave it alone. The file will start off being opened for "integrate" and a branch resolve will be scheduled.

 c:\test\resolve\yours - resolving delete from //depot/resolve/theirs#3
 Delete resolve:
 at: delete
 ay: ignore
 Accept(at/ay) Skip(s) Help(?) s:

The action taken by a delete resolve is to reopen your workspace file for "delete" so that it matches their file.

A filetype resolve handles files with different filetypes. Filetype resolves are scheduled when merging files with different filetypes.

 c:\test\resolve\yours - resolving filetype from //depot/resolve/theirs#2
 Filetype resolve:
 at: (text+x)
 ay: (text)
 Accept(a) Skip(s) Help(?) at:

The action taken by a filetype resolve is to reopen your workspace file with a new filetype so that it incorporates changes made in their file.

An attribute resolve handles files with different attributes. Attribute resolves are scheduled when merging files with different attributes. By default, an attribute resolve will attempt to propagate the "propagating" attributes (set with "p4 attribute -p") while ignoring "non-propagating" attributes.

 c:\test\resolve\yours - resolving attributes from //depot/resolve/theirs#2
 Attribute resolve:
 at: overwrite your open attributes with their set of 1 attribute(s)
 ay: leave your set of 0 open attribute(s) unchanged
 Accept(a) Skip(s) Help(?) ay: 

The action taken by a filetype resolve is to modify the attributes of your open workspace file so that it incorporates attribute changes from their file.

Charset resolves are new to 2013.2, and only affect "unicode" typed files. They function very similarly to filetype resolves, and are only scheduled when merging between two Unicode files that are associated with different charsets.

 c:\test\resolve\yours - resolving charset from //depot/resolve/theirs#2
 Charset resolve:
 at: overwrite your open character set with their character set of utf8
 ay: leave your character set of utf16 unchanged
 Accept(a) Skip(s) Help(?) at: 

The action taken by a charset resolve is to modify the charset associated with your open workspace file so that it matches their file.

When running "p4 resolve" from the command line, you can limit the actions resolve will take by using the -A flag to only see certain types of resolve and effectively skip the others:

            -Aa         Resolve attributes.
            -Ab         Resolve file branching.
            -Ac         Resolve file content changes.
            -Ad         Resolve file deletions.
            -Am         Resolve moved and renamed files.
            -At         Resolve filetype changes.
            -AQ         Resolve charset changes.

Resolves that you skip will still need to be completed before you can submit.

See also these earlier blog entries on filename, filetype, branch, and delete resolves:

Merging moves

Resolving Filetypes

Ignoring Branches (and Deletes)