Documentation

Unity Version Control

MERGE

Merge changes with the Unity Version Control CLI.
Read time 13 minutesLast updated 6 days ago

Description

Merges a branch with another branch.

Usage

cm merge <source_spec> [--merge] [--cherrypicking] [--forced] [--mergetype=(onlyone|onlysrc|onlydst|try|forced)] [--interval-origin=<csetspec> | --ancestor=<csetspec>] [--keepsource | --ks] [--keepdestination | --kd] [--automaticresolution=<conflict-types>[;...]] [--subtractive] [--mount] [--printcontributors] [--noprintoperations] [--silent] [(--to=<brspec> | --destination=<brspec>)[--shelve] [--fileconflictsresolutionsfile=<path>]] [--no-dst-changes] [-c=<str_comment> | --commentsfile=<comments_file>] [--resolveconflict --conflict=<index> --resolutionoption=(src|dst|(rename --resolutioninfo=<strname>)) --mergeresultfile=<path> --solvedconflictsfile=<path>] [--conflict-markers] [--nointeractiveresolution] [--machinereadable [--startlineseparator=<sep>] [--xml] [--encoding] [--endlineseparator=<sep>] [--fieldseparator=<sep>]]
Use the following syntax to list the files that still contain conflict markers:
cm merge --list-conflict-markers
Use the following syntax to mark one or more files that contain conflict markers as resolved:
cm merge --mark-resolved <path>[ ...]

Options

Option / Argument

Description

--mergePerforms the merge. Otherwise, prints the conflicts found.
--cherrypickingMerges the changes included on the source changesets. This option is not used if the merge source specification is a label.
--forcedDoes not check if the source and destination are already connected. This option is only available for interval merge and cherry picking.
--mergetypeType of the merge. See Remarks for more info.
--interval-originSpecifies which changeset is chosen as the interval origin, so the merge will only take the differences between the source changeset and the specified interval origin.
--ancestorThis is an alias of '--interval-origin'.
--keepsourceAccepts all changes from source contributor for items with conflicts.
--keepdestinationPreserves changes from destination contributor for items with conflicts.
--conflict-markers
Writes the conflicts of text files into the workspace files between diff3-style conflict markers, instead of launching a merge tool. Refer to Remarks for more info.
--list-conflict-markers
Lists the files merged with conflict markers that still contain them. Exits with code 1 while any file remains. Can't be combined with other merge options.
--mark-resolved
Marks the specified files as resolved without checking their content, even if they still contain conflict markers. Use it when the marker text is intentional. Can't be combined with other merge options.
--fileconflictsresolutionsfile
Used with
--to
and
--merge
, resolves the file conflicts of a merge-to with the resolutions in the specified JSON file, without asking: for each file, keep one contributor or use a file already merged. Takes precedence over
--keepsource
and
--keepdestination
, which still apply to the conflicts that aren't in the file. Refer to Remarks for more info.
--automaticresolutionUsed to resolve directory conflicts. This option lets you choose whether the source or the destination contributor should be automatically selected to resolve the conflict. Use a semicolon to separate conflict types. See Remarks for more info.
--subtractiveDeletes changes introduced by a merge. The parameter passed to the command (source_spec) is used to specify which is the source to delete changes. It must be a changeset. In the case of a changeset interval, the '--interval-origin' must be used to define the interval origin. To remove a change, the system creates a new checked out revision which will have the content of the previous one except for the deleted changes.
--mountThe mount point for the given repository.
--printcontributorsPrints the contributors (base, source, and destination).
--noprintoperationsSilently resolves merges without showing information about the resolution.
--silentNo output is shown unless an error happens.
--to | --destinationPerforms a merge-to operation to the specified branch (by entering a branch spec or brspec) with full conflict resolution. (Use 'cm help objectspec' to learn more about branch specs.) A "merge-to" (or workspace-less merge) is a merge done in the server side. While normal merges happen on a workspace merging "from" a branch, label or changeset, a merge-to happens entirely on the server. While in normal merges the "destination" is the workspace, in "merge-to" a destination must be always specified (that's why we call it "to"). Check the following link for more information about the "merge to" feature: https://www.plasticscm.com/download/help/mergeto
--shelveCreates a shelve with the changes of the merge result (plus merge traceability info) instead of creating a new changeset. This option is not available when the merge source is a shelve. This option is only available for server-side-merge (a.k.a. "merge-to"). Hence, the '--to' and '--merge' options are required.
--no-dst-changesEnsures that the destination contributor doesn't have changes (the destination changeset is also the common ancestor). When there are changes on the destination, the merge is not allowed.
-cApplies the specified comment to the changeset created in the merge operation.
--commentsfileApplies the comment in the specified file to the changeset created in the merge operation.
--resolveconflict(Mainly used by plugins. See Remarks for more info.) Used to solve a directory conflict.
--conflictUsed with the '--resolveconflict' flag, specifies the index of the conflict to solve starting at 1.
--resolutionoptionUsed with the '--resolveconflict' flag, indicates the type of the conflict resolution. Use one of the following options: 'src', 'dst', 'rename'. See Remarks for more info.
--resolutioninfoUsed with the '--resolveconflict' flag, provides the name to use when the '--resolutionoption' option is 'rename'.
--mergeresultfileUsed with the '--resolveconflict' flag, outputs into a file the information of the merge result between different calls .The specified path will be created during the first call and updated on each next call.
--solvedconflictsfileUsed with the '--resolveconflict' flag, outputs into a file the information of the conflicts solved between different calls. The specified path will be created during the first call and updated on each next call. --nointeractiveresolution (Mainly used by plugins. See Remarks for more info.) Avoids prompting the user for manual conflict. This way, a directory conflict won't be solved.
--machinereadable(Mainly used by plugins. See Remarks for more info.) Outputs the result in an easy-to-parse format.
--xmlPrints the output in XML format to the standard output. It is possible to specify an output file. This option cannot be combined with '--format' nor '--resolveconflict'.
--encodingUsed with the '--xml' option, specifies the encoding to use in the XML output, i.e.: utf-8. See the MSDN documentation at http://msdn.microsoft.com/en-us/library/system.text.encoding.aspx to get the table of supported encodings and its format, (at the end of the page, in the "Name" column).
--startlineseparatorUsed with the '--machinereadable' flag, specifies how the lines should start. (Default: empty string.)
--endlineseparatorUsed with the '--machinereadable' flag, specifies how the lines should end. (Default: empty string.)
--fieldseparatorUsed with the '--machinereadable' flag, specifies how the fields should be separated. (Default: whitespace.)
source_specSpecification of the source object to merge from (See Remarks for more info.)

Help

Remarks

This command is used to merge changes between two branches or between a label and a branch. The destination of the merge must be always a branch. The merge source is specified as an argument. Destination is the current content of the workspace. For example, to display the elements that will be merged from branch task001 to the main branch, the selector must point to the main branch, the workspace must be updated, and then:
cm merge br:/task001

To really perform the merge, '--merge' option is added

cm merge br:/task001 --merge

To define the merge source, the following specs can be used

  • Branch specification (brspec):
    • cm merge [br:/]br_name
    • Example: cm merge br:/main/task001 (Merges from the last changeset on this branch.)
  • Label specification (lbspec):
    • cm merge lb:lb_name
    • Example: cm merge lb:BL001 (Merges from the labeled changeset.)
  • Changeset specification (csetspec):
    • cm merge cs:cs_number
    • Example: cm merge cs:25 (Merges from the given changeset content.)
  • Shelve specification (shspec):
    • cm merge sh:shelve_number
    • Example: cm merge sh:2 (Merges from the given shelve content.)
To automatically resolve directory conflicts, use '--automaticresolution' option and specify the type of conflict followed by the contributor (source or destination) that must be selected during the merge operation. Separate each pair of conflict type and contributor with a semicolon (
;
). For example:
cm merge cs:2634 --merge --automaticresolution=eviltwin-src;changedelete-src
This merge from changeset 2634 resolves the
eviltwin
and
changedelete
conflicts by keeping the source contributor (
-src
) in both cases.
  • A "-src" suffix after a conflict type tells the merge command to keep the source contributor changes.
  • A "-dst" suffix will keep the destination contributor changes.

This is the list of conflict types the merge command supports

  • movedeviltwin
  • eviltwin
  • changedelete
  • deletechange
  • movedelete"
  • deletemove
  • loadedtwice
  • addmove
  • moveadd
  • divergentmove
  • cyclemove
  • all
The "all" value overrides the other options. In the following example, "eviltwin-dst" will be ignored:
cm merge br:/main/task062 --merge --automaticresolution=all-src;eviltwin-dst

These are the options for '--mergetype'

Option / Argument

Description

onlyoneAutomatic merge if only one contributor modified the item.
onlysrcAutomatic merge if only source contributor modified the item.
onlydstAutomatic merge if only destination contributor modified the item.
tryAutomatic merge if only one contributor has modified the conflictive piece of code (each conflict).
forcedAlways try to solve all non-automatic conflicts.

Resolve merge-to file conflicts from a file

To resolve the file conflicts of a merge-to without asking, use
--fileconflictsresolutionsfile
with a UTF-8 JSON file like this one:
{ "resolutions": [ { "path": "/src/Player.cs", "resultFile": "/tmp/merged/Player.cs" }, { "path": "/art/logo.png", "keep": "source" }, { "path": "/README.md", "keep": "destination" } ]}
  • path
    is the path of a conflicting file, exactly as the first field of its
    FILE_CONFLICT
    line in the output of
    cm merge <source_spec> --to=<brspec> --machinereadable
    . That's its path on the destination. A file inside a writable xlink uses its full path, starting with the path of the xlink.
  • keep
    is
    source
    or
    destination
    : the file keeps the revision of that contributor.
  • resultFile
    is the absolute path of a local file whose content becomes, as it is, the result of merging that file.
Each resolution has either
keep
or
resultFile
. The merge tool never opens for the files in the list. Conflicts that aren't in the list are resolved as without this option, for example with
--keepdestination
. If any resolution isn't valid, nothing is merged. The command never changes or deletes the JSON file or the result files.

Resolve conflicts on disk with conflict markers

With
--conflict-markers
, the merge doesn't launch a merge tool for text file conflicts. Instead, it writes the regions that both contributors changed into the workspace file, between conflict markers in the standard diff3 format. Use this mode when the caller can't drive a GUI, such as a script or a coding agent.
Each marked region holds the workspace content, the incoming content, and the common ancestor as context:
<<<<<<< destination: /src/Foo.cs@cs:57@/main (workspace) return Compute(x);||||||| base: /src/Foo.cs@cs:50@/main (common ancestor, context only) return Calc(x);======= return Compute(x, y);>>>>>>> source: /src/Foo.cs@cs:58@/main/task001 (incoming)
Each label names the file with the same workspace path that the command prints in its
CONFLICT_MARKERS
line, on every platform, so a script can match one with the other. You can resolve the file by editing the text, or with any tool that reads the diff3 format, such as VS Code, Rider, KDiff3, or Beyond Compare.
If a contributor deleted the region, its section is empty. The marker lines use the line endings and the encoding of the file.
The command prints one
CONFLICT_MARKERS <path>
line for each file, and exits with code 1 while any file is still pending.
cm status
and
cm merge --list-conflict-markers
list those files.
cm checkin
refuses the check-in while one of them still contains the markers, and names the file.
To finish the merge, remove the markers. If the marker text is intentional, run
cm merge --mark-resolved
on the file instead.
The command reports binary files, symlinks, and recursive merges whose intermediate merge has conflicts as unresolved, with an
UNRESOLVED <path> (binary|symlink|recursive)
line, and doesn't launch a merge tool for them. The merge stays in progress until you resolve the conflicts, for example with
--keepsource
or
--keepdestination
on that path.
With
--mergetype=onlysrc
,
--mergetype=onlydst
, or
--mergetype=onlyone
, a file with any conflict gets every region that both contributors changed written between markers, including the regions that would otherwise merge automatically.
Running the merge again with
--conflict-markers
leaves the files that were already merged with markers untouched.

These are the options that are mainly used by plugins and integrations

  • '--resolveconflict' to solve a directory conflict. You also have to use the following options:
    • '--conflict' is the index of the conflict that you want to solve, starting at 1.
    • '--resolutionoption' indicates the conflict resolution to use. This can be:
      • 'src' to keep the source change and discard the destination change
      • 'dst' to keep the destination change and discard the source change
      • 'rename' (only if the conflict type supports this resolution), to rename the destination to the given name provided with the '--resolutioninfo' option.
        • '--resolutioninfo' to provide the name to use on a 'rename' resolution
    • '--mergeresultfile' and '--solvedconflictsfile', both used to store the merge info between different calls.
  • '--nointeractiveresolution' indicates the merge to not ask the user for manual conflict resolution.
  • '--machinereadable' and '--startlineseparator', '--endlineseparator', '--fieldseparator' options to print the output on a machine-readable way (easier-to-parse).
Set the PLASTICEDITOR environment variable to specify an editor for entering comments. If the PLASTICEDITOR environment variable is set, and the comment is empty, the editor will be automatically launched to allow you to specify the comment.

Specification of the source

Option / Argument

Description

Branch specification'[br:/]br_name'
Label specification'lb:lb_name'
Changeset specification'cs:cs_number'
Shelve specification'sh:shelve_number'
For more information about specs, run
cm help objectspec
.

Examples

The following example doesn't merge, and only prints the items to merge:
cm merge br:/task001
The following example merges from branch
task001
:
cm merge br:/task001 --merge
The following example merges from branch
task001
, and writes text file conflicts into the workspace files between conflict markers instead of launching a merge tool:
cm merge br:/main/task001 --merge --conflict-markers
The following example cherry-picks the changes in the changeset interval (2,5]:
cm merge cs:5 --merge --cherrypicking --interval-origin=cs:2
The following example performs a subtractive merge from changeset 8, and keeps the destination changes for elements with conflicts:
cm merge cs:8 --merge --subtractive --keepdestination
The following example performs a server-side merge, also called a merge-to, from branch
task001
to branch
main
, and sets a comment:
cm merge br:/main/task001 --to=br:/main --merge -c="Integrated new UI"
The following example performs a server-side merge from branch
task001
to branch
main
, and leaves the result on a shelve:
cm merge br:/main/task001 --to=br:/main --merge --shelve
The following example performs a merge-to from branch
task001
to branch
main
. The file conflicts listed in
resolutions.json
are resolved as the file says, and the rest keep the destination:
cm merge br:/main/task001 --to=br:/main --merge --keepdestination --fileconflictsresolutionsfile=/tmp/resolutions.json
The following example applies shelve 2 to
main
only if the shelve was created from the current head of
main
:
cm merge sh:2 --to=br:/main --merge --no-dst-changes
The following example is for plugins and integrations:
cm merge --machinereadable --startlineseparator=start@_@line --endlineseparator=new@_@line --fieldseparator=def#_#sep --mergeresultfile=C:\Users\Borja\AppData\Local\Temp\2tmp4D6C.tmp --solvedconflictsfile=C:\Users\Borja\AppData\Local\Temp\2tmp4D6D.tmp --resolveconflict --conflict=1 --resolutionoption=rename --resolutioninfo=bin_dst br:/main/task --merge