@@ -46,3 +46,102 @@ cd repo/
46
46
# then:
47
47
48
48
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