This issue will be used to track the work needed to create two new Composer libraries, as per the first steps of this GSoC proposal: https://summerofcode.withgoogle.com/serve/6537380831952896/

  1. Library for Lowest Common Ancestor (LCA) traversal
  2. Library performing three-way merges

1. LCA traversal

We should depend on clue/graph and graphp/algorithms for creating and traversing the graph. There might even be solutions for LCA in these libraries that we should look for.

Stub code:


namespace Relaxed\LCA\LowestCommonAncerstor;

use Fhaculty\Graph\Vertex;
use Fhaculty\Graph\Graph;

class LowestCommonAncestor {

  function __construct(Graph $graph) {
    $this->graph = $graph;
  }

  function find(Vertex $local, Vertex $remote) {
    // @TODO
    return $ancestor;
  }
}

Example use:

use \Fhaculty\Graph\Graph as Graph;
use Relaxed\LCA\LowestCommonAncerstor as LCA;

$graph = new Graph();

// Create vertices.
$rev_a = $graph->createVertex('revision-A');
$rev_b = $graph->createVertex('revision-B');
$rev_c1 = $graph->createVertex('revision-C1');
$rev_c2 = $graph->createVertex('revision-C2');

// Connect edges.
$rev_b->createEdgeTo($rev_a);
$rev_c1->createEdgeTo($rev_b);
$rev_c2->createEdgeTo($rev_b);

// Search
$lca = new LCA($graph);
$ancestor = $lca->find($rev_c1, $rev_c2);

// In the above example $rev_b == $ancestor

2. Three-way merge

The three-way merge library should work on normalized arrays and be able to create a merge out of an original, local and remote versions of an array.

Ideally the algorithm should also handle merging of fields with multiple lines of text.

Stub code:


namespace Relaxed\Merge\ThreeWayMerge;

class ThreeWayMerge {

  function do(array $ancestor, array $local, array $remote) {
    // @TODO
    if ($conflict) {
      throw new MergeConflictException();
    }
    return $merged;
  }
}

Example use:


use Relaxed\Merge\ThreeWayMerge;

$original = [
  'title' => 'abc',
  'body' => "lorem ipsum",
];

$local = [
  'title' => 'abc',
  'body' => 'dolor',
];

$remote = [
  'title' => '123',
  'body' => 'lorem ipsum',
];

$merge = new ThreeWayMerge();
$merged = $merge->do($original, $local, $remote);

// $merged = [
//   'title' => '123',
//   'body' => 'dolor',
// ];

Testing

Both libraries should have PHPUnit tests.

Comments

dixon_ created an issue. See original summary.

dixon_’s picture

Issue summary: View changes
dixon_’s picture

Issue summary: View changes
dixon_’s picture

Issue summary: View changes
dixon_’s picture

Issue summary: View changes
dixon_’s picture

Issue summary: View changes
dixon_’s picture

Issue summary: View changes
rakesh_verma’s picture

If B is direct child of A and C is direct child of B, what would be the LCA of B and C? B or A??

jeqq’s picture

@rakesh_verma the LCA of B and C, in this case, would be B.

dixon_’s picture

Status: Active » Fixed

Marking this issue as fixed. As the libraries are done.

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.