From db8f6b7c2e3be39a5603cfdcc5ea9aeb896544db Mon Sep 17 00:00:00 2001 From: Kipras Melnikovas Date: Wed, 23 Mar 2022 01:14:01 +0200 Subject: [PATCH] feat: set-upstream to remote when pushing for the first time Signed-off-by: Kipras Melnikovas --- forcePush.ts | 57 ++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 55 insertions(+), 2 deletions(-) diff --git a/forcePush.ts b/forcePush.ts index aca88579..86fb0e83 100644 --- a/forcePush.ts +++ b/forcePush.ts @@ -2,6 +2,8 @@ // import fs from "fs"; +import Git from "nodegit"; + import { getWantedCommitsWithBranchBoundariesOurCustomImpl } from "./git-stacked-rebase"; import { branchSequencer, // @@ -10,6 +12,8 @@ import { // getBackupPathOfPreviousStackedRebase, } from "./branchSequencer"; +import { createQuestion } from "./util/createQuestion"; + export const forcePush: BranchSequencerBase = (argsBase) => // /** // * TODO TESTS we __really__ need to make sure we test this one lmao @@ -36,8 +40,57 @@ export const forcePush: BranchSequencerBase = (argsBase) => branchSequencer({ ...argsBase, // pathToStackedRebaseDirInsideDotGit, - actionInsideEachCheckedOutBranch: ({ execSyncInRepo }) => { - execSyncInRepo(`${argsBase.gitCmd} push --force`); + actionInsideEachCheckedOutBranch: async ({ execSyncInRepo, repo }) => { + const branch: Git.Reference = await repo.getCurrentBranch(); + const upstreamBranch: Git.Reference | null = await Git.Branch.upstream(branch).catch(() => null); + + if (!upstreamBranch) { + const remotes: string[] = await repo.getRemoteNames(); + + if (remotes.length === 0) { + throw new Error("0 remotes found, cannot push a new branch into a remote."); + } + + let remote: string; + + if (remotes.length === 1) { + remote = remotes[0]; + } else { + const indices: string[] = remotes.map((_, i) => i + 1).map((x) => x.toString()); + + const question = createQuestion(); + + let answer: string = ""; + + let first = true; + while (!remotes.includes(answer)) { + answer = ( + await question( + (first ? "\n" : "") + + "multiple remotes detected, please choose one for new branch:" + + remotes.map((r, i) => `\n ${i + 1} ${r}`).join("") + + "\n> " + ) + ) + .trim() + .toLowerCase(); + + if (indices.includes(answer)) { + answer = remotes[Number(answer) - 1]; + } + + first = false; + } + + remote = answer; + } + + const cmd = `push -u ${remote} ${branch.name()} --force`; + console.log(`running ${cmd}`); + execSyncInRepo(`${argsBase.gitCmd} ${cmd}`); + } else { + execSyncInRepo(`${argsBase.gitCmd} push --force`); + } }, delayMsBetweenCheckouts: 0, getBoundariesInclInitial: () =>