]> source.dussan.org Git - nextcloud-server.git/commitdiff
non working app. moved to the apps-playground repository
authorFrank Karlitschek <karlitschek@kde.org>
Tue, 24 Apr 2012 12:00:44 +0000 (14:00 +0200)
committerFrank Karlitschek <karlitschek@kde.org>
Tue, 24 Apr 2012 12:00:44 +0000 (14:00 +0200)
12 files changed:
apps/files_versioning/ajax/gethead.php [deleted file]
apps/files_versioning/ajax/sethead.php [deleted file]
apps/files_versioning/appinfo/app.php [deleted file]
apps/files_versioning/appinfo/info.xml [deleted file]
apps/files_versioning/appinfo/version [deleted file]
apps/files_versioning/css/settings.css [deleted file]
apps/files_versioning/js/settings.js [deleted file]
apps/files_versioning/lib_granite.php [deleted file]
apps/files_versioning/settings.php [deleted file]
apps/files_versioning/templates/settings.php [deleted file]
apps/files_versioning/versionstorage.php [deleted file]
apps/files_versioning/versionwrapper.php [deleted file]

diff --git a/apps/files_versioning/ajax/gethead.php b/apps/files_versioning/ajax/gethead.php
deleted file mode 100644 (file)
index cc93b7a..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-<?php
-/**
- * Copyright (c) 2011 Craig Roberts craig0990@googlemail.com
- * This file is licensed under the Affero General Public License version 3 or
- * later.
- */
-require_once('../../../lib/base.php');
-
-OC_JSON::checkLoggedIn();
-// Fetch current commit (or HEAD if not yet set)
-$head = OC_Preferences::getValue(OC_User::getUser(), 'files_versioning', 'head', 'HEAD');
-OC_JSON::encodedPrint(array("head" => $head));
diff --git a/apps/files_versioning/ajax/sethead.php b/apps/files_versioning/ajax/sethead.php
deleted file mode 100644 (file)
index d1b2df9..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-<?php
-/**
- * Copyright (c) 2011 Craig Roberts craig0990@googlemail.com
- * This file is licensed under the Affero General Public License version 3 or
- * later.
- */
-require_once('../../../lib/base.php');
-OC_JSON::checkLoggedIn();
-if(isset($_POST["file_versioning_head"])){
-       OC_Preferences::setValue(OC_User::getUser(), 'files_versioning', 'head', $_POST["file_versioning_head"]);
-       OC_JSON::success();
-}else{
-       OC_JSON::error();
-}
diff --git a/apps/files_versioning/appinfo/app.php b/apps/files_versioning/appinfo/app.php
deleted file mode 100644 (file)
index 24a8701..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-<?php
-
-// Include required files
-require_once('apps/files_versioning/versionstorage.php');
-require_once('apps/files_versioning/versionwrapper.php');
-// Register streamwrapper for versioned:// paths
-stream_wrapper_register('versioned', 'OC_VersionStreamWrapper');
-
-// Add an entry in the app list for versioning and backup
-OC_App::register( array(
-  'order' => 10,
-  'id' => 'files_versioning',
-  'name' => 'Versioning and Backup' ));
-
-// Include stylesheets for the settings page
-OC_Util::addStyle( 'files_versioning', 'settings' );
-OC_Util::addScript('files_versioning','settings');
-
-// Register a settings section in the Admin > Personal page
-OC_APP::registerPersonal('files_versioning','settings');
diff --git a/apps/files_versioning/appinfo/info.xml b/apps/files_versioning/appinfo/info.xml
deleted file mode 100644 (file)
index b9f56f6..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-<?xml version="1.0"?>
-<info>
-    <id>files_versioning</id>
-    <name>Versioning and Backup</name>
-    <licence>GPLv2</licence>
-    <author>Craig Roberts</author>
-    <require>3</require>
-    <description>Versions files using Git repositories, providing a simple backup facility. Currently in *beta* and explicitly without warranty of any kind.</description>
-       <types>
-               <filesystem/>
-       </types>
-</info>
diff --git a/apps/files_versioning/appinfo/version b/apps/files_versioning/appinfo/version
deleted file mode 100644 (file)
index afaf360..0000000
+++ /dev/null
@@ -1 +0,0 @@
-1.0.0
\ No newline at end of file
diff --git a/apps/files_versioning/css/settings.css b/apps/files_versioning/css/settings.css
deleted file mode 100644 (file)
index afe2cd5..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-#file_versioning_commit_chzn {
-    width: 15em;
-}
diff --git a/apps/files_versioning/js/settings.js b/apps/files_versioning/js/settings.js
deleted file mode 100644 (file)
index 8dd13ba..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-$(document).ready(function(){
-    $('#file_versioning_head').chosen();
-
-    $.getJSON(OC.filePath('files_versioning', 'ajax', 'gethead.php'), function(jsondata, status) {
-
-        if (jsondata.head == 'HEAD') {
-            // Most recent commit, do nothing
-        } else {
-            $("#file_versioning_head").val(jsondata.head);
-            // Trigger the chosen update call
-            // See http://harvesthq.github.com/chosen/
-            $("#file_versioning_head").trigger("liszt:updated");
-        }
-    });
-
-    $('#file_versioning_head').change(function() {
-
-        var data = $(this).serialize();
-        $.post( OC.filePath('files_versioning', 'ajax', 'sethead.php'), data, function(data){
-               if(data == 'error'){
-                       console.log('Saving new HEAD failed');
-               }
-        });
-    });
-});
diff --git a/apps/files_versioning/lib_granite.php b/apps/files_versioning/lib_granite.php
deleted file mode 100644 (file)
index 571e5ce..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-<?php
-
-require_once('granite/git/blob.php');
-require_once('granite/git/commit.php');
-require_once('granite/git/repository.php');
-require_once('granite/git/tag.php');
-require_once('granite/git/tree.php');
-require_once('granite/git/tree/node.php');
-require_once('granite/git/object/index.php');
-require_once('granite/git/object/raw.php');
-require_once('granite/git/object/loose.php');
-require_once('granite/git/object/packed.php');
diff --git a/apps/files_versioning/settings.php b/apps/files_versioning/settings.php
deleted file mode 100644 (file)
index 94af587..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
-<?php
-
-// Get the full path to the repository folder (FIXME: hard-coded to 'Backup')
-$path = OC_Config::getValue('datadirectory', OC::$SERVERROOT.'/data')
-        . DIRECTORY_SEPARATOR
-        . OC_User::getUser()
-        . DIRECTORY_SEPARATOR
-        . 'files'
-        . DIRECTORY_SEPARATOR
-        . 'Backup'
-        . DIRECTORY_SEPARATOR
-        . '.git'
-        . DIRECTORY_SEPARATOR;
-
-$repository = new Granite\Git\Repository($path);
-
-$commits = array();
-// Fetch most recent 50 commits (FIXME - haven't tested this much)
-$commit = $repository->head();
-for ($i = 0; $i < 50; $i++) {
-    $commits[] = $commit;
-    $parents = $commit->parents();
-    if (count($parents) > 0) {
-        $parent = $parents[0];
-    } else {
-        break;
-    }
-
-    $commit = $repository->factory('commit', $parent);
-}
-
-$tmpl = new OC_Template( 'files_versioning', 'settings');
-$tmpl->assign('commits', $commits);
-return $tmpl->fetchPage();
diff --git a/apps/files_versioning/templates/settings.php b/apps/files_versioning/templates/settings.php
deleted file mode 100644 (file)
index 17f4cc7..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-<fieldset id="status_list" class="personalblock">
-       <strong>Versioning and Backup</strong><br>
-       <p><em>Please note: Backing up large files (around 16MB+) will cause your backup history to grow very large, very quickly.</em></p>
-       <label class="bold">Backup Folder</label>
-       <select name="file_versioning_head" id="file_versioning_head">
-       <?php
-        foreach ($_['commits'] as $commit):
-            echo '<option value="' . $commit->sha() . '">' . $commit->message() . '</option>';
-        endforeach;
-       ?>
-       </select>
-</fieldset>
diff --git a/apps/files_versioning/versionstorage.php b/apps/files_versioning/versionstorage.php
deleted file mode 100644 (file)
index d083e62..0000000
+++ /dev/null
@@ -1,386 +0,0 @@
-<?php
-/**
- * ownCloud file storage implementation for Git repositories
- * @author Craig Roberts
- * @copyright 2012 Craig Roberts craig0990@googlemail.com
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU AFFERO GENERAL PUBLIC LICENSE for more details.
- *
- * You should have received a copy of the GNU Affero General Public
- * License along with this library.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-// Include Granite
-require_once('lib_granite.php');
-
-// Create a top-level 'Backup' directory if it does not already exist
-$user = OC_User::getUser();
-if (OC_Filesystem::$loaded and !OC_Filesystem::is_dir('/Backup')) {
-    OC_Filesystem::mkdir('/Backup');
-    OC_Preferences::setValue(OC_User::getUser(), 'files_versioning', 'head', 'HEAD');
-}
-
-// Generate the repository path (currently using 'full' repositories, as opposed to bare ones)
-$repo_path = DIRECTORY_SEPARATOR
-    . OC_User::getUser()
-    . DIRECTORY_SEPARATOR
-    . 'files'
-    . DIRECTORY_SEPARATOR
-    . 'Backup';
-
-// Mount the 'Backup' folder using the versioned storage provider below
-OC_Filesystem::mount('OC_Filestorage_Versioned', array('repo'=>$repo_path), $repo_path . DIRECTORY_SEPARATOR);
-
-class OC_Filestorage_Versioned extends OC_Filestorage {
-
-    /**
-     * Holds an instance of Granite\Git\Repository
-     */
-    protected $repo;
-
-    /**
-     * Constructs a new OC_Filestorage_Versioned instance, expects an associative
-     * array with a `repo` key set to the path of the repository's `.git` folder
-     *
-     * @param array $parameters An array containing the key `repo` pointing to the
-     *                             repository path.
-     */
-    public function __construct($parameters) {
-        // Get the full path to the repository folder
-        $path = OC_Config::getValue('datadirectory', OC::$SERVERROOT.'/data')
-                . $parameters['repo']
-                . DIRECTORY_SEPARATOR
-                . '.git'
-                . DIRECTORY_SEPARATOR;
-
-        try {
-            // Attempt to load the repository
-            $this->repo = new Granite\Git\Repository($path);
-        } catch (InvalidArgumentException $e) {
-            // $path is not a valid Git repository, we must create one
-            Granite\Git\Repository::init($path);
-
-            // Load the newly-initialised repository
-            $this->repo = new Granite\Git\Repository($path);
-
-            /**
-             * Create an initial commit with a README file
-             * FIXME: This functionality should be transferred to the Granite library
-             */
-            $blob = new Granite\Git\Blob($this->repo->path());
-            $blob->content('Your Backup directory is now ready for use.');
-
-            // Create a new tree to hold the README file
-            $tree = $this->repo->factory('tree');
-            // Create a tree node to represent the README blob
-            $tree_node = new Granite\Git\Tree\Node('README', '100644', $blob->sha());
-            $tree->nodes(array($tree_node->name() => $tree_node));
-
-            // Create an initial commit
-            $commit = new Granite\Git\Commit($this->repo->path());
-            $user_string = OC_User::getUser() . ' ' . time() . ' +0000';
-            $commit->author($user_string);
-            $commit->committer($user_string);
-            $commit->message('Initial commit');
-            $commit->tree($tree);
-
-            // Write it all to disk
-            $blob->write();
-            $tree->write();
-            $commit->write();
-
-            // Update the HEAD for the 'master' branch
-            $this->repo->head('master', $commit->sha());
-        }
-
-        // Update the class pointer to the HEAD
-        $head = OC_Preferences::getValue(OC_User::getUser(), 'files_versioning', 'head', 'HEAD');
-
-        // Load the most recent commit if the preference is not set
-        if ($head == 'HEAD') {
-            $this->head = $this->repo->head()->sha();
-        } else {
-            $this->head = $head;
-        }
-    }
-
-    public function mkdir($path) {
-        if (mkdir("versioned:/{$this->repo->path()}$path#{$this->head}")) {
-            $this->head = $this->repo->head()->sha();
-            OC_Preferences::setValue(OC_User::getUser(), 'files_versioning', 'head', $head);
-            return true;
-        }
-
-        return false;
-    }
-
-    public function rmdir($path) {
-
-    }
-
-    /**
-     * Returns a directory handle to the requested path, or FALSE on failure
-     *
-     * @param string $path The directory path to open
-     *
-     * @return boolean|resource A directory handle, or FALSE on failure
-     */
-    public function opendir($path) {
-        return opendir("versioned:/{$this->repo->path()}$path#{$this->head}");
-    }
-
-    /**
-     * Returns TRUE if $path is a directory, or FALSE if not
-     *
-     * @param string $path The path to check
-     *
-     * @return boolean
-     */
-    public function is_dir($path) {
-        return $this->filetype($path) == 'dir';
-    }
-
-    /**
-     * Returns TRUE if $path is a file, or FALSE if not
-     *
-     * @param string $path The path to check
-     *
-     * @return boolean
-     */
-    public function is_file($path) {
-        return $this->filetype($path) == 'file';
-    }
-
-    public function stat($path)
-       {
-           return stat("versioned:/{$this->repo->path()}$path#{$this->head}");
-    }
-
-    /**
-     * Returns the strings 'dir' or 'file', depending on the type of $path
-     *
-     * @param string $path The path to check
-     *
-     * @return string Returns 'dir' if a directory, 'file' otherwise
-     */
-    public function filetype($path) {
-           if ($path == "" || $path == "/") {
-               return 'dir';
-        } else {
-            if (substr($path, -1) == '/') {
-                $path = substr($path, 0, -1);
-            }
-
-            $node = $this->tree_search($this->repo, $this->repo->factory('commit', $this->head)->tree(), $path);
-
-            // Does it exist, or is it new?
-            if ($node == null) {
-                // New file
-                return 'file';
-            } else {
-                // Is it a tree?
-                try {
-                    $this->repo->factory('tree', $node);
-                    return 'dir';
-                } catch (InvalidArgumentException $e) {
-                    // Nope, must be a blob
-                    return 'file';
-                }
-            }
-        }
-    }
-
-    public function filesize($path) {
-        return filesize("versioned:/{$this->repo->path()}$path#{$this->head}");
-    }
-
-    /**
-     * Returns a boolean value representing whether $path is readable
-     *
-     * @param string $path The path to check
-     *(
-     * @return boolean Whether or not the path is readable
-     */
-    public function is_readable($path) {
-        return true;
-    }
-
-    /**
-     * Returns a boolean value representing whether $path is writable
-     *
-     * @param string $path The path to check
-     *(
-     * @return boolean Whether or not the path is writable
-     */
-    public function is_writable($path) {
-
-        $head = OC_Preferences::getValue(OC_User::getUser(), 'files_versioning', 'head', 'HEAD');
-        if ($head !== 'HEAD' && $head !== $this->repo->head()->sha()) {
-            // Cannot modify previous commits
-            return false;
-        }
-        return true;
-    }
-
-    /**
-     * Returns a boolean value representing whether $path exists
-     *
-     * @param string $path The path to check
-     *(
-     * @return boolean Whether or not the path exists
-     */
-    public function file_exists($path) {
-        return file_exists("versioned:/{$this->repo->path()}$path#{$this->head}");
-    }
-
-    /**
-     * Returns an integer value representing the inode change time
-     * (NOT IMPLEMENTED)
-     *
-     * @param string $path The path to check
-     *(
-     * @return int Timestamp of the last inode change
-     */
-    public function filectime($path) {
-        return -1;
-    }
-
-    /**
-     * Returns an integer value representing the file modification time
-     *
-     * @param string $path The path to check
-     *(
-     * @return int Timestamp of the last file modification
-     */
-    public function filemtime($path) {
-        return filemtime("versioned:/{$this->repo->path()}$path#{$this->head}");
-    }
-
-    public function file_get_contents($path) {
-        return file_get_contents("versioned:/{$this->repo->path()}$path#{$this->head}");
-    }
-
-    public function file_put_contents($path, $data) {
-        $success = file_put_contents("versioned:/{$this->repo->path()}$path#{$this->head}", $data);
-        if ($success !== false) {
-            // Update the HEAD in the preferences
-            OC_Preferences::setValue(OC_User::getUser(), 'files_versioning', 'head', $this->repo->head()->sha());
-            return $success;
-        }
-
-        return false;
-    }
-
-    public function unlink($path) {
-
-    }
-
-    public function rename($path1, $path2) {
-
-    }
-
-    public function copy($path1, $path2) {
-
-    }
-
-    public function fopen($path, $mode) {
-           return fopen("versioned:/{$this->repo->path()}$path#{$this->head}", $mode);
-    }
-
-    public function getMimeType($path) {
-        if ($this->filetype($path) == 'dir') {
-               return 'httpd/unix-directory';
-           } elseif ($this->filesize($path) == 0) {
-               // File's empty, returning text/plain allows opening in the web editor
-               return 'text/plain';
-           } else {
-            $finfo = new finfo(FILEINFO_MIME_TYPE);
-            /**
-             * We need to represent the repository path, the file path, and the
-             * revision, which can be simply achieved with a convention of using
-             * `.git` in the repository directory (bare or not) and the '#part'
-             * segment of a URL to specify the revision. For example
-             *
-             * versioned://var/www/myrepo.git/docs/README.md#HEAD ('bare' repo)
-             * versioned://var/www/myrepo/.git/docs/README.md#HEAD ('full' repo)
-             * versioned://var/www/myrepo/.git/docs/README.md#6a8f...8a54 ('full' repo and SHA-1 commit ID)
-             */
-            $mime = $finfo->buffer(file_get_contents("versioned:/{$this->repo->path()}$path#{$this->head}"));
-            return $mime;
-           }
-    }
-
-    /**
-     * Generates a hash based on the file contents
-     *
-     * @param string $type The hashing algorithm to use (e.g. 'md5', 'sha256', etc.)
-     * @param string $path The file to be hashed
-     * @param boolean $raw Outputs binary data if true, lowercase hex digits otherwise
-     *
-     * @return string Hashed string representing the file contents
-     */
-    public function hash($type, $path, $raw) {
-        return hash($type, file_get_contents($path), $raw);
-    }
-
-    public function free_space($path) {
-    }
-
-    public function search($query) {
-
-    }
-
-    public function touch($path, $mtime=null) {
-
-    }
-
-
-    public function getLocalFile($path) {
-    }
-
-    /**
-     * Recursively searches a tree for a path, returning FALSE if is not found
-     * or an SHA-1 id if it is found.
-     *
-     * @param string  $repo  The repository containing the tree object
-     * @param string  $tree  The tree object to search
-     * @param string  $path  The path to search for (relative to the tree)
-     * @param int     $depth The depth of the current search (for recursion)
-     *
-     * @return string|boolean The SHA-1 id of the sub-tree
-     */
-    private function tree_search($repo, $tree, $path, $depth = 0)
-    {
-        $paths = array_values(explode(DIRECTORY_SEPARATOR, $path));
-
-        $current_path = $paths[$depth];
-
-        $nodes = $tree->nodes();
-        foreach ($nodes as $node) {
-            if ($node->name() == $current_path) {
-
-                if (count($paths)-1 == $depth) {
-                    // Stop, found it
-                    return $node->sha();
-                }
-
-                // Recurse if necessary
-                if ($node->isDirectory()) {
-                    $tree = $this->repo->factory('tree', $node->sha());
-                    return $this->tree_search($repo, $tree, $path, $depth + 1);
-                }
-            }
-        }
-
-        return false;
-    }
-
-}
diff --git a/apps/files_versioning/versionwrapper.php b/apps/files_versioning/versionwrapper.php
deleted file mode 100644 (file)
index b83a4fd..0000000
+++ /dev/null
@@ -1,686 +0,0 @@
-<?php
-
-final class OC_VersionStreamWrapper {
-
-    /**
-     * Determines whether or not to log debug messages with `OC_Log::write()`
-     */
-    private $debug = true;
-
-    /**
-     * The name of the ".empty" files created in new directories
-     */
-    const EMPTYFILE = '.empty';
-
-    /**
-     * Stores the current position for `readdir()` etc. calls
-     */
-    private $dir_position = 0;
-
-    /**
-     * Stores the current position for `fread()`, `fseek()` etc. calls
-     */
-    private $file_position = 0;
-
-    /**
-     * Stores the current directory tree for `readdir()` etc. directory traversal
-     */
-    private $tree;
-
-    /**
-     * Stores the current file for `fread()`, `fseek()`, etc. calls
-     */
-    private $blob;
-
-    /**
-     * Stores the current commit for `fstat()`, `stat()`, etc. calls
-     */
-    private $commit;
-
-    /**
-     * Stores the current path for `fwrite()`, `file_put_contents()` etc. calls
-     */
-    private $path;
-
-    /**
-     * Close directory handle
-     */
-    public function dir_closedir() {
-        unset($this->tree);
-        return true;
-    }
-
-    /**
-     * Open directory handle
-     */
-    public function dir_opendir($path, $options) {
-        // Parse the URL into a repository directory, file path and commit ID
-        list($this->repo, $repo_file, $this->commit) = $this->parse_url($path);
-
-        if ($repo_file == '' || $repo_file == '/') {
-            // Set the tree property for the future `readdir()` etc. calls
-            $this->tree = array_values($this->commit->tree()->nodes());
-            return true;
-        } elseif ($this->tree_search($this->repo, $this->commit->tree(), $repo_file) !== false) {
-            // Something exists at this path, is it a directory though?
-            try {
-                $tree = $this->repo->factory(
-                    'tree',
-                    $this->tree_search($this->repo, $this->commit->tree(), $repo_file)
-                );
-                $this->tree = array_values($tree->nodes());
-                return true;
-            } catch (InvalidArgumentException $e) {
-                // Trying to call `opendir()` on a file, return false below
-            }
-        }
-
-        // Unable to find the directory, return false
-        return false;
-    }
-
-    /**
-     * Read entry from directory handle
-     */
-    public function dir_readdir() {
-        return isset($this->tree[$this->dir_position])
-               ? $this->tree[$this->dir_position++]->name()
-               : false;
-    }
-
-    /**
-     * Rewind directory handle
-     */
-    public function dir_rewinddir() {
-        $this->dir_position = 0;
-    }
-
-    /**
-     * Create a directory
-     * Git doesn't track empty directories, so a ".empty" file is added instead
-     */
-    public function mkdir($path, $mode, $options) {
-        // Parse the URL into a repository directory, file path and commit ID
-        list($this->repo, $repo_file, $this->commit) = $this->parse_url($path);
-
-        // Create an empty file for Git
-        $empty = new Granite\Git\Blob($this->repo->path());
-        $empty->content('');
-        $empty->write();
-
-        if (dirname($repo_file) == '.') {
-            // Adding a new directory to the root tree
-            $tree = $this->repo->head()->tree();
-        } else {
-            $tree = $this->repo->factory('tree', $this->tree_search(
-                    $this->repo, $this->repo->head()->tree(), dirname($repo_file)
-                )
-            );
-        }
-
-        // Create our new tree, with our empty file
-        $dir = $this->repo->factory('tree');
-        $nodes = array();
-        $nodes[self::EMPTYFILE] = new Granite\Git\Tree\Node(self::EMPTYFILE, '100644', $empty->sha());
-        $dir->nodes($nodes);
-        $dir->write();
-
-        // Add our new tree to its parent
-        $nodes = $tree->nodes();
-        $nodes[basename($repo_file)] = new Granite\Git\Tree\Node(basename($repo_file), '040000', $dir->sha());
-        $tree->nodes($nodes);
-        $tree->write();
-
-        // We need to recursively update each parent tree, since they are all
-        // hashed and the changes will cascade back up the chain
-
-        // So, we're currently at the bottom-most directory
-        $current_dir = dirname($repo_file);
-        $previous_tree = $tree;
-
-        if ($current_dir !== '.') {
-            do {
-                // Determine the parent directory
-                $previous_dir = $current_dir;
-                $current_dir = dirname($current_dir);
-
-                $current_tree = $current_dir !== '.'
-                                ? $this->repo->factory(
-                                      'tree', $this->tree_search(
-                                          $this->repo,
-                                          $this->repo->head()->tree(),
-                                          $current_dir
-                                      )
-                                  )
-                                : $this->repo->head()->tree();
-
-                $current_nodes = $current_tree->nodes();
-                $current_nodes[basename($previous_dir)] = new Granite\Git\Tree\Node(
-                    basename($previous_dir), '040000', $previous_tree->sha()
-                );
-                $current_tree->nodes($current_nodes);
-                $current_tree->write();
-
-                $previous_tree = $current_tree;
-            } while ($current_dir !== '.');
-
-            $tree = $previous_tree;
-        }
-
-        // Create a new commit to represent this write
-        $commit = $this->repo->factory('commit');
-        $username = OC_User::getUser();
-        $user_string = $username . ' ' . time() . ' +0000';
-        $commit->author($user_string);
-        $commit->committer($user_string);
-        $commit->message("$username created the `$repo_file` directory, " . date('d F Y H:i', time()) . '.');
-        $commit->parents(array($this->repo->head()->sha()));
-        $commit->tree($tree);
-
-        // Write it to disk
-        $commit->write();
-
-        // Update the HEAD for the 'master' branch
-        $this->repo->head('master', $commit->sha());
-
-        return true;
-    }
-
-    /**
-     * Renames a file or directory
-     */
-    public function rename($path_from, $path_to) {
-
-    }
-
-    /**
-     * Removes a directory
-     */
-    public function rmdir($path, $options) {
-
-    }
-
-    /**
-     * Retrieve the underlaying resource (NOT IMPLEMENTED)
-     */
-    public function stream_cast($cast_as) {
-        return false;
-    }
-
-    /**
-     * Close a resource
-     */
-    public function stream_close() {
-        unset($this->blob);
-        return true;
-    }
-
-    /**
-     * Tests for end-of-file on a file pointer
-     */
-    public function stream_eof() {
-        return !($this->file_position < strlen($this->blob));
-    }
-
-    /**
-     * Flushes the output (NOT IMPLEMENTED)
-     */
-    public function stream_flush() {
-        return false;
-    }
-
-    /**
-     * Advisory file locking (NOT IMPLEMENTED)
-     */
-    public function stream_lock($operation) {
-        return false;
-    }
-
-    /**
-     * Change stream options (NOT IMPLEMENTED)
-     * Called in response to `chgrp()`, `chown()`, `chmod()` and `touch()`
-     */
-    public function stream_metadata($path, $option, $var) {
-        return false;
-    }
-
-    /**
-     * Opens file or URL
-     */
-    public function stream_open($path, $mode, $options, &$opened_path) {
-        // Store the path, so we can use it later in `stream_write()` if necessary
-        $this->path = $path;
-        // Parse the URL into a repository directory, file path and commit ID
-        list($this->repo, $repo_file, $this->commit) = $this->parse_url($path);
-
-        $file = $this->tree_search($this->repo, $this->commit->tree(), $repo_file);
-        if ($file !== false) {
-            try {
-                $this->blob = $this->repo->factory('blob', $file)->content();
-                return true;
-            } catch (InvalidArgumentException $e) {
-                // Trying to open a directory, return false below
-            }
-        } elseif ($mode !== 'r') {
-            // All other modes allow opening for reading and writing, clearly
-            // some 'write' files may not exist yet...
-            return true;
-        }
-
-        // File could not be found or is not actually a file
-        return false;
-    }
-
-    /**
-     * Read from stream
-     */
-    public function stream_read($count) {
-        // Fetch the remaining set of bytes
-        $bytes = substr($this->blob, $this->file_position, $count);
-
-        // If EOF or empty string, return false
-        if ($bytes == '' || $bytes == false) {
-            return false;
-        }
-
-        // If $count does not extend past EOF, add $count to stream offset
-        if ($this->file_position + $count < strlen($this->blob)) {
-            $this->file_position += $count;
-        } else {
-            // Otherwise return all remaining bytes
-            $this->file_position = strlen($this->blob);
-        }
-
-        return $bytes;
-    }
-
-    /**
-     * Seeks to specific location in a stream
-     */
-    public function stream_seek($offset, $whence = SEEK_SET) {
-        $new_offset = false;
-
-        switch ($whence)
-        {
-            case SEEK_SET:
-                $new_offset = $offset;
-            break;
-            case SEEK_CUR:
-                $new_offset = $this->file_position += $offset;
-            break;
-            case SEEK_END:
-                $new_offset = strlen($this->blob) + $offset;
-            break;
-        }
-
-        $this->file_position = $offset;
-
-        return ($new_offset !== false);
-    }
-
-    /**
-     * Change stream options (NOT IMPLEMENTED)
-     */
-    public function stream_set_option($option, $arg1, $arg2) {
-        return false;
-    }
-
-    /**
-     * Retrieve information about a file resource (NOT IMPLEMENTED)
-     */
-    public function stream_stat() {
-
-    }
-
-    /**
-     * Retrieve the current position of a stream
-     */
-    public function stream_tell() {
-        return $this->file_position;
-    }
-
-    /**
-     * Truncate stream
-     */
-    public function stream_truncate($new_size) {
-
-    }
-
-    /**
-     * Write to stream
-     * FIXME: Could use heavy refactoring
-     */
-    public function stream_write($data) {
-        /**
-         * FIXME: This also needs to be added to Granite, in the form of `add()`,
-         * `rm()` and `commit()` calls
-         */
-
-        // Parse the URL into a repository directory, file path and commit ID
-        list($this->repo, $repo_file, $this->commit) = $this->parse_url($this->path);
-
-        $node = $this->tree_search($this->repo, $this->commit->tree(), $repo_file);
-
-        if ($node !== false) {
-            // File already exists, attempting modification of existing tree
-            try {
-                $this->repo->factory('blob', $node);
-
-                // Create our new blob with the provided $data
-                $blob = $this->repo->factory('blob');
-                $blob->content($data);
-                $blob->write();
-
-                // We know the tree exists, so strip the filename from the path and
-                // find it...
-
-                if (dirname($repo_file) == '.' || dirname($repo_file) == '') {
-                    // Root directory
-                    $tree = $this->repo->head()->tree();
-                } else {
-                    // Sub-directory
-                    $tree = $this->repo->factory('tree', $this->tree_search(
-                            $this->repo,
-                            $this->repo->head()->tree(),
-                            dirname($repo_file)
-                        )
-                    );
-                }
-
-                // Replace the old blob with our newly modified one
-                $tree_nodes = $tree->nodes();
-                $tree_nodes[basename($repo_file)] = new Granite\Git\Tree\Node(
-                    basename($repo_file), '100644', $blob->sha()
-                );
-                $tree->nodes($tree_nodes);
-                $tree->write();
-
-                // We need to recursively update each parent tree, since they are all
-                // hashed and the changes will cascade back up the chain
-
-                // So, we're currently at the bottom-most directory
-                $current_dir = dirname($repo_file);
-                $previous_tree = $tree;
-
-                if ($current_dir !== '.') {
-                    do {
-                        // Determine the parent directory
-                        $previous_dir = $current_dir;
-                        $current_dir = dirname($current_dir);
-
-                        $current_tree = $current_dir !== '.'
-                                        ? $this->repo->factory(
-                                              'tree', $this->tree_search(
-                                                  $this->repo,
-                                                  $this->repo->head()->tree(),
-                                                  $current_dir
-                                              )
-                                          )
-                                        : $this->repo->head()->tree();
-
-                        $current_nodes = $current_tree->nodes();
-                        $current_nodes[basename($previous_dir)] = new Granite\Git\Tree\Node(
-                            basename($previous_dir), '040000', $previous_tree->sha()
-                        );
-                        $current_tree->nodes($current_nodes);
-                        $current_tree->write();
-
-                        $previous_tree = $current_tree;
-                    } while ($current_dir !== '.');
-                }
-
-                // Create a new commit to represent this write
-                $commit = $this->repo->factory('commit');
-                $username = OC_User::getUser();
-                $user_string = $username . ' ' . time() . ' +0000';
-                $commit->author($user_string);
-                $commit->committer($user_string);
-                $commit->message("$username modified the `$repo_file` file, " . date('d F Y H:i', time()) . '.');
-                $commit->parents(array($this->repo->head()->sha()));
-                $commit->tree($previous_tree);
-
-                // Write it to disk
-                $commit->write();
-
-                // Update the HEAD for the 'master' branch
-                $this->repo->head('master', $commit->sha());
-
-                // If we made it this far, write was successful - update the stream
-                // position and return the number of bytes written
-                $this->file_position += strlen($data);
-                return strlen($data);
-
-            } catch (InvalidArgumentException $e) {
-                // Attempting to write to a directory or other error, fail
-                return 0;
-            }
-        } else {
-            // File does not exist, needs to be created
-
-            // Create our new blob with the provided $data
-            $blob = $this->repo->factory('blob');
-            $blob->content($data);
-            $blob->write();
-
-            if (dirname($repo_file) == '.') {
-                // Trying to add a new file to the root tree, nice and easy
-                $tree = $this->repo->head()->tree();
-                $tree_nodes = $tree->nodes();
-                $tree_nodes[basename($repo_file)] = new Granite\Git\Tree\Node(
-                    basename($repo_file), '100644', $blob->sha()
-                );
-                $tree->nodes($tree_nodes);
-                $tree->write();
-            } else {
-                // Trying to add a new file to a subdirectory, try and find it
-                $tree = $this->repo->factory('tree', $this->tree_search(
-                        $this->repo, $this->repo->head()->tree(), dirname($repo_file)
-                    )
-                );
-
-                // Add the blob to the tree
-                $nodes = $tree->nodes();
-                $nodes[basename($repo_file)] =  new Granite\Git\Tree\Node(
-                    basename($repo_file), '100644', $blob->sha()
-                );
-                $tree->nodes($nodes);
-                $tree->write();
-
-                // We need to recursively update each parent tree, since they are all
-                // hashed and the changes will cascade back up the chain
-
-                // So, we're currently at the bottom-most directory
-                $current_dir = dirname($repo_file);
-                $previous_tree = $tree;
-
-                if ($current_dir !== '.') {
-                    do {
-                        // Determine the parent directory
-                        $previous_dir = $current_dir;
-                        $current_dir = dirname($current_dir);
-
-                        $current_tree = $current_dir !== '.'
-                                        ? $this->repo->factory(
-                                              'tree', $this->tree_search(
-                                                  $this->repo,
-                                                  $this->repo->head()->tree(),
-                                                  $current_dir
-                                              )
-                                          )
-                                        : $this->repo->head()->tree();
-
-                        $current_nodes = $current_tree->nodes();
-                        $current_nodes[basename($previous_dir)] = new Granite\Git\Tree\Node(
-                            basename($previous_dir), '040000', $previous_tree->sha()
-                        );
-                        $current_tree->nodes($current_nodes);
-                        $current_tree->write();
-
-                        $previous_tree = $current_tree;
-                    } while ($current_dir !== '.');
-
-                    $tree = $previous_tree;
-                }
-            }
-
-            // Create a new commit to represent this write
-            $commit = $this->repo->factory('commit');
-            $username = OC_User::getUser();
-            $user_string = $username . ' ' . time() . ' +0000';
-            $commit->author($user_string);
-            $commit->committer($user_string);
-            $commit->message("$username created the `$repo_file` file, " . date('d F Y H:i', time()) . '.');
-            $commit->parents(array($this->repo->head()->sha()));
-            $commit->tree($tree); // Top-level tree (NOT the newly modified tree)
-
-            // Write it to disk
-            $commit->write();
-
-            // Update the HEAD for the 'master' branch
-            $this->repo->head('master', $commit->sha());
-
-            // If we made it this far, write was successful - update the stream
-            // position and return the number of bytes written
-            $this->file_position += strlen($data);
-            return strlen($data);
-        }
-
-        // Write failed
-        return 0;
-    }
-
-    /**
-     * Delete a file
-     */
-    public function unlink($path) {
-
-    }
-
-    /**
-     * Retrieve information about a file
-     */
-    public function url_stat($path, $flags) {
-        // Parse the URL into a repository directory, file path and commit ID
-        list($this->repo, $repo_file, $this->commit) = $this->parse_url($path);
-
-        $node = $this->tree_search($this->repo, $this->commit->tree(), $repo_file);
-
-        if ($node == false && $this->commit->sha() == $this->repo->head()->sha()) {
-            // A new file - no information available
-            $size = 0;
-            $mtime = -1;
-        } else {
-
-            // Is it a directory?
-            try {
-                $this->repo->factory('tree', $node);
-                $size = 4096; // FIXME
-            } catch (InvalidArgumentException $e) {
-                // Must be a file
-                $size = strlen(file_get_contents($path));
-            }
-
-            // Parse the timestamp from the commit message
-               preg_match('/[0-9]{10}+/', $this->commit->committer(), $matches);
-               $mtime = $matches[0];
-        }
-
-           $stat["dev"] = "";
-           $stat["ino"] = "";
-           $stat["mode"] = "";
-           $stat["nlink"] = "";
-           $stat["uid"] = "";
-           $stat["gid"] = "";
-           $stat["rdev"] = "";
-           $stat["size"] = $size;
-           $stat["atime"] = $mtime;
-           $stat["mtime"] = $mtime;
-           $stat["ctime"] = $mtime;
-           $stat["blksize"] = "";
-           $stat["blocks"] = "";
-
-           return $stat;
-    }
-
-    /**
-     * Debug function for development purposes
-     */
-    private function debug($message, $level = OC_Log::DEBUG)
-    {
-        if ($this->debug) {
-            OC_Log::write('files_versioning', $message, $level);
-        }
-    }
-
-    /**
-     * Parses a URL of the form:
-     * `versioned://path/to/git/repository/.git/path/to/file#SHA-1-commit-id`
-     * FIXME: Will throw an InvalidArgumentException if $path is invaid
-     *
-     * @param string $path The path to parse
-     *
-     * @return array An array containing an instance of Granite\Git\Repository,
-     *               the file path, and an instance of Granite\Git\Commit
-     * @throws InvalidArgumentException If the repository cannot be loaded
-     */
-    private function parse_url($path)
-    {
-        preg_match('/\/([A-Za-z0-9\/]+\.git\/)([A-Za-z0-9\/\.\/]*)(#([A-Fa-f0-9]+))*/', $path, $matches);
-
-        // Load up the repo
-        $repo = new \Granite\Git\Repository($matches[1]);
-        // Parse the filename (stripping any trailing slashes)
-        $repo_file = $matches[2];
-        if (substr($repo_file, -1) == '/') {
-            $repo_file = substr($repo_file, 0, -1);
-        }
-
-        // Default to HEAD if no commit is provided
-        $repo_commit = isset($matches[4])
-                       ? $matches[4]
-                       : $repo->head()->sha();
-
-        // Load the relevant commit
-        $commit = $repo->factory('commit', $repo_commit);
-
-        return array($repo, $repo_file, $commit);
-    }
-
-    /**
-     * Recursively searches a tree for a path, returning FALSE if is not found
-     * or an SHA-1 id if it is found.
-     *
-     * @param string  $repo  The repository containing the tree object
-     * @param string  $tree  The tree object to search
-     * @param string  $path  The path to search for (relative to the tree)
-     * @param int     $depth The depth of the current search (for recursion)
-     *
-     * @return string|boolean The SHA-1 id of the sub-tree
-     */
-    private function tree_search($repo, $tree, $path, $depth = 0)
-    {
-        $paths = array_values(explode(DIRECTORY_SEPARATOR, $path));
-
-        $current_path = $paths[$depth];
-
-        $nodes = $tree->nodes();
-        foreach ($nodes as $node) {
-            if ($node->name() == $current_path) {
-
-                if (count($paths)-1 == $depth) {
-                    // Stop, found it
-                    return $node->sha();
-                }
-
-                // Recurse if necessary
-                if ($node->isDirectory()) {
-                    $tree = $this->repo->factory('tree', $node->sha());
-                    return $this->tree_search($repo, $tree, $path, $depth + 1);
-                }
-            }
-        }
-
-        return false;
-    }
-
-}