Like finely tuned, crafted car engines outperforms mass-produced engines, Plastic SCM's merge engine
throttles with precision and power unseen in the industry. Unparalleled edge case coverage, turning
near-impossible cases into cake.
The reasons behind strong merging
As developers we require strong merging in order to support best development practices such as:
Get it rendered!
The Branch Explorer simplifies the merging process and helps the user understand the entire branching and
merging workflow.
Branch speed
Creating branches quickly is the key to implementing any successful branching and merging pattern. Creating
a
new branch should take less than a second, even when the codebase is bigger than 500k files.
Parallel development
No limits in which files you touch to fix a bug or create a new features, hence removing bottlenecks that
kill productivity
Refactoring
Keeping the code quality high reduces maintenance costs in the medium and long terms. Software development
used to have a truly pessimistic idea regarding how development costs evolved through time, but keeping
them low is the key behind the success of many software companies, empowered by the refactor technique:
Get it rendered!
The Branch Explorer simplifies the merging process and understanding the entire branching and
merging workflow.
It is able to:
Create new branches and labels.
Run all the merge operations (merge, merge to, cherry pick, subtractive, interval merge,
interval subtractive).
Launch replication operations (push and pull a given branch).
Visualize changes from remote repositories: the entire remote repository combined with the local or just
remote changes from a remote branch.
Diff changesets, labels and branches.
Launch code reviews.
Run update and switch-to branch operations.
Figure. Complex branch and merge situation rendered by the Branch Explorer.
Changesets from different sources in different colors.
Figure. Branch subdiagram showing only the pending merges to Fix-4.1.
Changesets coming from different repository replicas are rendered in different colors.
Figure Branch Explorer explaining the merge contributor.
Figure. Branch Explorer showing an in-progress subtractive merge from interval.
Branch speed
Creating branches fast is key to implement any successful branching and merging pattern.
Creating a new branch should take less than a second, even when the codebase is bigger than 500k files.
The difference between the older version controls and the newer ones is related to their capabilities
to create branches fast.
Older systems like Subversion, CVS, Perforce and others, relied on some sort of "copying" to create a
new branch, which means it is a time consuming operation. The copy can be optimized to be light, but as
soon as it is proportional to the number of files in the branch... it will end up being a blocker for
branch creation.
Plastic SCM uses the newer paradigm where a branch simply "inherits" from a given changeset, then
creating a new branch is not tied to the number of files in the codebase, the time is linear, and as
low as just a few miliseconds, even when the system is handling more than 500k files on the branch.
You can find more info about merge and conflict resolution in the
Plastic SCM Book
File conflicts
Plastic SCM provides a built-in 3-way
xmerge and xdiff tool able to handle the complex
cases plus the only one with moved code support.
Description
File merging is about combining what developers wrote in parallel to create a new resulting version
of the code. File conflicts will only happen when the same file has been modified in parallel. When
that happens, a good merge engine will need to locate the three contributors that are always involved
in a file merge.
The three contributors on a merge are:
The base or common ancestor: how the file was before being modified.
The source (or "theirs" in some tools' jargon): the code you're merging from.
The destination (or "yours"): the code you're merging to.
Additionally you consider the "result": the product of combining the three contributors.
Plastic SCM is able to render it using the Branch Explorer as follows:
A good merge engine will be able to handle many file conflicts automatically. That's why merge-tracking
(being able to correctly determine the 3 contributors) is key:
If only one of the contributors has been modified, the merge result is the CHANGED contributor.
Finally, there will be cases where, as the image above shows, the file has been modified in parallel.
That's when you will need a good 3-way merge tool.
Plastic SCM includes its own built-in merge tool capable of turning several complex cases into
automatic ones (provided the same line of code is not modified in parallel) and it is the only tool
including Xmerge and Xdiff to track code that has been
moved and modified.
To learn more about file merging, click here to find out why a 3-way merge is much better than older
2-way merges.
Optionally, you can plug in your preferred 3-way merge tool and still enjoy Plastic SCM's core merge
engine benefits.
You can find more info about file conflicts in our
Book
Files moved and modified
You move a file on a branch, and someone modifies it in a different one. The merge will handle the
rename and the modification correctly.
Description
It is a very common case when the code is being restructured (refactored) and it continues evolving
in parallel.
One developer decides to rename a file while, in parallel, a different developer has to make a
modification on the file.
The version control should be able to reconcile the two changes together: rename the file and
introduce the changes made by the other developer.
But still it is one of the most common reasons why teams avoid branching or are scared of working
in parallel: many version control tools fail to handle this simple case and will end up with two
files: the renamed one without the changes made by the second developer, and the modified one
including the changes but not the rename.
Plastic SCM is able to handle the case correctly.
Simple case
Developer one modifies /src/render/3d.c.
Developer two first modifies /src/render/3d.c, then renames 3d.c to engine.c.
After merge the resulting /src/render/engine.c must contain the changes made by both developers
and the old 3d.c shouldn't exist.
Complex case
The complex case would include not only a rename but also a move.
Developer one modifies /src/render/3d.c.
Developer two moves /src/render/3d.c to /src/opengl/base.c and modifies it.
After merge the result file must be /src/opengl/base.c and it must contain the merged changes
from the two contributors.
How Plastic SCM handles the case - What others do
The following picture shows how Plastic SCM is able to track the move and also find the file as
modified by the two contributors.
You can find more info about merging moved files in our
Book
Change/delete
Happens when you modify a file, and somebody else deletes it in parallel. Useful for refactors.
Description
It happens when a developer decides to delete a file and in the meantime it is deleted by a
different developer.
Since the new change can be an important one and preserving it key for the project, the version
control has to warn during the merge and let the developer choose between deleting the file and
preserving it.
Plastic SCM is able to handle the case correctly.
Simple case
Developer one modifies /src/render/3d.c.
Developer two deletes /src/render/3d.c.
During merge, the version control must warn about the conflicting operation and let the
developer choose:
Keep 3d.c deleted, and then discarding the changes from the other contributor.
Recover 3d.c and even merge it with the other contributor (if it was modified prior to be removed).
Complex case
There are many derived complex cases, since there are several possible combinations.
One slightly more complex case than the simple one involves deleting the directory containing the
file that is modified in parallel:
Developer one modifies /src/render/3d.c.
Developer two deletes /src/render.
During merge the version control must detect the case and allow the developer to recover the
deleted items or keep the deletion.
How Plastic SCM handles the case
The picture shows how Plastic SCM specifically handles the change/delete conflict helping the
developer doing the merge to find a safe solution.
You can find more info about change/delete conflicts in our
Book
Add/move
You add a file and, in another branch, somebody moves an existing file to the same location.
The merge will handle it and let you solve the case.
Description
The conflict happens when a developer adds a file and in parallel a different developer moves
an existing file so that it collides with the added one.
The version control system must detect the situation and let the developer decide what to do.
Simple case
Developer 1 adds src/foo.c.
Developer 2 moves core/bar.c to /src/foo.c.
During merge the version control system has to detect a conflict and let the user decide:
Keep the added foo.c: means you keep the added file and you undo the move
(so it stays in core/bar.c)
Keep the move: means you undo the added src/foo.c and you keep the move.
Rename the added or the moved: so that you can keep both but with different names.
Another alternative would be to merge the two (2-way merge would be required since they do
not have any common history).
Complex case
The complex case will involve directories for this type of conflict. Conceptually it will be
similar to the "simple case" but dealing with directories will make it more complex. Suppose
the following scenario:
Developer one modifies /src/render/3d.c.
Developer two deletes /src/render.
During merge the version control must detect the case and allow the developer to recover the
deleted items or keep the deletion.
How Plastic SCM handles the case
The add/move conflict is also handled explicitly by Plastic SCM, so the tool drives the developer and shows him the different alternatives to resolve the situation.
You can find more info about add/move conflicts in our
Book
Move/delete
You move a file or a directory into a different location, and in a different branch the destination
is deleted. If the version control doesn't warn you... you could end up losing valuable changes!
Description
This case involves one developer moving a file and the other deleting it in parallel.
Simple case
The simple case can be described as follows:
Developer 1 moves src/foo.c to src/bar.c.
Developer 2, in parallel, decides to delete his copy of src/foo.c.
During merge the system must detect the scenario and let the user decide whether he wants to
keep the deletion or the move.
Complex case
The complex case will involve using one directory. Suppose the following scenario:
Developer 1 modifies src/foo.c then moves src/foo.c into core/bar.c.
Developer 2 deletes the directory "core".
If the case is not detected correctly, the change made by Developer 1 will be lost, together
with the file core/bar.c.
How Plastic SCM handles the case
Plastic SCM detects the move/delete conflict and lets the user choose: whether he keeps the deletion
or preserves the change (undoing the deletion from the other contributor).
You can find more info about move/delete conflicts in our
Book
Divergent move
Happens when the same file or directory is renamed or moved to two different locations in parallel. The version control should help you setting the right location.
Description
This is one of the best cases to understand the power of a merge engine. It involves two developers
moving a file (or directory) to two different locations.
Simple case
The simple case is as follows:
Developer 1 renames foo.c to bar.c.
Developer 2 renames foo.c to moo.c.
The merge engine must detect the divergent rename and help the user keeping one of the two.
Complex case
Developer 1 moves com/render/OpenGL.java to com/engine/GLRender.java and modifies the file.
Developer 2 decides to move com/render/OpenGL.java to com/core/GL.java and modifies the file.
The merge engine must be clever enough to detect the "divergent move" scenario and first let
the user decide which move he wants to keep and then merge the files.
How Plastic SCM handles the case
The divergent move scenario is problematic for all version control systems but Plastic SCM is able
to deal with it specifically. In case the file was modified in both contributors, the file merge
would be handled after resolving the directory situation.
You can find more info about divergent move conflicts in our
Book
Cycle move
Not so usual but can happen if you move one directory inside a different one
(src into code/src) and in the meantime somebody else performs the opposite operation
(code intro src/code).
Description
What if the result of two directory moves creates a cycle? This is exactly what this
scenario is about.
Simple case
The case of cycle move is as follows:
Developers 1 and 2 start with a directory tree with the following structure:
/
/src
/doc
Developer 1 moves src to doc/src.
Developer 2 moves doc to src/doc.
The merge of the two operations would create a cycle, so the merge engine must detect it and help
developers decide which is the one to keep.
Complex case
The directory cycle can be more complex:
Developers start with the following structure:
/
/src
/src/client
/src/client/gui
/doc
/doc/gui
Developer 1 moves /doc to /src/client/gui/documentation.
Developer 2 moves /src/client to /doc/gui/client.
The result is a directory cycle if not handled correctly.
How Plastic SCM handles the case
The cycle move is a really complex scenario. The picture below shows how Plastic SCM specifically
handles the case.
You can find more info about cycle move conflicts in our
Book
Evil twin variations
Evil twins happen when an item with the same name (file or directory) is added in two parallel
branches.
Description
There are several types of "evil twins" but they all share the same concept: two different items
(files or directories) are added to the same location with the same name. They're not the same
element so they are what we call "evil twins".
The possible cases are:
Added / added: two developers add a file with the same name on the same location.
Moved / moved: two developers move different files to the same destination.
Variations of the cases above.
Simple case
Consider the following case:
Developer 1 adds /src/multiply.c on a branch.
Developer 2 adds /src/multiply.c on a different branch.
During merge, the version control will detect that the two files have been added and will let
the user choose the right solution.
Complex case
The complex case involves a move/move scenario:
Developer 1 moves kernel/timer.c to time/timecheck.c.
Developer 2 moves src/foo.c to time/timecheck.c.
Obviously they're not the same element so the version control system must deal with the scenario
and let the user choose what to do.
How Plastic SCM handles the case
The following picture shows a moved evil twin scenario (the complex case described above) and how Plastic SCM specifically deals with the situation.
You can find more info about evil twin conflicts in our
Book
Merge types
The Plastic SCM merge engine can deal with different kinds of merges that will be covered in
this section.
Regular merge
Regular merge happens when you just need to merge a branch or a changeset into a different branch.
Like in other version controls, the operations to perform are simple: you position yourself on the
destination then merge "from" the source. Once the merge is done, your repository
(and Branch Explorer) will look like this:
You tell Plastic SCM the "source" and "destination" contributors and it will calculate the "base"
(which won't always be as trivial as in this example) and will help you creating the "result". The
merge-machine is the motor powering the process.
You're merging into "main" the changes made in the changesets inside the branch "main/bug2061".
Cherry pick
Sometimes you don't need to get all the changes you made on a branch but just a single change.
In that case, you need to use "cherry pick" merge.
In the example below, suppose you just want to get the changes made in changeset "15" instead of the
entire "main" branch. You'll run a "cherry pick" from changeset "15".
Branch cherry pick
Suppose you want to merge just the changes made on a branch but not the ones coming from its parents.
If this is the case, you will be using "branch cherry pick".
The figure below shows an example where you want to merge the changes in "main/task10/task12" branch,
but not the changes made on "main/task10". If this is the case, you'll need to run a "branch
cherry pick" and the Branch Explorer will reflect the scenario with a graphic like the one below.
Interval cherry pick
Sometimes you need to merge changes made between two changesets, but the changesets do not
correspond to a full branch. If this is the case, you will need to use "interval cherry pick" as the
figure below shows.
You will be merging the changes done in changesets "6" to "8" (actually [6-8] range) and the Branch
Explorer will reflect the situation like the graphic above.
Please note that "branch cherry pick" is just a particular case of "interval cherry pick".
Subtractive merge
This is one of the most powerful merge cases that will help you undoing specific changes, like for
instance a broken bugfix.
Look at the figure below:
Suppose you want to get rid of the changes made on the changeset "92", but you still want to preserve
the ones done in changesets "93", "94" and "95". You can "subtract-merge" changeset "92" and get a new changeset "96"
with the changes of "93", "94" and "95" but without the ones of "92". It is like running the merge in reverse order.
Like all Plastic SCM merges it can be run from the Branch Explorer with just a few clicks.
Merge-to
All merges in Plastic SCM stick to this pattern: you put your workspace on the destination then
merge from the source.
"Merge-to" is different. Suppose you want to "merge-up" some changes from your branch to another
one and there can be conflicts like in the figure below:
Your workspace can be set to "main/scm121" like in the figure and you can "merge-to" branch "main"
to branch "main/scm141" directly creating a new changeset. You do not need to switch your workspace to "main/scm141"
before doing that and the new changeset will be automatically created after merge, no need
for checkin.
This "merge-to" mechanism is good for some "deploy" scenarios but we strongly recommend to build
and test your code prior to checkin a merge.