Example #1
0
 return Promise.map(references, reference => {
     return Git.Commit
         .lookup(reference.repo, reference.target())
         .then(commit => commit.getTree())
         .then(tree => {
             return new Promise((resolve, reject) => {
                 const walker = tree.walk();
                 walker.on('entry', entry => {
                     if(entry.isBlob()) {
                         entry.getBlob().then(
                             blob => reduceDocuments(
                                 documents,
                                 blob,
                                 entry,
                                 ignores,
                                 reference,
                                 name,
                                 type
                             )
                         )
                     }
                 });
                 walker.on('end', resolve);
                 walker.on('error', reject);
                 walker.start();
             });
         })
 }).then(() => documents);
Example #2
0
File: gitzo.js Project: unkhz/gitzo
 commitIds.map(async (commitId) => {
   console.log('Showing', commitId, commitIds.length);
   const commit = await Commit.lookup(repo, commitId);
   const diffs = await commit.getDiff();
   diffs.map(async (diff) => {
     const patches = await diff.patches();
     patches.map(async (patch) => {
       const hunks = await patch.hunks();
       hunks.map(async (hunk, index) => {
         const lines = await hunk.lines();
         const data = {
           hunkId: [commitId, index],
           commit: commit.sha(),
           isAdded: patch.isAdded(),
           isDeleted: patch.isDeleted(),
           isModified: patch.isModified(),
           context: hunk.header(),
           path: patch.newFile().path(),
           content: lines.map((line) => line.content()).join('')
         };
         onData(data);
       });
     });
   });
 });
Example #3
0
                const manipulator = co.wrap(function*(repos, maps) {
                    const repo = repos.x;
                    const index = yield SubmoduleUtil.getSubmoduleNames(
                        repo);
                    const open = yield SubmoduleUtil.listOpenSubmodules(
                        repo);
                    const resolvedPaths = SubmoduleUtil.resolvePaths(c.paths,
                                                                     index,
                                                                     open,
                                                                     true);
                    let checkoutFromIndex;
                    let annotated;
                    if (c.commit === ":0") {
                        checkoutFromIndex = true;
                    } else {
                        const mapped = maps.reverseCommitMap[c.commit];
                        annotated = yield NodeGit.Commit.lookup(repo, mapped);
                    }

                    yield Checkout.checkoutFiles(repo, {
                        commit: annotated,
                        resolvedPaths: resolvedPaths,
                        checkoutFromIndex: checkoutFromIndex
                    });
                });
Example #4
0
exports.fastForwardMerge = co.wrap(function *(repo, mode, commit, message) {
    assert.instanceOf(repo, NodeGit.Repository);
    assert.isNumber(mode);
    assert.instanceOf(commit, NodeGit.Commit);
    assert.isString(message);

    // Remember the current branch; the checkoutCommit function will move it.

    const branch = yield repo.getCurrentBranch();
    let result = null;
    let newHead;
    if (MODE.FORCE_COMMIT !== mode) {
        // If we're not generating a commit, we just need to checkout the one
        // we're fast-forwarding to.

        yield Checkout.checkoutCommit(repo, commit, false);
        newHead = commit;
    }
    else {
        // Checkout the commit we're fast-forwarding to.

        const head = yield repo.getHeadCommit();
        yield Checkout.checkoutCommit(repo, commit, false);

        // Then, generate a new commit that has the previous HEAD and commit to
        // merge as children.

        const sig = repo.defaultSignature();
        const tree = yield commit.getTree();
        const id = yield NodeGit.Commit.create(
                                           repo,
                                           0,
                                           sig,
                                           sig,
                                           null,
                                           Commit.ensureEolOnLastLine(message),
                                           tree,
                                           2,
                                           [head, commit]);
        newHead = yield repo.getCommit(id);
        result = newHead.id().tostrS();

        // Move HEAD to point to the new commit.

        yield NodeGit.Reset.reset(repo,
                                  newHead,
                                  NodeGit.Reset.TYPE.HARD,
                                  null,
                                  branch.name());
    }

    // If we were on a branch, make it current again.

    if (branch.isBranch()) {
        yield branch.setTarget(newHead, "ffwd merge");
        yield repo.setHead(branch.name());
    }
    return result;
});
Example #5
0
const makeShadowCommitForRepo = co.wrap(function *(repo,
                                                   status,
                                                   message,
                                                   incrementTimestamp,
                                                   includeUntracked,
                                                   indexOnly) {
    assert.instanceOf(repo, NodeGit.Repository);
    assert.instanceOf(status, RepoStatus);
    assert.isString(message);
    assert.isBoolean(includeUntracked);
    assert.isBoolean(incrementTimestamp);
    assert.isBoolean(indexOnly);

    if (indexOnly) {
        const index = yield repo.index();
        const tree = yield index.writeTree();
        const sig = repo.defaultSignature();
        const subCommit = yield repo.createCommit(null, sig, sig,
                                                     message, tree, []);
        return subCommit.tostrS();
    }

    const changes = yield TreeUtil.listWorkdirChanges(repo,
                                                      status,
                                                      includeUntracked);
    const head = yield repo.getHeadCommit();
    const parents = [];

    const index = yield repo.index();
    const treeOid = yield index.writeTree();
    const indexTree = yield repo.getTree(treeOid);

    const newTree = yield TreeUtil.writeTree(repo, indexTree, changes);
    if (null !== head) {
        parents.push(head);
        const headTree = yield head.getTree();
        if (newTree.id().equal(headTree.id())) {
            return head.sha();
        }
    }

    let sig = repo.defaultSignature();
    if (incrementTimestamp && null !== head) {
        sig = NodeGit.Signature.create(sig.name(),
                                       sig.email(),
                                       head.time() + 1,
                                       head.timeOffset());
    }
    const id = yield NodeGit.Commit.create(repo,
                                           null,
                                           sig,
                                           sig,
                                           null,
                                           message,
                                           newTree,
                                           parents.length,
                                           parents);
    return id.tostrS();
});
Example #6
0
     .then(function (repo) {
     repos = repo;
     addCommand("git fetch");
     addCommand("git checkout -b " + bn);
     var cid = remoteName[bn];
     console.log("2.0  " + cid);
     return Git.Commit.lookup(repo, cid);
 })
Example #7
0
	.then(function(id) {
		if (mergeRequired) {
			// a merge commit was created, cleanup MERGE_* files in .git/
			var retCode = repo.stateCleanup();
			if (retCode !== git.Error.CODE.OK) {
				throw new Error("Internal merge cleanup failed (error code " + retCode + ")");
			}
		}
		return git.Commit.lookup(repo, id);
	});
Example #8
0
    const writeCommit = co.wrap(function *(sha) {
        const commit = commits[sha];
        const parents = commit.parents;

        // Get commit objects for parents.

        let parentTrees;
        let newParents = [];  // Array of commit IDs
        for (let i = 0; i < parents.length; ++i) {
            const parent = parents[i];
            if (0 === i) {
                parentTrees = treeCache[parent];
            }
            const parentSha = oldCommitMap[parent];
            const parentCommit = yield repo.getCommit(parentSha);
            newParents.push(parentCommit);
        }

        // Calculate the tree.  `trees` describes the directory tree specified
        // by the commit at `sha` and has caches for subtrees and submodules.

        const trees = yield writeTree(repo,
                                      oldCommitMap,
                                      commit.changes,
                                      parentTrees);

        // Store the returned tree information for potential use by descendants
        // of this commit.

        treeCache[sha] = trees;

        // Make a commit from the tree.

        const commitId = yield NodeGit.Commit.create(repo,
                                                     0,
                                                     sig,
                                                     sig,
                                                     0,
                                                     commit.message,
                                                     trees.tree,
                                                     newParents.length,
                                                     newParents);
        const commitSha = commitId.tostrS();

        // Store bi-directional mappings between generated and logical sha.

        oldCommitMap[sha] = commitSha;
        newCommitMap[commitSha] = sha;
        commitObjs[commitSha] = (yield repo.getCommit(commitSha));
        return commitSha;
    });
Example #9
0
const populateLibgit2MergeBugData = co.wrap(function*(repo, data) {
    if (data.mergeBases === undefined) {
        const head = data.head;
        const targetCommit = data.targetCommit;
        const mergeBases = yield GitUtil.mergeBases(repo, head, targetCommit);
        data.mergeBases = [];
        for (const base of mergeBases) {
            const commit = yield NodeGit.Commit.lookup(repo, base);
            data.mergeBases.push(commit);
        }
    }

    return data.mergeBases;
});
Example #10
0
 const commitAndBranch = co.wrap(function *(treeId, type) {
     const tree = yield NodeGit.Tree.lookup(repo, treeId);
     const commitId = yield NodeGit.Commit.create(repo,
                                                  null,
                                                  sig,
                                                  sig,
                                                  null,
                                                  type,
                                                  tree,
                                                  0,
                                                  []);
     const commit = yield repo.getCommit(commitId);
     yield NodeGit.Branch.create(repo, type, commit, 1);
     commitMap[commitId.tostrS()] = type;
 });
Example #11
0
exports.writeNotes = co.wrap(function *(repo, refName, contents) {
    assert.instanceOf(repo, NodeGit.Repository);
    assert.isString(refName);
    assert.isObject(contents);

    if (0 === Object.keys(contents).length) {
        // Nothing to do if no contents; no point in making an empty commit or
        // in making clients check themselves.
        return;                                                       // RETURN
    }

    // We're going to directly write the tree/commit for a new note containing
    // `contents`.

    let currentTree = null;
    const parents = [];
    const ref = yield GitUtil.getReference(repo, refName);
    if (null !== ref) {
        const currentCommit = yield repo.getCommit(ref.target());
        parents.push(currentCommit);
        currentTree = yield currentCommit.getTree();
    }
    const odb = yield repo.odb();
    const changes = {};
    const ODB_BLOB = 3;
    const BLOB = NodeGit.TreeEntry.FILEMODE.BLOB;
    const writeBlob = co.wrap(function *(sha) {
        const content = contents[sha];
        const blobId = yield odb.write(content, content.length, ODB_BLOB);
        const sharded = exports.shardSha(sha);
        changes[sharded] = new TreeUtil.Change(blobId, BLOB);
    });
    yield DoWorkQueue.doInParallel(Object.keys(contents), writeBlob);

    const newTree = yield TreeUtil.writeTree(repo, currentTree, changes);
    const sig = yield ConfigUtil.defaultSignature(repo);
    const commit = yield NodeGit.Commit.create(repo,
                                               null,
                                               sig,
                                               sig,
                                               null,
                                               "git-meta updating notes",
                                               newTree,
                                               parents.length,
                                               parents);
    yield NodeGit.Reference.create(repo, refName, commit, 1, "updated");
});
Example #12
0
    const prepSub = co.wrap(function*(subName) {
        const info = {};
        const subRepo = yield SubmoduleUtil.getRepo(repo, subName);
        info.repo = subRepo;

        const paths = resolvedPaths[subName];
        if (options.checkoutFromIndex) {
            const index = yield subRepo.index();
            info.index = index;
            // libgit2 doesn't care if requested paths don't exist,
            // but we do.
            for (const path of paths) {
                if (undefined === index.getByPath(path, stage)) {
                    errors.push(noSuchFileMessage(subName, path));
                }
            }
        } else {
            const subCommit = subCommits[subName];
            const resolvedSubCommit = yield NodeGit.Commit.lookup(subRepo,
                                                                  subCommit);
            info.resolvedSubCommit = resolvedSubCommit;
            // libgit2 doesn't care if requested paths don't exist,
            // but we do.
            const treeId = resolvedSubCommit.treeId();
            const tree = yield NodeGit.Tree.lookup(subRepo, treeId);

            for (const path of paths) {
                const entry = yield tree.entryByPath(path);
                if (null === entry) {
                    errors.push(noSuchFileMessage(subName, path));
                }
            }
        }

        submoduleInfo[subName] = info;
    });
Example #13
0
exports.save = co.wrap(function *(repo, status, includeUntracked, message) {
    assert.instanceOf(repo, NodeGit.Repository);
    assert.instanceOf(status, RepoStatus);
    assert.isBoolean(includeUntracked);
    if (null !== message) {
        assert.isString(message);
    }

    const subResults = {};  // name to sha
    const subChanges = {};  // name to TreeUtil.Change
    const subRepos   = {};  // name to submodule open repo

    const sig = repo.defaultSignature();

    // First, we process the submodules.  If a submodule is open and dirty,
    // we'll create the stash commits in its repo, populate `subResults` with
    // the `Stash.Submodule` that will be returned, `subChanges` with the sha
    // of the commit to be made to be used in generating the new submodule
    // tree, and `subRepos` to cache the open repo for each sub to be used
    // later.

    const submodules = status.submodules;
    yield Object.keys(submodules).map(co.wrap(function *(name) {
        const sub = submodules[name];
        const wd = sub.workdir;
        if (null === wd ||
            (wd.status.isClean() &&
             (sub.commit === null ||
              wd.status.headCommit === sub.commit.sha) &&
             (!includeUntracked ||
              0 === Object.keys(wd.status.workdir).length))) {
            // Nothing to do for closed or clean subs

            return;                                                   // RETURN
        }
        const subRepo = yield SubmoduleUtil.getRepo(repo, name);
        subRepos[name] = subRepo;

        let stashId;
        if (sub.commit !== null && wd.status.headCommit === sub.commit.sha) {
            const FLAGS = NodeGit.Stash.FLAGS;
            const flags = includeUntracked ?
                  FLAGS.INCLUDE_UNTRACKED :
                  FLAGS.DEFAULT;
            stashId = yield NodeGit.Stash.save(subRepo, sig, "stash",
                                                     flags);
        }
        else {
            stashId = NodeGit.Oid.fromString(wd.status.headCommit);
        }
        subResults[name] = stashId.tostrS();
        // Record the values we've created.

        subChanges[name] = new TreeUtil.Change(
                                            stashId,
                                            NodeGit.TreeEntry.FILEMODE.COMMIT);
    }));
    const head = yield repo.getHeadCommit();
    const headTree = yield head.getTree();
    const subsTree = yield TreeUtil.writeTree(repo, headTree, subChanges);
    const stashId = yield NodeGit.Commit.create(repo,
                                                null,
                                                sig,
                                                sig,
                                                null,
                                                "stash",
                                                subsTree,
                                                1,
                                                [head]);

    const stashSha = stashId.tostrS();

    // Make synthetic-meta-ref style refs for sub-repos.

    yield Object.keys(subRepos).map(co.wrap(function *(name) {
        const sha = subResults[name];
        const refName = makeSubRefName(sha);
        yield NodeGit.Reference.create(subRepos[name],
                                       refName,
                                       sha,
                                       1,
                                       "sub stash");
    }));

    // Update the stash ref and the ref log

    if (null === message) {
        message = yield exports.makeLogMessage(repo);
    }
    yield NodeGit.Reference.create(repo,
                                   metaStashRef,
                                   stashId,
                                   1,
                                   message);

    yield exports.createReflogIfNeeded(repo, metaStashRef, stashSha, message);
    return subResults;
});
Example #14
0
	.then(function(repo) {
		theRepo = repo;
		fileDir = clone.getfileDir(repo,req);
		return git.Commit.lookup(repo, commitId);
	})
Example #15
0
	.then(function(repo) {
		theRepo = repo;
		return git.Commit.lookup(repo, commitToRevert);
	})
Example #16
0
	.then(function(head) {
		theHead = head;
		return git.Commit.lookup(theRepo, commitToCherrypick);
	})
Example #17
0
	.then(function(repo) {
		theRepo = repo;
		fileDir = api.join(fileRoot, repo.workdir().substring(req.user.workspaceDir.length + 1));
		return git.Commit.lookup(repo, commitId);
	})
Example #18
0
exports.writeStitchedCommit = co.wrap(function *(repo,
                                                 commit,
                                                 subChanges,
                                                 parents,
                                                 keepAsSubmodule,
                                                 adjustPath,
                                                 skipEmpty,
                                                 whitelist) {
    assert.instanceOf(repo, NodeGit.Repository);
    assert.instanceOf(commit, NodeGit.Commit);
    assert.isObject(subChanges);
    assert.isArray(parents);
    assert.isFunction(keepAsSubmodule);
    assert.isFunction(adjustPath);
    assert.isBoolean(skipEmpty);
    assert.instanceOf(whitelist, Set);

    let updateModules = false;  // if any kept subs added or removed
    const changes = {};         // changes and additions
    let subCommits = {};        // included submodule commits
    const stitchSub = co.wrap(function *(name, oldName, sha) {
        let subCommit;
        try {
            subCommit = yield repo.getCommit(sha);
        }
        catch (e) {
            const metaSha = commit.id().tostrS();
            if (whitelist.has(metaSha)) {
                return;                                               // RETURN
            }
            throw new UserError(`\
On meta-commit ${metaSha}, ${name} is missing ${sha}.
To add to allow this submodule change to be skipped, run:
git notes --ref ${exports.whitelistNoteRef} add -m skip ${metaSha}`);
        }
        const subTreeId = subCommit.treeId();
        changes[name] = new TreeUtil.Change(subTreeId, FILEMODE.TREE);

        // Now, record this submodule change as introduced by this commit,
        // unless it already existed in another of its parents, i.e., it was
        // merged in.

        const alreadyExisted =
                yield exports.sameInAnyOtherParent(repo, commit, oldName, sha);
        if (!alreadyExisted) {
            subCommits[name] = subCommit;
        }
    });

    function changeKept(name, newSha) {
        const id = NodeGit.Oid.fromString(newSha);
        changes[name] = new TreeUtil.Change(id, FILEMODE.COMMIT);
    }

    for (let name in subChanges) {
        const mapped = adjustPath(name);
        if (null === mapped) {
            continue;                                               // CONTINUE
        }
        const newSha = subChanges[name].newSha;
        changes[mapped] = null;

        if (keepAsSubmodule(name)) {
            updateModules = true;
            if (null !== newSha) {
                changeKept(name, newSha);
            }
        } else if (null !== newSha) {
            yield stitchSub(mapped, name, newSha);
        }
    }

    // If any kept submodules were added or removed, rewrite the modules
    // file.

    if (updateModules) {
        const newUrls =
               yield SubmoduleConfigUtil.getSubmodulesFromCommit(repo, commit);
        const content = yield exports.computeModulesFile(repo,newUrls,
                                                         keepAsSubmodule,
                                                         adjustPath);
        changes[SubmoduleConfigUtil.modulesFileName] = content;
    }

    let newCommit = null;

    if (!skipEmpty || 0 !== Object.keys(changes).length) {
        // If we've got changes or are not skipping commits, we make one.

        let parentTree = null;
        if (0 !== parents.length) {
            const parentCommit = parents[0];
            parentTree = yield parentCommit.getTree();
        }

        const newTree = yield TreeUtil.writeTree(repo, parentTree, changes);

        const commitMessage = exports.makeStitchCommitMessage(commit,
                                                              subCommits);
        const newCommitId = yield NodeGit.Commit.create(
                                                      repo,
                                                      null,
                                                      commit.author(),
                                                      commit.committer(),
                                                      commit.messageEncoding(),
                                                      commitMessage,
                                                      newTree,
                                                      parents.length,
                                                      parents);
        newCommit = yield repo.getCommit(newCommitId);
    } else if (0 !== parents.length) {
        // If we skip this commit, map to its parent to indicate that whenever
        // we see this commit in the future, substitute its parent.

        newCommit = parents[0];
        subCommits = {};
    }
    return {
        stitchedCommit: newCommit,
        subCommits: subCommits,
    };
});
Example #19
0
	.then(function(id) {
		return git.Commit.lookup(repo, id);
	});