diff --git a/lib/bindings/bindings.js b/lib/bindings/bindings.js
index 1d86fcc..6ebf237 100644
--- a/lib/bindings/bindings.js
+++ b/lib/bindings/bindings.js
@@ -186,10 +186,9 @@ Gitteh.error.GIT_ENOTIMPLEMENTED = undefined;
Repository.prototype.getCommit = function(sha1, callback) {};
/**
- * Creates a new Commit and immediately stores it in the Repository.
- * @param {Object} data The data for the commit. Should be the same properties that a {@link Commit} contains.
- * @param {Function} [callback] If provided, the Commit will be created asynchronously, and the newly created Commit object returned to the callback.
- * @throws If Commit couldn't be created.
+ * Creates a new {@link Commit} and immediately stores it in the Repository.
+ * @param {Object} data The data for the commit. Should be the same properties that a {@link Commit} contains, but without id.
+ * @param {Function} [callback] The id of the newly created Commit is returned to the callback.
*/
Repository.prototype.createCommit = function(data, callback) {};
@@ -203,12 +202,11 @@ Repository.prototype.createCommit = function(data, callback) {};
Repository.prototype.getTree = function(sha1, callback) {};
/**
- * Creates a new {@link Tree} in the Repository with the given data. NOTE:
- * this is currently unimplemented.
- * @param {Object} data
- * @param {Function} [callback]
+ * Creates a new {@link Tree} in the Repository with the given entries.
+ * @param {Array} entries A list of file-entries from which to create the tree. Each entry should have a name, id (of the blob object) and mode. The mode should be any of the values 0040000, 0100644, 0100755, 0120000 or 0160000.
+ * @param {Function} [callback] The id of the newly created Tree is returned to the callback.
*/
-Repository.prototype.createTree = function(data, callback) {};
+Repository.prototype.createTree = function(entries, callback) {};
/**
* Retrieves a {@link Reference} from the Repository with the given name.
@@ -307,6 +305,13 @@ Repository.prototype.getTag = function(sha1, callback) {};
*/
Repository.prototype.createBlob = function(data, callback) {};
+/**
+ * Creates a new {@link Blob} in the Repository.
+ * @param {String} path The path to a file from which data will be made into the Blob.
+ * @param {Function} [callback] The id of the newly created Blob is returned to the callback.
+ */
+Repository.prototype.createBlobFromDisk = function(path, callback) {};
+
/**
* Retrieves a Blob from the Repository with given id.
* @param {String} sha1 The sha1 hash id of the blob.
diff --git a/src/args.coffee b/src/args.coffee
index 8ebe3aa..0eeaa6c 100644
--- a/src/args.coffee
+++ b/src/args.coffee
@@ -71,4 +71,10 @@ fn.validators =
return objectTypes.indexOf val > -1
remoteDir: (val) ->
- return remoteDirs.indexOf val > -1
\ No newline at end of file
+ return remoteDirs.indexOf val > -1
+
+ array: (val) ->
+ return val instanceof Array
+
+ object: (val) ->
+ return typeof val is "object"
\ No newline at end of file
diff --git a/src/gitteh.coffee b/src/gitteh.coffee
index fb8bf41..41b5173 100644
--- a/src/gitteh.coffee
+++ b/src/gitteh.coffee
@@ -188,7 +188,7 @@ Gitteh.Tree = class Tree
* **id**: *(String)* OID this entry points to.
* **name**: *(String)* file name of this entry.
* **type**: *(String)* kind of object pointed to by this entry
- * **attributes**: *(Number)* UNIX file attributes for this entry.
+ * **filemode**: *(Number)* UNIX file filemode for this entry.
###
constructor: (@repository, obj) ->
@@ -200,7 +200,7 @@ Gitteh.Tree = class Tree
.set("id")
.set("name")
.set("type")
- .set("attributes")
+ .set("filemode")
_immutable(@, obj)
.set("id")
.set("entries")
@@ -580,6 +580,70 @@ Gitteh.Repository = class Repository
_priv.native.createRemote name, url, _wrapCallback cb, (remote) =>
return cb null, new Remote @, remote
+ createBlobFromDisk: ->
+ ###
+ Creates a new Blob for this repository from the file-content loaded
+ from `path`. Calls `cb` when the operation has completed.
+ ###
+ _priv = _getPrivate @
+ [path, cb] = args
+ path: type: "string"
+ cb: type: "function"
+ _priv.native.createBlobFromDisk path, _wrapCallback cb, (blob) =>
+ return cb null, blob
+
+ createBlobFromBuffer: ->
+ ###
+ Creates a new Blob for this repository from the data supplied
+ as `buffer`. Calls `cb` when the operation has completed.
+ ###
+ _priv = _getPrivate @
+ [buffer, cb] = args
+ buffer: type: "object"
+ cb: type: "function"
+ _priv.native.createBlobFromBuffer buffer, _wrapCallback cb, (blob) =>
+ return cb null, blob
+
+ createTree: ->
+ ###
+ Creates a new Tree for this repository from the `entities`
+ that contain the content (as a blob), the name and the filemode
+ of the tree-entities that will be in the new Tree.
+ Calls `cb` when the operation has completed.
+ ###
+ _priv = _getPrivate @
+ [entities, cb] = args
+ entities: type: "array"
+ cb: type: "function"
+ _priv.native.createTree entities, _wrapCallback cb, (tree) =>
+ return cb null, tree
+
+ createCommit: ->
+ ###
+ Creates a new Commit for this repository from `data`.
+ `data` should contain the following keys:
+
+ * **updateref**: updates this reference to the new commit. (optional, default: do not update any refs)
+ * **author**: a signature of the author (optional, default: committer is used)
+ * **committer**: a signature of the committer
+ * **message**: the message of the commit
+ * **tree**: the id of a tree object
+ * **parents**: an array of parents.
+
+ A signature has the following keys:
+
+ * **name**: the name of the author/committer
+ * **email**: the email of the author/committer
+ * **time**: the time of the commit (optional)
+ * **offset**: timezone offset of the commit-time (optional)
+ ###
+ _priv = _getPrivate @
+ [data, cb] = args
+ data: type: "object"
+ cb: type: "function"
+ _priv.native.createCommit data, _wrapCallback cb, (commit) =>
+ return cb null, commit
+
###*
* Alias of {@link #reference}.
* @param {String} oid id of reference to be fetched.
@@ -691,7 +755,7 @@ Gitteh.clone = =>
else if entry.type is "blob"
repo.blob entry.id, _wrapCallback cb, (blob) ->
file = fs.createWriteStream _path.join(dest, entry.name),
- mode: entry.attributes
+ mode: entry.filemode
file.write blob.data
file.end()
cb()
diff --git a/src/repository.cc b/src/repository.cc
index 86f1a39..f969b0f 100644
--- a/src/repository.cc
+++ b/src/repository.cc
@@ -52,6 +52,22 @@ static Persistent ref_target_symbol;
static Persistent object_id_symbol;
static Persistent object_type_symbol;
+static Persistent tree_entry_id_symbol;
+static Persistent tree_entry_name_symbol;
+static Persistent tree_entry_filemode_symbol;
+
+static Persistent signature_name_symbol;
+static Persistent signature_email_symbol;
+static Persistent signature_time_symbol;
+static Persistent signature_offset_symbol;
+
+static Persistent commit_updateref_symbol;
+static Persistent commit_author_symbol;
+static Persistent commit_committer_symbol;
+static Persistent commit_message_symbol;
+static Persistent commit_parents_symbol;
+static Persistent commit_tree_symbol;
+
class OpenRepoBaton : public Baton {
public:
string path ;
@@ -171,6 +187,53 @@ class CreateRemoteBaton : public RepositoryBaton {
CreateRemoteBaton(Repository *r) : RepositoryBaton(r) { }
};
+class CreateBlobFromDiskBaton : public RepositoryBaton {
+public:
+ string path;
+ git_oid id;
+ CreateBlobFromDiskBaton(Repository *r) : RepositoryBaton(r) { }
+};
+
+class CreateBlobFromBufferBaton : public RepositoryBaton {
+public:
+ void *data;
+ int length;
+ git_oid id;
+ CreateBlobFromBufferBaton(Repository *r) : RepositoryBaton(r) { }
+};
+
+class TreeEntry {
+public:
+ git_oid id;
+ string name;
+ git_filemode_t filemode;
+};
+class CreateTreeBaton : public RepositoryBaton {
+public:
+ list entries;
+ git_oid treeid;
+ CreateTreeBaton(Repository *r) : RepositoryBaton(r), entries() { }
+};
+
+class CommitSignature {
+public:
+ string name;
+ string email;
+ git_time_t time;
+ int offset;
+};
+class CreateCommitBaton : public RepositoryBaton {
+public:
+ string update_ref;
+ CommitSignature author;
+ CommitSignature committer;
+ string message;
+ list parents;
+ git_oid treeid;
+ git_oid commitid;
+ CreateCommitBaton(Repository *r) : RepositoryBaton(r) { }
+};
+
Persistent Repository::constructor_template;
Repository::Repository() {
@@ -230,6 +293,25 @@ void Repository::Init(Handle