var assert = require("assert"); var path = require("path"); var local = path.join.bind(path, __dirname); var fse = require("fs-extra"); 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"; var previousCommitOid = "c82fb078a192ea221c9f1093c64321c60d64aa0d"; var filePath = "package.json"; beforeEach(function() { var test = this; return Repository.open(reposPath) .then(function(repository) { test.repo = repository; return test.repo.getCommit(currentCommitOid); }) .then(function(commit) { test.currentCommit = commit; return commit.getEntry(filePath); }) .then(function(entry) { return entry.getBlob(); }) .then(function(blob) { test.currentCommitBlob = blob; return test.repo.getCommit(previousCommitOid); }) .then(function(commit) { test.previousCommit = commit; return commit.getEntry(filePath); }) .then(function(entry) { return entry.getBlob(); }) .then(function(blob) { test.previousCommitBlob = blob; }); }); it("can reset a file to a previous commit", function() { var test = this; return Reset.default(test.repo, test.previousCommit, filePath) .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(); }) .then(function(blob) { var currentCommitContents = test.currentCommitBlob.toString(); var previousCommitContents = test.previousCommitBlob.toString(); var resetContents = blob.toString(); assert(resetContents != currentCommitContents); assert(resetContents == previousCommitContents); }) .then(function() { return Reset.default(test.repo, test.currentCommit, filePath); }) .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(); }) .then(function(blob) { var currentCommitContents = test.currentCommitBlob.toString(); var previousCommitContents = test.previousCommitBlob.toString(); var resetContents = blob.toString(); assert(resetContents == currentCommitContents); assert(resetContents != previousCommitContents); }); }); 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 repo.refreshIndex(); }) .then(function(index) { return index.writeTree(); }) .then(function(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 nwe reset to assert(resetContents == currentCommitContents); assert(resetContents != previousCommitContents); return Reset(test.repo, test.currentCommit, Reset.TYPE.HARD); }); }); it("can perform a mixed reset", function() { var test = this; 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(); 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 a hard reset", function() { var test = this; 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(); 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("reset fails if parameter is not a Commit object", function() { var test = this; var commit = test.repo.getReferenceCommit("master"); try { Reset.reset(test.repo, commit, Reset.TYPE.HARD); assert.fail( "Should not be able to pass a Promise (Commit) into the function" ); } catch (err) { // ok assert.equal( "Repository and target commit's repository does not match", err.message ); } }); it("reset fails if originating repository is not the same", function() { var test = this; var testCommit = null; return test.repo.getReferenceCommit("master") .then(function(commit) { testCommit = commit; return Repository.open(reposPath); }) .then(function(repo) { return Reset.reset(repo, testCommit, Reset.TYPE.HARD); }) .then(function() { assert.fail("Different source repository instance should fail"); }) .catch(function(err) { assert.equal( "Repository and target commit's repository does not match", err.message ); }); }); });