summaryrefslogtreecommitdiff
path: root/src/lib/git
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/git')
-rw-r--r--src/lib/git/log.ts162
1 files changed, 99 insertions, 63 deletions
diff --git a/src/lib/git/log.ts b/src/lib/git/log.ts
index bcf6888..4545f17 100644
--- a/src/lib/git/log.ts
+++ b/src/lib/git/log.ts
@@ -1,4 +1,4 @@
-import { defined } from "../../utils/anonymous.ts";
+import { defined, get } from "../../utils/anonymous.ts";
import { type MaybeIterable, surelyIterable } from "../../utils/iterator.ts";
import { gitDir } from "./index.ts";
import type { Commit, CommitFile } from "./types.ts";
@@ -23,72 +23,86 @@ export async function getLastCommitForOneOfFiles(
sources: MaybeIterable<URL>,
): Promise<Commit | undefined> {
const files = surelyIterable(sources);
- const gitLog = new Deno.Command("git", {
- args: [
- "log",
- "-1",
- `--pretty=format:${format.map((x) => `%${x}`).join("%n")}`,
- "--",
- // deno-lint-ignore no-undef
- ...Iterator.from(files).map((x) => x.pathname),
- ],
- });
+ const gitLogs = (await Promise.all(
+ Iterator.from(files).map(async ({ pathname }) => {
+ const gitLog = new Deno.Command("git", {
+ args: [
+ "log",
+ "--follow",
+ "-1",
+ `--pretty=format:${format.map((x) => `%${x}`).join("%n")}`,
+ "--",
+ pathname,
+ ],
+ });
+ const { stdout } = await gitLog.output();
+ const result = new TextDecoder().decode(stdout).trim();
- const { stdout } = await gitLog.output();
- const result = new TextDecoder().decode(stdout).trim();
+ if (result.length <= 0) {
+ return undefined;
+ }
- if (result.length <= 0) {
- return undefined;
- }
+ const [
+ hash,
+ abbrHash,
+ authorDate,
+ authorName,
+ authorEmail,
+ committerDate,
+ committerName,
+ committerEmail,
+ // signatureValidation,
+ signer,
+ key,
+ keyFingerPrint,
+ ...rawLines
+ ] = result.split("\n");
- const [
- hash,
- abbrHash,
- authorDate,
- authorName,
- authorEmail,
- committerDate,
- committerName,
- committerEmail,
- // signatureValidation,
- signer,
- key,
- keyFingerPrint,
- ...rawLines
- ] = result.split("\n");
-
- const raw = rawLines.join("\n").trim();
-
- const commit: Commit = {
- // deno-lint-ignore no-undef
- files: await fileStatusFromCommit(hash, Iterator.from(files)),
- hash: { long: hash, short: abbrHash },
- author: {
- date: new Date(authorDate),
- name: authorName,
- email: authorEmail,
- },
- committer: {
- date: new Date(committerDate),
- name: committerName,
- email: committerEmail,
- },
- };
-
- if (raw.length > 0) {
- commit.signature = {
- type: raw.startsWith("gpgsm:")
- ? "x509"
- : raw.startsWith("gpg:")
- ? "gpg"
- : "ssh",
- signer,
- key: { long: keyFingerPrint, short: key },
- rawMessage: raw,
- };
- }
+ const raw = rawLines.join("\n").trim();
+
+ const commit: Commit = {
+ // deno-lint-ignore no-undef
+ files: await fileStatusFromCommit(hash, Iterator.from(files)),
+ hash: { long: hash, short: abbrHash },
+ author: {
+ date: new Date(authorDate),
+ name: authorName,
+ email: authorEmail,
+ },
+ committer: {
+ date: new Date(committerDate),
+ name: committerName,
+ email: committerEmail,
+ },
+ };
+
+ if (raw.length > 0) {
+ commit.signature = {
+ type: raw.startsWith("gpgsm:")
+ ? "x509"
+ : raw.startsWith("gpg:")
+ ? "gpg"
+ : "ssh",
+ signer,
+ key: { long: keyFingerPrint, short: key },
+ rawMessage: raw,
+ };
+ }
+
+ return commit;
+ }),
+ )).filter(defined);
+
+ const last = gitLogs.sort(({ committer: a }, { committer: b }) =>
+ b.date.getTime() - a.date.getTime()
+ )?.[0];
+
+ if (last === undefined) return undefined;
- return commit;
+ const final = gitLogs.filter(({ hash }) => hash.long === last.hash.long);
+
+ last.files = final.flatMap(get("files"));
+ return last;
}
async function fileStatusFromCommit(
@@ -132,3 +146,25 @@ async function fileStatusFromCommit(
return undefined;
}).filter(defined);
}
+
+export async function fileCreationCommitDate(
+ file: URL,
+): Promise<Date | undefined> {
+ const gitDiffTree = new Deno.Command("git", {
+ args: [
+ "log",
+ "--follow",
+ "--diff-filter=A",
+ "--format=%cI",
+ "--",
+ file.pathname,
+ ],
+ });
+
+ const { stdout } = await gitDiffTree.output();
+ try {
+ return new Date(new TextDecoder().decode(stdout).trim());
+ } catch {
+ return undefined;
+ }
+}