Skip to content

Commit 7e33750

Browse files
committed
merge amends into the 1st rebase that comes after them
Signed-off-by: Kipras Melnikovas <[email protected]>
1 parent 2f6d505 commit 7e33750

File tree

1 file changed

+77
-58
lines changed

1 file changed

+77
-58
lines changed

reduce-path.js

Lines changed: 77 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
const assert = require("assert")
66
const fs = require("fs")
7+
const { execSync } = require("child_process")
78

89
const obj1 = {
910
"a": "b",
@@ -103,75 +104,93 @@ const prefix = "" // "test/.tmp-described.off/"
103104
const rewrittenListFile = fs.readFileSync(prefix + ".git/stacked-rebase/rewritten-list", { encoding: "utf-8" })
104105
console.log({ rewrittenListFile })
105106

106-
// const rewrittenLists = rewrittenListFile
107-
// .split("\n---\n")
108-
// .map(lines => lines.split("\n"))
109-
// .map(lines => lines.slice(1)) // remove $1
110-
// .filter(lines => lines.length && lines.every(line => line.length)) // remove empty "amend"
111-
// console.log({ lists: rewrittenLists });
107+
/**
108+
* $1 (amend/rebase)
109+
*/
110+
const extraOperatorLineCount = 1
112111

113112
const rewrittenLists = rewrittenListFile
114113
.split("\n\n")
115114
.map(lists => lists.split("\n"))
116115
.map(list => list[list.length - 1] === "" ? list.slice(0, -1) : list)
117116
// .slice(0, -1)
118-
.filter(list => list.length)
119-
.map(list => list.map(line => line.split(" ")))
120-
.map(list => Object.fromEntries(list))
121-
console.log({ rewrittenLists });
122-
123-
const reducedRewrittenLists = rewrittenLists
124-
// .map(list => (reducePath(list), list))
125-
.map(list => reducePath(list))
126-
127-
console.log({ reducedRewrittenLists });
117+
.filter(list => list.length > extraOperatorLineCount)
118+
.map(list => ({
119+
type: list[0],
120+
mapping: Object.fromEntries(
121+
list.slice(1).map(line => line.split(" "))
122+
)
123+
})
124+
)
125+
// .map(list => Object.fromEntries(list))
126+
console.log("rewrittenLists", rewrittenLists)
127+
128+
let prev = []
129+
let mergedReducedRewrittenLists = []
130+
for (const list of rewrittenLists) {
131+
if (list.type === "amend") {
132+
prev.push(list)
133+
} else if (list.type === "rebase") {
134+
/**
135+
* merging time
136+
*/
137+
for (const amend of prev) {
138+
assert.equal(Object.keys(amend.mapping).length, 1)
139+
140+
const [key, value] = Object.entries(amend.mapping)[0]
141+
142+
/**
143+
* (try to) merge
144+
*/
145+
if (key in list.mapping) {
146+
if (value === list.mapping[key]) {
147+
// pointless
148+
continue
149+
} else {
150+
throw new Error(
151+
`NOT IMPLEMENTED - identical key in 'amend' and 'rebase', but different values.`
152+
+ `(key = "${key}", amend's value = "${value}", rebase's value = "${list.mapping[key]}")`
153+
)
154+
}
155+
} else {
156+
if (Object.values(list.mapping).includes(key)) {
157+
/**
158+
* add the single new entry of amend's mapping into rebase's mapping.
159+
* it will get `reducePath`'d later.
160+
*/
161+
Object.assign(list.mapping, amend.mapping)
162+
} else {
163+
throw new Error(
164+
"NOT IMPLEMENTED - neither key nor value of 'amend' was included in the 'rebase'."
165+
+ "could be that we missed the ordering, or when we call 'reducePath', or something else."
166+
)
167+
}
168+
}
169+
}
128170

129-
const last = reducedRewrittenLists[reducedRewrittenLists.length - 1]
130-
const lastVals = Object.values(last).reverse()
131-
console.log({ lastVals });
171+
prev = []
172+
reducePath(list.mapping)
173+
mergedReducedRewrittenLists.push(list)
174+
} else {
175+
throw new Error(`invalid list type (got "${list.type}")`)
176+
}
177+
}
132178
/**
133-
* compare with
134-
* git log --pretty=format:"%H"
179+
* TODO handle multiple rebases
180+
* or, multiple separate files for each new rebase,
181+
* since could potentially lose some info if skipping partial steps?
135182
*/
136183

137-
/**
138-
* ayo lol, prolly found a bug in git -- the output in
139-
* rewritten-list, or /dev/stdin, after the rebase is done,
140-
* is not fully complete -- it doesn't correctly print the SHAs
141-
* that got changed while the rebase was paused,
142-
* e.g. commit --amend while paused by "edit" or "break" commands.
143-
*
144-
* thus, at least until we report it and confirm it's actually a bug
145-
* and not intended this way,
146-
* we can get the desired output for ourselves
147-
* by merging all the rewrittenLists!
148-
*
149-
*/
184+
console.log("mergedReducedRewrittenLists", mergedReducedRewrittenLists)
150185

151-
/**
152-
* TODO verify keys/values are not identical in a bad way
153-
*/
154-
const merge = (A, B) => ({
155-
...A,
156-
...B
157-
})
186+
const b4 = Object.keys(mergedReducedRewrittenLists[0].mapping)
187+
const after = Object.values(mergedReducedRewrittenLists[0].mapping)
158188

159-
const mergedReducedRewrittenLists = reducedRewrittenLists.reduce((acc, curr) => reducePath(merge(acc, curr)), {})
189+
fs.writeFileSync("b4", b4.join("\n") + "\n")
190+
fs.writeFileSync("after", after.join("\n") + "\n")
160191

161-
console.log({ mergedReducedRewrittenLists });
162-
const vals = Object.values(mergedReducedRewrittenLists).reverse()
163-
console.log({ vals });
192+
const N = after.length
193+
console.log({ N })
164194

165-
/**
166-
* it fixes the above issues!
167-
*
168-
* but wait! we cannot just merge like this,
169-
* because when we take the values,
170-
* the commits whom were not the full list (and only 1 commit remap, because --amend,
171-
* or not full rebase up till the initial branch (TODO need to confirm the 2nd case)),
172-
* end up being in the wrong place (they end up either in the start or the end).
173-
*
174-
* the problem is that we don't know __when__ the rewrite of the commit happened.
175-
* TODO need to track that as well?
176-
*
177-
*/
195+
execSync(`git log --pretty=format:"%H" | head -n ${N} | tac - > curr`)
196+
execSync(`diff -us curr after`, { stdio: "inherit" })

0 commit comments

Comments
 (0)