mirror of
https://github.com/HeyPuter/puter.git
synced 2025-01-23 22:40:20 +08:00
docs(git): Document git client
This commit is contained in:
parent
622b6a9b92
commit
c0562d78a2
@ -1,3 +1,93 @@
|
||||
# Puter Git Client
|
||||
|
||||
This is a git client running on the Puter filesystem, using [isomorphic-git](https://isomorphic-git.org).
|
||||
This is a JavaScript in-browser git client running on the Puter filesystem, using [isomorphic-git](https://isomorphic-git.org).
|
||||
|
||||
It aims to match `git`'s interface, so that running a command behaves the same way as it would there.
|
||||
Of course, `git` has a large variety of subcommands and options, some of which are obscure, so many will be missing.
|
||||
Consider adding them if you are interested! :^)
|
||||
|
||||
While this is built for Puter, the only Puter-specific parts are:
|
||||
- `src/filesystem.js` which integrates with Puter's filesystem.
|
||||
- `src/main.js` which uses the Puter SDK to connect to the parent Phoenix shell.
|
||||
|
||||
By modifying these, and the values in `config/`, you should be able to port it to other environments.
|
||||
|
||||
## 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:
|
||||
|
||||
```js
|
||||
export default {
|
||||
// The subcommand's name
|
||||
name: 'help',
|
||||
// A string or array of strings, for how the subcommand is run. Shown in the help.
|
||||
usage: [
|
||||
'git help [-a|--all]',
|
||||
'git help <command>',
|
||||
],
|
||||
// A description, shown in the help.
|
||||
description: `Display help information for git itself, or a subcommand.`,
|
||||
// Arguments object, passed to `parseArgs()`
|
||||
args: {
|
||||
allowPositionals: true,
|
||||
options: {
|
||||
all: {
|
||||
// The one deviation from parseArgs() is that each option gets a description,
|
||||
// which is shown in the help output.
|
||||
description: 'List all available subcommands.',
|
||||
type: 'boolean',
|
||||
}
|
||||
},
|
||||
},
|
||||
// Function to actually run the subcommand.
|
||||
// The return value can be a posix-style exit code, or a plain `return` as a shorthand for 0.
|
||||
// Throwing errors is allowed.
|
||||
// Throwing the special `SHOW_USAGE` value defined in `src/help.js` can be used to print the command usage text.
|
||||
execute: async (ctx) => {
|
||||
// ctx has the following structure:
|
||||
ctx = {
|
||||
io: {
|
||||
stdout, // Function that takes a string, and prints it to stdout
|
||||
stderr, // Function that takes a string, and prints it to stderr
|
||||
},
|
||||
fs, // A filesystem implementation, for isomorphic-git
|
||||
args, // An object returned from `parseArgs()`.
|
||||
env, // Object containing environment variables, such as PWD for the current working directory.
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
These are them listed in `src/subcommands/__exports__.js`, which can be automatically generated by running `packages/phoenix/tools/gen.js packages/git/src/subcommands` from the Puter repo root. But it's not hard to modify manually.
|
||||
|
||||
## Common patterns
|
||||
|
||||
### Shared options
|
||||
|
||||
It's common in a few places that options are shared between commands, for example options related to formatting commits are shared by `git log` and `git show`.
|
||||
In these cases, those options are defined in an object in `src/format.js` with an accompanying function to process their results into a more convenient format.
|
||||
For example, `diff_formatting_options` and `process_diff_formatting_options(options)`:
|
||||
Some of the options are shorthands for others; some "imply" another; and some are set by default under certain conditions.
|
||||
All this is handled in one place instead of in each subcommand that needs them.
|
||||
|
||||
### Repo root
|
||||
|
||||
Since the `git` command may be run from a repository, a subdirectory, or a non-repository, you can locate the git directory like so:
|
||||
```js
|
||||
const { dir, gitdir } = await find_repo_root(fs, env.PWD);
|
||||
```
|
||||
The `dir` and `gitdir` variables can then be passed to isomorphic-git methods that expect them.
|
||||
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
|
||||
|
||||
The library we use for most interaction with git's files is [isomorphic-git](https://isomorphic-git.org).
|
||||
|
||||
It handles most of the basics, but because we want to do everything that [git](https://git-scm.com) does, a lot has to
|
||||
be implemented manually. For example, it has a `git.add()` method for adding files, but whereas `git add deleted_file`
|
||||
will stage that deletion, `git.add({ filepath: 'deleted_file', ... })` will complain that the file does not exist. So
|
||||
our implementation of `git add` manually iterates the changed files and either calls `git.add()` or `git.remove()` as
|
||||
appropriate.
|
||||
|
||||
### Troubleshooting tips:
|
||||
- File paths given to isomorphic-git need to be relative to the repo root. Absolute paths often silently do nothing!
|
||||
|
Loading…
Reference in New Issue
Block a user