Example #1
0
            const shadower = co.wrap(function *(repos, mapping) {
                // If a meta commit was made, map it to "m" and create a branch
                // named "m" pointing to it.  For each submodule commit made,
                // map the commit to one with that submodule's name, and make a
                // branch in the submodule with that name.

                const repo = repos.x;
                const message = c.message || "message\n";
                const meta = c.includeMeta;
                const includeUntracked =
                        undefined === c.includeUntracked || c.includeUntracked;
                const incrementTimestamp =
                        (undefined === c.incrementTimestamp) ?
                        false : c.incrementTimestamp;
                const result = yield StashUtil.makeShadowCommit(
                                                            repo,
                                                            message,
                                                            incrementTimestamp,
                                                            meta,
                                                            includeUntracked,
                                                            false);

                const commitMap = {};
                if (null !== result) {
                    const metaSha = result.metaCommit;
                    const commit = yield repo.getCommit(metaSha);
                    const head = yield repo.getHeadCommit();
                    if (incrementTimestamp) {
                        assert.equal(commit.time(), head.time() + 1);
                    }
                    commitMap[metaSha] = "m";
                    yield NodeGit.Branch.create(repo, "m", commit, 1);
                    for (let path in result.subCommits) {
                        const subSha = result.subCommits[path];
                        const subRepo = yield SubmoduleUtil.getRepo(repo,
                                                                    path);
                        const subCommit = yield subRepo.getCommit(subSha);
                        if (!(subSha in mapping.commitMap)) {
                            commitMap[subSha] = path;
                            yield NodeGit.Branch.create(subRepo,
                                                        path,
                                                        subCommit,
                                                        1);
                        }
                    }
                }
                return {
                    commitMap: commitMap,
                };
            });
Example #2
0
		.then(function(ref) {
			if (git.Branch.delete(ref) === 0) {
				res.status(200).end();
			} else {
				writeError(403, res);
			}
		})
Example #3
0
			.then(function(commit) {
				theCommit = commit;
				if (branch) {
					return git.Branch.create(theRepo, branch, commit, 0).then(function() {
						return theRepo.checkoutBranch("refs/heads/" + branch, checkOptions);
					});
				}
			 	return git.Checkout.tree(theRepo, commit, checkOptions).then(function() {
					return theRepo.setHeadDetached(theCommit);
				});
			});
           repo.getBranchCommit(ref.shorthand()).then(function (commit) {
 
             nodegit.Branch.create(repo, thisHook.context.params.name, commit, 0).then(function (reference) {
 
               data.messages.push({
                 "message": "Branch created"
               });
               thisHook.pass(data);
 
             });
 
           });
Example #5
0
exports.executeCheckout = co.wrap(function *(repo,
                                             commit,
                                             newBranch,
                                             switchBranch,
                                             force) {
    assert.instanceOf(repo, NodeGit.Repository);
    if (null !== commit) {
        assert.instanceOf(commit, NodeGit.Commit);
    }
    if (null !== newBranch) {
        assert.isObject(newBranch);
        assert.isString(newBranch.name);
        if (null !== newBranch.tracking) {
            assert.isObject(newBranch.tracking);
            if (null !== newBranch.tracking.remoteName) {
                assert.isString(newBranch.tracking.remoteName);
            }
            assert.isString(newBranch.tracking.branchName);
        }
    }
    if (null !== switchBranch) {
        assert.isString(switchBranch);
    }
    assert.isBoolean(force);

    // attempt the checkout first.

    if (null !== commit) {
        yield exports.checkoutCommit(repo, commit, force);
    }
    if (null !== newBranch) {
        const name = newBranch.name;
        const branch = yield GitUtil.createBranchFromHead(repo, name);
        const tracking = newBranch.tracking;
        if (null !== tracking) {
            const trackingName = tracking.branchName;
            const remote = tracking.remoteName;
            let trackingBranchName;
            if (null !== remote) {
                trackingBranchName = `${remote}/${trackingName}`;
            }
            else {
                trackingBranchName = trackingName;
            }
            yield NodeGit.Branch.setUpstream(branch, trackingBranchName);
        }
    }
    if (null !== switchBranch) {
        yield repo.setHead(`refs/heads/${switchBranch}`);
    }
});
Example #6
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 #7
0
							return Promise.all(branches.map(function(branch) {
								return git.Branch.lookup(repo, api.join(remote.name(), branch.Name), git.Branch.BRANCH.REMOTE).then(function(remoteBranch) {
									return repo.getBranchCommit(remoteBranch).then(function(commit) {
										var rJson = mRemotes.remoteJSON(remote, fileDir, [mRemotes.remoteBranchJSON(remoteBranch, commit, remote, fileDir)]);
										var trackingRemote = config.branch && config.branch[branch.Name] && config.branch[branch.Name].remote;
										if (trackingRemote === remote.name() || !trackingRemote) {
											branch["RemoteLocation"].splice(0, 0, rJson);
										} else {
											branch["RemoteLocation"].push(rJson);
										}
									});
								}).catch(function() {
									//No remote tracking branch
									branch["RemoteLocation"].push(mRemotes.remoteJSON(remote, fileDir, [mRemotes.remoteBranchJSON(null, null, remote, fileDir, branch)]));
								});
							}));
Example #8
0
    const writeRepo = co.wrap(function *(repo, ast) {
        assert.instanceOf(ast, RepoAST);

        // Now we should have all the commits from `commitRepo` so delete it
        // and all associated refs.  We have to detach the head or it keeps
        // around the current branch.

        repo.detachHead();

        const refs = yield repo.getReferences(NodeGit.Reference.TYPE.LISTALL);
        for (let i = 0; i < refs.length; ++i) {
            NodeGit.Branch.delete(refs[i]);
        }
        yield NodeGit.Remote.delete(repo, "origin");

        // Then set up the rest of the repository.
        yield configureRepo(repo, ast, commitMaps.oldToNew, treeCache);
        const cleanupString = `\
git -C '${repo.path()}' -c gc.reflogExpire=0 -c gc.reflogExpireUnreachable=0 \
-c gc.rerereresolved=0 -c gc.rerereunresolved=0 \
-c gc.pruneExpire=now gc`;
        yield exec(cleanupString);
    });
Example #9
0
 }).then((branch) => {
   currentBranch = branch
   return Branch.upstream(currentBranch)
 }).then((currentOrigin) => {
Example #10
0
		.then(function(commit) {
			var branch = "master";
			return git.Branch.create(subrepo, branch, commit, 0).then(function() {
				return subrepo.checkoutBranch(branch, {});
			});
		})
Example #11
0
		.then(function(repo) {
			return git.Branch.lookup(repo, branchName, git.Branch.BRANCH.LOCAL);
		})
Example #12
0
		.then(function(commit) {
			if (!branchName) {
				branchName = theRef.shorthand().split("/").slice(1).join("/");
			}
			return git.Branch.create(theRepo, branchName, commit, 0);
		})
Example #13
0
			.then(function(repo) {
				theRepo = repo;
				fileDir = clone.getfileDir(repo,req);
				return git.Branch.lookup(repo, branchName, git.Branch.BRANCH.LOCAL);
			})
Example #14
0
const configureRepo = co.wrap(function *(repo, ast, commitMap, treeCache) {
    const makeConflictEntry = co.wrap(function *(data) {
        assert.instanceOf(repo, NodeGit.Repository);
        if (null === data) {
            return null;
        }
        if (data instanceof RepoAST.Submodule) {
            //TODO: some day support putting conflicts in the .gitmodules file.
            assert.equal("",
                         data.url,
                         "submodule conflicts must have empty URL");
            const sha = commitMap[data.sha];
            return new ConflictUtil.ConflictEntry(FILEMODE.COMMIT, sha);
        }
        const id = yield GitUtil.hashObject(repo, data.contents);
        const mode = data.isExecutable ? FILEMODE.EXECUTABLE : FILEMODE.BLOB;
        return new ConflictUtil.ConflictEntry(mode, id.tostrS());
    });

    const makeRef = co.wrap(function *(name, commit) {
        const newSha = commitMap[commit];
        const newId = NodeGit.Oid.fromString(newSha);
        return yield NodeGit.Reference.create(repo,
                                              name,
                                              newId,
                                              0,
                                              "made ref");
    });

    let newHeadSha = null;
    if (null !== ast.head) {
        newHeadSha = commitMap[ast.head];
    }

    // Then create the refs

    for (let ref in ast.refs) {
        yield makeRef("refs/" + ref, ast.refs[ref]);
    }

    // Handle remotes.

    for (let remoteName in ast.remotes) {
        const remote = ast.remotes[remoteName];
        yield NodeGit.Remote.create(repo, remoteName, remote.url);

        // Explicitly create the desired refs for the remote.

        for (let branchName in remote.branches) {
            yield makeRef(`refs/remotes/${remoteName}/${branchName}`,
                          remote.branches[branchName]);
        }
    }

    // Then create the branches we want.

    for (let branch in ast.branches) {
        const astBranch = ast.branches[branch];
        const ref = yield makeRef("refs/heads/" + branch, astBranch.sha);
        if (null !== astBranch.tracking) {
            yield NodeGit.Branch.setUpstream(ref, astBranch.tracking);
        }
    }

    // Deal with bare repos.

    if (ast.bare) {
        if (null !== ast.currentBranchName) {
            yield repo.setHead("refs/heads/" + ast.currentBranchName);
        }
        else {
            repo.setHeadDetached(newHeadSha);
        }
    }
    else if (null !== ast.currentBranchName || null !== ast.head) {
        // If we use NodeGit to checkout, it will not respect the
        // sparse-checkout settings.

        if (null === ast.currentBranchName) {
            repo.detachHead();
        }

        const toCheckout = ast.currentBranchName || newHeadSha;
        const checkoutStr = `\
git -C '${repo.workdir()}' checkout ${toCheckout}
`;
        try {
            yield exec(checkoutStr);
        } catch (e) {
            // This can fail if there is no .gitmodules file to checkout and
            // it's sparse.  Git will complain that it cannot do the checkout
            // because the worktree is empty.
        }
    }

    const notes = ast.notes;
    const sig = repo.defaultSignature();
    for (let notesRef in notes) {
        const commits = notes[notesRef];
        for (let commit in commits) {
            const message = commits[commit];
            yield NodeGit.Note.create(repo, notesRef, sig, sig,
                                      commitMap[commit], message, 0);
        }
    }

    if (!ast.bare) {

        let indexHead = ast.head;

        // Set up a rebase if there is one, this has to come right before
        // setting up the workdir, otherwise the rebase won't be allowed to
        // start.

        if (null !== ast.rebase) {
            const rebase = ast.rebase;
            const originalSha = commitMap[rebase.originalHead];
            const ontoSha = commitMap[rebase.onto];
            const original = yield NodeGit.AnnotatedCommit.lookup(repo,
                                                                  originalSha);
            const onto = yield NodeGit.AnnotatedCommit.lookup(repo, ontoSha);

            // `init` creates the rebase, but it's not actually started (some
            // files are not made) until the first call to `next`.

            const rb  =
                   yield NodeGit.Rebase.init(repo, original, onto, null, null);
            yield rb.next();
            const gitDir = repo.path();
            const rbDir = yield RebaseFileUtil.findRebasingDir(gitDir);
            const headNamePath = path.join(gitDir,
                                           rbDir,
                                           RebaseFileUtil.headFileName);
            yield fs.writeFile(headNamePath, rebase.headName + "\n");

            // Starting a rebase will change the HEAD  If we render the index
            // against `ast.head`, it will be incorrect; we must adjust so that
            // we render against the new head, `onto`.

            indexHead = rebase.onto;
        }

        // Write out sequencer state if there is one.
        const sequencer = ast.sequencerState;
        if (null !== sequencer) {
            const mapped = SequencerStateUtil.mapCommits(sequencer, commitMap);
            yield SequencerStateUtil.writeSequencerState(repo.path(), mapped);
        }

        // Set up the index.  We render the current commit and apply the index
        // on top of it.

        let indexParent;
        if (null !== indexHead) {
            indexParent = treeCache[indexHead];
        }
        const trees = yield writeTree(repo,
                                      commitMap,
                                      ast.index,
                                      indexParent);
        const index = yield repo.index();
        const treeObj = trees.tree;
        yield index.readTree(treeObj);
        for (let filename in ast.index) {
            const data = ast.index[filename];
            if (data instanceof RepoAST.Conflict) {
                const ancestor = yield makeConflictEntry(data.ancestor);
                const our = yield makeConflictEntry(data.our);
                const their = yield makeConflictEntry(data.their);
                const conflict = new ConflictUtil.Conflict(ancestor,
                                                           our,
                                                           their);
                yield ConflictUtil.addConflict(index, filename, conflict);
            }
        }

        yield index.write();

        // TODO: Firgure out if this can be done with NodeGit; extend if
        // not.  I didn't see anything about `clean` and `Checkout.index`
        // didn't seem to work..

        const filesStr = ast.sparse ? "-- .gitmodules" : "-a";
        const checkoutIndexStr = `\
git -C '${repo.workdir()}' checkout --
git -C '${repo.workdir()}' clean -f -d
git -C '${repo.workdir()}' checkout-index -f ${filesStr}
`;
        yield exec(checkoutIndexStr);

        // Now apply changes to the workdir.

        const workdir = ast.workdir;
        for (let filePath in workdir) {
            const change = workdir[filePath];
            const absPath = path.join(repo.workdir(), filePath);
            if (null === change) {
                yield fs.unlink(absPath);
            }
            else {
                const dirname = path.dirname(absPath);
                mkdirp.sync(dirname);
                yield fs.writeFile(absPath, change.contents);
                if (change.isExecutable) {
                    yield fs.chmod(absPath, "755");
                }
            }
        }
    }

    return repo;
});
Example #15
0
exports.stitch = co.wrap(function *(repoPath,
                                    commitish,
                                    targetBranchName,
                                    options) {
    assert.isString(repoPath);
    assert.isString(commitish);
    assert.isString(targetBranchName);
    assert.isObject(options);

    let fetch = false;
    let url = null;
    if ("fetch" in options) {
        assert.isBoolean(options.fetch);
        fetch = options.fetch;
        assert.isString(options.url, "url required with fetch");
        url = options.url;
    }

    assert.isFunction(options.keepAsSubmodule);

    let joinRoot = null;
    if ("joinRoot" in options) {
        assert.isString(options.joinRoot);
        joinRoot = options.joinRoot;
    }

    assert.isNumber(options.numParallel);

    let skipEmpty = false;
    if ("skipEmpty" in options) {
        assert.isBoolean(options.skipEmpty);
        skipEmpty = options.skipEmpty;
    }

    const repo = yield NodeGit.Repository.open(repoPath);
    const annotated = yield GitUtil.resolveCommitish(repo, commitish);
    if (null === annotated) {
        throw new Error(`Could not resolve ${commitish}.`);
    }
    const commit = yield repo.getCommit(annotated.id());

    console.log("Listing previously converted commits.");

    let convertedCommits = {};
    if (options.preloadCache) {
        convertedCommits = yield exports.readConvertedCommits(repo);
    }
    const getConverted = exports.makeGetConvertedCommit(repo,
                                                        convertedCommits);

    console.log("listing unconverted ancestors of", commit.id().tostrS());

    const commitsToStitch =
                 yield exports.listCommitsToStitch(repo, commit, getConverted);

    console.log("listing submodule changes");

    const changes = yield exports.listSubmoduleChanges(repo, commitsToStitch);

    const adjustPath = exports.makeAdjustPathFunction(joinRoot);

    console.log(commitsToStitch.length, "to stitch");

    if (fetch) {
        console.log("listing fetches");
        const fetches = yield exports.listFetches(repo,
                                                  commitsToStitch,
                                                  changes,
                                                  options.keepAsSubmodule,
                                                  adjustPath,
                                                  options.numParallel);
        console.log("Found", Object.keys(fetches).length, "subs to fetch.");
        const subNames = Object.keys(fetches);
        const doFetch = co.wrap(function *(name, i) {
            const subFetches = fetches[name];
            const fetchTimeMessage = `\
(${i + 1}/${subNames.length}) -- fetched ${subFetches.length} SHAs for \
${name}`;
            console.time(fetchTimeMessage);
            yield exports.fetchSubCommits(repo, url, subFetches);
            console.timeEnd(fetchTimeMessage);
        });
        yield DoWorkQueue.doInParallel(subNames, doFetch, options.numParallel);
    }

    console.log("Now stitching");
    let lastCommit = null;

    let records = {};

    const writeNotes = co.wrap(function *() {
        console.log(
                  `Writing notes for ${Object.keys(records).length} commits.`);
        const convertedNotes = {};
        const referenceNotes = {};
        for (let sha in records) {
            const record = records[sha];
            const stitchedCommit = record.stitchedCommit;
            const stitchedSha =
                 null === stitchedCommit ? null : stitchedCommit.id().tostrS();
            convertedNotes[sha] =
                                 exports.makeConvertedNoteContent(stitchedSha);
            if (null !== stitchedSha) {
                referenceNotes[stitchedSha] =
                      exports.makeReferenceNoteContent(sha, record.subCommits);
            }
        }
        yield BulkNotesUtil.writeNotes(repo,
                                       exports.referenceNoteRef,
                                       referenceNotes);
        yield BulkNotesUtil.writeNotes(repo,
                                       exports.convertedNoteRef,
                                       convertedNotes);
        records = {};
    });

    const whitelist = yield exports.readWhitelist(repo);

    for (let i = 0; i < commitsToStitch.length; ++i) {
        const next = commitsToStitch[i];

        const nextSha = next.id().tostrS();
        const parents = yield next.getParents();
        const newParents = [];
        for (const parent of parents) {
            const newParentSha = yield getConverted(parent.id().tostrS());
            if (null !== newParentSha && undefined !== newParentSha) {
                const newParent = yield repo.getCommit(newParentSha);
                newParents.push(newParent);
            }
        }

        const result = yield exports.writeStitchedCommit(
                                                       repo,
                                                       next,
                                                       changes[nextSha],
                                                       newParents,
                                                       options.keepAsSubmodule,
                                                       adjustPath,
                                                       skipEmpty,
                                                       whitelist);
        records[nextSha] = result;
        const newCommit = result.stitchedCommit;
        const newSha = null === newCommit ? null : newCommit.id().tostrS();
        convertedCommits[nextSha] = newSha;
        const desc = null === newCommit ? "skipped" : newCommit.id().tostrS();
        const log = `\
Of [${commitsToStitch.length}] done [${i + 1}] : ${nextSha} -> ${desc}`;
        console.log(log);

        if (10000 <= Object.keys(records).length) {
            yield writeNotes();
        }

        // If `writeStitchedCommit` returned null to indicate that it did not
        // make a commit (because it would have been empty), leave `lastCommit`
        // unchanged.

        lastCommit = newCommit || lastCommit;
    }
    yield writeNotes();

    // Delete submodule change cache if we succeeded; we won't need these
    // submodules again.

    if (0 !== Object.keys(changes)) {
        NodeGit.Reference.remove(repo, exports.changeCacheRef);
    }

    if (null !== lastCommit) {
        console.log(
               `Updating ${targetBranchName} to ${lastCommit.id().tostrS()}.`);
        yield NodeGit.Branch.create(repo, targetBranchName, lastCommit, 1);
    }
});
Example #16
0
 .then(([repo, local]) => {
   const upstream = Git.Branch.upstream(local)
   return Promise.all([repo, local, upstream])
 })
Example #17
0
 const deleteBranch = co.wrap(function *(repo) {
     const branch = yield GitUtil.findBranch(repo, branchName);
     if (null !== branch) {
         NodeGit.Branch.delete(branch);
     }
 });
Example #18
0
 .then(branch => Git.Branch.upstream(branch))
Example #19
0
     .then(function (commit) {
     console.log("3.0");
     return Git.Branch.create(repos, bn, commit, 0);
 })