Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
const mergeSubmodule = co.wrap(function *(name) {
const subRepo = yield opener.getSubrepo(name, true);
const change = subs[name];
const theirSha = change.newSha;
const ourSha = change.ourSha;
yield fetcher.fetchSha(subRepo, name, theirSha);
yield fetcher.fetchSha(subRepo, name, ourSha);
const theirCommit = yield subRepo.getCommit(theirSha);
const ourCommit = yield subRepo.getCommit(ourSha);
// Commit forwards or backwards are handled at meta repo level.
if ((yield NodeGit.Graph.descendantOf(subRepo, ourSha, theirSha)) ||
(yield NodeGit.Graph.descendantOf(subRepo, theirSha, ourSha))) {
return result; // RETURN
}
console.log(`Submodule ${colors.blue(name)}: merging commit ` +
`${colors.green(theirSha)}.`);
// Start the merge.
let subIndex = yield NodeGit.Merge.commits(subRepo,
ourCommit,
theirCommit,
null);
// Abort if conflicted.
if (subIndex.hasConflicts()) {
result.conflicts[name] = theirSha;
const headCommit = yield repo.getHeadCommit();
const headRef = yield repo.head();
const headSha = headCommit.id().tostrS();
const ontoSha = onto.id().tostrS();
// First, see if 'commit' already exists in the current history. If so, we
// can exit immediately.
if (yield GitUtil.isUpToDate(repo, headSha, ontoSha)) {
const name = headRef.shorthand();
console.log(`${colors.green(name)} is up-to-date.`);
return result; // RETURN
}
const canFF = yield NodeGit.Graph.descendantOf(repo, ontoSha, headSha);
if (canFF) {
yield Reset.reset(repo, onto, Reset.TYPE.HARD);
console.log(`Fast-forwarded to ${GitUtil.shortSha(ontoSha)}`);
yield Hook.execHook(repo, "post-checkout", [headSha, ontoSha, "1"]);
return result; // RETURN
}
console.log("First, rewinding head to replay your work on top of it...");
yield Checkout.checkoutCommit(repo, onto, true);
const commits = yield exports.listRebaseCommits(repo, headCommit, onto);
const headName = headRef.isBranch() ? headRef.name() : null;
const seq = new SequencerState({
type: SequencerState.TYPE.REBASE,
originalHead: new CommitAndRef(headSha, headName),
yield fetcher.fetchSha(subRepo, subName, theirSha);
if (null !== change.ourSha) {
yield fetcher.fetchSha(subRepo, subName, change.ourSha);
}
const theirCommit = yield subRepo.getCommit(theirSha);
const ourSha = change.ourSha;
const ourCommit = yield subRepo.getCommit(ourSha);
const result = {
mergeSha: null,
conflictSha: null,
};
// See if up-to-date
if (yield NodeGit.Graph.descendantOf(subRepo, ourSha, theirSha)) {
return result; // RETURN
}
// See if can fast-forward and update HEAD if the submodule is opened.
if (yield NodeGit.Graph.descendantOf(subRepo, theirSha, ourSha)) {
if (isHalfOpened) {
yield CherryPickUtil.addSubmoduleCommit(metaIndex,
subName,
theirSha);
} else {
yield GitUtil.setHeadHard(subRepo, theirCommit);
yield metaIndex.addByPath(subName);
}
return result; // RETURN
}
if (null !== statusError) {
return MergeStepResult.error(statusError); // RETURN
}
if (!status.isDeepClean(false)) {
errorMessage = "The repository has uncommitted changes. "+
"Please stash or commit them before running merge.";
return MergeStepResult.error(errorMessage); // RETURN
}
}
if (ourCommitSha === theirCommitSha) {
infoMessage = "Nothing to do.";
return MergeStepResult.justMeta(infoMessage, theirCommit); // RETURN
}
const upToDate = yield NodeGit.Graph.descendantOf(metaRepo,
ourCommitSha,
theirCommitSha);
if (upToDate) {
return MergeStepResult.justMeta(infoMessage, ourCommitSha); // RETURN
}
return MergeStepResult.empty();
});
}
else {
// Check to see if the commit we're looking for is descended
// from the current commit. First, look in the cache.
if (isDescended.has(subShaForCommit)) {
result = isDescended.get(subShaForCommit);
}
else {
// Ensure that the commit we're checking against is
// present; we can't do a descendant check otherwise.
yield subFetcher.fetchSha(subRepo,
submoduleName,
subShaForCommit);
result = (yield NodeGit.Graph.descendantOf(
subRepo,
NodeGit.Oid.fromString(subShaForCommit),
subCommit.id())) !== 0;
isDescended.set(subShaForCommit, result);
}
}
}
existsInSha.set(sha, result);
return result;
});
exports.isUpToDate = co.wrap(function *(repo, source, target) {
assert.instanceOf(repo, NodeGit.Repository);
assert.isString(source);
assert.isString(target);
if (source === target) {
return true; // RETURN
}
return yield NodeGit.Graph.descendantOf(repo, source, target);
});
const enqueue = co.wrap(function *(commit) {
const sha = commit.id().tostrS();
// If we've seen a commit already, do not process it or any of its
// children. Otherwise, record that we've seen it.
if (seen.has(sha)) {
return; // RETURN
}
seen.add(sha);
// Skip this commit if it's an ancestor of `onto`.
const inHistory = yield NodeGit.Graph.descendantOf(repo, ontoSha, sha);
if (inHistory) {
return; // RETURN
}
const parents = yield commit.getParents();
// Record a null as the `sha` if this was a merge commit so that we
// know not to add it to `result` after processing its parents. We
// work from the back, so reverse the parents to get left first.
todo.push({
sha: 1 >= parents.length ? sha : null,
parents: parents.reverse(),
});
});
exports.isUpToDate = co.wrap(function *(repo, source, target) {
assert.instanceOf(repo, NodeGit.Repository);
assert.isString(source);
assert.isString(target);
if (source === target) {
return true; // RETURN
}
return yield NodeGit.Graph.descendantOf(repo, source, target);
});
// immediately. Detach head as this is the normal behavior.
if (headSha === branchSha ||
(yield NodeGit.Graph.descendantOf(repo, headSha, branchSha))) {
repo.detachHead();
return result; // RETURN
}
// If the upstream is non-null, but is an ancestor of HEAD or equal to it,
// libgit2 will try to rewrite commits that should not be rewritten and
// fail. In this case, we set upstream to null, indicating at all commits
// should be included (as they should).
if (null !== upstream) {
if (upstreamSha === headSha ||
(yield NodeGit.Graph.descendantOf(repo, headSha, upstreamSha))) {
upstream = null;
}
}
// We can do a fast-forward if `branch` and its entire history should be
// included. This requires two things to be true:
// 1. `branch` is a descendant of `head` or equal to `head`
// 2. `null === upstream` (implying that all ancestors are to be included)
if (null === upstream) {
if (yield NodeGit.Graph.descendantOf(repo, branchSha, headSha)) {
yield GitUtil.setHeadHard(repo, branch);
result.ffwd = true;
return result; // RETURN
}
}
.then((commits) => {
if (commits) {
return nodegit.Graph.aheadBehind(repository.git, commits[0].id(), commits[1].id());
} else {
return {
ahead: 0,
behind: 0
};
}
})
.then((result) => {