@dotinc/ogre 0.7.0 → 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.tap/processinfo/{21e0110c-397c-4c38-a84a-89c55de41e7e.json → 12fba5c1-f3d6-4b95-865b-9251ded2f6e3.json} +7 -6
- package/.tap/processinfo/{51b87298-fd44-42a9-b0f8-d4533e58fd1c.json → 38a3e28a-f045-4a32-bfc3-ca756e9457eb.json} +35 -34
- package/.tap/processinfo/{d1b618cb-a921-4f1c-ae4a-6bca359b5909.json → 594c45a4-6863-423e-9759-b092527c8ac4.json} +23 -22
- package/.tap/processinfo/{36da4059-ca5e-4b70-a993-7f99f94f7588.json → 671766c2-87ab-40cf-8051-2b74d41d0bc5.json} +7 -6
- package/.tap/processinfo/{75459f57-2341-476b-8576-587b93699d8b.json → a2952f0b-bb22-4fd6-a729-f9c500431030.json} +7 -6
- package/.tap/processinfo/{4aa37d99-4038-4033-9d38-beea00272892.json → cfca41ce-a29e-4cef-9564-b1f52749806b.json} +7 -6
- package/.tap/processinfo/{9656a0a0-72ab-4ea7-abb7-7415cd3842b4.json → d116ec0f-f197-434d-8a14-1f09a4b274ea.json} +23 -22
- package/.tap/test-results/src/branch.test.ts.tap +6 -6
- package/.tap/test-results/src/checkout.test.ts.tap +9 -9
- package/.tap/test-results/src/commit.test.ts.tap +18 -18
- package/.tap/test-results/src/merge.test.ts.tap +2 -2
- package/.tap/test-results/src/repository.test.ts.tap +23 -23
- package/.tap/test-results/src/tag.test.ts.tap +3 -3
- package/.tap/test-results/src/utils.test.ts.tap +7 -7
- package/CHANGELOG.md +13 -0
- package/lib/git2json.js +3 -4
- package/lib/repository.d.ts +1 -18
- package/lib/repository.js +39 -196
- package/lib/utils.d.ts +55 -0
- package/lib/utils.js +183 -2
- package/package.json +2 -2
- package/src/commit.test.ts +2 -1
- package/src/git2json.ts +6 -2
- package/src/repository.test.ts +2 -1
- package/src/repository.ts +28 -195
- package/src/utils.ts +194 -0
package/src/repository.test.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { test } from "tap";
|
|
2
2
|
|
|
3
|
-
import {
|
|
3
|
+
import { Repository } from "./repository";
|
|
4
4
|
import {
|
|
5
5
|
addOneStep,
|
|
6
6
|
addOneStep as addOneNested,
|
|
@@ -12,6 +12,7 @@ import {
|
|
|
12
12
|
} from "./test.utils";
|
|
13
13
|
import { History, Reference } from "./interfaces";
|
|
14
14
|
import { compare, Operation } from "fast-json-patch";
|
|
15
|
+
import { printChange, printChangeLog } from "./utils";
|
|
15
16
|
|
|
16
17
|
test("diff is ok", async (t) => {
|
|
17
18
|
const [repo, obj] = await getBaseline();
|
package/src/repository.ts
CHANGED
|
@@ -1,27 +1,37 @@
|
|
|
1
1
|
import {
|
|
2
|
-
|
|
3
|
-
unobserve,
|
|
4
|
-
compare,
|
|
2
|
+
applyPatch,
|
|
5
3
|
applyReducer,
|
|
4
|
+
compare,
|
|
6
5
|
deepClone,
|
|
7
6
|
generate,
|
|
7
|
+
JsonPatchError,
|
|
8
|
+
observe,
|
|
8
9
|
Observer,
|
|
9
10
|
Operation,
|
|
11
|
+
unobserve,
|
|
10
12
|
validate,
|
|
11
|
-
applyPatch,
|
|
12
|
-
JsonPatchError,
|
|
13
13
|
} from "fast-json-patch";
|
|
14
14
|
import { calculateCommitHash, Commit } from "./commit";
|
|
15
15
|
import { History, Reference } from "./interfaces";
|
|
16
|
-
import {
|
|
17
|
-
import {
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
16
|
+
import { compressSync, strToU8 } from "fflate";
|
|
17
|
+
import {
|
|
18
|
+
brancheNameToRef,
|
|
19
|
+
cleanRefValue,
|
|
20
|
+
commitAtRefIn,
|
|
21
|
+
createHeadRefValue,
|
|
22
|
+
getLastRefPathElement,
|
|
23
|
+
headValueRefPrefix,
|
|
24
|
+
localHeadPathPrefix,
|
|
25
|
+
mapPath,
|
|
26
|
+
REFS_HEAD_KEY,
|
|
27
|
+
REFS_MAIN_KEY,
|
|
28
|
+
refsAtCommit,
|
|
29
|
+
shaishToCommit,
|
|
30
|
+
tagToRef,
|
|
31
|
+
treeToObject,
|
|
32
|
+
validateBranchName,
|
|
33
|
+
validateRef,
|
|
34
|
+
} from "./utils";
|
|
25
35
|
|
|
26
36
|
export interface RepositoryOptions<T extends { [k: string]: any }> {
|
|
27
37
|
history?: History;
|
|
@@ -196,7 +206,7 @@ export class Repository<T extends { [k: PropertyKey]: any }>
|
|
|
196
206
|
const refs = refsAtCommit(this.refs, commit);
|
|
197
207
|
// reset only moves heads and not tags
|
|
198
208
|
const moveableRefs = refs.filter((r) =>
|
|
199
|
-
r.name.startsWith(
|
|
209
|
+
r.name.startsWith(localHeadPathPrefix()),
|
|
200
210
|
);
|
|
201
211
|
|
|
202
212
|
for (const ref of moveableRefs) {
|
|
@@ -216,7 +226,7 @@ export class Repository<T extends { [k: PropertyKey]: any }>
|
|
|
216
226
|
|
|
217
227
|
if (currentHeadRef.value.includes(headValueRefPrefix)) {
|
|
218
228
|
const refName = cleanRefValue(currentHeadRef.value);
|
|
219
|
-
if (this.refs.has(refName)) return
|
|
229
|
+
if (this.refs.has(refName)) return getLastRefPathElement(refName);
|
|
220
230
|
}
|
|
221
231
|
|
|
222
232
|
return REFS_HEAD_KEY; // detached state
|
|
@@ -471,7 +481,7 @@ export class Repository<T extends { [k: PropertyKey]: any }>
|
|
|
471
481
|
const val =
|
|
472
482
|
typeof value === "string" ? createHeadRefValue(value) : value.hash;
|
|
473
483
|
if (!ref) {
|
|
474
|
-
ref = { name:
|
|
484
|
+
ref = { name: getLastRefPathElement(refName), value: val };
|
|
475
485
|
} else {
|
|
476
486
|
ref.value = val;
|
|
477
487
|
}
|
|
@@ -486,7 +496,7 @@ export class Repository<T extends { [k: PropertyKey]: any }>
|
|
|
486
496
|
throw new Error(`unreachable: HEAD not present`);
|
|
487
497
|
}
|
|
488
498
|
throw new Error(
|
|
489
|
-
`fatal: not a valid object name: '${
|
|
499
|
+
`fatal: not a valid object name: '${getLastRefPathElement(headRef)}'`,
|
|
490
500
|
);
|
|
491
501
|
}
|
|
492
502
|
this.refs.set(refKey, { name: name, value: headCommit.hash });
|
|
@@ -516,180 +526,3 @@ export class Repository<T extends { [k: PropertyKey]: any }>
|
|
|
516
526
|
return tagRef;
|
|
517
527
|
}
|
|
518
528
|
}
|
|
519
|
-
|
|
520
|
-
const treeToObject = <T = any>(tree: string): T => {
|
|
521
|
-
return JSON.parse(strFromU8(decompressSync(Buffer.from(tree, "base64"))));
|
|
522
|
-
};
|
|
523
|
-
|
|
524
|
-
const getLastItem = (thePath: string) =>
|
|
525
|
-
thePath.substring(thePath.lastIndexOf("/") + 1);
|
|
526
|
-
|
|
527
|
-
const mapPath = (
|
|
528
|
-
from: Commit,
|
|
529
|
-
to: Commit,
|
|
530
|
-
commits: Commit[],
|
|
531
|
-
): [isAncestor: boolean] => {
|
|
532
|
-
let c: Commit | undefined = to;
|
|
533
|
-
while (c !== undefined) {
|
|
534
|
-
c = commits.find((parent) => parent.hash === c?.parent);
|
|
535
|
-
if (c?.hash === from.hash) {
|
|
536
|
-
return [true];
|
|
537
|
-
}
|
|
538
|
-
}
|
|
539
|
-
return [false];
|
|
540
|
-
};
|
|
541
|
-
|
|
542
|
-
/**
|
|
543
|
-
* Returns the commit to which the provided ref is pointing
|
|
544
|
-
* @param ref - needs to be in key format, e.g. refs/heads/... or refs/tags/...
|
|
545
|
-
* @param references
|
|
546
|
-
* @param commitsList
|
|
547
|
-
*/
|
|
548
|
-
const commitAtRefIn = (
|
|
549
|
-
ref: string,
|
|
550
|
-
references: Map<string, Reference>,
|
|
551
|
-
commitsList: Commit[],
|
|
552
|
-
) => {
|
|
553
|
-
const reference = references.get(ref);
|
|
554
|
-
if (!reference) {
|
|
555
|
-
throw new Error(`unreachable: '${ref}' is not present`);
|
|
556
|
-
}
|
|
557
|
-
let commitHash;
|
|
558
|
-
if (reference.value.includes(headValueRefPrefix)) {
|
|
559
|
-
const refKey = cleanRefValue(reference.value);
|
|
560
|
-
const targetRef = references.get(refKey);
|
|
561
|
-
if (!targetRef) {
|
|
562
|
-
// target branch may not have been saved yet
|
|
563
|
-
return undefined;
|
|
564
|
-
}
|
|
565
|
-
commitHash = targetRef.value;
|
|
566
|
-
} else {
|
|
567
|
-
commitHash = reference.value;
|
|
568
|
-
}
|
|
569
|
-
for (const c of commitsList) {
|
|
570
|
-
if (c.hash === commitHash) {
|
|
571
|
-
return c;
|
|
572
|
-
}
|
|
573
|
-
}
|
|
574
|
-
return undefined;
|
|
575
|
-
};
|
|
576
|
-
|
|
577
|
-
const refsAtCommit = (references: Map<string, Reference>, commit: Commit) => {
|
|
578
|
-
const list: Array<Reference> = [];
|
|
579
|
-
for (const [name, ref] of references.entries()) {
|
|
580
|
-
if (ref.value === commit.hash) {
|
|
581
|
-
list.push(ref);
|
|
582
|
-
}
|
|
583
|
-
}
|
|
584
|
-
return list;
|
|
585
|
-
};
|
|
586
|
-
|
|
587
|
-
/**
|
|
588
|
-
* Accepts a shaish expression (e.g. refs (branches, tags), commitSha) and returns
|
|
589
|
-
* - a commit of type Commit
|
|
590
|
-
* - isRef boolean whether it is a direct reference
|
|
591
|
-
* - ref the key of the reference
|
|
592
|
-
*/
|
|
593
|
-
const shaishToCommit = (
|
|
594
|
-
shaish: string,
|
|
595
|
-
references: Map<string, Reference>,
|
|
596
|
-
commitsList: Commit[],
|
|
597
|
-
): [commit: Commit, isRef: boolean, ref: string | undefined] => {
|
|
598
|
-
let sha = shaish;
|
|
599
|
-
let isRef = false;
|
|
600
|
-
let refKey: string | undefined = undefined;
|
|
601
|
-
|
|
602
|
-
// check for refs
|
|
603
|
-
for (const [name, ref] of references.entries()) {
|
|
604
|
-
// match on
|
|
605
|
-
if (ref.name === shaish || name === shaish) {
|
|
606
|
-
isRef = true;
|
|
607
|
-
refKey = name;
|
|
608
|
-
sha = ref.value;
|
|
609
|
-
if (sha.includes(headValueRefPrefix)) {
|
|
610
|
-
const cleanedRef = cleanRefValue(sha);
|
|
611
|
-
const c = commitAtRefIn(cleanedRef, references, commitsList);
|
|
612
|
-
if (!c) {
|
|
613
|
-
throw new Error(`${cleanedRef} points to non-existing commit`);
|
|
614
|
-
}
|
|
615
|
-
return [c, isRef, refKey];
|
|
616
|
-
}
|
|
617
|
-
break;
|
|
618
|
-
}
|
|
619
|
-
}
|
|
620
|
-
// check for partial sha matches
|
|
621
|
-
const found = commitsList.filter((c) => c.hash.indexOf(sha) > -1);
|
|
622
|
-
if (found.length === 0) {
|
|
623
|
-
throw new Error(`pathspec '${shaish}' did not match any known refs`);
|
|
624
|
-
}
|
|
625
|
-
// but sha should be specific enough to resolve to 1 commit
|
|
626
|
-
if (found.length > 1) {
|
|
627
|
-
throw new Error(`commit `);
|
|
628
|
-
}
|
|
629
|
-
return [found[0], isRef, refKey];
|
|
630
|
-
};
|
|
631
|
-
|
|
632
|
-
export const createHeadRefValue = (refKey: string) => {
|
|
633
|
-
return `${headValueRefPrefix}${refKey}`;
|
|
634
|
-
};
|
|
635
|
-
|
|
636
|
-
export const isTagRef = (refKey: string) =>
|
|
637
|
-
refKey.indexOf(tagRefPathPrefix) > -1;
|
|
638
|
-
|
|
639
|
-
export const cleanRefValue = (ref: string) =>
|
|
640
|
-
ref.replace(headValueRefPrefix, "");
|
|
641
|
-
|
|
642
|
-
export const brancheNameToRef = (name: string) => {
|
|
643
|
-
return `${headsRefPathPrefix}${name}`;
|
|
644
|
-
};
|
|
645
|
-
|
|
646
|
-
export const tagToRef = (tag: string) => {
|
|
647
|
-
return `${tagRefPathPrefix}${tag}`;
|
|
648
|
-
};
|
|
649
|
-
|
|
650
|
-
export const validateBranchName = (name: string) => {
|
|
651
|
-
if (!validBranch(name)) {
|
|
652
|
-
throw new Error(`invalid ref name`);
|
|
653
|
-
}
|
|
654
|
-
};
|
|
655
|
-
|
|
656
|
-
export const validateRef = (name: string, oneLevel: boolean = true) => {
|
|
657
|
-
if (!validRef(name, oneLevel)) {
|
|
658
|
-
throw new Error(`invalid ref name`);
|
|
659
|
-
}
|
|
660
|
-
};
|
|
661
|
-
|
|
662
|
-
/**
|
|
663
|
-
* Prints the underlying changelog of a repository
|
|
664
|
-
* @param repository
|
|
665
|
-
*/
|
|
666
|
-
export const printChangeLog = <T extends { [k: string]: any }>(
|
|
667
|
-
repository: RepositoryObject<T>,
|
|
668
|
-
) => {
|
|
669
|
-
console.log("----------------------------------------------------------");
|
|
670
|
-
console.log("Changelog");
|
|
671
|
-
console.log("----------------------------------------------------------");
|
|
672
|
-
const history = repository.getHistory();
|
|
673
|
-
const head = commitAtRefIn(repository.head(), history.refs, history.commits);
|
|
674
|
-
if (!head) {
|
|
675
|
-
throw new Error(`fatal: HEAD is not defined`);
|
|
676
|
-
}
|
|
677
|
-
let c: Commit | undefined = head;
|
|
678
|
-
while (c) {
|
|
679
|
-
console.log(
|
|
680
|
-
`${c.hash} ${refsAtCommit(history.refs, c)
|
|
681
|
-
.map((r) => r.name)
|
|
682
|
-
.join(" ")}`,
|
|
683
|
-
);
|
|
684
|
-
for (const chg of c.changes) {
|
|
685
|
-
printChange(chg);
|
|
686
|
-
}
|
|
687
|
-
c = history.commits.find((parent) => parent.hash === c?.parent);
|
|
688
|
-
}
|
|
689
|
-
console.log("End of changelog");
|
|
690
|
-
console.log("----------------------------------------------------------");
|
|
691
|
-
};
|
|
692
|
-
|
|
693
|
-
export const printChange = (chg: Operation) => {
|
|
694
|
-
console.log(` ${JSON.stringify(chg)}`);
|
|
695
|
-
};
|
package/src/utils.ts
CHANGED
|
@@ -1,4 +1,11 @@
|
|
|
1
1
|
// [RFC5322](https://www.ietf.org/rfc/rfc5322.txt)
|
|
2
|
+
import { Commit } from "./commit";
|
|
3
|
+
import { Reference } from "./interfaces";
|
|
4
|
+
import { decompressSync, strFromU8 } from "fflate";
|
|
5
|
+
import { validBranch, validRef } from "./ref";
|
|
6
|
+
import { Operation } from "fast-json-patch";
|
|
7
|
+
import { RepositoryObject } from "./repository";
|
|
8
|
+
|
|
2
9
|
const emailRegex =
|
|
3
10
|
/(?:[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*|"(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21\x23-\x5b\x5d-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])*")@(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?|\[(?:(?:(2(5[0-5]|[0-4][0-9])|1[0-9][0-9]|[1-9]?[0-9]))\.){3}(?:(2(5[0-5]|[0-4][0-9])|1[0-9][0-9]|[1-9]?[0-9])|[a-z0-9-]*[a-z0-9]:(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21-\x5a\x53-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])+)\])/;
|
|
4
11
|
|
|
@@ -23,3 +30,190 @@ export const cleanAuthor = (author: string): [name: string, email: string] => {
|
|
|
23
30
|
// unrecognized format
|
|
24
31
|
return [author, ""];
|
|
25
32
|
};
|
|
33
|
+
|
|
34
|
+
export const localRefPrefix = `refs/`;
|
|
35
|
+
export const remoteRefPrefix = `refs/remotes/origin/`;
|
|
36
|
+
export const tagRefPathPrefix = "tags/";
|
|
37
|
+
export const headsRefPathPrefix = "heads/";
|
|
38
|
+
export const headValueRefPrefix = "ref: ";
|
|
39
|
+
export const localHeadPathPrefix = () =>
|
|
40
|
+
`${localRefPrefix}${headsRefPathPrefix}`;
|
|
41
|
+
export const remoteHeadPathPrefix = () =>
|
|
42
|
+
`${remoteRefPrefix}${headsRefPathPrefix}`;
|
|
43
|
+
export const localTagPathPrefix = () => `${localRefPrefix}${tagRefPathPrefix}`;
|
|
44
|
+
export const remoteTagPathPrefix = () =>
|
|
45
|
+
`${remoteRefPrefix}${tagRefPathPrefix}`;
|
|
46
|
+
export const REFS_HEAD_KEY = "HEAD";
|
|
47
|
+
/**
|
|
48
|
+
* Should only be used in local context
|
|
49
|
+
*/
|
|
50
|
+
export const REFS_MAIN_KEY = `${localHeadPathPrefix()}main`;
|
|
51
|
+
export const treeToObject = <T = any>(tree: string): T => {
|
|
52
|
+
return JSON.parse(strFromU8(decompressSync(Buffer.from(tree, "base64"))));
|
|
53
|
+
};
|
|
54
|
+
export const mapPath = (
|
|
55
|
+
from: Commit,
|
|
56
|
+
to: Commit,
|
|
57
|
+
commits: Commit[],
|
|
58
|
+
): [isAncestor: boolean] => {
|
|
59
|
+
let c: Commit | undefined = to;
|
|
60
|
+
while (c !== undefined) {
|
|
61
|
+
c = commits.find((parent) => parent.hash === c?.parent);
|
|
62
|
+
if (c?.hash === from.hash) {
|
|
63
|
+
return [true];
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
return [false];
|
|
67
|
+
};
|
|
68
|
+
/**
|
|
69
|
+
* Returns the commit to which the provided ref is pointing
|
|
70
|
+
* @param ref - needs to be in key format, e.g. refs/heads/... or refs/tags/...
|
|
71
|
+
* @param references
|
|
72
|
+
* @param commitsList
|
|
73
|
+
*/
|
|
74
|
+
export const commitAtRefIn = (
|
|
75
|
+
ref: string,
|
|
76
|
+
references: Map<string, Reference>,
|
|
77
|
+
commitsList: Commit[],
|
|
78
|
+
) => {
|
|
79
|
+
const reference = references.get(ref);
|
|
80
|
+
if (!reference) {
|
|
81
|
+
throw new Error(`unreachable: '${ref}' is not present`);
|
|
82
|
+
}
|
|
83
|
+
let commitHash;
|
|
84
|
+
if (reference.value.includes(headValueRefPrefix)) {
|
|
85
|
+
const refKey = cleanRefValue(reference.value);
|
|
86
|
+
const targetRef = references.get(refKey);
|
|
87
|
+
if (!targetRef) {
|
|
88
|
+
// target branch may not have been saved yet
|
|
89
|
+
return undefined;
|
|
90
|
+
}
|
|
91
|
+
commitHash = targetRef.value;
|
|
92
|
+
} else {
|
|
93
|
+
commitHash = reference.value;
|
|
94
|
+
}
|
|
95
|
+
for (const c of commitsList) {
|
|
96
|
+
if (c.hash === commitHash) {
|
|
97
|
+
return c;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
return undefined;
|
|
101
|
+
};
|
|
102
|
+
export const refsAtCommit = (
|
|
103
|
+
references: Map<string, Reference>,
|
|
104
|
+
commit: Commit,
|
|
105
|
+
) => {
|
|
106
|
+
const list: Array<Reference> = [];
|
|
107
|
+
for (const [name, ref] of references.entries()) {
|
|
108
|
+
if (ref.value === commit.hash) {
|
|
109
|
+
list.push(ref);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
return list;
|
|
113
|
+
};
|
|
114
|
+
/**
|
|
115
|
+
* Accepts a shaish expression (e.g. refs (branches, tags), commitSha) and returns
|
|
116
|
+
* - a commit of type Commit
|
|
117
|
+
* - isRef boolean whether it is a direct reference
|
|
118
|
+
* - ref the key of the reference
|
|
119
|
+
*/
|
|
120
|
+
export const shaishToCommit = (
|
|
121
|
+
shaish: string,
|
|
122
|
+
references: Map<string, Reference>,
|
|
123
|
+
commitsList: Commit[],
|
|
124
|
+
): [commit: Commit, isRef: boolean, ref: string | undefined] => {
|
|
125
|
+
let sha = shaish;
|
|
126
|
+
let isRef = false;
|
|
127
|
+
let refKey: string | undefined = undefined;
|
|
128
|
+
|
|
129
|
+
// check for refs
|
|
130
|
+
for (const [name, ref] of references.entries()) {
|
|
131
|
+
// match on
|
|
132
|
+
if (ref.name === shaish || name === shaish) {
|
|
133
|
+
isRef = true;
|
|
134
|
+
refKey = name;
|
|
135
|
+
sha = ref.value;
|
|
136
|
+
if (sha.includes(headValueRefPrefix)) {
|
|
137
|
+
const cleanedRef = cleanRefValue(sha);
|
|
138
|
+
const c = commitAtRefIn(cleanedRef, references, commitsList);
|
|
139
|
+
if (!c) {
|
|
140
|
+
throw new Error(`${cleanedRef} points to non-existing commit`);
|
|
141
|
+
}
|
|
142
|
+
return [c, isRef, refKey];
|
|
143
|
+
}
|
|
144
|
+
break;
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
// check for partial sha matches
|
|
148
|
+
const found = commitsList.filter((c) => c.hash.indexOf(sha) > -1);
|
|
149
|
+
if (found.length === 0) {
|
|
150
|
+
throw new Error(`pathspec '${shaish}' did not match any known refs`);
|
|
151
|
+
}
|
|
152
|
+
// but sha should be specific enough to resolve to 1 commit
|
|
153
|
+
if (found.length > 1) {
|
|
154
|
+
throw new Error(`commit `);
|
|
155
|
+
}
|
|
156
|
+
return [found[0], isRef, refKey];
|
|
157
|
+
};
|
|
158
|
+
export const createHeadRefValue = (refKey: string) => {
|
|
159
|
+
return `${headValueRefPrefix}${refKey}`;
|
|
160
|
+
};
|
|
161
|
+
export const isTagRef = (refKey: string) =>
|
|
162
|
+
refKey.indexOf(localTagPathPrefix()) > -1;
|
|
163
|
+
export const cleanRefValue = (ref: string) =>
|
|
164
|
+
ref.replace(headValueRefPrefix, "");
|
|
165
|
+
export const brancheNameToRef = (name: string) => {
|
|
166
|
+
return `${localHeadPathPrefix()}${name}`;
|
|
167
|
+
};
|
|
168
|
+
export const tagToRef = (tag: string) => {
|
|
169
|
+
return `${localTagPathPrefix()}${tag}`;
|
|
170
|
+
};
|
|
171
|
+
export const validateBranchName = (name: string) => {
|
|
172
|
+
if (!validBranch(name)) {
|
|
173
|
+
throw new Error(`invalid ref name`);
|
|
174
|
+
}
|
|
175
|
+
};
|
|
176
|
+
export const validateRef = (name: string, oneLevel: boolean = true) => {
|
|
177
|
+
if (!validRef(name, oneLevel)) {
|
|
178
|
+
throw new Error(`invalid ref name`);
|
|
179
|
+
}
|
|
180
|
+
};
|
|
181
|
+
/**
|
|
182
|
+
* Prints the underlying changelog of a repository
|
|
183
|
+
* @param repository
|
|
184
|
+
*/
|
|
185
|
+
export const printChangeLog = <T extends { [k: string]: any }>(
|
|
186
|
+
repository: RepositoryObject<T>,
|
|
187
|
+
) => {
|
|
188
|
+
console.log("----------------------------------------------------------");
|
|
189
|
+
console.log("Changelog");
|
|
190
|
+
console.log("----------------------------------------------------------");
|
|
191
|
+
const history = repository.getHistory();
|
|
192
|
+
const head = commitAtRefIn(repository.head(), history.refs, history.commits);
|
|
193
|
+
if (!head) {
|
|
194
|
+
throw new Error(`fatal: HEAD is not defined`);
|
|
195
|
+
}
|
|
196
|
+
let c: Commit | undefined = head;
|
|
197
|
+
while (c) {
|
|
198
|
+
console.log(
|
|
199
|
+
`${c.hash} ${refsAtCommit(history.refs, c)
|
|
200
|
+
.map((r) => r.name)
|
|
201
|
+
.join(" ")}`,
|
|
202
|
+
);
|
|
203
|
+
for (const chg of c.changes) {
|
|
204
|
+
printChange(chg);
|
|
205
|
+
}
|
|
206
|
+
c = history.commits.find((parent) => parent.hash === c?.parent);
|
|
207
|
+
}
|
|
208
|
+
console.log("End of changelog");
|
|
209
|
+
console.log("----------------------------------------------------------");
|
|
210
|
+
};
|
|
211
|
+
export const printChange = (chg: Operation) => {
|
|
212
|
+
console.log(` ${JSON.stringify(chg)}`);
|
|
213
|
+
};
|
|
214
|
+
/**
|
|
215
|
+
* Should be called with a `/` delimited ref path. E.g. refs/heads/main
|
|
216
|
+
* @param thePath
|
|
217
|
+
*/
|
|
218
|
+
export const getLastRefPathElement = (thePath: string) =>
|
|
219
|
+
thePath.substring(thePath.lastIndexOf("/") + 1);
|