This problem is known as merging. You have an original file A and two modified versions B and C, and you want to make a version D that combines both modifications. This only works if the changes are independent; otherwise, merging is a manual process. Handling merges of concurrent changes to source code is a frequent task in software engineering.
In simple cases, a patch produced by
diff will already work if the source file has changed. The
patch utility allows some “fuzz”: if you make a diff from A to B, and the areas affected by that diff are identical (but possibly at different offsets in the file) in A and C, then the patch will apply cleanly on C. This works well as long as the changed areas in B and C aren't at the same locations (there has to be a couple of lines' separation).
When patches don't apply cleanly, merging is a difficult and domain-specific problem. For example, consider these two changes:
A B C
a=2 a=3 b=2
x=a x=a x=b
Human beings tend to spot the pattern that B has changed
3 and C has renamed
b, so the result of the merge should be
x=b. But automated tools are likely to flag the first line as a conflict, because it's been modified in two different ways.
Writing a patch that “does something sensible” to both B and C is a difficult (AI-complete) problem. In practical cases, for many typical situations, using
diff -u A B as the patch tends to either work and produce the desired D out of C, or fail with an error stating that the patch doesn't apply cleanly.