@@ -139,16 +139,114 @@ export function combineRewrittenLists(rewrittenListFileContent: string): Combine
139139 }
140140 } else {
141141 if ( Object . values ( list . mapping ) . includes ( key ) ) {
142+ if ( Object . values ( list . mapping ) . includes ( value ) ) {
143+
144+ console . warn ( `value already in values` , {
145+ [ key ] : value ,
146+ [ Object . entries ( list . mapping ) . find ( ( [ _k , v ] ) => v === value ) ! [ 0 ] ] : value ,
147+ } )
148+ // continue
149+ // throw;
150+
151+ /**
152+ * happened when:
153+ * mark "edit" on commit A and B,
154+ * reach commit A,
155+ * do git commit --amend to change the title,
156+ * continue to commit B,
157+ * stop because of the another "edit",
158+ * reset to HEAD~ (commit A) (changes kept in workdir),
159+ * add all changes,
160+ * git commit --amend them into commit A.
161+ *
162+ * how things ended up in the rewritten-list, was that:
163+ *
164+ * amend
165+ * TMP_SHA -> NEW_SHA
166+ *
167+ * rebase
168+ * COMMIT_A_SHA -> TMP_SHA
169+ * COMMIT_B_SHA -> NEW_SHA
170+ *
171+ *
172+ * and would end up as
173+ *
174+ * COMMIT_A_SHA -> NEW_SHA
175+ * COMMIT_B_SHA -> NEW_SHA
176+ *
177+ * from our `git-rebase-todo` file, the ~~OLD_SHA_2~~ COMMIT_B_SHA was the original one found,
178+ * BUT, it pointed to commit B, not commit A!
179+ *
180+ * there were more mappings in the rewritten-list that included the commit A's SHA...
181+ * this is getting complicated.
182+ *
183+ * ---rm
184+ * the 1st mapping of TMP_SHA -> NEW_SHA ended up first in the rewritten-list inside an "amend".
185+ * the 2nd mapping of OLD_SHA_2 -> NEW_SHA ended up second in the rewritten-list inside the "rebase".
186+ * ---
187+ *
188+ *
189+ * TODO needs more testing.
190+ *
191+ * i mean, we very well could just get rid of the key->value pair
192+ * if there exists another one with the same value,
193+ * but how do we know which key to keep?
194+ *
195+ * wait... you keep the earliest key?
196+ *
197+ */
198+ // fwiw, i don't think this algo makes you keep the earliest key (or does it?)
199+ Object . entries ( list . mapping ) . forEach ( ( [ k , v ] ) => {
200+ if ( v === value && k !== key ) {
201+ // if it's not our key, delete it
202+ // (our key will get assigned a new value below.)
203+ console . info ( "deleting entry because duplicate A->B, C->A, D->B, ends up C->B, D->B, keeping only one" , {
204+ [ k ] : list . mapping [ k ] ,
205+ } )
206+ delete list . mapping [ k ]
207+ }
208+ } )
209+ /**
210+ * TODO test if you "fixup" (reset, add, amend) first --
211+ * does this reverse the order & you'd need the last key?
212+ *
213+ * TODO what if you did both and you need a key from the middle? lol
214+ *
215+ */
216+ }
217+
142218 /**
143219 * add the single new entry of amend's mapping into rebase's mapping.
144220 * it will get `reducePath`'d later.
145221 */
146222 Object . assign ( list . mapping , amend . mapping )
147223 } else {
148- throw new Error (
149- "NOT IMPLEMENTED - neither key nor value of 'amend' was included in the 'rebase'."
150- + "could be that we missed the ordering, or when we call 'reducePath', or something else."
151- )
224+ if ( Object . values ( list . mapping ) . includes ( value ) ) {
225+ /**
226+ * TODO needs more testing.
227+ * especially which one is the actually newer one -- same questions apply as above.
228+ */
229+ console . warn ( "the `rebase`'s mapping got a newer value than the amend, apparently. continuing." , {
230+ [ key ] : value ,
231+ [ Object . entries ( list . mapping ) . find ( ( [ _k , v ] ) => v === value ) ! [ 0 ] ] : value ,
232+ } )
233+ continue
234+ } else {
235+ console . warn (
236+ "NOT IMPLEMENTED - neither key nor value of 'amend' was included in the 'rebase'."
237+ + "\ncould be that we missed the ordering, or when we call 'reducePath', or something else." ,
238+ {
239+ [ key ] : value ,
240+ } )
241+
242+ /**
243+ * i think this happens when commit gets rewritten,
244+ * then amended, and amended again.
245+ *
246+ * looks like it's fine to ignore it.
247+ */
248+ continue
249+ }
152250 }
153251 }
154252 }
0 commit comments