Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions generate/input/descriptor.json
Original file line number Diff line number Diff line change
Expand Up @@ -2097,6 +2097,17 @@
"return": {
"isErrorCode": true
}
},
"git_reset_from_annotated": {
"args": {
"checkout_opts": {
"isOptional": true
}
},
"isAsync": true,
"return": {
"isErrorCode": true
}
}
}
},
Expand Down
23 changes: 23 additions & 0 deletions lib/reset.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ var normalizeOptions = NodeGit.Utils.normalizeOptions;
var Reset = NodeGit.Reset;
var _default = Reset.default;
var _reset = Reset.reset;
var _fromAnnotated = Reset.fromAnnotated;

/**
* Look up a refs's commit.
Expand Down Expand Up @@ -50,3 +51,25 @@ Reset.reset = function(repo, target, resetType, opts) {

return _reset.call(this, repo, target, resetType, opts);
};

/**
* Sets the current head to the specified commit oid and optionally
* resets the index and working tree to match.
*
* This behaves like reset but takes an annotated commit, which lets
* you specify which extended sha syntax string was specified by a
* user, allowing for more exact reflog messages.
*
* See the documentation for reset.
*
* @async
* @param {Repository} repo
* @param {AnnotatedCommit} target
* @param {Number} resetType
* @param {CheckoutOptions} opts
*/
Reset.fromAnnotated = function(repo, target, resetType, opts) {
opts = normalizeOptions(opts, NodeGit.CheckoutOptions);

return _fromAnnotated.call(this, repo, target, resetType, opts);
};
129 changes: 91 additions & 38 deletions test/tests/reset.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ describe("Reset", function() {
var NodeGit = require("../../");
var Repository = NodeGit.Repository;
var Reset = NodeGit.Reset;
var AnnotatedCommit = NodeGit.AnnotatedCommit;

var reposPath = local("../repos/workdir");
var currentCommitOid = "32789a79e71fbc9e04d3eff7425e1771eb595150";
Expand Down Expand Up @@ -104,33 +105,65 @@ describe("Reset", function() {
});
});

it("can perform a soft reset", function() {
var test = this;

return Reset.reset(test.repo, test.previousCommit, Reset.TYPE.SOFT)
function resetFrom(repo, commit, resetType, annotated) {
var promise = null;
if (annotated) {
promise = AnnotatedCommit.lookup(repo, commit.id())
.then(function(annotatedCommit) {
return Reset.fromAnnotated(repo, annotatedCommit, resetType);
});
} else {
promise = Reset.reset(repo, commit, resetType);
}
return promise
.then(function() {
return test.repo.refreshIndex();
return repo.refreshIndex();
})
.then(function(index) {
return index.writeTree();
})
.then(function(oid) {
return test.repo.getTree(oid);
return repo.getTree(oid);
})
.then(function(tree) {
return tree.getEntry(filePath);
})
.then(function(entry) {
return entry.getBlob();
})
});
}

it("can perform a soft reset", function() {
var test = this;

return resetFrom(test.repo, test.previousCommit, Reset.TYPE.SOFT, false)
.then(function(blob) {
var currentCommitContents = test.currentCommitBlob.toString();
var previousCommitContents = test.previousCommitBlob.toString();
var resetContents = blob.toString();

// With a soft reset all of the changes should be in the index
// still so the index should still == what we had at the current
// commit and not the one nwe reset to
assert(resetContents == currentCommitContents);
assert(resetContents != previousCommitContents);

return Reset(test.repo, test.currentCommit, Reset.TYPE.HARD);
});
});

it("can perform an annotated soft reset", function() {
var test = this;

return resetFrom(test.repo, test.previousCommit, Reset.TYPE.SOFT, true)
.then(function(blob) {
var currentCommitContents = test.currentCommitBlob.toString();
var previousCommitContents = test.previousCommitBlob.toString();
var resetContents = blob.toString();

// With a soft reset all of the changes should be in the index
// still so the index should still == what we had at the current
// commit and not the one we reset to
// commit and not the one nwe reset to
assert(resetContents == currentCommitContents);
assert(resetContents != previousCommitContents);

Expand All @@ -141,22 +174,32 @@ describe("Reset", function() {
it("can perform a mixed reset", function() {
var test = this;

return Reset.reset(test.repo, test.previousCommit, Reset.TYPE.MIXED)
.then(function() {
return test.repo.refreshIndex();
})
.then(function(index) {
return index.writeTree();
})
.then(function(oid) {
return test.repo.getTree(oid);
})
.then(function(tree) {
return tree.getEntry(filePath);
})
.then(function(entry) {
return entry.getBlob();
return resetFrom(test.repo, test.previousCommit, Reset.TYPE.MIXED, false)
.then(function(blob) {
var currentCommitContents = test.currentCommitBlob.toString();
var previousCommitContents = test.previousCommitBlob.toString();
var resetContents = blob.toString();

// With a mixed reset all of the changes should removed from the index
// but still in the working directory. (i.e. unstaged)
assert(resetContents != currentCommitContents);
assert(resetContents == previousCommitContents);

return fse.readFile(path.join(test.repo.workdir(), filePath));
})
.then(function(fileContents) {
var currentCommitContents = test.currentCommitBlob.toString();

assert(fileContents == currentCommitContents);

return Reset.reset(test.repo, test.currentCommit, Reset.TYPE.HARD);
});
});

it("can perform an annotated mixed reset", function() {
var test = this;

return resetFrom(test.repo, test.previousCommit, Reset.TYPE.MIXED, true)
.then(function(blob) {
var currentCommitContents = test.currentCommitBlob.toString();
var previousCommitContents = test.previousCommitBlob.toString();
Expand All @@ -181,22 +224,32 @@ describe("Reset", function() {
it("can perform a hard reset", function() {
var test = this;

return Reset.reset(test.repo, test.previousCommit, Reset.TYPE.HARD)
.then(function() {
return test.repo.refreshIndex();
})
.then(function(index) {
return index.writeTree();
})
.then(function(oid) {
return test.repo.getTree(oid);
})
.then(function(tree) {
return tree.getEntry(filePath);
})
.then(function(entry) {
return entry.getBlob();
return resetFrom(test.repo, test.previousCommit, Reset.TYPE.HARD, false)
.then(function(blob) {
var currentCommitContents = test.currentCommitBlob.toString();
var previousCommitContents = test.previousCommitBlob.toString();
var resetContents = blob.toString();

// With a hard reset all of the changes should removed from the index
// and also removed from the working directory
assert(resetContents != currentCommitContents);
assert(resetContents == previousCommitContents);

return fse.readFile(path.join(test.repo.workdir(), filePath));
})
.then(function(fileContents) {
var previousCommitContents = test.previousCommitBlob.toString();

assert(fileContents == previousCommitContents);

return Reset.reset(test.repo, test.currentCommit, Reset.TYPE.HARD);
});
});

it("can perform an annotated hard reset", function() {
var test = this;

return resetFrom(test.repo, test.previousCommit, Reset.TYPE.HARD, true)
.then(function(blob) {
var currentCommitContents = test.currentCommitBlob.toString();
var previousCommitContents = test.previousCommitBlob.toString();
Expand Down