A note-taking app inspired by nb
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

git: don't crash and burn when we're not in a Git repo

bitquabit.com 591529d9 f8256725

verified
+35
+35
git.ts
··· 1 1 import $ from "@david/dax"; 2 + import { existsSync } from "@std/fs/exists"; 2 3 import { join } from "@std/path"; 3 4 4 5 import { Notebook } from "./notebook.ts"; 5 6 7 + export function hasGit(notebook: Notebook): boolean { 8 + return existsSync(join(notebook.root, ".git"), { isDirectory: true }); 9 + } 10 + 11 + export async function hasRemote(notebook: Notebook): Promise<boolean> { 12 + if (!hasGit(notebook)) return false; 13 + const remotes = await $`git remote`.cwd(notebook.root).text(); 14 + return remotes.trim() !== ""; 15 + } 16 + 6 17 export async function commit(notebook: Notebook, message: string) { 18 + if (!hasGit(notebook)) return; 7 19 const changed = await $`git status --porcelain`.cwd(notebook.root).text(); 8 20 if (changed.trim() === "") return; 9 21 await $`git add .`.cwd(notebook.root); ··· 24 36 } 25 37 26 38 export async function syncNotebook(notebook: Notebook, force: boolean = false) { 39 + if (!hasGit(notebook)) return; 40 + 27 41 const root = notebook.root; 28 42 const status = await $`git status --porcelain`.cwd(root).text(); 29 43 if (status.trim() !== "") { 30 44 await commit(notebook, "Checkpointing untracked changes"); 31 45 } 46 + 47 + if (!await hasRemote(notebook)) return; 48 + 32 49 const last = lastSyncTime(notebook); 33 50 // FIXME(bmps): Make time configurable 34 51 if ( ··· 49 66 root: string, 50 67 relpath: string, 51 68 ): Promise<Temporal.Instant> { 69 + const fullPath = join(root, relpath); 70 + if (!existsSync(join(root, ".git"), { isDirectory: true })) { 71 + const stat = Deno.statSync(fullPath); 72 + return (stat.birthtime ?? stat.mtime ?? new Date()).toTemporalInstant(); 73 + } 52 74 const out = 53 75 (await $`git --no-pager log --reverse --date=iso-local --format="%aI" -- ${relpath}` 54 76 .cwd(root).env({ "TZ": "UTC" }).text()).split("\n")[0]; 77 + if (!out) { 78 + const stat = Deno.statSync(fullPath); 79 + return (stat.birthtime ?? stat.mtime ?? new Date()).toTemporalInstant(); 80 + } 55 81 return Temporal.Instant.from(out); 56 82 } 57 83 ··· 59 85 root: string, 60 86 relpath: string, 61 87 ): Promise<Temporal.Instant> { 88 + const fullPath = join(root, relpath); 89 + if (!existsSync(join(root, ".git"), { isDirectory: true })) { 90 + const stat = Deno.statSync(fullPath); 91 + return (stat.mtime ?? new Date()).toTemporalInstant(); 92 + } 62 93 const out = 63 94 (await $`git --no-pager log --date=iso-local --format="%aI" -- ${relpath}` 64 95 .cwd(root).env({ "TZ": "UTC" }).text()).split("\n")[0]; 96 + if (!out) { 97 + const stat = Deno.statSync(fullPath); 98 + return (stat.mtime ?? new Date()).toTemporalInstant(); 99 + } 65 100 return Temporal.Instant.from(out); 66 101 }