From d077504f9bf1d8ffb71183eb0744531d92725ea7 Mon Sep 17 00:00:00 2001 From: Sam Atkins Date: Fri, 28 Jun 2024 09:58:48 +0100 Subject: [PATCH] doc(git): Expand documentation and add FIXMEs --- packages/git/README.md | 14 ++++++++++++++ packages/git/src/subcommands/add.js | 2 ++ packages/git/src/subcommands/branch.js | 2 ++ packages/git/src/subcommands/checkout.js | 3 +++ packages/git/src/subcommands/restore.js | 3 +++ 5 files changed, 24 insertions(+) diff --git a/packages/git/README.md b/packages/git/README.md index 15ec952ce..dc9af44ef 100644 --- a/packages/git/README.md +++ b/packages/git/README.md @@ -12,6 +12,12 @@ While this is built for Puter, the only Puter-specific parts are: By modifying these, and the values in `config/`, you should be able to port it to other environments. +## Libraries + +- [**chalk**](https://www.npmjs.com/package/chalk): For more convenient coloring and styling of output. +- [**diff**](https://www.npmjs.com/package/diff): For producing and applying diff patches. +- [**isomorphic-git**](https://isomorphic-git.org): For interacting with the git repository. See section below. + ## Subcommand structure The `git` CLI is structured as a series of sub-commands - `git branch` has nothing in common with `git version`, for example. Each of these is modelled as its own file in `src/subcommands`, and should export a default object with the following structure: @@ -79,6 +85,14 @@ The `dir` and `gitdir` variables can then be passed to isomorphic-git methods th If no repository is found, this will throw an error, which is then printed to stderr. (isomorphic-git's `git.findRoot()` does not implement checks for a `.git` text file that points to an alternative directory that git's metadata is stored in. We should maybe upstream this.) +### Parallel processing + +Filesystem access going over the network has a performance cost, so to try and counteract this, we try to +do things in parallel. There's a lot of use of `await Promise.all(...)` and `await Promise.allSettled()`. +Because isomorphic-git has its own caching, (using the `cache` object,) it's possible that this doesn't +actually help. Once performance becomes an issue, it'd be worth experimenting to see if running the same +commands in sequence is faster, especially where they access the same files. + ## Isomorphic-git The library we use for most interaction with git's files is [isomorphic-git](https://isomorphic-git.org). diff --git a/packages/git/src/subcommands/add.js b/packages/git/src/subcommands/add.js index 32155a33c..c2a278755 100644 --- a/packages/git/src/subcommands/add.js +++ b/packages/git/src/subcommands/add.js @@ -50,6 +50,8 @@ export default { filepaths: pathspecs, }); + // TODO: We should complain if one or more pathspecs don't match anything. + const operations = file_status .filter(([ filepath, head, worktree, staged ]) => worktree !== staged) .map(([ filepath, head, worktree, index ]) => { diff --git a/packages/git/src/subcommands/branch.js b/packages/git/src/subcommands/branch.js index a44abaa63..947e47f78 100644 --- a/packages/git/src/subcommands/branch.js +++ b/packages/git/src/subcommands/branch.js @@ -76,6 +76,8 @@ const BRANCH = { const { options, positionals, tokens } = args; const cache = {}; + // TODO: This manual processing is done because parseArgs() doesn't allow options to have only a short name. + // Replace it with a better args parsing library. for (const token of tokens) { if (token.kind !== 'option') continue; diff --git a/packages/git/src/subcommands/checkout.js b/packages/git/src/subcommands/checkout.js index 95d3b4e65..2433979bb 100644 --- a/packages/git/src/subcommands/checkout.js +++ b/packages/git/src/subcommands/checkout.js @@ -51,6 +51,8 @@ const CHECKOUT = { const { options, positionals, tokens } = args; const cache = {}; + // TODO: This manual processing is done because parseArgs() doesn't allow options to have only a short name. + // Replace it with a better args parsing library. for (const token of tokens) { if (token.kind !== 'option') continue; @@ -124,6 +126,7 @@ const CHECKOUT = { // Check out a branch or commit // TODO: Check out files. + // TODO: Checking out a branch name that exists in a remote but not locally, should create a new branch tracking that remote. { if (positionals.length === 0 || positionals.length > 1) { stderr('error: Expected 1 argument, for .'); diff --git a/packages/git/src/subcommands/restore.js b/packages/git/src/subcommands/restore.js index 686488c39..6090ec5d2 100644 --- a/packages/git/src/subcommands/restore.js +++ b/packages/git/src/subcommands/restore.js @@ -69,6 +69,8 @@ export default { const { dir, gitdir } = await find_repo_root(fs, env.PWD); + // TODO: We should complain if one or more pathspecs don't match anything. + const operations = await git.walk({ fs, dir, gitdir, cache, trees: [ @@ -86,6 +88,7 @@ export default { return null; } + // FIXME: Allow restoring ignored files that are tracked if (await git.isIgnored({ fs, dir, gitdir, filepath })) return null;