Exemplo n.º 1
0
 private static function mergeUnmergedPath($repository, $path)
 {
     $shellrepo = escapeshellarg($repository);
     $common_ancestor = uniqid(sys_get_temp_dir() . "/") . "ancestor";
     $argument = escapeshellarg(":1:{$path}");
     $command = "cd {$shellrepo}; git show {$argument} > {$common_ancestor}";
     exec($command, $output, $exit_code);
     $head_version = uniqid(sys_get_temp_dir() . "/") . "head";
     $argument = escapeshellarg(":2:{$path}");
     $command = "cd {$shellrepo}; git show {$argument} > {$head_version}";
     exec($command, $output, $exit_code);
     $merge_head_version = uniqid(sys_get_temp_dir() . "/") . "merge_head";
     $argument = escapeshellarg(":3:{$path}");
     $command = "cd {$shellrepo}; git show {$argument} > {$merge_head_version}";
     exec($command, $output, $exit_code);
     $mergeBase = file_get_contents($common_ancestor);
     $userData = file_get_contents($head_version);
     $serverData = file_get_contents($merge_head_version);
     $mergedData = Filter_Merge::run($mergeBase, $userData, $serverData);
     $mergedData = str_replace("new__line", "\n", $mergedData);
     $mergedData = trim($mergedData);
     file_put_contents("{$repository}/{$path}", $mergedData);
     unlink($common_ancestor);
     unlink($head_version);
     unlink($merge_head_version);
 }
Exemplo n.º 2
0
 public static function run($base, $user, $server)
 {
     // The three files for merging.
     $mergeBaseFile = uniqid(sys_get_temp_dir() . "/") . "mergebase.txt";
     $userModificationFile = uniqid(sys_get_temp_dir() . "/") . "usermodification.txt";
     $serverModificationFile = uniqid(sys_get_temp_dir() . "/") . "servermodification.txt";
     $success = false;
     // Try a standard line-based merge. Should be sufficient for most cases.
     file_put_contents($mergeBaseFile, $base);
     file_put_contents($userModificationFile, $user);
     file_put_contents($serverModificationFile, $server);
     $exit_code = Filter_Merge::merge($mergeBaseFile, $userModificationFile, $serverModificationFile);
     $result = file_get_contents($userModificationFile);
     if ($exit_code == 0) {
         $success = true;
     }
     if (!$success) {
         // Convert the data to one word per line, and try to merge again.
         $baseWords = Filter_Merge::lines2words($base);
         $userWords = Filter_Merge::lines2words($user);
         $serverWords = Filter_Merge::lines2words($server);
         file_put_contents($mergeBaseFile, $baseWords);
         file_put_contents($userModificationFile, $userWords);
         file_put_contents($serverModificationFile, $serverWords);
         $exit_code = Filter_Merge::merge($mergeBaseFile, $userModificationFile, $serverModificationFile);
         $result = file_get_contents($userModificationFile);
         $result = Filter_Merge::words2lines($result);
         if ($exit_code == 0) {
             $success = true;
         }
     }
     if (!$success) {
         // Convert the data so it has one grapheme per line, and try again.
         $baseGraphemes = Filter_Merge::lines2graphemes($base);
         $userGraphemes = Filter_Merge::lines2graphemes($user);
         $serverGraphemes = Filter_Merge::lines2graphemes($server);
         file_put_contents($mergeBaseFile, $baseGraphemes);
         file_put_contents($userModificationFile, $userGraphemes);
         file_put_contents($serverModificationFile, $serverGraphemes);
         $exit_code = Filter_Merge::merge($mergeBaseFile, $userModificationFile, $serverModificationFile);
         $result = file_get_contents($userModificationFile);
         $result = Filter_Merge::graphemes2lines($result);
         if ($exit_code == 0) {
             $success = true;
         }
     }
     if (!$success) {
         // Everthing failed. Return the server data.
         $result = $server;
     }
     // Clear up.
     @unlink($mergeBaseFile);
     @unlink($userModificationFile);
     @unlink($serverModificationFile);
     // Merge result.
     return $result;
 }
Exemplo n.º 3
0
 public static function run($base, $user, $server)
 {
     $success = false;
     // Try a standard line-based merge. Should be sufficient for most cases.
     $result = Filter_Merge::merge($base, $user, $server);
     if ($result) {
         $success = true;
     }
     if (!$success) {
         // Convert the data to one word per line, and try to merge again.
         $baseWords = Filter_Merge::lines2words($base);
         $userWords = Filter_Merge::lines2words($user);
         $serverWords = Filter_Merge::lines2words($server);
         $result = Filter_Merge::merge($baseWords, $userWords, $serverWords);
         $result = Filter_Merge::words2lines($result);
         if ($result) {
             $success = true;
         }
     }
     if (!$success) {
         // Convert the data so it has one grapheme per line, and try again.
         $baseGraphemes = Filter_Merge::lines2graphemes($base);
         $userGraphemes = Filter_Merge::lines2graphemes($user);
         $serverGraphemes = Filter_Merge::lines2graphemes($server);
         $result = Filter_Merge::merge($baseGraphemes, $userGraphemes, $serverGraphemes);
         $result = Filter_Merge::graphemes2lines($result);
         if ($result) {
             $success = true;
         }
     }
     if (!$success) {
         // Everything failed. Return the server data.
         $result = $server;
     }
     // Merge result.
     return $result;
 }
Exemplo n.º 4
0
    $database_logs->log($message, Filter_Roles::MANAGER_LEVEL);
    echo $message;
    die;
}
$serverusfm = $database_bibles->getChapter($bible, $book, $chapter);
// Gather data for recording the changes made by the user, for the change notifications.
$old_id = $database_bibles->getChapterId($bible, $book, $chapter);
$old_text = $serverusfm;
$new_text = $newusfm;
if ($serverusfm == "") {
    // If the chapter on the server is still empty, then just store the client's version on the server, and that's it.
    Bible_Logic::storeChapter($bible, $book, $chapter, $newusfm);
} else {
    if ($newusfm != $serverusfm) {
        // Do a merge in case the client sends USFM that differs from what's on the server.
        $mergedusfm = Filter_Merge::run($oldusfm, $newusfm, $serverusfm);
        if ($mergedusfm == $serverusfm) {
            // When the merged USFM is the same as what's already on the server, then it means there was a merge conflict.
            // Email the user with the details, so the user can resolve the conflicts.
            $subject = "Problem sending chapter to server";
            $body = "<p>While sending {$bible} {$bookname} {$chapter} to the server, the server didn't manage to merge it.</p>";
            $body .= "<p>Please re-enter your changes as you see fit.</p>";
            $body .= "<p>Here is the chapter you sent to the server:</p>";
            $body .= "<pre>{$newusfm}</pre>";
            $database_mail->send($username, $subject, $body);
        } else {
            // Update the server with the new chapter data.
            Bible_Logic::storeChapter($bible, $book, $chapter, $mergedusfm);
        }
    }
}
Exemplo n.º 5
0
                $database_logs->log(Locale_Translate::_("Failure getting chapter:") . " {$bible} {$book_name} {$chapter}", Filter_Roles::TRANSLATOR_LEVEL);
                continue;
            }
            // Verify the checksum of the chapter on the server, to be sure there's no corruption during transmission.
            $server_usfm = explode("\n", $server_usfm);
            $checksum = array_shift($server_usfm);
            $server_usfm = implode("\n", $server_usfm);
            if (!Checksum_Logic::get($server_usfm) == $checksum) {
                $database_logs->log(Locale_Translate::_("Checksum error while receiving chapter from server:") . " {$bible} {$book_name} {$chapter}", Filter_Roles::TRANSLATOR_LEVEL);
                continue;
            }
            // Check whether the user on the client has made changes in this chapter since the edits were sent to the server.
            // If there are none, then the client stores the chapter as it gets it from the server, and is done.
            $old_usfm = $database_bibleactions->getUsfm($bible, $book, $chapter);
            if ($old_usfm == "") {
                $database_bibles->storeChapter($bible, $book, $chapter, $server_usfm);
                continue;
            }
            // At this stage we're in a situation that there are changes on the client, and changes on the server.
            // Merge them.
            // It uses a 3-way merge, taking the chapter from the bible actions as the basis, and the other two (client and server) to merge together.
            // Store the merged data on the client.
            // It stores through the Bible Logic so the changes are staged to be sent.
            // The changes will be sent to the server during the next synchronize action.
            $database_logs->log(Locale_Translate::_("Merging changes on server and client:") . " {$bible} {$book_name} {$chapter}", Filter_Roles::TRANSLATOR_LEVEL);
            $client_usfm = $database_bibles->getChapter($bible, $book, $chapter);
            $merged_usfm = Filter_Merge::run($old_usfm, $client_usfm, $server_usfm);
            Bible_Logic::storeChapter($bible, $book, $chapter, $merged_usfm);
        }
    }
}
Exemplo n.º 6
0
    public function testPracticalMergeExampleOne()
    {
        $this->mergeBaseData = <<<'EOD'
\c 1
\p
\v 1 This is really the text of the first (1st) verse.
\v 2 And this is what the second (2nd) verse contains.
\v 3 The third (3rd) verse.
\v 4 The fourth (4th) verse.
\v 5
EOD;
        $this->userModificationData = <<<'EOD'
\c 1
\p
\v 1 This is really the text of the first (1st) verse.
\v 2 And this is what the second verse contains.
\v 3 The third verse.
\v 4 The fourth (4th) verse.
\v 5
EOD;
        $this->serverModificationData = <<<'EOD'
\c 1
\p
\v 1 This is really the text of the first verse.
\v 2 And this is what the second (2nd) verse contains.
\v 3 The third (3rd) verse.
\v 4 The fourth verse.
\v 5
EOD;
        $output = Filter_Merge::run($this->mergeBaseData, $this->userModificationData, $this->serverModificationData);
        $standard = <<<'EOD'
\c 1
\p
\v 1 This is really the text of the first verse.
\v 2 And this is what the second verse contains.
\v 3 The third verse.
\v 4 The fourth verse.
\v 5
EOD;
        $this->assertEquals($standard, $output);
    }
Exemplo n.º 7
0
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
/*
Note: This object should not call other objects within the Bibledit-Web source,
because this object is also called from Bibledit-Gtk, and does not have access
to those other objects.
Calling other objects would result in faral errors that break Bibledit-Gtk.
*/
// This calls Bibledit-Web's three-way merge filter from the command line.
// Security: The script runs from the cli SAPI only.
if (php_sapi_name() != "cli") {
    echo "Fatal: This only runs through the cli Server API\n";
    die;
}
if ($argc != 5) {
    echo "Three-way file merge with grapheme granularity.\n";
    echo "It needs the following four arguments:\n";
    echo "- Name of the file with the merge base\n";
    echo "- Name of the file with the user modifications\n";
    echo "- Name of the file with the server modifications\n";
    echo "- Name of the file to store the merged output\n";
    die;
}
$mergeBase = file_get_contents($argv[1]);
$userModification = file_get_contents($argv[2]);
$serverModification = file_get_contents($argv[3]);
include "merge.php";
include "rmdir.php";
$output = Filter_Merge::run($mergeBase, $userModification, $serverModification);
file_put_contents($argv[4], $output);