Skip to content

Commit b222d94

Browse files
committed
fix: fix multiple issues by adding break as first cmd to git-rebase-todo and --continueing after launching rebase
Signed-off-by: Kipras Melnikovas <kipras@kipras.org>
1 parent 717a3c9 commit b222d94

File tree

1 file changed

+119
-0
lines changed

1 file changed

+119
-0
lines changed

git-stacked-rebase.ts

Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,115 @@ function areOptionsIncompetible(
9191
return reasons.length > 0;
9292
}
9393

94+
/**
95+
* some notes:
96+
*
97+
* 1. re: "the different ways to launch git rebase":
98+
*
99+
* 1.1 initially, we started probably the hardest way:
100+
* we tried to replicate the behavior of git rebase, by:
101+
*
102+
* 1) finding which commits we need (manually by ourselves),
103+
* 2) letting the user edit our own git-rebase-todo file
104+
* (already containing branch boundaries generated by us),
105+
* 3) creating & writing to files inside `.git/rebase-{merge|apply}/`,
106+
* just like git rebase would, to represent the current state [1].
107+
* 4) and then exec'ing a `git rebase --continue`,
108+
* so that the user gets launched into the rebase.
109+
*
110+
*
111+
* 1.2 later, we started using 2 rebases - 1st for finding the commits, 2nd for the actual rebase.
112+
*
113+
* important switch that i didn't think had significance until 1.3 --
114+
* using `editorScript`s (providing an env var - a string of a path to a bash script
115+
* that will move the user-edited & our-processed git-rebase-todo file
116+
* into the proper place (.git/rebase-{merge|apply}/git-rebase-todo)
117+
* right when the rebase starts, thus no longer having to `--continue` (!),
118+
* which is what broke things that were discovered
119+
* and fixed in 1.3 by (fabricately) introducing `--continue` back)
120+
*
121+
*
122+
* 1.3 but soon after, things started breaking.
123+
*
124+
* i didn't understand why.
125+
*
126+
* but after playing w/ it for a while, realized that it's stuff like `reword`
127+
* that breaks, as long as we launch the rebase with an `editorScript`.
128+
* e.g. git would ask to identify yourself - config wouldn't be detected,
129+
* and our `--apply` was completely broken as well [2].
130+
*
131+
* thus we started manually adding a first command `break`
132+
* into the proper `git-rebase-todo` file [3]
133+
* so that we can launch `--continue` again,
134+
* after the `editorScript` had finished,
135+
* and that somehow fixed everything & we're back to normal.
136+
*
137+
*
138+
*
139+
* i am still not sure what the best approach is,
140+
* though i think i know which one's aren't.
141+
*
142+
* 1.1 seems bad because imitating the full behavior is hard,
143+
*
144+
* e.g. respecting commit.gpgSign required creating a file `gpg_sign_opt`
145+
* with content `-S` - there's probably a ton of stuff like this i didn't even realize
146+
* that git has, and it's possible more will be added in the future.
147+
* you can obviously see the problems that stem from this.
148+
*
149+
* 1.2 seems bad because it, apart from being broken until 1.3,
150+
* also used 2 rebases instead of 1, and that is kinda hacky.
151+
* stuff like git hooks exists, e.g. post-write,
152+
* that even we ourselves utilize,
153+
* and launching 2 rebases means producing side-effects
154+
* like this, and we're potentially breaking end users' workflows.
155+
*
156+
* thus, 1.3 seems like a clear winner, at least for now.
157+
* especially up until we investigate the break + continue thingie -
158+
* ideally we wouldn't need it.
159+
*
160+
*
161+
*
162+
* ---
163+
*
164+
* [1]
165+
* on representing the _state_ -- git rebase,
166+
* specifically the --interactive one (which is what we have here as well),
167+
* is _not_ a continuous command that goes through and is 100% done when it exits.
168+
*
169+
* there are some cases where it intentionally exits, to allow the user
170+
* to do further interactions, and later --continue the rebase
171+
* (e.g. `edit`, `break` etc.).
172+
*
173+
* thus, some state needs to be saved, so that the user, once they're done,
174+
* can tell git to --continue.
175+
*
176+
* turns out, git does this very simply - by saving files inside `.git/`,
177+
* and `.git/rebase-{merge|apply}/` folders.
178+
* this simple design is a big part in allowing tools like us,
179+
* git-stacked-rebase, to work, or rather - to expand upon the existing stuff,
180+
* w/o having to re-implement everything ourselves.
181+
*
182+
* [2]
183+
* on the --apply being broken - it's the logic of `parseNewGoodCommands` that seems broken.
184+
*
185+
* right before realizing 1.3 and writing this comment,
186+
* i wrote a lengthy comment there as well, with thoughts of what's likely broken.
187+
*
188+
* but now, after discovering 1.3, i do not understand yet how the
189+
* `--continue` exec fixes things, and am not sure if i want to mess
190+
* with the `parseNewGoodCommands` logic before i do.
191+
*
192+
* [3]
193+
* the user would never see the `break` command, since just like in 1.1 2),
194+
* we give the user to edit our own git-rebase-todo file, which contains branch boundaries,
195+
* and then extracting the normal git rebase commands and creating
196+
* the git-rebase-todo file for git rebase to run on.
197+
*
198+
* ---
199+
*
200+
*
201+
*
202+
*/
94203
export const gitStackedRebase = async (
95204
nameOfInitialBranch: string,
96205
specifiedOptions: SomeOptionsForGitStackedRebase = {}
@@ -305,6 +414,11 @@ export const gitStackedRebase = async (
305414
// let lastCommitFromEditedTodo;
306415
const regularRebaseTodoLines: string[] = [];
307416

417+
/**
418+
* part 1 of "the different ways to launch git rebase"
419+
*/
420+
regularRebaseTodoLines.push("break");
421+
308422
const goodCommands: GoodCommand[] = parseTodoOfStackedRebase(pathToStackedRebaseTodoFile);
309423

310424
const proms: Promise<void>[] = goodCommands.map(async (cmd) => {
@@ -600,6 +714,11 @@ mv -f "${preparedRegularRebaseTodoFile}" "${pathToRegularRebaseTodoFile}"
600714
);
601715
log("big buns - 2nd rebase returned (the proper one)");
602716

717+
/**
718+
* part 2 of "the different ways to launch git rebase"
719+
*/
720+
execSyncInRepo(`${options.gitCmd} rebase --continue`);
721+
603722
/** END COPY-PASTA */
604723

605724
/**

0 commit comments

Comments
 (0)