Skip to content

Commit

Permalink
feat: reset (#146)
Browse files Browse the repository at this point in the history
<!-- GITHUB_RELEASE PR BODY: canary-version -->
<details>
  <summary>📦 Published PR as canary version: <code>Canary Versions</code></summary>
  <br />

  ✨ Test out this PR locally via:
  
  ```bash
  npm install @dotinc/[email protected]
  npm install @dotinc/[email protected]
  # or 
  yarn add @dotinc/[email protected]
  yarn add @dotinc/[email protected]
  ```
</details>
<!-- GITHUB_RELEASE PR BODY: canary-version -->
  • Loading branch information
nadilas authored Feb 20, 2024
2 parents 358fd0a + 76f71f0 commit 4194cda
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 14 deletions.
12 changes: 8 additions & 4 deletions packages/ogre/src/repository.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ test("reconstruction", async (t) => {
t.is(
repo.ref("refs/heads/main"),
firstStep,
"main is pointing at wrong commit"
"main is pointing at wrong commit",
);
t.is(history.commits.length, 2, "incorrect # of commits");

Expand All @@ -37,7 +37,7 @@ test("reconstruction", async (t) => {
t.is(
sumChanges(history2.commits),
changeEntries,
"incorrect # of changelog entries"
"incorrect # of changelog entries",
);
});

Expand Down Expand Up @@ -72,7 +72,7 @@ test("reconstruct with 2 commits", async (t) => {
t.is(
sumChanges(history2.commits),
changeEntries,
"incorrect # of changelog entries"
"incorrect # of changelog entries",
);
});

Expand Down Expand Up @@ -107,6 +107,10 @@ test("diff is ok", async (t) => {
t.is(
diff.length,
changeEntries,
`invalid # of change entries: ${JSON.stringify(diff)}`
`invalid # of change entries: ${JSON.stringify(diff)}`,
);
});

// test("reset hard", async (t) => {
// // TODO: test reset feature
// });
65 changes: 55 additions & 10 deletions packages/ogre/src/repository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,13 @@ export interface RepositoryObject<T extends { [k: string]: any }> {
branch(): string;

tag(tag: string): string;

/**
* Moves the HEAD and the branch to a specific shaish (commit or tag)
* @param mode hard - discard changes
* @param shaish
*/
reset(mode?: "soft" | "hard", shaish?: string): void;
}

/**
Expand Down Expand Up @@ -89,7 +96,9 @@ export class Repository<T extends { [k: PropertyKey]: any }>
private readonly original: T;

data: T;

private observer: Observer<T>;

private readonly refs: Map<string, Reference>;
private readonly commits: Commit[];

Expand All @@ -104,6 +113,32 @@ export class Repository<T extends { [k: PropertyKey]: any }>
this.observer = observe(this.data);
}

reset(
mode: "soft" | "hard" | undefined = "hard",
shaish: string | undefined = REFS_HEAD_KEY,
): void {
if (mode === "hard") {
unobserve(this.data, this.observer);
}

const [commit] = shaishToCommit(shaish, this.refs, this.commits);
this.moveTo(commit);

const refs = refsAtCommit(this.refs, commit);
// reset only moves heads and not tags
const moveableRefs = refs.filter((r) =>
r.name.startsWith(headsRefPathPrefix),
);

for (const ref of moveableRefs) {
this.moveRef(ref.name, commit);
}

if (mode === "hard") {
this.observer = observe(this.data);
}
}

branch(): string {
const currentHeadRef = this.refs.get(REFS_HEAD_KEY);
if (!currentHeadRef) {
Expand Down Expand Up @@ -145,20 +180,20 @@ export class Repository<T extends { [k: PropertyKey]: any }>
const [commit, isRef, refKey] = shaishToCommit(
shaish,
this.refs,
this.commits
this.commits,
);
this.moveTo(commit);
this.moveRef(
REFS_HEAD_KEY,
isRef && refKey !== undefined ? refKey : commit
isRef && refKey !== undefined ? refKey : commit,
);
}
}

async commit(
message: string,
author: string,
amend?: boolean
amend?: boolean,
): Promise<string> {
let parent = this.commitAtHead();
if (amend && !parent) {
Expand Down Expand Up @@ -196,7 +231,7 @@ export class Repository<T extends { [k: PropertyKey]: any }>
});

const treeHash = Buffer.from(
compressSync(strToU8(JSON.stringify(this.data)), { level: 6, mem: 8 })
compressSync(strToU8(JSON.stringify(this.data)), { level: 6, mem: 8 }),
).toString("base64");
const commit = {
hash: sha,
Expand Down Expand Up @@ -307,7 +342,7 @@ export class Repository<T extends { [k: PropertyKey]: any }>
throw new Error(
`fatal: source type (${
source instanceof Repository ? "Repository" : "History"
}) not implemented`
}) not implemented`,
);
}

Expand Down Expand Up @@ -374,7 +409,7 @@ export class Repository<T extends { [k: PropertyKey]: any }>
throw new Error(`unreachable: HEAD not present`);
}
throw new Error(
`fatal: not a valid object name: '${getLastItem(headRef)}'`
`fatal: not a valid object name: '${getLastItem(headRef)}'`,
);
}
this.refs.set(refKey, { name: name, value: headCommit.hash });
Expand Down Expand Up @@ -430,7 +465,7 @@ const traverseAndCollectChangelog = (commit: Commit, commitsList: Commit[]) => {
const mapPath = (
from: Commit,
to: Commit,
commits: Commit[]
commits: Commit[],
): [isAncestor: boolean] => {
let c: Commit | undefined = to;
while (c !== undefined) {
Expand All @@ -451,7 +486,7 @@ const mapPath = (
const commitAtRefIn = (
ref: string,
references: Map<string, Reference>,
commitsList: Commit[]
commitsList: Commit[],
) => {
const reference = references.get(ref);
if (!reference) {
Expand All @@ -477,6 +512,16 @@ const commitAtRefIn = (
return undefined;
};

const refsAtCommit = (references: Map<string, Reference>, commit: Commit) => {
const list: Array<Reference> = [];
for (const [name, ref] of references.entries()) {
if (ref.value === commit.hash) {
list.push(ref);
}
}
return list;
};

/**
* Accepts a shaish expression (e.g. refs (branches, tags), commitSha) and returns
* - a commit of type Commit
Expand All @@ -486,7 +531,7 @@ const commitAtRefIn = (
const shaishToCommit = (
shaish: string,
references: Map<string, Reference>,
commitsList: Commit[]
commitsList: Commit[],
): [commit: Commit, isRef: boolean, ref: string | undefined] => {
let sha = shaish;
let isRef = false;
Expand Down Expand Up @@ -557,7 +602,7 @@ export const validateRef = (name: string, oneLevel: boolean = true) => {
* @param repository
*/
export const printChangeLog = <T extends { [k: string]: any }>(
repository: RepositoryObject<T>
repository: RepositoryObject<T>,
) => {
console.log("----------------------------------------------------------");
console.log(`Changelog at ${repository.head()}`);
Expand Down

0 comments on commit 4194cda

Please sign in to comment.