Skip to content

Commit b9de273

Browse files
committed
fix: properly handle fetched but not merged (pulled) initialBranch, use branchEnd finding
Signed-off-by: Kipras Melnikovas <kipras@kipras.org>
1 parent caa906d commit b9de273

File tree

2 files changed

+41
-147
lines changed

2 files changed

+41
-147
lines changed

git-stacked-rebase.ts

Lines changed: 40 additions & 147 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import { branchSequencer } from "./branchSequencer";
1717

1818
import { createExecSyncInRepo } from "./util/execSyncInRepo";
1919
import { noop } from "./util/noop";
20+
import { uniq } from "./util/uniq";
2021
import { parseTodoOfStackedRebase } from "./parse-todo-of-stacked-rebase/parseTodoOfStackedRebase";
2122
import { processWriteAndOrExit, fail, EitherExitFinal } from "./util/Exitable";
2223
import { namesOfRebaseCommandsThatMakeRebaseExitToPause } from "./parse-todo-of-stacked-rebase/validator";
@@ -823,30 +824,8 @@ async function getWantedCommitsWithBranchBoundaries(
823824
bb: Git.Reference,
824825
currentBranch: Git.Reference
825826
): Promise<CommitAndBranchBoundary[]> {
826-
const fixBranchName = (name: string): string =>
827-
name
828-
// .replace(beginningBranchName.includes(name) ? "" : "refs/heads/", "") //
829-
.replace("refs/heads/", ""); //
830-
// TODO: consider
831-
// .replace(name.includes(beginningBranchName) ? "refs/remotes/" : "", "");
832-
833-
const refs = await Git.Reference.list(repo);
834-
const branches: Git.Reference[] = ((
835-
await Promise.all(
836-
refs.map(
837-
(ref: string): Promise<Git.Reference | undefined> =>
838-
Git.Branch.lookup(
839-
repo, //
840-
fixBranchName(ref),
841-
Git.Branch.BRANCH.ALL /** filtering seems broken, all act the same as ALL */
842-
).catch(() => undefined)
843-
)
844-
)
845-
).filter((branch) => !!branch) as Git.Reference[]).map(
846-
(branch) => (!branch.cmp(bb) ? bb : branch) //
847-
);
848-
849-
console.log({ refs, branches: branches.map((b) => fixBranchName(b?.name())) });
827+
const refNames: string[] = await Git.Reference.list(repo);
828+
const refs: Git.Reference[] = await Promise.all(refNames.map((ref) => Git.Reference.lookup(repo, ref)));
850829

851830
/**
852831
* BEGIN check e.g. fork & origin/fork
@@ -916,133 +895,47 @@ async function getWantedCommitsWithBranchBoundaries(
916895
)
917896
);
918897

919-
console.log({
920-
wantedCommits: wantedCommits.map((c) =>
921-
[
922-
c.sha(), //
923-
c.summary(),
924-
c.parentcount(),
925-
].join(" ")
926-
),
927-
});
928-
929-
const commitsByBranch = Object.fromEntries<Git.Commit | null>(branches.map((b) => [b.name(), null]));
930-
931-
await Promise.all(
932-
branches
933-
.map(async (branch) => {
934-
const commitOfBranch = await branch.peel(Git.Object.TYPE.COMMIT);
935-
// console.log({ branch: branch.name(), commitOfBranch: commitOfBranch.id().tostrS() });
936-
937-
wantedCommits.map((commit) => {
938-
const matches = !commitOfBranch.id().cmp(commit.id());
939-
940-
(commit as any).meta = (commit as any).meta || { branchEnd: null };
941-
942-
if (matches) {
943-
// // console.log({
944-
// // matches, //
945-
// // commitOfBranch: commitOfBranch.id().tostrS(),
946-
// // commit: commit.id().tostrS(),
947-
// // });
948-
// commitsByBranch[branch.name()].push(commit);
949-
950-
// if (commitsByBranch[branch.name()]) {
951-
if ((commit as any).meta.branchEnd) {
952-
console.error({
953-
commit: commit?.summary(),
954-
branchOld: (commit as any).meta.branchEnd.name(),
955-
branchNew: branch.name(),
956-
});
957-
/**
958-
* TODO FIXME BFS (starting from beginningBranch? since child only has 1 parent?)
959-
*
960-
* UPD: lol this will go off if e.g. we have 2 branches on the same commit,
961-
* even tho one of them has nothing to do w/ this.
962-
*
963-
* but, ofc, we don't know which one should be ignored (yet?)
964-
*/
965-
throw new Error(
966-
"2 (or more) branches for the same commit, both in the same path - cannot continue (until explicit branch specifying is implemented)."
967-
);
968-
}
969-
970-
commitsByBranch[branch.name()] = commit;
971-
(commit as any).meta.branchEnd = branch;
972-
973-
// // return {
974-
// // commit,
975-
// // branch,
976-
// // };
977-
}
978-
// else
979-
// return {
980-
// commit,
981-
// branch: null,
982-
// };
983-
});
984-
})
985-
.flat()
986-
);
987-
988-
const wantedCommitByBranch = Object.fromEntries(
989-
// Object.entries(commitsByBranch).filter(([_branchName, commits]) => commits.length)
990-
Object.entries(commitsByBranch).filter(([_, commit]) => !!commit)
991-
);
992-
// const wantedCommitsByBranch = commitsByBranch;
993-
994-
// Object.entries(wantedCommitsByBranch).forEach(([_, commits]) => {
995-
// assert(commits.length === 1);
996-
// });
997-
998-
const wantedCommitByBranchStr = Object.fromEntries(
999-
Object.entries(wantedCommitByBranch).map(([branchName, commit]) => [
1000-
branchName, //
1001-
// commits.map((c) => c.summary()),
1002-
commit?.sha(),
1003-
// commits.map((c) => c.sha()),
1004-
// ].join(" \n")
1005-
])
898+
let matchedRefs: Git.Reference[];
899+
900+
const wantedCommitsWithBranchEnds: CommitAndBranchBoundary[] = await Promise.all(
901+
wantedCommits.map(
902+
(c: Git.Commit) => (
903+
(matchedRefs = refs.filter((ref) => !!ref.target()?.equal(c.id()))),
904+
assert(
905+
matchedRefs.length <= 1 ||
906+
(matchedRefs.length === 2 &&
907+
uniq(
908+
matchedRefs.map((r) =>
909+
r
910+
?.name()
911+
.replace(/^refs\/heads\//, "")
912+
.replace(/^refs\/remotes\/[^/]*\//, "")
913+
)
914+
).length === 1),
915+
"" +
916+
"2 (or more) branches for the same commit, both in the same path - cannot continue" +
917+
"(until explicit branch specifying is implemented)" +
918+
"\n\n" +
919+
"matchedRefs = " +
920+
matchedRefs.map((mr) => mr?.name()) +
921+
"\n"
922+
),
923+
matchedRefs.length === 2 &&
924+
(matchedRefs = matchedRefs.some((r) => r?.name() === bb.name())
925+
? [bb]
926+
: matchedRefs.filter((r) => !r?.isRemote() /* r?.name().includes("refs/heads/") */)),
927+
assert(matchedRefs.length <= 1, "refs/heads/ and refs/remotes/*/ replacement went wrong"),
928+
{
929+
commit: c,
930+
branchEnd: !matchedRefs.length ? null : matchedRefs[0],
931+
}
932+
)
933+
)
1006934
);
1007935

1008-
console.log({
1009-
wantedCommitByBranch: wantedCommitByBranchStr,
1010-
// wantedCommitsByBranch.map(([branchName, commits]) => [
1011-
// branchName,
1012-
// commits.map((c) => c),
1013-
// ]),
1014-
wantedBranchByCommit: swapKeyVal(wantedCommitByBranch),
1015-
});
1016-
1017-
console.log({
1018-
wantedCommits: wantedCommits.map(
1019-
(c) =>
1020-
c.sha() + //
1021-
" " +
1022-
((c as any).meta?.branchEnd as Git.Reference)?.name()
1023-
),
1024-
});
1025-
1026-
const commitsAndBranchBoundaries: CommitAndBranchBoundary[] = wantedCommits.map((c) => ({
1027-
commit: c,
1028-
branchEnd: (c as any).meta?.branchEnd as Git.Reference | null,
1029-
}));
1030-
1031-
return commitsAndBranchBoundaries;
1032-
}
1033-
1034-
function swapKeyVal(obj: {}) {
1035-
return Object.entries(obj) //
1036-
.reduce(
1037-
(
1038-
acc, //
1039-
[k, v]
1040-
) => Object.assign(acc, { [(v as unknown) as string]: k }),
1041-
{}
1042-
);
936+
return wantedCommitsWithBranchEnds;
1043937
}
1044938

1045-
noop(getCommitOfBranch);
1046939
async function getCommitOfBranch(repo: Git.Repository, branchReference: Git.Reference) {
1047940
const branchOid: Git.Oid = await (await branchReference.peel(Git.Object.TYPE.COMMIT)).id();
1048941
return await Git.Commit.lookup(repo, branchOid);

util/uniq.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export const uniq = <T>(arr: T[]): T[] => [...new Set(arr)];

0 commit comments

Comments
 (0)