Skip to content

Commit 3adc27d

Browse files
committed
docs: add info on how it works + (perhaps too thorough?) info on the potential issues
Signed-off-by: Kipras Melnikovas <[email protected]>
1 parent a0139bb commit 3adc27d

File tree

1 file changed

+99
-0
lines changed

1 file changed

+99
-0
lines changed

README.md

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,3 +46,102 @@ cd repo/
4646
# then:
4747

4848
git-stacked-rebase --help
49+
```
50+
<!--
51+
## What problems do we solve
52+
53+
whatever `git-stacked-rebase` is doing, you could do manually,
54+
55+
i.e. checking out separate branches, keeping them up to date -
56+
constantly rebasing the first branch onto master, and subsequent branches
57+
on the previous one, all while having to drop now-empty/duplicate commits.
58+
59+
but, it doesn't have to be like this.
60+
61+
<++>
62+
-->
63+
64+
## how it works, the tricky parts, & things to be aware of
65+
66+
instead of rebasing one partial branch on top of another,
67+
we always use the latest branch and rebase it onto the initial branch,
68+
and then reset the partial branches to point to new commits.
69+
70+
the last part is the hardest, and likely still has many bugs yet unsolved.
71+
72+
the tricky part comes from the power of git-rebase.
73+
as long as a rebase finishes without exiting, we are golden.
74+
but, as soon as a user indicates that they want to do some further
75+
operations, by e.g. changing a command from `pick` to `edit` or `break`,
76+
then git-rebase, when it reaches that point, has to exit (!) to let the user
77+
do whatever actions they want to do, and of course allows the user to continue
78+
the rebase via `git rebase --continue`.
79+
80+
<!--
81+
this ability to pause the execution of the rebase,
82+
and then continue later on, is very powerful & useful,
83+
and the fact that it makes our job harder is not a bad thing;
84+
rather, it's a natural occurence <++>
85+
-->
86+
87+
why this matters is because we need to recover the branches
88+
to point to the new commits.
89+
90+
git, upon finishing (?) the rebase, writes out a file
91+
inside `.git/rebase-{merge|apply}/` -- `rewritten-list`.
92+
this file contains the rewritten list of commits -
93+
either `1 -> 1` mapping, or, if multiple commits got merged into 1
94+
(e.g. `squash` / `fixup` / manually with `edit`, or similar),
95+
`N -> 1` mapping (?).
96+
it's very simple - old commit SHA, space, new commit SHA, newline.
97+
98+
again, this is how we understand the new positions that the branches
99+
need to be poiting to.
100+
101+
and no, we cannot simply use the `git-rebase-todo` file (the one you edit
102+
when launching `git rebase -i` / `git-stacked-rebase`),
103+
because of commands like `break`, `edit`, etc., whom, again, allow you
104+
to modify the history, and we cannot infer of what will happen
105+
by simply using the `git-rebase-todo` file.
106+
107+
<!-- now, issue(s) come up when -->
108+
let's first do a scenario without the issue(s) that we'll describe soon -
109+
you ran `git-stacked-rebase`, you did some `fixup`s, `squash`es, `reword`s,
110+
etc. - stuff that _does not_ make git-rebase exit.
111+
112+
all went well, git-rebase wrote out the `rewritten-list` file,
113+
we snagged it up with a `post-rewrite` script that we placed
114+
inside `.git/hooks/`, we combined it with the now outdated
115+
`git-rebase-todo` file (old SHAs etc.) to figure out where the
116+
branch boundaries (partial branches) should end up at in the
117+
new history, and we reset them successfully. all good and well.
118+
119+
now, the scenario w/ a potential issue (?) -- you did
120+
all the same as above, but you also had an `edit` command,
121+
and when git-rebase progressed to it, you `git reset HEAD~`
122+
your commit and instead create 3 new commits, and then continued
123+
& the rebase via `git rebase --continue`.
124+
125+
since `git-rebase` exited before it was done,
126+
we, `git-stacked-rebase`, were __not__ able to reset the branches
127+
to the new history, because of course, if git-rebase exits,
128+
but the rebase is still in progress, we know you are _not_ done,
129+
thus we exit as well.
130+
131+
so when you finish, your changes are applied to your latest branch,
132+
__but__ the partial branches are now out of date.
133+
134+
what you need to do in this case is run `git-stacked-rebase <branch> --apply`,
135+
which, in the 1st scenario, happened automatically.
136+
137+
__the real issue arises when you forget to do the `--apply` part in time__,
138+
i.e. if you do any other history rewritting, including `git commit --amend`,
139+
before you `--apply`ied, `git-stacked-rebase` can no longer (?) properly figure out
140+
where the partial branches should point to, and you're stuck in having to do it
141+
manually.
142+
143+
in the future, we might consider storing the list of partial branches
144+
and if they end up gone, we could e.g. place them at the end of the
145+
`git-rebase-todo` file the next time you invoke `git-stacked-rebase`,
146+
thus you'd be able to drag them into their proper places yourself.
147+
but until then, beware this issue exists (?).

0 commit comments

Comments
 (0)