doc(git): Expand documentation and add FIXMEs

This commit is contained in:
Sam Atkins 2024-06-28 09:58:48 +01:00 committed by Eric Dubé
parent 711dbc0d2f
commit d077504f9b
5 changed files with 24 additions and 0 deletions

View File

@ -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. 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 ## 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: 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. 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.) (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 ## Isomorphic-git
The library we use for most interaction with git's files is [isomorphic-git](https://isomorphic-git.org). The library we use for most interaction with git's files is [isomorphic-git](https://isomorphic-git.org).

View File

@ -50,6 +50,8 @@ export default {
filepaths: pathspecs, filepaths: pathspecs,
}); });
// TODO: We should complain if one or more pathspecs don't match anything.
const operations = file_status const operations = file_status
.filter(([ filepath, head, worktree, staged ]) => worktree !== staged) .filter(([ filepath, head, worktree, staged ]) => worktree !== staged)
.map(([ filepath, head, worktree, index ]) => { .map(([ filepath, head, worktree, index ]) => {

View File

@ -76,6 +76,8 @@ const BRANCH = {
const { options, positionals, tokens } = args; const { options, positionals, tokens } = args;
const cache = {}; 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) { for (const token of tokens) {
if (token.kind !== 'option') continue; if (token.kind !== 'option') continue;

View File

@ -51,6 +51,8 @@ const CHECKOUT = {
const { options, positionals, tokens } = args; const { options, positionals, tokens } = args;
const cache = {}; 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) { for (const token of tokens) {
if (token.kind !== 'option') continue; if (token.kind !== 'option') continue;
@ -124,6 +126,7 @@ const CHECKOUT = {
// Check out a branch or commit // Check out a branch or commit
// TODO: Check out files. // 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) { if (positionals.length === 0 || positionals.length > 1) {
stderr('error: Expected 1 argument, for <branch>.'); stderr('error: Expected 1 argument, for <branch>.');

View File

@ -69,6 +69,8 @@ export default {
const { dir, gitdir } = await find_repo_root(fs, env.PWD); 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({ const operations = await git.walk({
fs, dir, gitdir, cache, fs, dir, gitdir, cache,
trees: [ trees: [
@ -86,6 +88,7 @@ export default {
return null; return null;
} }
// FIXME: Allow restoring ignored files that are tracked
if (await git.isIgnored({ fs, dir, gitdir, filepath })) if (await git.isIgnored({ fs, dir, gitdir, filepath }))
return null; return null;