UNPKG

git-documentdb

Version:

Offline-first database that syncs with Git

147 lines (143 loc) 5.45 kB
"use strict"; /** * GitDocumentDB * Copyright (c) Hidekazu Kubota * * This source code is licensed under the Mozilla Public License Version 2.0 * found in the LICENSE file in the root directory of gitDDB source tree. */ var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.pushWorker = void 0; const isomorphic_git_1 = __importDefault(require("isomorphic-git")); const fs_extra_1 = __importDefault(require("fs-extra")); const worker_utils_1 = require("./worker_utils"); const remote_engine_1 = require("./remote_engine"); /** * Push and get changes * * @throws # Errors from push * @throws - {@link InvalidGitRemoteError} * @throws - {@link UnfetchedCommitExistsError} * @throws - {@link InvalidURLFormatError} * @throws - {@link NetworkError} * @throws - {@link HTTPError401AuthorizationRequired} * @throws - {@link HTTPError404NotFound} * @throws - {@link HTTPError403Forbidden} * @throws - {@link CannotConnectError} * @throws - {@link CannotConnectError} * @throws - {@link HttpProtocolRequiredError} * @throws - {@link InvalidRepositoryURLError} * @throws - {@link InvalidSSHKeyPathError} * @throws - {@link InvalidAuthenticationTypeError} * * @throws # Errors from getChanges * @throws - {@link Err.InvalidJsonObjectError} * * @internal */ // eslint-disable-next-line complexity async function pushWorker(gitDDB, sync, taskMetadata, skipStartEvent = false, afterMerge = false) { const syncOptions = sync.options; if (!skipStartEvent) { sync.eventHandlers.start.forEach(listener => { listener.func({ ...taskMetadata, collectionPath: listener.collectionPath }, sync.currentRetries()); }); } /** a) The first push --[baseCommit(remoteCommit)]--(...)--[headCommit(localCommit)] b) Fast forward --[baseCommit]--(...)--[remoteCommit]--(...)--[headCommit(localCommit)] c) HEAD is a merge commit ┌--(...)--[localCommit]---┐ --[baseCommit]--+ +--[headCommit] └--(...)--[remoteCommit]--┘ */ const headCommitOid = await isomorphic_git_1.default.resolveRef({ fs: fs_extra_1.default, dir: gitDDB.workingDir, ref: 'HEAD', }); const headCommit = await isomorphic_git_1.default.readCommit({ fs: fs_extra_1.default, dir: gitDDB.workingDir, oid: headCommitOid, }); let localCommitOid; const remoteCommitOid = await isomorphic_git_1.default .resolveRef({ fs: fs_extra_1.default, dir: gitDDB.workingDir, ref: `refs/remotes/${sync.remoteName}/${gitDDB.defaultBranch}`, }) .catch(() => undefined); if (headCommit.commit.parent.length === 2) { // HEAD is a merge commit. localCommitOid = headCommit.commit.parent[0]; } else { localCommitOid = headCommitOid; } let baseCommitOid; if (remoteCommitOid === undefined) { // This is the first push in this repository. // Get the first commit. const logs = await isomorphic_git_1.default.log({ fs: fs_extra_1.default, dir: gitDDB.workingDir }); baseCommitOid = logs[logs.length - 1].oid; if (baseCommitOid === localCommitOid) { baseCommitOid = undefined; } } else { [baseCommitOid] = await isomorphic_git_1.default.findMergeBase({ fs: fs_extra_1.default, dir: gitDDB.workingDir, oids: [localCommitOid, remoteCommitOid], }); } // Push const res = await remote_engine_1.RemoteEngine[sync.engine] .push(gitDDB.workingDir, syncOptions, sync.remoteName, gitDDB.defaultBranch, gitDDB.defaultBranch, gitDDB.tsLogger) .catch(err => err); if (res instanceof Error) { const error = (0, remote_engine_1.wrappingRemoteEngineError)(res); if (error instanceof remote_engine_1.RemoteErr.UnfetchedCommitExistsError) { if (localCommitOid === remoteCommitOid) { return { action: 'nop' }; } } throw error; } // NodeGit does not throw UnfetchedCommitExistsError when localCommitOid equals remoteCommitOid, // So check it again here. if (localCommitOid === remoteCommitOid) { return { action: 'nop' }; } let remoteChanges; if (afterMerge) { remoteChanges = undefined; } else { remoteChanges = await (0, worker_utils_1.getChanges)(gitDDB.workingDir, remoteCommitOid, headCommitOid, gitDDB.serializeFormat); } const syncResult = { action: 'push', changes: { remote: remoteChanges, }, }; // Get a list of commits which will be pushed to remote. let commitListRemote; if (syncOptions.includeCommits) { commitListRemote = await (0, worker_utils_1.getCommitLogs)(gitDDB.workingDir, headCommitOid, baseCommitOid, remoteCommitOid); syncResult.commits = { remote: commitListRemote, }; } return syncResult; } exports.pushWorker = pushWorker; //# sourceMappingURL=push_worker.js.map