Cuando se trabaja con revisiones de texto, a veces uno se enfrenta al problema de que hay varias revisiones basadas en el mismo texto original. En lugar de elegir una y descartar la otra, queremos fusionar las dos revisiones.
Git ya lo hace maravillosamente. En una aplicación php queremos una herramienta simple que haga lo mismo. Existe la extensión xdiff PECL que tiene la función xdiff_string_merge3. Pero xdiff_string_merge3
no se comporta de la misma manera que git y es posible que xdiff no esté disponible en su sistema.
PhpMerge es una pequeña biblioteca que resuelve este problema. Hay dos clases: PhpMergePhpMerge
y PhpMergeGitMerge
que implementan PhpMergePhpMergeInterface
que solo tiene un método merge
.
PhpMerge
usa SebastianBergmannDiffDiffer
para obtener las diferencias entre las diferentes versiones y calcula el texto combinado a partir de ellas. GitMerge
usa SymplifyGitWrapperGitWrapper
, escribe el texto en un archivo temporal y usa la línea de comando git para fusionar el texto.
Ejemplo sencillo:
use PhpMerge PhpMerge ;
// Create a merger instance.
$ merger = new PhpMerge ();
// Get the texts to merge.
$ original = <<<'EOD'
unchanged
replaced
unchanged
normal
unchanged
unchanged
removed
EOD;
$ version1 = <<<'EOD'
added
unchanged
replacement
unchanged
normal
unchanged
unchanged
EOD;
$ version2 = <<<'EOD'
unchanged
replaced
unchanged
normal??
unchanged
unchanged
EOD;
$ expected = <<<'EOD'
added
unchanged
replacement
unchanged
normal??
unchanged
unchanged
EOD;
$ result = $ merger -> merge ( $ original , $ version1 , $ version2 );
// $result === $expected;
Con conflictos de fusión:
// Continuing from before with:
use Phpmerge MergeException ;
use PhpMerge MergeConflict ;
$ conflicting = <<<'EOD'
unchanged
replaced
unchanged
normal!!
unchanged
unchanged
EOD;
try {
$ merger -> merge ( $ original , $ version2 , $ conflicting );
} catch ( MergeException $ exception ) {
/** @var MergeConflict[] $conflicts */
$ conflicts = $ exception -> getConflicts ();
$ original_lines = $ conflicts [ 0 ]-> getBase ();
// $original_lines === ["normaln"];
$ version2_lines = $ conflicts [ 0 ]-> getRemote ();
// $version2_lines === ["normal??n"];
$ conflicting_lines = $ conflicts [ 0 ]-> getLocal ();
// $conflicting_lines === ["normal!!n"];
$ line_numer_of_conflict = $ conflicts [ 0 ]-> getBaseLine ();
// $line_numer_of_conflict === 3; // Count starts with 0.
// It is also possible to get the merged version using the first version
// to resolve conflicts.
$ merged = $ exception -> getMerged ();
// $merged === $version2;
// In this case, but in general there could be non-conflicting changes.
$ line_in_merged = $ conflicts [ 0 ]-> getMergedLine ();
// $line_in_merged === 3; // Count starts with 0.
}
Usando la línea de comando git para realizar la fusión:
use PhpMerge GitMerge ;
$ merger = new GitMerge ();
// Use as the previous example.
PhpMerge se puede instalar con Composer agregando la biblioteca como una dependencia a su archivo compositor.json.
{
"require" : {
"bircher/php-merge" : " ~4.0 "
}
}
Para usar la línea de comando git con GitMerge
:
{
"require" : {
"bircher/php-merge" : " ~4.0 " ,
"symplify/git-wrapper" : " ^9.1|^10.0 "
}
}
Consulte la documentación de Composer para obtener instrucciones de instalación y uso.
En la versión ~4.0 cambiamos de cpliakas/git-wrapper
a symplify/git-wrapper
ya que el primero está obsoleto. Esta actualización significa que no hay cambios cuando solo se usa PhpMergePhpMerge
.