Merge implementation
====================
This is a simple 3-way merge implementation written in AWK. It demonstrates that
the 3-way merge algorithm used in various SCM is not difficult to write nor to
understand. This implementation is not proven to be bug-free. However, it gives
similar results as git merge does.
The implementation is divided into two files:
* merge.awk - determines lines added, removed and in case of a conflict, it provides
all alternatives (prefixed with b, l, r)
* merge-solve.awk - eats output from merge.awk and generates the output diff-like
format (it is not a standardized one, however).
Examples
--------
There are two simple examples. However, the implementation has been tested on other
cases as well. Interestingly, this script beats the meld merging tool. The meld gives
very big conflicts in cases where git merge or this AWK implementation gives only
small ones.
1) Some blablabla text: base.txt, left.txt, right.txt:
$ ./merge.awk base.txt left.txt right.txt
b a true story
+ A true story
+
r this is a true story about the 3-way merge. It is nice to have a simple
b this is a true story about the 3-way merge. It is nice to have a simple
l This is a true story about the 3-way merge. It is nice to have a simple
+ script that can show, how the 3-way merge behaves.
b It is not that difficult to get the basic idea. However, a more complex example may lead to
l It is not that difficult to get the basic idea. However, a more complex
l example may lead to
l a quite complex code. The basic issue is to compute the diffs well.
b a quite complex code. The basic issue is to compute the diffs well.
r It is not that difficult to get the basic idea. However, a more complex
r example may lead to a quite complex code. The basic issue is to compute the diffs well.
+
+ End of the story.
$ ./merge.awk base.txt left.txt right.txt | ./merge-solve.awk
A true story
This is a true story about the 3-way merge. It is nice to have a simple
script that can show, how the 3-way merge behaves.
<<<<<<< LEFT
It is not that difficult to get the basic idea. However, a more complex
example may lead to
a quite complex code. The basic issue is to compute the diffs well.
|||||||
It is not that difficult to get the basic idea. However, a more complex example may lead to
a quite complex code. The basic issue is to compute the diffs well.
|||||||
It is not that difficult to get the basic idea. However, a more complex
example may lead to a quite complex code. The basic issue is to compute the diffs well.
>>>>>>> RIGHT
End of the story.
2) Some non-sense C-code: base.c, left.c, right.c
$ ./merge.awk base.c left.c right.c
+ /**
b * base.c
r * right.c
l * left.c
+ * Copyright (C) 2014 Jan Viktorin
+ */
+
r #include <assert.h>
+ #include <stdio.h>
+
+ int main(int argc, char **argv)
+ {
+ if (argc > 1)
+ printf("%s\n", argv[1]);
r else if (argc > 1)
b else if (argc > 1)
l else if (argc > 2)
+ printf("%s\n", argv[2]);
+
r assert(argc > 0);
+ printf("me: %s\n", argv[0]);
+
+ return 0;
+ }
$ ./merge.awk base.c left.c right.c | ./merge-solve.awk
/**
<<<<<<< LEFT
* left.c
|||||||
* base.c
|||||||
* right.c
>>>>>>> RIGHT
* Copyright (C) 2014 Jan Viktorin
*/
#include <assert.h>
#include <stdio.h>
int main(int argc, char **argv)
{
if (argc > 1)
printf("%s\n", argv[1]);
else if (argc > 2)
printf("%s\n", argv[2]);
assert(argc > 0);
printf("me: %s\n", argv[0]);
return 0;
}