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
103 changes: 97 additions & 6 deletions lib/repository.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
var promisify = require("promisify-node");
var fse = promisify(require("fs-extra"));
var fp = require("lodash/fp");
var NodeGit = require("../");
var Blob = NodeGit.Blob;
var Checkout = NodeGit.Checkout;
Expand Down Expand Up @@ -184,12 +185,35 @@ function getPathHunks(repo, index, filePath, isStaged, additionalDiffOptions) {
* invocation of next(). If the callback
* returns a promise, the next() will be
* called when the promise resolves.
* @param {Function} beforeFinishFn Callback called before the invocation
* of finish(). If the callback returns a
* promise, finish() will be called when the
* promise resolves. This callback will be
* provided a detailed overview of the rebase
* @return {Int|Index} An error code for an unsuccesful rebase or an index for
* a rebase with conflicts
*/
function performRebase(repository, rebase, signature, beforeNextFn) {
function performRebase(
repository,
rebase,
signature,
beforeNextFn,
beforeFinishFn
) {
var beforeNextFnResult;

function readRebaseMetadataFile(fileName) {
return fse.readFile(
path.join(repository.path(), "rebase-merge", fileName),
{ encoding: "utf8" }
)
.then(fp.trim);
}

function calcHeadName(input) {
return input.replace(/refs\/heads\/(.*)/, "$1");
}

function getPromise() {
return rebase.next()
.then(function() {
Expand All @@ -201,11 +225,51 @@ function performRebase(repository, rebase, signature, beforeNextFn) {

rebase.commit(null, signature);

return performRebase(repository, rebase, signature, beforeNextFn);
return performRebase(
repository,
rebase,
signature,
beforeNextFn,
beforeFinishFn
);
});
}, function(error) {
if (error && error.errno === NodeGit.Error.CODE.ITEROVER) {
return rebase.finish(signature);
const calcRewritten = fp.flow([
fp.split("\n"),
fp.map(fp.split(" "))
]);

const beforeFinishFnPromise = !beforeFinishFn ?
Promise.resolve() :
Promise.all([
readRebaseMetadataFile("onto_name"),
readRebaseMetadataFile("onto"),
readRebaseMetadataFile("head-name").then(calcHeadName),
readRebaseMetadataFile("orig-head"),
readRebaseMetadataFile("rewritten").then(calcRewritten)
])
.then(function([
ontoName,
ontoSha,
originalHeadName,
originalHeadSha,
rewritten
]) {
return beforeFinishFn({
ontoName,
ontoSha,
originalHeadName,
originalHeadSha,
rebase,
rewritten
});
});

return beforeFinishFnPromise
.then(function() {
return rebase.finish(signature);
});
} else {
throw error;
}
Expand Down Expand Up @@ -354,10 +418,19 @@ Repository.prototype.checkoutRef = function(reference, opts) {
* promise, the rebase will resume when the
* promise resolves. The rebase object is
* is passed to the callback.
* @param {Function} beforeFinishFn Callback called before the invocation
* of finish(). If the callback returns a
* promise, finish() will be called when the
* promise resolves. This callback will be
* provided a detailed overview of the rebase
* @return {Oid|Index} A commit id for a succesful merge or an index for a
* rebase with conflicts
*/
Repository.prototype.continueRebase = function(signature, beforeNextFn) {
Repository.prototype.continueRebase = function(
signature,
beforeNextFn,
beforeFinishFn
) {
var repo = this;

signature = signature || repo.defaultSignature();
Expand All @@ -373,7 +446,13 @@ Repository.prototype.continueRebase = function(signature, beforeNextFn) {
.then(function(rebase) {
rebase.commit(null, signature);

return performRebase(repo, rebase, signature, beforeNextFn);
return performRebase(
repo,
rebase,
signature,
beforeNextFn,
beforeFinishFn
);
})
.then(function(error) {
if (error) {
Expand Down Expand Up @@ -1218,6 +1297,11 @@ Repository.prototype.isReverting = function() {
* promise, the rebase will resume when the
* promise resolves. The rebase object is
* is passed to the callback.
* @param {Function} beforeFinishFn Callback called before the invocation
* of finish(). If the callback returns a
* promise, finish() will be called when the
* promise resolves. This callback will be
* provided a detailed overview of the rebase
* @return {Oid|Index} A commit id for a succesful merge or an index for a
* rebase with conflicts
*/
Expand All @@ -1227,6 +1311,7 @@ Repository.prototype.rebaseBranches = function(
onto,
signature,
beforeNextFn,
beforeFinishFn,
rebaseOptions
)
{
Expand Down Expand Up @@ -1278,7 +1363,13 @@ Repository.prototype.rebaseBranches = function(
rebaseOptions
)
.then(function(rebase) {
return performRebase(repo, rebase, signature, beforeNextFn);
return performRebase(
repo,
rebase,
signature,
beforeNextFn,
beforeFinishFn
);
})
.then(function(error) {
if (error) {
Expand Down
Loading