From 0291ab1c481dc63c114fa07d70df5615d10aa63c Mon Sep 17 00:00:00 2001 From: Kipras Melnikovas Date: Sun, 23 Jan 2022 04:10:31 +0200 Subject: [PATCH] fix: fix multiple issues by adding `break` as first cmd to git-rebase-todo and `--continue`ing after launching rebase Signed-off-by: Kipras Melnikovas --- git-stacked-rebase.ts | 119 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 119 insertions(+) diff --git a/git-stacked-rebase.ts b/git-stacked-rebase.ts index a84ade07..51b3526f 100755 --- a/git-stacked-rebase.ts +++ b/git-stacked-rebase.ts @@ -87,6 +87,115 @@ function areOptionsIncompetible( return reasons.length > 0; } +/** + * some notes: + * + * 1. re: "the different ways to launch git rebase": + * + * 1.1 initially, we started probably the hardest way: + * we tried to replicate the behavior of git rebase, by: + * + * 1) finding which commits we need (manually by ourselves), + * 2) letting the user edit our own git-rebase-todo file + * (already containing branch boundaries generated by us), + * 3) creating & writing to files inside `.git/rebase-{merge|apply}/`, + * just like git rebase would, to represent the current state [1]. + * 4) and then exec'ing a `git rebase --continue`, + * so that the user gets launched into the rebase. + * + * + * 1.2 later, we started using 2 rebases - 1st for finding the commits, 2nd for the actual rebase. + * + * important switch that i didn't think had significance until 1.3 -- + * using `editorScript`s (providing an env var - a string of a path to a bash script + * that will move the user-edited & our-processed git-rebase-todo file + * into the proper place (.git/rebase-{merge|apply}/git-rebase-todo) + * right when the rebase starts, thus no longer having to `--continue` (!), + * which is what broke things that were discovered + * and fixed in 1.3 by (fabricately) introducing `--continue` back) + * + * + * 1.3 but soon after, things started breaking. + * + * i didn't understand why. + * + * but after playing w/ it for a while, realized that it's stuff like `reword` + * that breaks, as long as we launch the rebase with an `editorScript`. + * e.g. git would ask to identify yourself - config wouldn't be detected, + * and our `--apply` was completely broken as well [2]. + * + * thus we started manually adding a first command `break` + * into the proper `git-rebase-todo` file [3] + * so that we can launch `--continue` again, + * after the `editorScript` had finished, + * and that somehow fixed everything & we're back to normal. + * + * + * + * i am still not sure what the best approach is, + * though i think i know which one's aren't. + * + * 1.1 seems bad because imitating the full behavior is hard, + * + * e.g. respecting commit.gpgSign required creating a file `gpg_sign_opt` + * with content `-S` - there's probably a ton of stuff like this i didn't even realize + * that git has, and it's possible more will be added in the future. + * you can obviously see the problems that stem from this. + * + * 1.2 seems bad because it, apart from being broken until 1.3, + * also used 2 rebases instead of 1, and that is kinda hacky. + * stuff like git hooks exists, e.g. post-write, + * that even we ourselves utilize, + * and launching 2 rebases means producing side-effects + * like this, and we're potentially breaking end users' workflows. + * + * thus, 1.3 seems like a clear winner, at least for now. + * especially up until we investigate the break + continue thingie - + * ideally we wouldn't need it. + * + * + * + * --- + * + * [1] + * on representing the _state_ -- git rebase, + * specifically the --interactive one (which is what we have here as well), + * is _not_ a continuous command that goes through and is 100% done when it exits. + * + * there are some cases where it intentionally exits, to allow the user + * to do further interactions, and later --continue the rebase + * (e.g. `edit`, `break` etc.). + * + * thus, some state needs to be saved, so that the user, once they're done, + * can tell git to --continue. + * + * turns out, git does this very simply - by saving files inside `.git/`, + * and `.git/rebase-{merge|apply}/` folders. + * this simple design is a big part in allowing tools like us, + * git-stacked-rebase, to work, or rather - to expand upon the existing stuff, + * w/o having to re-implement everything ourselves. + * + * [2] + * on the --apply being broken - it's the logic of `parseNewGoodCommands` that seems broken. + * + * right before realizing 1.3 and writing this comment, + * i wrote a lengthy comment there as well, with thoughts of what's likely broken. + * + * but now, after discovering 1.3, i do not understand yet how the + * `--continue` exec fixes things, and am not sure if i want to mess + * with the `parseNewGoodCommands` logic before i do. + * + * [3] + * the user would never see the `break` command, since just like in 1.1 2), + * we give the user to edit our own git-rebase-todo file, which contains branch boundaries, + * and then extracting the normal git rebase commands and creating + * the git-rebase-todo file for git rebase to run on. + * + * --- + * + * + * + */ export const gitStackedRebase = async ( nameOfInitialBranch: string, specifiedOptions: SomeOptionsForGitStackedRebase = {} @@ -293,6 +402,11 @@ export const gitStackedRebase = async ( // let lastCommitFromEditedTodo; const regularRebaseTodoLines: string[] = []; + /** + * part 1 of "the different ways to launch git rebase" + */ + regularRebaseTodoLines.push("break"); + const goodCommands: GoodCommand[] = parseTodoOfStackedRebase(pathToStackedRebaseTodoFile); const proms: Promise[] = goodCommands.map(async (cmd) => { @@ -587,6 +701,11 @@ mv -f "${preparedRegularRebaseTodoFile}" "${pathToRegularRebaseTodoFile}" ); console.log("big buns - the proper rebase returned"); + /** + * part 2 of "the different ways to launch git rebase" + */ + execSyncInRepo(`${options.gitCmd} rebase --continue`); + /** END COPY-PASTA */ /**